Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2ce0c190ea | |||
| 9f4262566c | |||
| 3b72059307 |
@@ -0,0 +1,59 @@
|
||||
# This awk scripts adds an attachment to an email message
|
||||
#
|
||||
# Variables:
|
||||
# fpath: path to file
|
||||
|
||||
# Include data
|
||||
function attach() {
|
||||
cmd = "file --brief --mime-type '"fpath"'"
|
||||
suc = cmd | getline ctype
|
||||
close(cmd)
|
||||
if (suc != 1)
|
||||
exit 1
|
||||
print "Content-Type: "ctype end
|
||||
print "Content-Transfer-Encoding: base64"end
|
||||
filename = a[split(fpath, a, "/")]
|
||||
gsub(/[^[:alnum:]\.\-\_\ ]/, "", filename)
|
||||
print "Content-Disposition: attachment; filename=\""filename"\""end
|
||||
print "MIME-Version: 1.0"end
|
||||
print ""end
|
||||
cmd = "base64 '"fpath"'"
|
||||
while ((cmd | getline line) == 1)
|
||||
print line end
|
||||
close(cmd)
|
||||
}
|
||||
|
||||
# Compute fresh boundary string
|
||||
function genboundary() {
|
||||
return sprintf("===============%020d==", int(exp(20*log(10))*rand()))
|
||||
}
|
||||
|
||||
BEGIN { srand(); gsub(/'/, "'\\''", fpath); }
|
||||
/^\r?$/ && !inbody { inbody = 1; end = $0 }
|
||||
/^\r?$/ && !boundary {
|
||||
nb = genboundary()
|
||||
print "MIME-Version: 1.0"end
|
||||
print "Content-Type: multipart/mixed; boundary=\""nb"\""end
|
||||
print ""end
|
||||
print "--"nb end
|
||||
print "Content-Type: text/plain"end
|
||||
print "Content-Transfer-Encoding: 7bit"end
|
||||
}
|
||||
/^Content-Type:/ && !inbody {
|
||||
match($0, "boundary=\"[^\"]+\"")
|
||||
boundary = RSTART ? substr($0, RSTART+10, RLENGTH-11) : ""
|
||||
}
|
||||
$0 ~ "^--"boundary"--" {
|
||||
print "--"boundary end
|
||||
attach()
|
||||
print ""end
|
||||
}
|
||||
{ print }
|
||||
END {
|
||||
if (!nb) exit
|
||||
print ""end
|
||||
print "--"nb end
|
||||
attach()
|
||||
print ""end
|
||||
print "--"nb"--"end
|
||||
}
|
||||
+6
-6
@@ -32,8 +32,8 @@ set -eu
|
||||
# preview functions
|
||||
. "sh/preview.sh"
|
||||
|
||||
# varia functions
|
||||
. "sh/varia.sh"
|
||||
# userprompt functions
|
||||
. "sh/userprompt.sh"
|
||||
|
||||
# tags
|
||||
. "sh/tags.sh"
|
||||
@@ -143,7 +143,7 @@ if [ "${1:-}" = "--open-part" ]; then
|
||||
[ "$res" ] || exit
|
||||
tmpfile=$(mktemp)
|
||||
nm_message_get_part "$messageid" "$res" > "$tmpfile"
|
||||
if ynprompt "Are you sure you want to open this file?" "$($0 --preview-file-info "$tmpfile")"; then
|
||||
if $0 --preview-file-info "$tmpfile" | ynprompt "Are you sure you want to open this file?"; then
|
||||
# TODO: should we clean up at some point?
|
||||
open "$tmpfile" >/dev/null 2>/dev/stdout
|
||||
fi
|
||||
@@ -203,7 +203,7 @@ if [ "${1:-}" = "--purge" ]; then
|
||||
shift
|
||||
query="tag:$TAG_DEL and ($(echo " $*" | sed "s/\s\(\S\)/ thread:\1/g"))"
|
||||
files=$(nm_files_all "$query")
|
||||
if ynprompt "Are you sure you want to purge these files?" "$files"; then
|
||||
if echo "$files" | ynprompt "Are you sure you want to purge these files?"; then
|
||||
printf '%s' "$files" | xargs -d "\n" rm
|
||||
nm_new
|
||||
fi
|
||||
@@ -301,8 +301,8 @@ if [ "${1:-}" = "--list-deleted" ]; then
|
||||
--bind="$KEYS_DOWN_HP:half-page-down" \
|
||||
--bind="$KEYS_UP_HP:half-page-up" \
|
||||
--bind="$KEYS_ENTER:" \
|
||||
--bind="$KEYS_PURGE_ALL:select-all+execute-silent($0 --purge {+4})+reload:$0 --list-threads \"tag:$TAG_DEL\"" \
|
||||
--bind="$KEYS_DELETE:execute-silent($0 --purge {+4})+reload:$0 --list-threads \"tag:$TAG_DEL\"" \
|
||||
--bind="$KEYS_PURGE_ALL:select-all+execute($0 --purge {+4})+reload:$0 --list-threads \"tag:$TAG_DEL\"" \
|
||||
--bind="$KEYS_DELETE:execute($0 --purge {+4})+reload:$0 --list-threads \"tag:$TAG_DEL\"" \
|
||||
--bind="$KEYS_ENTER_ALTERNATIVE:execute-silent($0 --undelete {+4})+reload:$0 --list-threads \"tag:$TAG_DEL\"" \
|
||||
--bind="$KEYS_VIEW_LOGS:execute:$0 --view-logs"
|
||||
exit
|
||||
|
||||
@@ -27,5 +27,12 @@ EOF
|
||||
)
|
||||
export AWK_PARTNR
|
||||
|
||||
AWK_ATTACH=$(
|
||||
cat <<'EOF'
|
||||
@@include awk/attach.awk
|
||||
EOF
|
||||
)
|
||||
export AWK_ATTACH
|
||||
|
||||
export AWK_LOADED=1
|
||||
fi
|
||||
|
||||
+31
-3
@@ -1,9 +1,37 @@
|
||||
# Add attachment
|
||||
# This function updates the email file. Errors are suppressed silently, and the
|
||||
# email will not be altered.
|
||||
#
|
||||
# @argument $1: email file
|
||||
attatchto() {
|
||||
f="$($FZF \
|
||||
--bind="$KEYS_ENTER:accept" \
|
||||
--bind="$KEYS_CANCEL:abort" \
|
||||
--bind="$KEYS_DOWN_HP:half-page-down" \
|
||||
--bind="$KEYS_UP_HP:half-page-up" \
|
||||
--walker=file \
|
||||
--walker-root="$HOME" || true)"
|
||||
[ -r "$f" ] || return 0
|
||||
eml=$(mktemp)
|
||||
awk -v fpath="$f" "$AWK_ATTACH" < "$1" > "$eml" || return 0
|
||||
mv "$eml" "$1"
|
||||
}
|
||||
|
||||
# Send email
|
||||
# @argument $1: Path to email file
|
||||
# @argument $2: if set, don't prompt the user (optional)
|
||||
send() {
|
||||
if [ ! "${2:-}" ] && ! ynprompt "Do you want to send this email?" "$($CATEMAIL "$tmpfile")"; then
|
||||
return
|
||||
if [ ! "${2:-}" ]; then
|
||||
# Prompt user
|
||||
undecided=1
|
||||
while [ "$undecided" ]; do
|
||||
case "$($CATEMAIL "$1" | multiprompt "Do you want to send this email?" "$YESSTRING\n$EDITSTRING\n$ATTACHSTRING\n$ABORTSTRING")" in
|
||||
0) undecided= ;;
|
||||
1) $EDITOR "$1" ;;
|
||||
2) attatchto "$1" ;;
|
||||
3) return ;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
$MSMTP -t --read-envelope-from -X "$SMTPLOGFILE" < "$1" >/dev/null 2>&1 || true
|
||||
log=$(tail -1 "$SMTPLOGFILE")
|
||||
@@ -11,7 +39,7 @@ send() {
|
||||
return
|
||||
fi
|
||||
# Handle errors
|
||||
res=$(printf "0 Retry\n1 Edit email\n2 Abort\n" | multiprompt "Could not send the email. What's next?" "$(echo "$log" | $CATLOG)")
|
||||
res=$(echo "$log" | $CATLOG | multiprompt "Could not send the email. What's next?" "Retry\n$EDITSTRING\n$ABORTSTRING")
|
||||
case "$res" in
|
||||
0) send "$1" ;;
|
||||
1) $EDITOR "$1"; send "$1" ;;
|
||||
|
||||
@@ -12,8 +12,15 @@ if [ ! "${THEME_LOADED:-}" ]; then
|
||||
COLTAGS="$(printf '\033[38;5;%sm' "$ANSICOLORTAGS")"
|
||||
COLRESET="$(printf '\033[0m')"
|
||||
|
||||
YESSTRING="${YESSTRING:-$(printf '\033[32mYes\033[0m')}"
|
||||
NOSTRING="${NOSTRING:-$(printf '\033[31mNo\033[0m')}"
|
||||
ABORTSTRING="${ABORTSTRING:-$(printf '\033[31mAbort\033[0m')}"
|
||||
EDITSTRING="${EDITSTRING:-$(printf '\033[33mEdit email\033[0m')}"
|
||||
ATTACHSTRING="${ATTACHSTRING:-$(printf '\033[35mAttach file\033[0m')}"
|
||||
|
||||
export ANSICOLORDATE ANSICOLORCNTS ANSICOLORFROM ANSICOLORSUBJ ANSICOLORTAGS
|
||||
export COLDATE COLCNTS COLFROM COLSUBJ COLTAGS COLRESET
|
||||
export YESSTRING NOSTRING ABORTSTRING EDITSTRING ATTACHSTRING
|
||||
|
||||
export THEME_LOADED=1
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
# Various functions
|
||||
|
||||
# This prompts the user for a series of options.
|
||||
# The content for the preview is read from stdin.
|
||||
# The possible options are given as newlineline-delimited string.
|
||||
# The function prints the line number (zero-based) of the selected option.
|
||||
#
|
||||
# @argument $1: Question
|
||||
# @argument $2: Options
|
||||
multiprompt() {
|
||||
pf=$(mktemp)
|
||||
cat > "$pf"
|
||||
echo "$2" | awk '{ print FNR-1, $0 }' | $FZF \
|
||||
--reverse \
|
||||
--no-input \
|
||||
--header="$1" \
|
||||
--preview-window='60%,border-line,wrap-word' \
|
||||
--margin='5%,5%,5%,15%' \
|
||||
--preview="cat \"$pf\"" \
|
||||
--bind="$KEYS_PREVIEW_DOWN:preview-down" \
|
||||
--bind="$KEYS_PREVIEW_UP:preview-up" \
|
||||
--bind="$KEYS_PREVIEW_DOWN_HP:preview-half-page-down" \
|
||||
--bind="$KEYS_PREVIEW_UP_HP:preview-half-page-up" \
|
||||
--bind="$KEYS_PREVIEW_TOGGLE_WRAP:toggle-preview-wrap-word" \
|
||||
--with-nth=2.. \
|
||||
--accept-nth=1 \
|
||||
--header-border='line' \
|
||||
--bind="ctrl-c,esc,ctrl-q:" \
|
||||
--color='border:yellow,header:yellow' || true
|
||||
rm -f "$pf"
|
||||
}
|
||||
|
||||
# This prompts the user for a "yes" or a "no", and shows the content from stdin
|
||||
# in the preview window.
|
||||
# @argument $1: Question
|
||||
# @return: 0 if the user answered "yes" and 1 otherwise.
|
||||
ynprompt() {
|
||||
return "$(cat | multiprompt "$1" "$YESSTRING\n$NOSTRING")"
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
# Various functions
|
||||
|
||||
# This prompts the user for a "yes" or a "no"
|
||||
# @argument $1: Question
|
||||
# @argument $2: Content to show in preview window
|
||||
# @return: 0 if the user answered "yes" and 1 otherwise.
|
||||
ynprompt() {
|
||||
return "$(printf '0 \033[32myes\033[0m\n1 \033[31mno\033[0m\n' |
|
||||
$FZF \
|
||||
--sync \
|
||||
--bind='start:pos(2)' \
|
||||
--bind='ctrl-c,ctrl-g,ctrl-q,esc:pos(2)+accept' \
|
||||
--reverse \
|
||||
--no-input \
|
||||
--header="$1" \
|
||||
--preview-window='60%,border-line,wrap-word' \
|
||||
--margin='5%,5%,5%,15%' \
|
||||
--preview="echo \"$2\"" \
|
||||
--with-nth=2.. \
|
||||
--accept-nth=1 \
|
||||
--header-border='line' \
|
||||
--color='border:yellow,header:yellow')"
|
||||
}
|
||||
|
||||
# This prompts the user for a series of options.
|
||||
# The options are read from stdin in the form "integer\toption\n".
|
||||
# Prints number
|
||||
#
|
||||
# @argument $1: Question
|
||||
# @argument $2: Content to show in preview window
|
||||
multiprompt() {
|
||||
cat |
|
||||
$FZF \
|
||||
--reverse \
|
||||
--no-input \
|
||||
--header="$1" \
|
||||
--preview-window='60%,border-line,wrap-word' \
|
||||
--margin='5%,5%,5%,15%' \
|
||||
--preview="echo \"$2\"" \
|
||||
--with-nth=2.. \
|
||||
--accept-nth=1 \
|
||||
--header-border='line' \
|
||||
--bind="ctrl-c,esc,ctrl-q:" \
|
||||
--color='border:yellow,header:yellow' | head -1 || true
|
||||
}
|
||||
Reference in New Issue
Block a user