| Fixing YT blocking and browser setup. - dotfiles - These are my dotfiles. There… | |
| git clone git://jay.scot/dotfiles | |
| Log | |
| Files | |
| Refs | |
| README | |
| --- | |
| commit b8e22accd07e63bdd8c6c82136312268bb37f9b3 | |
| parent 7b3c1c38ea8f8bbe950e06903fbfa6a271b16252 | |
| Author: Jay Scott <[email protected]> | |
| Date: Wed, 6 Aug 2025 13:40:01 +0100 | |
| Fixing YT blocking and browser setup. | |
| Diffstat: | |
| M README | 4 ++-- | |
| M ashrc | 4 ++-- | |
| D bin/ytd | 73 -----------------------------… | |
| M bootstrap.sh | 2 +- | |
| M isync/mbsyncrc | 2 +- | |
| M mutt/muttrc | 7 +++++++ | |
| M newsraft/config | 3 +++ | |
| M newsraft/feeds | 36 ++++++++---------------------… | |
| M qutebrowser/config.py | 14 ++++++++++---- | |
| A qutebrowser/userscripts/password_f… | 388 +++++++++++++++++++++++++++… | |
| M sway/config | 3 ++- | |
| M waybar/config | 25 ++++++++++++++++++++++++- | |
| M waybar/style.css | 14 ++++++++++++-- | |
| A waybar/waybar_newsraft.sh | 11 +++++++++++ | |
| 14 files changed, 472 insertions(+), 114 deletions(-) | |
| --- | |
| diff --git a/README b/README | |
| @@ -17,9 +17,9 @@ my main desktop OS and are forever evolving. | |
| terminal : foot | |
| launcher : bemenu | |
| email : neomutt | |
| - browser : firefox / lynx | |
| + browser : librewolf / lynx | |
| media : kew / mpv | |
| - password mgmt : gopass | |
| + password mgmt : pass | |
| vpn : mullvad | |
| news : newsraft | |
| diff --git a/ashrc b/ashrc | |
| @@ -10,7 +10,7 @@ export PASSWORD_STORE_DIR="$XDG_CONFIG_HOME"/pass | |
| GPG_TTY=$(tty) | |
| export GPG_TTY | |
| export EDITOR="nvim" | |
| -export BROWSER="librewolf" | |
| +export BROWSER="qutebrowser" | |
| export PATH=$PATH:$HOME/bin | |
| # tools | |
| @@ -43,7 +43,7 @@ alias mutt='neomutt' | |
| alias mpv="mpv --autofit=30% --really-quiet --no-terminal" | |
| # vpn | |
| -alias von='doas wg-quick up se-sto-wg-011' | |
| +alias von='doas resolvconf -u && doas wg-quick up se-sto-wg-011' | |
| alias voff='doas wg-quick down se-sto-wg-011' | |
| alias vcheck='curl https://am.i.mullvad.net/connected' | |
| diff --git a/bin/ytd b/bin/ytd | |
| @@ -1,73 +0,0 @@ | |
| -#!/bin/sh | |
| - | |
| -# yt-dlp subscription fetcher | |
| -# jay <[email protected]> | |
| - | |
| -savepath="$HOME/media/youtube" | |
| -cachedir="$HOME/.cache/yt_dl" | |
| -yt="yt-dlp" | |
| -baseurl="https://www.youtube.com/playlist?list=" | |
| - | |
| -info() { | |
| - printf "\033[35mYT ➤\033[36m %s\033[0m\n" "$1" | |
| -} | |
| - | |
| -main() { | |
| - mkdir -p "${cachedir}" | |
| - mkdir -p "${savepath}" | |
| - | |
| - action="$1" | |
| - "$action" "steve1989mreinfo" "UU2I6Et1JkidnnbWgJFiMeHA" | |
| - "$action" "dave_snider" "UU7uO9V1Frl_wPd9d1qOm_RQ" | |
| - "$action" "bright_sun_films" "UU5k3Kc0avyDJ2nG9Kxm9JmQ" | |
| - "$action" "simon_wilson" "UUQCrKxBj5Id79syQEsY2Qxg" | |
| - "$action" "sidenote" "UURvWwMPr2SmSG7rXXzeEUdA" | |
| - "$action" "c90adventures" "UUVqpNG1R72i21jh-nAxEk4A" | |
| - "$action" "indigo_traveller" "UUXulruMI7BHj3kGyosNa0jA" | |
| - "$action" "pppeter" "UUnHEz9DZ6EAof1-DaQGD_Xw" | |
| - "$action" "abroad_in_japan" "UUHL9bfHTxCMi-7vfxQ-AYtg" | |
| - "$action" "serpentza" "UUl7mAGnY4jh4Ps8rhhh8XZg" | |
| - "$action" "noel_phillips" "UU2O6HDtMOZf9FkUAepz9Atg" | |
| - "$action" "the_lazy_peon" "UUE-f0sqi-H7kuLT0YiW9rcA" | |
| - "$action" "zav_alsop" "UUcjx6m03fZwtRBFn1Cf7kKQ" | |
| - "$action" "steve_marsh" "UUBhQuxcHU3aydk_zTXcbdTg" | |
| - "$action" "planes_trains_everything" "UUcKw8Eg0FfRvhIAnC0cPGAA" | |
| - "$action" "we_hate_the_cold" "UULmltEyJ0zBsKnL8bWSdn3A" | |
| - "$action" "christopher_collects" "UUv8Po8UR9OfhPhPCLjz1d8Q" | |
| - "$action" "astonishing_glasgow" "UUIDIqg7LhjLFCyD2awY_38g" | |
| - "$action" "mike_okay" "UUpp3cHR9TWVyXqL1AVw4XkA" | |
| - "$action" "all_the_gear" "UUSwl4SnA68L8iDfj5gBf-yA" | |
| - "$action" "rhykker" "UURl31PWkfF0a3j3hiDRaCGA" | |
| - "$action" "brodie_robertson" "UUld68syR8Wi-GY_n4CaoJGA" | |
| - "$action" "distrotube" "UUVls1GmFKf6WlTraIb_IaJg" | |
| - "$action" "linux_cast" "UUylGUf9BvQooEFjgdNudoQg" | |
| -} | |
| - | |
| -get_video() { | |
| - info "Fetching latest from $1" | |
| - mkdir -p "${savepath}/${1}" | |
| - | |
| - "$yt" -q --restrict-filename \ | |
| - --download-archive "${cachedir}/${1}" \ | |
| - "${baseurl}${2}" \ | |
| - -o "${savepath}/${1}/%(playlist_index)s_%(title)s.%(ext)s" \ | |
| - --cookies ~/tmp/cookies.txt | |
| -} | |
| - | |
| -catchup() { | |
| - info "Catching up on $1" | |
| - "$yt" --flat-playlist --get-id \ | |
| - "${baseurl}${2}" | sed 's/.*/youtube &/' >"${cachedir}/${1}" | |
| -} | |
| - | |
| -case "$1" in | |
| --m) | |
| - main catchup | |
| - ;; | |
| --n) | |
| - catchup "$2" "$3" | |
| - ;; | |
| -*) | |
| - main get_video | |
| - ;; | |
| -esac | |
| diff --git a/bootstrap.sh b/bootstrap.sh | |
| @@ -4,7 +4,7 @@ DOTFILES=$(pwd) | |
| FILES='ashrc profile' | |
| ROOT='bin' | |
| -CONFIG='foot git isync lynx mutt newsraft nvim sway waybar' | |
| +CONFIG='foot git isync lynx mutt newsraft nvim qutebrowser sway waybar' | |
| link() { | |
| for f in $FILES; do ln -sfn "$DOTFILES/$f" "$HOME/.$f"; done | |
| diff --git a/isync/mbsyncrc b/isync/mbsyncrc | |
| @@ -7,7 +7,7 @@ SyncState * | |
| IMAPAccount jay | |
| Host imap.mailbox.org | |
| User [email protected] | |
| -PassCmd "gopass show -o tech/mailbox.org" | |
| +PassCmd "pass show tech/smtp.mailbox.org" | |
| TLSType IMAPS | |
| IMAPStore jay-remote | |
| diff --git a/mutt/muttrc b/mutt/muttrc | |
| @@ -3,6 +3,8 @@ source ~/.config/mutt/gruvbox | |
| # info | |
| set realname = 'Jay Scott' | |
| set from = '[email protected]' | |
| +set my_user = '[email protected]' | |
| +set my_pass = "`pass tech/smtp.mailbox.org`" | |
| # general | |
| set envelope_from = yes | |
| @@ -48,6 +50,11 @@ set record = "+jay/Sent" | |
| # inbox | |
| mailboxes ! `echo ~/.mail/jay/*` | |
| +# SMTP settings | |
| +set smtp_pass = $my_pass | |
| +set smtp_url = smtps://[email protected] | |
| +set ssl_force_tls = yes | |
| + | |
| # aliases | |
| set alias_file = ~/.config/mutt/aliases | |
| set sort_alias = alias | |
| diff --git a/newsraft/config b/newsraft/config | |
| @@ -5,3 +5,6 @@ feeds-menu-paramount-explore true | |
| # key bindings | |
| bind f exec "~/bin/link-handler %l" | |
| + | |
| +# appearance | |
| +status-placeholder | |
| diff --git a/newsraft/feeds b/newsraft/feeds | |
| @@ -21,30 +21,12 @@ https://www.jeffgeerling.com/blog.xml "Jeff Geerling" | |
| @ GAMING | |
| https://www.gamingonlinux.com/article_rss.php "Gaming On Linux" | |
| -#@ YOUTUBE | |
| -#https://www.youtube.com/feeds/videos.xml?channel_id=UC2I6Et1JkidnnbWgJFiMeHA … | |
| -#https://www.youtube.com/feeds/videos.xml?channel_id=UC7uO9V1Frl_wPd9d1qOm_RQ … | |
| -#https://www.youtube.com/feeds/videos.xml?channel_id=UC5k3Kc0avyDJ2nG9Kxm9JmQ … | |
| -#https://www.youtube.com/feeds/videos.xml?channel_id=UCQCrKxBj5Id79syQEsY2Qxg … | |
| -#https://www.youtube.com/feeds/videos.xml?channel_id=UCRvWwMPr2SmSG7rXXzeEUdA … | |
| -#https://www.youtube.com/feeds/videos.xml?channel_id=UCVqpNG1R72i21jh-nAxEk4A … | |
| -#https://www.youtube.com/feeds/videos.xml?channel_id=UCXulruMI7BHj3kGyosNa0jA … | |
| -#https://www.youtube.com/feeds/videos.xml?channel_id=UCnHEz9DZ6EAof1-DaQGD_Xw … | |
| -#https://www.youtube.com/feeds/videos.xml?channel_id=UCHL9bfHTxCMi-7vfxQ-AYtg … | |
| -#https://www.youtube.com/feeds/videos.xml?channel_id=UCl7mAGnY4jh4Ps8rhhh8XZg … | |
| -#https://www.youtube.com/feeds/videos.xml?channel_id=UC2O6HDtMOZf9FkUAepz9Atg … | |
| -#https://www.youtube.com/feeds/videos.xml?channel_id=UCE-f0sqi-H7kuLT0YiW9rcA … | |
| -#https://www.youtube.com/feeds/videos.xml?channel_id=UCcjx6m03fZwtRBFn1Cf7kKQ … | |
| -#https://www.youtube.com/feeds/videos.xml?channel_id=UCBhQuxcHU3aydk_zTXcbdTg … | |
| -#https://www.youtube.com/feeds/videos.xml?channel_id=UCcKw8Eg0FfRvhIAnC0cPGAA … | |
| -#https://www.youtube.com/feeds/videos.xml?channel_id=UCLmltEyJ0zBsKnL8bWSdn3A … | |
| -#https://www.youtube.com/feeds/videos.xml?channel_id=UCv8Po8UR9OfhPhPCLjz1d8Q … | |
| -#https://www.youtube.com/feeds/videos.xml?channel_id=UCIDIqg7LhjLFCyD2awY_38g … | |
| -#https://www.youtube.com/feeds/videos.xml?channel_id=UC7sGXeJOixPBgJ3r5R55JYg … | |
| -#https://www.youtube.com/feeds/videos.xml?channel_id=UCpp3cHR9TWVyXqL1AVw4XkA … | |
| -#https://www.youtube.com/feeds/videos.xml?channel_id=UCSwl4SnA68L8iDfj5gBf-yA … | |
| -#https://www.youtube.com/feeds/videos.xml?channel_id=UCRl31PWkfF0a3j3hiDRaCGA … | |
| -#https://www.youtube.com/feeds/videos.xml?channel_id=UCsxidPdmPXDlsS3rn7arJsA … | |
| -#https://www.youtube.com/feeds/videos.xml?channel_id=UCld68syR8Wi-GY_n4CaoJGA … | |
| -#https://www.youtube.com/feeds/videos.xml?channel_id=UCVls1GmFKf6WlTraIb_IaJg … | |
| -#https://www.youtube.com/feeds/videos.xml?channel_id=UCylGUf9BvQooEFjgdNudoQg … | |
| +@ ODYSEE | |
| +https://odysee.com/$/rss/@AlphaNerd:8 "Mental Outlaw" | |
| +https://odysee.com/$/rss/@DistroTube:2 "DistroTube" | |
| +https://odysee.com/$/rss/@techlore:3 "TechLore" | |
| +https://odysee.com/$/rss/@NaomiBrockwell:4 "Naomi Brockwell" | |
| +https://odysee.com/$/rss/@BrodieRobertson:5 "Brodie Robertson" | |
| +https://odysee.com/$/rss/@davidbombal:0 "David Bombal" | |
| +https://odysee.com/$/rss/@thelinuxcast:4 "The Linux Cast" | |
| +https://odysee.com/$/rss/@GreatScott:a "Great Scott" | |
| diff --git a/qutebrowser/config.py b/qutebrowser/config.py | |
| @@ -31,8 +31,13 @@ c.tabs.favicons.show = "never" | |
| # hints | |
| c.colors.hints.bg = "rgb(207,186,88)" #cfba58 | |
| c.colors.hints.fg = "rgb(34, 34, 34)" #222222 | |
| -c.colors.webpage.darkmode.enabled = False | |
| -c.colors.webpage.darkmode.algorithm = "lightness-hsl" | |
| + | |
| +# darkmode | |
| +c.colors.webpage.darkmode.enabled = True | |
| +#c.colors.webpage.darkmode.algorithm = "lightness-hsl" | |
| +c.colors.webpage.darkmode.algorithm = 'lightness-cielab' | |
| +c.colors.webpage.darkmode.policy.images = 'never' | |
| +config.set('colors.webpage.darkmode.enabled', False, 'file://*') | |
| # misc | |
| c.fonts.hints = "10pt Hack" | |
| @@ -42,6 +47,7 @@ c.hints.uppercase = True | |
| c.scrolling.smooth = True | |
| c.editor.command = ["alacritty", "vim '{}'"] | |
| c.auto_save.session = True | |
| +c.zoom.default = "140%" | |
| # ad-block | |
| c.content.blocking.enabled = True | |
| @@ -74,14 +80,14 @@ c.content.autoplay = False # no autoplay on <video> tags | |
| c.content.headers.accept_language = "en-US,en;q=0.5" | |
| c.content.headers.user_agent = "Mozilla/5.0 (X11; Linux i686; rv:109.0) Gecko/… | |
| c.content.headers.custom = {"accept": "text/html,application/xhtml+xml,applica… | |
| -c.content.headers.referer = "same-domain" | |
| +c.content.headers.referer = "never" | |
| c.content.cookies.accept = "no-3rdparty" | |
| c.content.javascript.enabled = False # disable tracking etc | |
| c.content.canvas_reading = False # canvas blocking | |
| c.content.geolocation = False # location ident | |
| c.content.webrtc_ip_handling_policy = "disable-non-proxied-udp" | |
| c.content.hyperlink_auditing = False # disable pingbacks | |
| -c.content.dns_prefetch = False # disable pre-fetching | |
| +c.content.dns_prefetch = False # disable dns pre-fetching | |
| # search engine shortneners | |
| c.url.searchengines = { | |
| diff --git a/qutebrowser/userscripts/password_fill b/qutebrowser/userscripts/pa… | |
| @@ -0,0 +1,388 @@ | |
| +#!/usr/bin/env bash | |
| +help() { | |
| + blink=$'\e[1;31m' reset=$'\e[0m' | |
| +cat <<EOF | |
| +This script can only be used as a userscript for qutebrowser | |
| +2015, Thorsten Wißmann <edu _at_ thorsten-wissmann _dot_ de> | |
| +In case of questions or suggestions, do not hesitate to send me an E-Mail or to | |
| +directly ask me via IRC (nickname thorsten\`) in #qutebrowser on Libera Chat. | |
| + | |
| + $blink!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$reset | |
| + WARNING: the passwords are stored in qutebrowser's | |
| + debug log reachable via the url qute://log | |
| + $blink!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!$reset | |
| + | |
| +Usage: run as a userscript form qutebrowser, e.g.: | |
| + spawn --userscript ~/.config/qutebrowser/password_fill | |
| + | |
| +Pass backend: (see also passwordstore.org) | |
| + This script expects pass to store the credentials of each page in an extra | |
| + file, where the filename (or filepath) contains the domain of the respective | |
| + page. The first line of the file must contain the password, the login name | |
| + must be contained in a later line beginning with "user:", "login:", or | |
| + "username:" (configurable by the user_pattern variable). | |
| + | |
| +Behavior: | |
| + It will try to find a username/password entry in the configured backend | |
| + (currently only pass) for the current website and will load that pair of | |
| + username and password to any form on the current page that has some password | |
| + entry field. If multiple entries are found, a zenity menu is offered. | |
| + | |
| + If no entry is found, then it crops subdomains from the url if at least one | |
| + entry is found in the backend. (In that case, it always shows a menu) | |
| + | |
| +Configuration: | |
| + This script loads the bash script ~/.config/qutebrowser/password_fill_rc (if | |
| + it exists), so you can change any configuration variable and overwrite any | |
| + function you like. | |
| + | |
| +EOF | |
| +} | |
| + | |
| +set -o errexit | |
| +set -o pipefail | |
| +shopt -s nocasematch # make regexp matching in bash case insensitive | |
| + | |
| +if [ -z "$QUTE_FIFO" ] ; then | |
| + help | |
| + exit | |
| +fi | |
| + | |
| +error() { | |
| + local msg="$*" | |
| + echo "message-error '${msg//\'/\\\'}'" >> "$QUTE_FIFO" | |
| +} | |
| +msg() { | |
| + local msg="$*" | |
| + echo "message-info '${msg//\'/\\\'}'" >> "$QUTE_FIFO" | |
| +} | |
| +die() { | |
| + error "$*" | |
| + exit 0 | |
| +} | |
| + | |
| +javascript_escape() { | |
| + # print the first argument in an escaped way, such that it can safely | |
| + # be used within javascripts double quotes | |
| + # shellcheck disable=SC2001 | |
| + sed "s,[\\\\'\"],\\\\&,g" <<< "$1" | |
| +} | |
| + | |
| +# ======================================================= # | |
| +# CONFIGURATION | |
| +# ======================================================= # | |
| +# The configuration file is per default located in | |
| +# ~/.config/qutebrowser/password_fill_rc and is a bash script that is loaded | |
| +# later in the present script. So basically you can replace all of the | |
| +# following definitions and make them fit your needs. | |
| + | |
| +# The following simplifies a URL to the domain (e.g. "wiki.qutebrowser.org") | |
| +# which is later used to search the correct entries in the password backend. If | |
| +# you e.g. don't want the "www." to be removed or if you want to distinguish | |
| +# between different paths on the same domain. | |
| + | |
| +simplify_url() { | |
| + simple_url="${1##*://}" # remove protocol specification | |
| + simple_url="${simple_url%%\?*}" # remove GET parameters | |
| + simple_url="${simple_url%%/*}" # remove directory path | |
| + simple_url="${simple_url%:*}" # remove port | |
| + simple_url="${simple_url##www.}" # remove www. subdomain | |
| +} | |
| + | |
| +# no_entries_found() is called if the first query_entries() call did not find | |
| +# any matching entries. Multiple implementations are possible: | |
| +# The easiest behavior is to quit: | |
| +#no_entries_found() { | |
| +# if [ 0 -eq "${#files[@]}" ] ; then | |
| +# die "No entry found for »$simple_url«" | |
| +# fi | |
| +#} | |
| +# But you could also fill the files array with all entries from your pass db | |
| +# if the first db query did not find anything | |
| +# no_entries_found() { | |
| +# if [ 0 -eq "${#files[@]}" ] ; then | |
| +# query_entries "" | |
| +# if [ 0 -eq "${#files[@]}" ] ; then | |
| +# die "No entry found for »$simple_url«" | |
| +# fi | |
| +# fi | |
| +# } | |
| + | |
| +# Another behavior is to drop another level of subdomains until search hits | |
| +# are found: | |
| +no_entries_found() { | |
| + while [ 0 -eq "${#files[@]}" ] && [ -n "$simple_url" ]; do | |
| + # shellcheck disable=SC2001 | |
| + shorter_simple_url=$(sed 's,^[^.]*\.,,' <<< "$simple_url") | |
| + if [ "$shorter_simple_url" = "$simple_url" ] ; then | |
| + # if no dot, then even remove the top level domain | |
| + simple_url="" | |
| + query_entries "$simple_url" | |
| + break | |
| + fi | |
| + simple_url="$shorter_simple_url" | |
| + query_entries "$simple_url" | |
| + #die "No entry found for »$simple_url«" | |
| + # enforce menu if we do "fuzzy" matching | |
| + menu_if_one_entry=1 | |
| + done | |
| + if [ 0 -eq "${#files[@]}" ] ; then | |
| + die "No entry found for »$simple_url«" | |
| + fi | |
| +} | |
| + | |
| +# Backend implementations tell, how the actual password store is accessed. | |
| +# Right now, there is only one fully functional password backend, namely for | |
| +# the program "pass". | |
| +# A password backend consists of three actions: | |
| +# - init() initializes backend-specific things and does sanity checks. | |
| +# - query_entries() is called with a simplified url and is expected to fill | |
| +# the bash array $files with the names of matching password entries. There | |
| +# are no requirements how these names should look like. | |
| +# - open_entry() is called with some specific entry of the $files array and is | |
| +# expected to write the username of that entry to the $username variable and | |
| +# the corresponding password to $password | |
| + | |
| +# shellcheck disable=SC2329 | |
| +reset_backend() { | |
| + init() { true ; } | |
| + query_entries() { true ; } | |
| + open_entry() { true ; } | |
| +} | |
| + | |
| +# choose_entry() is expected to choose one entry from the array $files and | |
| +# write it to the variable $file. | |
| +choose_entry() { | |
| + choose_entry_zenity | |
| +} | |
| + | |
| +# The default implementation chooses a random entry from the array. So if there | |
| +# are multiple matching entries, multiple calls to this userscript will | |
| +# eventually pick the "correct" entry. I.e. if this userscript is bound to | |
| +# "zl", the user has to press "zl" until the correct username shows up in the | |
| +# login form. | |
| +choose_entry_random() { | |
| + local nr=${#files[@]} | |
| + file="${files[$((RANDOM % nr))]}" | |
| + # Warn user, that there might be other matching password entries | |
| + if [ "$nr" -gt 1 ] ; then | |
| + msg "Picked $file out of $nr entries: ${files[*]}" | |
| + fi | |
| +} | |
| + | |
| +# another implementation would be to ask the user via some menu (like rofi or | |
| +# dmenu or zenity or even qutebrowser completion in future?) which entry to | |
| +# pick | |
| +MENU_COMMAND=( head -n 1 ) | |
| +# whether to show the menu if there is only one entry in it | |
| +menu_if_one_entry=0 | |
| +choose_entry_menu() { | |
| + local nr=${#files[@]} | |
| + if [ "$nr" -eq 1 ] && ! ((menu_if_one_entry)) ; then | |
| + file="${files[0]}" | |
| + else | |
| + file=$( printf '%s\n' "${files[@]}" | "${MENU_COMMAND[@]}" ) | |
| + fi | |
| +} | |
| + | |
| +choose_entry_rofi() { | |
| + MENU_COMMAND=( rofi -p "qutebrowser> " -dmenu | |
| + -mesg $'Pick a password entry for <b>'"${QUTE_URL//&/&… | |
| + choose_entry_menu || true | |
| +} | |
| + | |
| +choose_entry_zenity() { | |
| + MENU_COMMAND=( zenity --list --title "qutebrowser password fill" | |
| + --text "Pick the password entry:" | |
| + --column "Name" ) | |
| + choose_entry_menu || true | |
| +} | |
| + | |
| +choose_entry_zenity_radio() { | |
| + # shellcheck disable=SC2329 | |
| + zenity_helper() { | |
| + awk '{ print $0 ; print $0 }' \ | |
| + | zenity --list --radiolist \ | |
| + --title "qutebrowser password fill" \ | |
| + --text "Pick the password entry:" \ | |
| + --column " " --column "Name" | |
| + } | |
| + MENU_COMMAND=( zenity_helper ) | |
| + choose_entry_menu || true | |
| +} | |
| + | |
| +# ======================================================= | |
| +# backend: PASS | |
| + | |
| +# configuration options: | |
| +match_filename=1 # whether allowing entry match by filepath | |
| +match_line=0 # whether allowing entry match by URL-Pattern in file | |
| + # Note: match_line=1 gets very slow, even for small password … | |
| +match_line_pattern='^url: .*' # applied using grep -iE | |
| +user_pattern='^(user|username|login): ' | |
| + | |
| +GPG_OPTS=( "--quiet" "--yes" "--compress-algo=none" "--no-encrypt-to" ) | |
| +GPG="gpg" | |
| +export GPG_TTY="${GPG_TTY:-$(tty 2>/dev/null)}" | |
| +command -v gpg2 &>/dev/null && GPG="gpg2" | |
| +[[ -n $GPG_AGENT_INFO || $GPG == "gpg2" ]] && GPG_OPTS+=( "--batch" "--use-age… | |
| + | |
| +pass_backend() { | |
| + init() { | |
| + PREFIX="${PASSWORD_STORE_DIR:-$HOME/.password-store}" | |
| + if ! [ -d "$PREFIX" ] ; then | |
| + die "Can not open password store dir »$PREFIX«" | |
| + fi | |
| + } | |
| + query_entries() { | |
| + local url="$1" | |
| + | |
| + if ((match_line)) ; then | |
| + # add entries with matching URL-tag | |
| + while read -r -d "" passfile ; do | |
| + if $GPG "${GPG_OPTS[@]}" -d "$passfile" \ | |
| + | grep --max-count=1 -iE "${match_line_pattern}${url}" > … | |
| + then | |
| + passfile="${passfile#"$PREFIX"}" | |
| + passfile="${passfile#/}" | |
| + files+=( "${passfile%.gpg}" ) | |
| + fi | |
| + done < <(find -L "$PREFIX" -iname '*.gpg' -print0) | |
| + fi | |
| + if ((match_filename)) ; then | |
| + # add entries with matching filepath | |
| + while read -r passfile ; do | |
| + passfile="${passfile#"$PREFIX"}" | |
| + passfile="${passfile#/}" | |
| + files+=( "${passfile%.gpg}" ) | |
| + done < <(find -L "$PREFIX" -iname '*.gpg' | grep "$url") | |
| + fi | |
| + } | |
| + open_entry() { | |
| + local path="$PREFIX/${1}.gpg" | |
| + password="" | |
| + local firstline=1 | |
| + while read -r line ; do | |
| + if ((firstline)) ; then | |
| + password="$line" | |
| + firstline=0 | |
| + else | |
| + if [[ $line =~ $user_pattern ]] ; then | |
| + # remove the matching prefix "user: " from the beginning o… | |
| + username=${line#"${BASH_REMATCH[0]}"} | |
| + break | |
| + fi | |
| + fi | |
| + done < <($GPG "${GPG_OPTS[@]}" -d "$path" | awk 1 ) | |
| + } | |
| +} | |
| +# ======================================================= | |
| + | |
| +# ======================================================= | |
| +# backend: secret | |
| +# shellcheck disable=SC2329 | |
| +secret_backend() { | |
| + init() { | |
| + return | |
| + } | |
| + query_entries() { | |
| + local domain="$1" | |
| + while read -r line ; do | |
| + if [[ "$line" == "attribute.username = "* ]] ; then | |
| + files+=("$domain ${line:21}") | |
| + fi | |
| + done < <( secret-tool search --unlock --all domain "$domain" 2>&1 ) | |
| + } | |
| + open_entry() { | |
| + local domain="${1%% *}" | |
| + username="${1#* }" | |
| + password=$(secret-tool lookup domain "$domain" username "$username") | |
| + } | |
| +} | |
| +# ======================================================= | |
| + | |
| +# load some sane default backend | |
| +reset_backend | |
| +pass_backend | |
| +# load configuration | |
| +QUTE_CONFIG_DIR=${QUTE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/qutebrows… | |
| +PWFILL_CONFIG=${PWFILL_CONFIG:-${QUTE_CONFIG_DIR}/password_fill_rc} | |
| +if [ -f "$PWFILL_CONFIG" ] ; then | |
| + # shellcheck source=/dev/null | |
| + source "$PWFILL_CONFIG" | |
| +fi | |
| +init | |
| + | |
| +simplify_url "$QUTE_URL" | |
| +query_entries "${simple_url}" | |
| +no_entries_found | |
| +# remove duplicates | |
| +mapfile -t files < <(printf '%s\n' "${files[@]}" | sort | uniq ) | |
| +choose_entry | |
| +if [ -z "$file" ] ; then | |
| + # choose_entry didn't want any of these entries | |
| + exit 0 | |
| +fi | |
| +open_entry "$file" | |
| +#username="$(date)" | |
| +#password="XYZ" | |
| +#msg "$username, ${#password}" | |
| + | |
| +[ -n "$username" ] || die "Username not set in entry $file" | |
| +[ -n "$password" ] || die "Password not set in entry $file" | |
| + | |
| +js() { | |
| +cat <<EOF | |
| + function isVisible(elem) { | |
| + var style = elem.ownerDocument.defaultView.getComputedStyle(elem, null… | |
| + | |
| + if (style.getPropertyValue("visibility") !== "visible" || | |
| + style.getPropertyValue("display") === "none" || | |
| + style.getPropertyValue("opacity") === "0") { | |
| + return false; | |
| + } | |
| + | |
| + return elem.offsetWidth > 0 && elem.offsetHeight > 0; | |
| + }; | |
| + function hasPasswordField(form) { | |
| + var inputs = form.getElementsByTagName("input"); | |
| + for (var j = 0; j < inputs.length; j++) { | |
| + var input = inputs[j]; | |
| + if (input.type == "password") { | |
| + return true; | |
| + } | |
| + } | |
| + return false; | |
| + }; | |
| + function loadData2Form (form) { | |
| + var inputs = form.getElementsByTagName("input"); | |
| + for (var j = 0; j < inputs.length; j++) { | |
| + var input = inputs[j]; | |
| + if (isVisible(input) && (input.type == "text" || input.type == "em… | |
| + input.focus(); | |
| + input.value = "$(javascript_escape "${username}")"; | |
| + input.dispatchEvent(new Event('change')); | |
| + input.blur(); | |
| + } | |
| + if (input.type == "password") { | |
| + input.focus(); | |
| + input.value = "$(javascript_escape "${password}")"; | |
| + input.dispatchEvent(new Event('change')); | |
| + input.blur(); | |
| + } | |
| + } | |
| + }; | |
| + | |
| + var forms = document.getElementsByTagName("form"); | |
| + for (i = 0; i < forms.length; i++) { | |
| + if (hasPasswordField(forms[i])) { | |
| + loadData2Form(forms[i]); | |
| + } | |
| + } | |
| +EOF | |
| +} | |
| + | |
| +printjs() { | |
| + js | sed 's,//.*$,,' | tr '\n' ' ' | |
| +} | |
| +echo "jseval -q $(printjs)" >> "$QUTE_FIFO" | |
| diff --git a/sway/config b/sway/config | |
| @@ -18,6 +18,7 @@ font pango: Hack:style=Regular 2 | |
| # application assignment | |
| #for_window [app_id="mpv"] floating enable, sticky enable, resize set 560 280,… | |
| assign [app_id="librewolf"] 2 | |
| +assign [app_id="qutebrowser"] 2 | |
| # misc | |
| xwayland enable | |
| @@ -49,7 +50,7 @@ focus output DP-1 | |
| # keybinds | |
| bindsym $mod+Space exec footclient | |
| bindsym $mod+p exec $menu | |
| -bindsym $mod+f exec librewolf | |
| +bindsym $mod+f exec qutebrowser | |
| bindsym $mod+m exec /home/jay/bin/music | |
| bindsym $mod+s exec flatpak run com.heroicgameslauncher.hgl | |
| diff --git a/waybar/config b/waybar/config | |
| @@ -15,6 +15,8 @@ | |
| ], | |
| "modules-right": [ | |
| + "custom/newsraft", | |
| + "custom/mail", | |
| "pulseaudio", | |
| "tray", | |
| "clock" | |
| @@ -54,7 +56,28 @@ | |
| "exec": "$HOME/.config/waybar/waybar_vpn.sh" | |
| }, | |
| + "custom/mail": { | |
| + "format": "{icon}", | |
| + "format-icons": { | |
| + "default": ["🖂"] | |
| + }, | |
| + "return-type": "json", | |
| + "interval": 60, | |
| + "exec": "$HOME/.config/waybar/waybar_mail.sh" | |
| + }, | |
| + | |
| + "custom/newsraft": { | |
| + "format": "{icon}", | |
| + "format-icons": { | |
| + "default": ["💩"] | |
| + }, | |
| + "return-type": "json", | |
| + "interval": 60, | |
| + "exec": "$HOME/.config/waybar/waybar_newsraft.sh" | |
| + }, | |
| + | |
| "tray": { | |
| - "icon-size": 12 | |
| + "icon-size": 16, | |
| + "spacing": 10 | |
| } | |
| } | |
| diff --git a/waybar/style.css b/waybar/style.css | |
| @@ -1,5 +1,5 @@ | |
| * { | |
| - font-size: 12px; | |
| + font-size: 16px; | |
| font-family: Hack; | |
| } | |
| @@ -25,8 +25,18 @@ window#waybar { | |
| color: #d22635; | |
| } | |
| +#custom-mail.new { | |
| + color: #268bd2; | |
| +} | |
| + | |
| +#custom-newsraft.new { | |
| + color: #268bd2; | |
| +} | |
| + | |
| #clock, | |
| #custom-vpn, | |
| +#custom-mail, | |
| +#custom-newsraft, | |
| #pulseaudio { | |
| - padding: 0 3px; | |
| + padding: 0 5px; | |
| } | |
| diff --git a/waybar/waybar_newsraft.sh b/waybar/waybar_newsraft.sh | |
| @@ -0,0 +1,11 @@ | |
| +#!/bin/sh | |
| + | |
| +new="$(newsraft -e print-unread-items-count)" | |
| + | |
| +if [ $new -gt 0 ] | |
| +then | |
| + echo "{\"text\":\"$new\",\"tooltip\":\"$new articles\",\"class\":\"new… | |
| +else | |
| + echo '{"text":"No new articles","tooltip":"","class":""}' | |
| +fi | |
| + |