this repo has no description

.qutebrowser: update 1password script, config

+241 -88
+21 -1
private_dot_qutebrowser/config.py
··· 18 18 # c.fonts.tabs.unselected = "bold default_size default_family" 19 19 # c.fonts.completion.category = "bold default_size default_family" 20 20 # c.fonts.completion.entry = "bold default_size default_family" 21 - c.window.hide_decoration = False 21 + c.window.hide_decoration = True 22 22 c.colors.webpage.darkmode.enabled = False 23 23 c.editor.command = ["/usr/local/bin/zed", "--wait", "{file}:{line}:{column0}"] 24 + c.url.start_pages = ["about:blank"] 25 + c.scrolling.smooth = True 26 + c.statusbar.show = "always" 27 + c.url.default_page = "https://kagi.com" 24 28 c.url.start_pages = ["about:blank"] 25 29 26 30 # All keybindings organized by mode ··· 44 48 "<Alt-d>": "fake-key <Ctrl-Delete>", 45 49 "<Alt-Backspace>": "fake-key <Ctrl-Backspace>", 46 50 "<Ctrl-y>": "insert-text {primary}", 51 + "<Ctrl-x><Ctrl-e>": "edit-text", 47 52 }, 48 53 "normal": { 49 54 # Navigation 50 55 "\\ff": "cmd-set-text -s :tab-select", 56 + "gt": "tab-next", 57 + "gT": "tab-prev", 58 + "\\nh": "search", 51 59 "<Ctrl-o>": "back", 52 60 "<Ctrl-i>": "forward", 61 + "<Ctrl-[>": "back", 62 + "<Ctrl-]>": "forward", 53 63 # Tab position toggle 54 64 "\\tt": "config-cycle tabs.position left top", 55 65 # Overlay killer ··· 69 79 "cmd-later 10s set content.javascript.clipboard none", 70 80 ] 71 81 ), 82 + "\\<Ctrl-f>": "spawn --userscript qute-1pass", 83 + "\\\\": "clear-messages", 84 + "\\<Ctrl-c>": "hint code userscript code_select.py", 85 + "\\<Ctrl-x><Ctrl-e>": "edit-text", 72 86 }, 73 87 "command": { 74 88 "<Ctrl+e>": "edit-command", 75 89 }, 76 90 } 77 91 92 + 93 + c.hints.selectors["code"] = [ 94 + # Selects all code tags whose direct parent is not a pre tag 95 + ":not(pre) > code", 96 + "pre", 97 + ] 78 98 # Domain-specific clipboard settings 79 99 for pattern in [ 80 100 r"*://github.com",
-87
private_dot_qutebrowser/userscripts/executable_1password.sh
··· 1 - #!/usr/bin/env bash 2 - 3 - set -e 4 - 5 - # JS field injection code from https://github.com/qutebrowser/qutebrowser/blob/master/misc/userscripts/password_fill 6 - javascript_escape() { 7 - # print the first argument in an escaped way, such that it can safely 8 - # be used within javascripts double quotes 9 - # shellcheck disable=SC2001 10 - sed "s,[\\\\'\"],\\\\&,g" <<<"$1" 11 - } 12 - 13 - js() { 14 - cat <<EOF 15 - function isVisible(elem) { 16 - var style = elem.ownerDocument.defaultView.getComputedStyle(elem, null); 17 - if (style.getPropertyValue("visibility") !== "visible" || 18 - style.getPropertyValue("display") === "none" || 19 - style.getPropertyValue("opacity") === "0") { 20 - return false; 21 - } 22 - return elem.offsetWidth > 0 && elem.offsetHeight > 0; 23 - }; 24 - function hasPasswordField(form) { 25 - var inputs = form.getElementsByTagName("input"); 26 - for (var j = 0; j < inputs.length; j++) { 27 - var input = inputs[j]; 28 - if (input.type == "password") { 29 - return true; 30 - } 31 - } 32 - return false; 33 - }; 34 - function loadData2Form (form) { 35 - var inputs = form.getElementsByTagName("input"); 36 - for (var j = 0; j < inputs.length; j++) { 37 - var input = inputs[j]; 38 - if (isVisible(input) && (input.type == "text" || input.type == "email")) { 39 - input.focus(); 40 - input.value = "$(javascript_escape "${USERNAME}")"; 41 - input.dispatchEvent(new Event('change')); 42 - input.blur(); 43 - } 44 - if (input.type == "password") { 45 - input.focus(); 46 - input.value = "$(javascript_escape "${PASSWORD}")"; 47 - input.dispatchEvent(new Event('change')); 48 - input.blur(); 49 - } 50 - } 51 - }; 52 - var forms = document.getElementsByTagName("form"); 53 - for (i = 0; i < forms.length; i++) { 54 - if (hasPasswordField(forms[i])) { 55 - loadData2Form(forms[i]); 56 - } 57 - } 58 - EOF 59 - } 60 - 61 - URL=$(echo "$QUTE_URL" | awk -F/ '{print $3}' | sed 's/www.//g') 62 - echo "message-info 'Looking for password for $URL...'" >>$QUTE_FIFO 63 - 64 - UUID_URL=$(op item list --format=json | jq -r '.[] | "\(.id):\(.urls[]?.href)" ' | grep "$URL") || $(echo "message-error 'No entry found for $URL'" >>$QUTE_FIFO) 65 - 66 - IFS=: read -r UUID var2 <<<"$UUID_URL" 67 - ITEM=$(op item get --reveal --format=json "$UUID") 68 - 69 - PASSWORD=$(echo "$ITEM" | jq -r '.fields[]? | select(.purpose=="PASSWORD") | .value') 70 - 71 - if [ -n "$PASSWORD" ]; then 72 - TITLE=$(echo "$ITEM" | jq -r '.title') 73 - USERNAME=$(echo "$ITEM" | jq -r '.fields[]? | select(.purpose=="USERNAME") | .value') 74 - 75 - printjs() { 76 - js | sed 's,//.*$,,' | tr '\n' ' ' 77 - } 78 - echo "jseval -q $(printjs)" >>"$QUTE_FIFO" 79 - 80 - # TOTP=$(echo "$ITEM" | op get totp --session="$TOKEN" "$UUID") 81 - # if [ -n "$TOTP" ]; then 82 - # echo "$TOTP" | pbcopy 83 - # echo "One time password for $TITLE: $TOTP in clipboard" | terminal-notifier -title "Qutebrowser 1Password" -sound default 84 - # fi 85 - else 86 - echo "No password found for $URL" | terminal-notifier -title "Qutebrowser 1Password" -sound default 87 - fi
+64
private_dot_qutebrowser/userscripts/executable_code_select.py
··· 1 + #!/usr/bin/env python3 2 + 3 + import os 4 + import html 5 + import re 6 + import sys 7 + import xml.etree.ElementTree as ET 8 + try: 9 + import pyperclip 10 + except ImportError: 11 + try: 12 + import pyclip as pyperclip 13 + except ImportError: 14 + PYPERCLIP = False 15 + else: 16 + PYPERCLIP = True 17 + else: 18 + PYPERCLIP = True 19 + 20 + 21 + def parse_text_content(element): 22 + # https://stackoverflow.com/a/35591507/15245191 23 + magic = '''<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 24 + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" [ 25 + <!ENTITY nbsp ' '> 26 + ]>''' 27 + root = ET.fromstring(magic + element) 28 + text = ET.tostring(root, encoding="unicode", method="text") 29 + text = html.unescape(text) 30 + return text 31 + 32 + 33 + def send_command_to_qute(command): 34 + with open(os.environ.get("QUTE_FIFO"), "w") as f: 35 + f.write(command) 36 + 37 + 38 + def main(): 39 + delimiter = sys.argv[1] if len(sys.argv) > 1 else ";" 40 + # For info on qute environment vairables, see 41 + # https://github.com/qutebrowser/qutebrowser/blob/master/doc/userscripts.asciidoc 42 + element = os.environ.get("QUTE_SELECTED_HTML") 43 + code_text = parse_text_content(element) 44 + re_remove_dollars = re.compile(r"^(\$ )", re.MULTILINE) 45 + code_text = re.sub(re_remove_dollars, '', code_text) 46 + if PYPERCLIP: 47 + pyperclip.copy(code_text) 48 + send_command_to_qute( 49 + "message-info 'copied to clipboard: {info}{suffix}'".format( 50 + info=code_text.splitlines()[0].replace("'", "\""), 51 + suffix="..." if len(code_text.splitlines()) > 1 else "" 52 + ) 53 + ) 54 + else: 55 + # Qute's yank command won't copy accross multiple lines so we 56 + # compromise by placing lines on a single line seperated by the 57 + # specified delimiter 58 + code_text = re.sub("(\n)+", delimiter, code_text) 59 + code_text = code_text.replace("'", "\"") 60 + send_command_to_qute("yank inline '{code}'\n".format(code=code_text)) 61 + 62 + 63 + if __name__ == "__main__": 64 + main()
+156
private_dot_qutebrowser/userscripts/executable_qute-1pass
··· 1 + #!/usr/bin/env bash 2 + 3 + # Temporary script awaiting merge of https://github.com/qutebrowser/qutebrowser/pull/7469 4 + 5 + set +e 6 + 7 + # JS field injection code from https://github.com/qutebrowser/qutebrowser/blob/master/misc/userscripts/password_fill 8 + javascript_escape() { 9 + # print the first argument in an escaped way, such that it can safely 10 + # be used within javascripts double quotes 11 + # shellcheck disable=SC2001 12 + sed "s,[\\\\'\"\/],\\\\&,g" <<<"$1" 13 + } 14 + 15 + js() { 16 + cat <<EOF 17 + function isVisible(elem) { 18 + var style = elem.ownerDocument.defaultView.getComputedStyle(elem, null); 19 + if (style.getPropertyValue("visibility") !== "visible" || 20 + style.getPropertyValue("display") === "none" || 21 + style.getPropertyValue("opacity") === "0") { 22 + return false; 23 + } 24 + return elem.offsetWidth > 0 && elem.offsetHeight > 0; 25 + }; 26 + function hasPasswordField(form) { 27 + var inputs = form.getElementsByTagName("input"); 28 + for (var j = 0; j < inputs.length; j++) { 29 + var input = inputs[j]; 30 + if (input.type == "password") { 31 + return true; 32 + } 33 + } 34 + return false; 35 + }; 36 + function loadData2Form (form) { 37 + var inputs = form.getElementsByTagName("input"); 38 + for (var j = 0; j < inputs.length; j++) { 39 + var input = inputs[j]; 40 + if (isVisible(input) && (input.type == "text" || input.type == "email")) { 41 + input.focus(); 42 + input.value = "$(javascript_escape "${USERNAME}")"; 43 + input.dispatchEvent(new Event('change')); 44 + input.blur(); 45 + } 46 + if (input.type == "password") { 47 + input.focus(); 48 + input.value = "$(javascript_escape "${PASSWORD}")"; 49 + input.dispatchEvent(new Event('change')); 50 + input.blur(); 51 + } 52 + } 53 + }; 54 + var forms = document.getElementsByTagName("form"); 55 + for (i = 0; i < forms.length; i++) { 56 + if (hasPasswordField(forms[i])) { 57 + loadData2Form(forms[i]); 58 + } 59 + } 60 + EOF 61 + } 62 + 63 + URL=$(echo "$QUTE_URL" | awk -F/ '{print $3}' | sed 's/www.//g') 64 + 65 + dmenu-prompt() { 66 + local PROMPT="$1" 67 + choose -p "$PROMPT" 68 + } 69 + 70 + clipboard-copy() { 71 + pbcopy 72 + } 73 + 74 + PATH+=:/opt/homebrew/bin 75 + 76 + if ! command -v op >/dev/null; then 77 + echo "message-error 'Missing required command-line tool: op'" >>"$QUTE_FIFO" 78 + exit 1 79 + fi 80 + 81 + if ! command -v jq >/dev/null; then 82 + echo "message-error 'Missing required command-line tool: jq'" >>"$QUTE_FIFO" 83 + exit 1 84 + fi 85 + 86 + OP_VERSION="$(op --version)" 87 + OP_MAJOR_VERSION="$(echo "$OP_VERSION" | grep --only-matching '^[0-9]')" 88 + 89 + if [[ "$OP_MAJOR_VERSION" -lt 2 ]]; then 90 + echo "message-error 'Requires op CLI v2.0.0 or higher, but got: $OP_VERSION'" >>"$QUTE_FIFO" 91 + exit 1 92 + fi 93 + 94 + echo "message-info 'Looking for password for $URL...'" >>"$QUTE_FIFO" 95 + 96 + JQ_TITLE_EXPR='.title + " (in vault \"" + .vault.name + "\")"' 97 + 98 + if ! LIST_ITEM_OUT="$(op item list --format=json)"; then 99 + echo "message-error 'Failed to list items.'" >>"$QUTE_FIFO" 100 + exit 1 101 + fi 102 + 103 + MATCHING_ITEMS="$(echo "$LIST_ITEM_OUT" | jq --arg url "$URL" '[.[] | select((.urls//[])[].href | test($url))]')" 104 + MATCHING_COUNT="$(echo "$MATCHING_ITEMS" | jq -r 'length')" 105 + 106 + UUID="" 107 + if [[ "$MATCHING_COUNT" == 1 ]]; then 108 + UUID="$(echo "$MATCHING_ITEMS" | jq -r '.[0].id')" 109 + TITLE="$(echo "$MATCHING_ITEMS" | jq -r '.[0] | '"$JQ_TITLE_EXPR")" 110 + echo "message-info 'Found 1 entry for $URL: $TITLE'" >>"$QUTE_FIFO" 111 + elif [[ "$MATCHING_COUNT" -gt 1 ]]; then 112 + echo "message-info 'Found $MATCHING_COUNT entries for $URL'" >>"$QUTE_FIFO" 113 + TITLE="$(echo "$MATCHING_ITEMS" | jq -r '.[] | '"$JQ_TITLE_EXPR" | dmenu-prompt "Select item for $URL")" || TITLE="" 114 + if [ -n "$TITLE" ]; then 115 + UUID=$(echo "$MATCHING_ITEMS" | jq --arg title "$TITLE" -r '[.[] | select('"$JQ_TITLE_EXPR"' == $title).id] | first // ""') || UUID="" 116 + else 117 + UUID="" 118 + fi 119 + else 120 + echo "message-error 'No entry found for $URL'" >>"$QUTE_FIFO" 121 + TITLE="$(echo "$LIST_ITEM_OUT" | jq -r '.[] | '"$JQ_TITLE_EXPR" | dmenu-prompt)" || TITLE="" 122 + if [ -n "$TITLE" ]; then 123 + UUID=$(echo "$LIST_ITEM_OUT" | jq --arg title "$TITLE" -r '[.[] | select('"$JQ_TITLE_EXPR"' == $title).id] | first // ""') || UUID="" 124 + else 125 + UUID="" 126 + fi 127 + fi 128 + 129 + if [[ -z "$UUID" ]]; then 130 + echo "message-error 'No item picked.'" >>"$QUTE_FIFO" 131 + exit 1 132 + fi 133 + 134 + ITEM="$(op item get --format=json "$UUID")" 135 + 136 + TITLE="$(echo "$ITEM" | jq -r "$JQ_TITLE_EXPR")" 137 + PASSWORD="$(echo "$ITEM" | jq -r '[.fields[] | select(.purpose=="PASSWORD") | .value] | first // ""')" 138 + 139 + if [ -z "$PASSWORD" ]; then 140 + echo "message-error 'No password found in $TITLE'" >>"$QUTE_FIFO" 141 + exit 1 142 + fi 143 + 144 + USERNAME="$(echo "$ITEM" | jq -r '[.fields[] | select(.purpose=="USERNAME") | .value] | first // ""')" 145 + 146 + printjs() { 147 + js | sed 's,//.*$,,' | tr '\n' ' ' 148 + } 149 + echo "jseval -q $(printjs)" >>"$QUTE_FIFO" 150 + echo "message-info 'Using credentials from: $TITLE'" >>"$QUTE_FIFO" 151 + 152 + TOTP="$(echo "$ITEM" | op item get --otp "$UUID")" || TOTP="" 153 + if [ -n "$TOTP" ]; then 154 + echo "$TOTP" | clipboard-copy 155 + echo "message-info 'Pasted one time password for $TITLE to clipboard'" >>"$QUTE_FIFO" 156 + fi