From d5c4d917df28bae6207677588f53db60225af541 Mon Sep 17 00:00:00 2001 From: Anthony Debucquoy Date: Thu, 17 Apr 2025 14:16:23 +0200 Subject: [PATCH] bin --- bin/.bin/0x0 | 4 ++ bin/.bin/disc | 8 +++ bin/.bin/emailbook | 141 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 153 insertions(+) create mode 100755 bin/.bin/0x0 create mode 100755 bin/.bin/disc create mode 100755 bin/.bin/emailbook diff --git a/bin/.bin/0x0 b/bin/.bin/0x0 new file mode 100755 index 0000000..b19ab04 --- /dev/null +++ b/bin/.bin/0x0 @@ -0,0 +1,4 @@ +#!/bin/bash + +curl -F"file=@$@" https://0x0.st | tee >(xclip -sel clip) + diff --git a/bin/.bin/disc b/bin/.bin/disc new file mode 100755 index 0000000..811f81c --- /dev/null +++ b/bin/.bin/disc @@ -0,0 +1,8 @@ +#!/bin/sh + +tmux ls -F \#S | grep disc && \ + tmux attach -t disc \ +|| \ + tmux new-session -s disc 'scli --save-history' \; \ + split-window -h -l 75% 'aerc' \; \ + split-window -v 'weechat' \; \ diff --git a/bin/.bin/emailbook b/bin/.bin/emailbook new file mode 100755 index 0000000..f43754d --- /dev/null +++ b/bin/.bin/emailbook @@ -0,0 +1,141 @@ +#!/bin/sh +VERSION="0.2.1" +usage() { + echo "emailbook $VERSION"' +A minimalistic address book for e-mails only. + +Usage: emailbook FILE [OPTIONS] + +Prints all values in FILE if no option is given. + +Options: +-a, --add [KEY] VALUE Add KEY/VALUE pair to FILE. If KEY is omitted, + VALUE is used as key, too. +[-s, --search] QUERY Search FILE for entries with keys or values containing QUERY. +-k, --key QUERY Like `--search` but limit search to keys/aliases. +-v, --value QUERY Like `--search` but limit search to values. +-p, --parse SOURCE Parse stdin for e-mail addresses in header and add them to FILE. + SOURCE might be either --from, --to , --cc, --bcc, or --all. +-h, --help Show this help. +-V, --version Print version. +' +} + +checkfilename() { + [ $QUIET ] || [ -e "$filename" ] \ + || echo "File $filename not found. Creating it." 1>&2 +} + +keyexists() { + escaped=$(echo "$*" | sed 's/[][\.|$(){}?+*^]/\\&/g') + # also check display name with/without double quotes + quotestoggled=$(echo "$*" | sed -E 's/^"([^"]+)"( +<[^>]+>)/\1\2/;t;s/^([^"]+?)( +<[^>]+>)/"\1"\2/') + quotestoggledescaped=$(echo "$quotestoggled" | sed 's/[][\.|$(){}?+*^]/\\&/g') + grep -q -E "^$escaped( :|\$)" "$filename" 2> /dev/null \ + || grep -q -E "^$quotestoggledescaped( :|\$)" "$filename" 2> /dev/null +} + +addentry() { + if keyexists "$1"; then + [ $QUIET ] || echo "! $1 (skipped)" + else + [ "$2" ] && line="$1 : $2" || line="$1" + [ $QUIET ] || echo "+ $line" + echo "$line" >> "$filename" + fi +} + +add() { + checkfilename + case $# in + 1|2) addentry "$@" ;; + *) echo "Expected one or two arguments after -a!"; exit 1 ;; + esac +} + +addfromstdin() { + # Skip lines without "@", skip lines containing no-reply (or similar), + # strip \r, strip leading spaces, do the following replacements: + # "'John Doe'" → "John Doe" + # 'John Doe' → John Doe + # "john.doe@example.com" + # "" + # john.doe@example.com → + grep '@' \ + | grep -v -i -E '\bnot?[_-]?reply' \ + | sed 's/\r$//' \ + | sed -E 's/^ +//g' \ + | sed -E "s/(\"?)'([^'\"]+)'(\"?)/\1\2\3/" \ + | sed -E 's/^"]*)>?" +<\1>/<\1>/' \ + | sed -E 's/^[^<>@ ]*@[^<>@ ]+$/<\0>/' \ + | sort -u \ + | while read -r line; do addentry "$line"; done +} + +searchall() { + # show entries with matching alias first + searchbyalias "$*" + searchbyvalueonly "$*" +} + +searchbyalias() { + grep -i -E "$* :" "$filename" | sed -E 's/^[^:]+:\s*//' +} + +searchbyvalue() { + sed -E 's/^[^:]+:\s*//' "$filename" | grep -i -E "$*" +} + +searchbyvalueonly() { + # exclude matches found by searchbyalias + grep -i -E -v "$* :" "$filename" | sed -E 's/^[^:]+:\s*//' | grep -i -E "$*" +} + +parsefields() { + # Find header fields starting with $1 (p.e. 'To:') plus following lines + # starting with a space. Split entries at commas except when quoted. Skip + # empty lines. Decode encoded strings. Squeeze double spaces. + sed -E '/^\r?$/Q' - \ + | sed -E -n "/^$1:/{:a ; \$!N ; s/\n\s+/ / ; ta ; P ; D}" \ + | sed -E "s/^$1:\\s*//" \ + | grep -v -P '[\x80-\xFF]' \ + | awk -vFPAT='([^,"]*)("[^"]+")?([^,]*)?' -vOFS='\n' \ + '{for(i=1;i<=NF;i++) printf("%s\n",$i)}' \ + | sed -E -e '/^ *$/d' \ + | perl -CS -MEncode -ne 'print decode("MIME-Header", $_)' \ + | sed -E -e 's/ +/ /g' \ + | addfromstdin +} + +parse() { + checkfilename + case "$1" in + --all) parsefields '(From|To|Cc|CC|Bcc)' ;; + # TODO: Include References, In-Reply-To, Reply-To, Return-Path? + --from) parsefields 'From' ;; + --to) parsefields 'To' ;; + --cc) parsefields '(Cc|CC)' ;; + --bcc) parsefields 'Bcc' ;; + esac +} + + +case "$1" in +-h|--help|'') usage; exit ;; +-V|--version) echo "$VERSION"; exit ;; +esac + +filename="$1"; shift + +case "$1" in +-q|--quiet) shift; QUIET=1 ;; +esac + +case "$1" in +-a|--add) shift; add "$@" ;; +-s|--search) shift; searchall "$*" ;; +-k|--key) shift; searchbyalias "$*" ;; +-v|--value) shift; searchbyvalue "$*" ;; +-p|--parse) shift; parse "$@" ;; +*) searchall "$*" ;; +esac