diff --git a/.config/qutebrowser/autoconfig.yml b/.config/qutebrowser/autoconfig.yml index 7eff885..63c04fb 100755 --- a/.config/qutebrowser/autoconfig.yml +++ b/.config/qutebrowser/autoconfig.yml @@ -18,9 +18,15 @@ settings: normal: : tab-prev : spawn fish -c 'cd Downloads; ydl "{url}"' - : spawn mpv {url} + : spawn -u qute-keepass -p ~/.keepass + : spawn -d mpv {url} : close + : spawn --userscript readability : tab-close + sd: spawn -u open_download + passthrough: + exit: leave-mode + : null colors.completion.category.bg: global: '#222D32' colors.completion.category.border.bottom: diff --git a/.local/share/qutebrowser/userscripts/.gitignore b/.local/share/qutebrowser/userscripts/.gitignore new file mode 100644 index 0000000..21d086b --- /dev/null +++ b/.local/share/qutebrowser/userscripts/.gitignore @@ -0,0 +1 @@ +readability.html diff --git a/.local/share/qutebrowser/userscripts/open_download b/.local/share/qutebrowser/userscripts/open_download new file mode 100755 index 0000000..fe9ed12 --- /dev/null +++ b/.local/share/qutebrowser/userscripts/open_download @@ -0,0 +1,114 @@ +#!/usr/bin/env bash +# Both standalone script and qutebrowser userscript that opens a rofi menu with +# all files from the download directory and opens the selected file. It works +# both as a userscript and a standalone script that is called from outside of +# qutebrowser. +# +# Suggested keybinding (for "show downloads"): +# spawn --userscript ~/.config/qutebrowser/open_download +# sd +# +# Requirements: +# - rofi (in a recent version) +# - xdg-open and xdg-mime +# - You should configure qutebrowser to download files to a single directory +# - It comes in handy if you enable downloads.remove_finished. If you want to +# see the recent downloads, just press "sd". +# +# Thorsten Wißmann, 2015 (thorsten` on freenode) +# Any feedback is welcome! + +set -e + +# open a file from the download directory using rofi +DOWNLOAD_DIR=${DOWNLOAD_DIR:-$QUTE_DOWNLOAD_DIR} +DOWNLOAD_DIR=${DOWNLOAD_DIR:-$HOME/Downloads} +# the name of the rofi command +ROFI_CMD=${ROFI_CMD:-rofi} +ROFI_ARGS=${ROFI_ARGS:-} + +msg() { + local cmd="$1" + shift + local msg="$*" + if [ -z "$QUTE_FIFO" ] ; then + echo "$cmd: $msg" >&2 + else + echo "message-$cmd '${msg//\'/\\\'}'" >> "$QUTE_FIFO" + fi +} +die() { + msg error "$*" + if [ -n "$QUTE_FIFO" ] ; then + # when run as a userscript, the above error message already informs the + # user about the failure, and no additional "userscript exited with status + # 1" is needed. + exit 0; + else + exit 1; + fi +} + +if ! [ -d "$DOWNLOAD_DIR" ] ; then + die "Download directory »$DOWNLOAD_DIR« not found!" +fi +if ! command -v "${ROFI_CMD}" > /dev/null ; then + die "Rofi command »${ROFI_CMD}« not found in PATH!" +fi + +rofi_default_args=( + -monitor -2 # place above window + -location 6 # aligned at the bottom + -i + -no-custom + -format i # make rofi return the index + -l 10 + -p 'Open download' -dmenu + ) + +crop-first-column() { + local maxlength=${1:-40} + local expression='s|^\([^\t]\{0,'"$maxlength"'\}\)[^\t]*\t|\1\t|' + sed "$expression" +} + +ls-files() { + # add the slash at the end of the download dir enforces to follow the + # symlink, if the DOWNLOAD_DIR itself is a symlink + # shellcheck disable=SC2010 + ls -Q --quoting-style escape -h -o -1 -A -t "${DOWNLOAD_DIR}/" \ + | grep '^[-]' \ + | cut -d' ' -f3- \ + | sed 's,^\(.*[^\]\) \(.*\)$,\2\t\1,' \ + | sed 's,\\\(.\),\1,g' +} + +mapfile -t entries < <(ls-files) + +# we need to manually check that there are items, because rofi doesn't show up +# if there are no items and -no-custom is passed to rofi. +if [ "${#entries[@]}" -eq 0 ] ; then + die "Download directory »${DOWNLOAD_DIR}« empty" +fi + +line=$(printf '%s\n' "${entries[@]}" \ + | crop-first-column 55 \ + | column -s $'\t' -t \ + | $ROFI_CMD "${rofi_default_args[@]}" "$ROFI_ARGS") || true +if [ -z "$line" ]; then + exit 0 +fi + +file="${entries[$line]}" +file="${file%%$'\t'*}" +path="$DOWNLOAD_DIR/$file" +filetype=$(xdg-mime query filetype "$path") +application=$(xdg-mime query default "$filetype") + +if [ -z "$application" ] ; then + die "Do not know how to open »$file« of type $filetype" +fi + +msg info "Opening »$file« (of type $filetype) with ${application%.desktop}" + +xdg-open "$path" & diff --git a/.local/share/qutebrowser/userscripts/readability b/.local/share/qutebrowser/userscripts/readability new file mode 100755 index 0000000..f9cbbf8 --- /dev/null +++ b/.local/share/qutebrowser/userscripts/readability @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +# +# Executes python-readability on current page and opens the summary as new tab. +# +# Depends on the python-readability package, or its fork: +# +# - https://github.com/buriy/python-readability +# - https://github.com/bookieio/breadability +# +# Usage: +# :spawn --userscript readability +# +from __future__ import absolute_import +import codecs, os + +tmpfile = os.path.join( + os.environ.get('QUTE_DATA_DIR', + os.path.expanduser('~/.local/share/qutebrowser')), + 'userscripts/readability.html') + +if not os.path.exists(os.path.dirname(tmpfile)): + os.makedirs(os.path.dirname(tmpfile)) + +# Styling for dynamic window margin scaling and line height +HEADER = """ + + + + + %s + + + +""" + +with codecs.open(os.environ['QUTE_HTML'], 'r', 'utf-8') as source: + data = source.read() + + try: + from breadability.readable import Article as reader + doc = reader(data) + title = doc._original_document.title + content = HEADER % title + doc.readable + "" + except ImportError: + from readability import Document + doc = Document(data) + title = doc.title() + content = doc.summary().replace('', HEADER % title) + + with codecs.open(tmpfile, 'w', 'utf-8') as target: + target.write(content.lstrip()) + + with open(os.environ['QUTE_FIFO'], 'w') as fifo: + fifo.write('open -t %s' % tmpfile)