2021-01-06

Rofi Menu for the buku Bookmark Manager

Tags: linux . web . index

Buku is a command-line bookmark manager, that takes the bookmarks out of the browser. I have completely converted to it, since it allows bookmarks to work independently of the browser, and makes syncing between different machines very trivial.

I’m not going into the usage details here, since it is well documented by buku themselves.

To share the bookmarks between different machines, all that is needed is the copying of the database file, located at .local/share/buku/bookmarks.db.

There are various ways of invoking buku, including browser based add-ons. However, I prefer using it through a dmenu/rofi style menu.

An existing implementation is buku_run, which tries to offer most of the buku functionality, including adding/deleting entries.

However, I find that too complicated for my needs. Especially, since it’s very easy to make your own.

But, the problem was, none of the buku output formats were suitable for me.

One way is by using buku --format:

buku -p --format 5 \
    | tail -n +2 \
    | awk -F$'\t' '{ print $1"\t"$3"\t"$2 }' \
    | column -t -s $'\t'

Getting the output in JSON format is more consistent, however, you will then need to parse that, with some lengthy complication like this:

buku -p -j \
    | tail -n +2 \
    | jq -r '.[] | "\(.index)\t\(.tags)\t\(.title)"' \
    | column -t -s $'\t'

Turns out we also need tail -n +2 for both these cases, or a way to skip the first line, because when not run from a terminal, buku prints a message before the output.

So, in the end, I decided to “cheat” and access the database directly, since it’s standard SQLite anyway.

Following is my complete buku_menu:

#!/usr/bin/env bash

getbookmarks() {
    sqlite3 -column -separator $'\t' ~/.local/share/buku/bookmarks.db \
        "select id,trim(tags,','),metadata from bookmarks order by tags"
}

menu=$(getbookmarks | rofi -dmenu -i -width 1000 -p '> ')
id="${menu%% *}"

buku -o "${id}"

I am also sorting the bookmarks by tags, which is one of the advantages of this method, as we can extract and display the data however we want.