Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/mbuczko/linkify

DIY pinboard
https://github.com/mbuczko/linkify

links rust

Last synced: 15 days ago
JSON representation

DIY pinboard

Awesome Lists containing this project

README

        

* Make your own Pinboard

Linkify is a CLI tool and HTTP server in one binary, which lets you store links in local database (SQLite powered) and query for results either from command-line or with fancy browser extension. A simple user/password (or alternatively - api-token) authorization makes it ideal match for multiple browser profiles - one can categorize links between personal and work accounts or even make certain links common (shared) across defined profiles.

No additional database installation required. Linkify works straight out of the box.

#+begin_src
linkify 0.2.1
Saves your precious links into local vault

USAGE:
linkify [OPTIONS] [SUBCOMMAND]

FLAGS:
-h, --help Prints help information
-V, --version Prints version information

OPTIONS:
-k, --apikey user's API key [env: LINKIFY_API_KEY]
-b, --db database to use [env: LINKIFY_DB_PATH]
-p, --password user's password [env: LINKIFY_PASSWORD]
-u, --user user's login [env: LINKIFY_USER]

SUBCOMMANDS:
add Adds a new link
del Deletes already stored link
help Prints this message or the help of the given subcommand(s)
import Imports links from JSON file
ls Lists matching links
server Runs a server
users Manages with users
#+end_src

** command-line

Linkify in CLI mode works pretty much like a git command - exposes a few subcommands to deal with links (obviously), authorization and adds few helpers on top, like importing links from json file.

To store a link a database location needs to be specified first. Linkify opens one, given by =--db= parameter, or creates it if database at given location does not exist yet. Following command creates a database and adds initial user (foobar):

#+begin_src
linkify users add foobar --db /usr/local/var/linkify/default.db
#+end_src

Having a database and user created adding a link comes down to:

#+begin_src
linkify add --db /usr/local/var/linkify/default.db --user foobar -n "My social stuff" -t social,reddit http://reddit.com
#+end_src

A word of explanation about attributes attached to the link:

- _name_ (=-n= or =--name= flag) - required human readable link name (a title)
- optional _description_ (=-d= or =--description=) - additional chunk of text describing what the link is about
- optional _tags_ (=-t= or =--tags=) - a comma-separated list of keywords to make link easier to find

Tags together with name and description provide quite a powerful way to locate link in database so it's worth to spend a few seconds to think them over a bit.

All the examples above specify =--db= and =--user= every time, which might be frustrating in practice, it's highly recommended to move this information into environmental variables:

#+begin_src shell
export LINKIFY_DB_PATH=/usr/local/var/linkify/default.db
export LINKIFY_USER=foobar
export LINKIFY_PASSWORD=secret
#+end_src

That can be simplified (secured?) even further by providing API key instead of user/password pair, but more on this later.

Let's see links stored so far:

#+begin_src shell
$ linkify ls

http://reddit.com | My social stuff
#+end_src

Storing the same URL with different name or tags simply overrides existing data:

#+begin_src shell
$ linkify add -n "Time waster" http://reddit.com
$ linkify ls

http://reddit.com | Time waster
#+end_src

*** Tags

At some point searching by name might be not enough and having tons of links in db without any kind of categorization sooner or later turns entire database into a mess. To avoid this situation, please welcome tags. Tags are those helpful little labels (optionally) assigned to stored link, which can be used later in a query to trace given link back.

Tags in a query are classified as _optional_, _+required_ and _-excluded_ which allows to form the query even more concrete. Say, we have a bunch of links tagged with "rust", "programming" and "doc" keywords. Searching by "rust,programming" tags:

#+begin_src
linkify ls "tags:rust,programming"
#+end_src

returns all results which are tagged EITHER with "rust" OR "programming". This is in fact how "optional" tags work - link is returned if it has AT LEAST one optional tag attached. But this way we also get in result links tagged with "rust,doc" or "programming,doc" since they all have either "programming" or "rust" tag attached. Not interested in documentation? Let's modify query by introducing _excluded_ tag:

#+begin_src
linkify ls "tags:rust,programming,-doc"
#+end_src

All the "doc" tagged results should disappear immediately. And yes, same for _required_ tags. Once enforced, only links containing ALL of required tags will be returned, eg:

#+begin_src
linkify ls "tags:rust,programming,+doc"
#+end_src

returns all the links having "rust" OR "programming" tag AND required "doc" one.

*** Flags

Apart from =tags=, linkify handles few =flags=:
- =toread= : matches all the links marked as "read later".
- =favourite= : matches all the links marked as "favourite".
- =shared= : matches all the links marked as "shared". Shared links are visible for all the users.

Sample query: =tags:rust flags:toread async tokio=

*** Saved searches

_Saved search_ is one step further towards simplicity. The idea behind is straightforward - instead of remembering the query every time, let's store it under some name and use that name instead.

_Note - saved search can be created only with browser plugin for now._

Going back to the previous example. Having =tags:rust,programming,-doc= query stored as "rust", one may simplify command line to the following:

#+begin_src
linkify ls @rust
#+end_src

but it's even better than that. Want to still narrow result to links having "async" string in URL or name?

#+begin_src
linkify ls @rust/async
#+end_src

*** Importing

Linkify imports everything you wish, provided as following json:

#+begin_src json
[{
"href": "https://developer.airly.eu/docs",
"name": "Airly for Developers",
"description": "Making air quality information available for all",
"shared": true,
"toread": false,
"tags": [
"api"
]
},
{
"href": "https://registry.hub.docker.com/",
"name": "Docker Hub Registry - Repositories of Docker Images",
"shared": true,
"toread": false,
"tags": [
"docker"
]
}]
#+end_src

Have Pinboard account?

You can import your Pinboard links straight into linkify in 3 simple steps:
- export your Pinboard links into some pinboard_export.json file (Settings » backup » JSON)
- do =jq= magic to adjust json to required format:

#+begin_src
jq '[.[] | .["name"] = .description | .["description"] = .extended | del(.extended)] | map(.tags |= split(" "))|map(.shared |= test("yes"))|map(.toread |= test("yes"))' pinboard_export.json > linkify.json
#+end_src

- import linkify.json:

#+begin_src
linkify import linkify.json
#+end_src

*** Integration with fzf

Use [[https://github.com/junegunn/fzf][fzf]] to search links like a pro :)

#+begin_src shell
linkify ls | fzf -e -0 --print0
#+end_src

Have a [[https://fishshell.com/][fish]] shell? Bind the command to single key press:

#+begin_src shell
bind \ch 'begin; set url (linkify ls|fzf -e -0 --print0); if string length -q -- $url; open (echo $url | cut -d "|" -f1 | awk \'{$1=$1};1\'); end; end'
#+end_src

Now, =control-h= invokes linkify which pipes collected links directly to fzf. Selection is automagically opened in default browser via =open= command (available on Mac).

[[https://github.com/mbuczko/linkify/blob/master/doc/fzf.png]]

** HTTP server

Most of the links are usually collected with web browser and this is where linkify comes onto scene with its second nature - HTTP sever and accompanying browser extension (chrome/brave for now). This delicious combo lets you store/modify/remove links instantaneously without leaving the browser:

[[https://github.com/mbuczko/linkify/blob/master/doc/dialog.png]]

As mentioned, this combination requires linkify server set up. Sample command may looks like this:

#+begin_src shell
linkify server --db /usr/local/var/linkify/default.db
#+end_src

To get some more information what's actually going on when the server starts up, change =LOG_LEVEL= environmental variable to =debug=:

#+begin_src shell
LOG_LEVEL=debug linkify server --db /usr/local/var/linkify/default.db
#+end_src

Having server up and running next step is to generate an access token so the server would know what user the extension impersonates:

#+begin_src shell
linkify users token --db /usr/local/var/linkify/default.db
#+end_src

Generated token may be also used as a replacement for user/pass pair for linkify run in CLI:

#+begin_src shell
export LINKIFY_API_KEY=
#+end_src

Last missing part is extension itself. While it's not available yet in a store it needs to be installed directly from a package (in developer mode):

[[https://github.com/mbuczko/linkify/blob/master/extensions/linkify.crx]]

Having extension added it should be possible from now on to add or remove links from database (look at the pin icon) and compose queries with =control-\= command (be sure to reload page after extension installation).

[[https://github.com/mbuczko/linkify/blob/master/doc/query.png]]

Also, as extension comes with own search engine (activated in address bar by =ly= followed by space), the query can be placed like this:

[[https://github.com/mbuczko/linkify/blob/master/doc/omnibox.png]]

* Installation
** Homebrew
#+begin_src
brew tap mbuczko/linkify
brew install linkify
#+end_src

and follow the information how to set up a local server. It will be required to have a chrome extension working.

** From sources
#+begin_src
https://github.com/mbuczko/linkify.git
cd linkify
cargo install --locked --root /usr/local/
#+end_src

No cargo installed? [[https://doc.rust-lang.org/cargo/getting-started/installation.html][Installation Guide]].

* Licence

Eclipse Public License - v 2.0

Pin icon by Amit Jakhu (http://demo.amitjakhu.com/dripicons/)