Update 2022-12-08 13:17 OpenBSD/amd64

This commit is contained in:
c0dev0id 2022-12-08 13:17:01 +01:00
parent bacc864a23
commit bfa921461c
18 changed files with 1111 additions and 0 deletions

View File

@ -0,0 +1,13 @@
asterisk= "*";
min_password_length = 24
prompt = "GnuPG"
font = "FuraCodeNerdFont-13";
bottom = false;
prompt_fg = "#FFFFFF";
prompt_bg = "#771818";
normal_fg = "#FFFFFF";
normal_bg = "#771818";
select_fg = "#FFFFFF";
select_bg = "#181818";
desc_fg = "#CCCCCC";
desc_bg = "#771818";

65
.mutt/colors/codevoid256 Normal file
View File

@ -0,0 +1,65 @@
# Programcolors (fg/bg)
color attachment green default
color tree cyan default
color error cyan default
color normal white default
color indicator white color15
color signature cyan default
color status white brightyellow
color tilde green default
color message cyan default # info messages
color search brightred green # search matches
color markers red default # + at beginning of
color underline brightred default # hilighting underlined
# Headercolors
color hdrdefault green default
color header yellow default ^From:
color header yellow default ^Cc:
color header brightyellow default ^X
color header green default ^Subject:
color header blue default ^Organization:
color header blue default ^Reply
color header yellow default ^From
color header brightcyan default ^X-Mailer:
color header yellow default ^To:
color header brightyellow default ^X-Mailing-List:
color header brightyellow default ^OpenPGP:
color header brightyellow default ^OpenGPG:
color header brightyellow default ^X-OpenGPG:
color header red default ^Date:
color header brightyellow default ^User-Agent:
color header brightyellow default ^List-Id:
color header brightyellow default ^Sender:
color header brightyellow default ^X-PGP-Fingerprint:
# Quoting levels
color quoted green default
color quoted1 cyan default
color quoted2 brightblue default
color quoted3 yellow default
color quoted4 green default
color quoted5 cyan default
color quoted6 brightblue default
color quoted7 yellow default
# Smilies etc.
#color body red default "<[Gg]>"
#color body red default "<[Bb][Gg]>"
#color body red default " [;:]-*[)>(<|]"
# Emails
color body brightred default "[-a-z_0-9.%$]+@[-a-z_0-9.]+\\.[-a-z][-a-z]+"
# URLs
color body green default "(https|http|ftp|news|telnet|finger|gopher)://[^ ]*"
color body green default "mailto:[-a-z_0-9.\+]+@[-a-z_0-9.]+"
# Message types
color index brightyellow default '~P' # from me
#color index cyan default '~p' # personal
color index green default '~G' # PGP
color index red default '~F' # flagged
#color index green default '~Q' # replied
#color index brightwhite default '~N' # new
#color index red default '~D' # deleted

3
.mutt/defaultfolders Normal file
View File

@ -0,0 +1,3 @@
mailboxes \
"imaps://mail.codevoid.de" \
"~/.emails"

52
.mutt/mailcap Normal file
View File

@ -0,0 +1,52 @@
# USAGE: <type> <command> <flags>
# Tyle: text/plain
# Command: cmd %s
# Flags:
# - copiousoutput use pager
# - needsterminal open in new terminal
# - text=xxx rule is valid if program xxx returns true
# - textualnewlines=0 turn off newline conversation for text
# - compose=xxx %s use program xxx to compose this type
# - edit=xxx use program xxx to edit this type
# - description=xxx set description
# - nametemplate=%s.html define temporary file name
# Format:
# - %s - Filename (if %s is not used, data will be sent to stdin)
# - %t - Mime Type
# - %{var1} - Specified by: var1=foobar;
#
# Env Variables:
# METAMAIL_PAGER=less
#
# Tests:
# test -n "$DISPLAY" true when X is running
# html
text/html; w3m -I %{charset} -T %t -cols "$COLUMNS" -s -no-graph -o display_link=1 -o display_link_number=1; copiousoutput;
# documents
application/pdf; zathura %s; nametemplate=%s.pdf;
application/vnd.openxmlformats-officedocument.wordprocessingml.document; libreoffice %s;
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; libreoffice %s;
application/vnd.openxmlformats-officedocument.presentationml.presentation; libreoffice %s;
application/vnd.oasis.opendocument.text; libreoffice %s;
application/vnd.oasis.opendocument.spreadsheet; libreoffice %s;
application/vnd.oasis.opendocument.presentation; libreoffice %s;
# media
image/*; nsxiv %s; needsterminal;
video/*; mpv %s; needsterminal;
audio/*; mpv %s; needsterminal;
application/ogg; mpv %s; needsterminal;
# calendar
text/calendar; clear && ~/.mutt/scripts/mutt-ical.py -i -e "stefan.hagen@sap.com" %s; nametemplate=%s.ics
application/ics; clear && ~/.mutt/scripts/mutt-ical.py -i -e "stefan.hagen@sap.com" %s; nametemplate=%s.ics
# winmail.dat fix
application/ms-tnef; tnef -w %s
# fallback
application/*; vim %s; needsterminal;
#text/*; cat %s; copiousoutput;

42
.mutt/rc-account-private Normal file
View File

@ -0,0 +1,42 @@
source ~/.mutt/rc-common
set from="sh@codevoid.de"
set realname="Stefan Hagen"
unmy_hdr *
my_hdr Precedence: first-class
my_hdr Priority: normal
my_hdr X-Editor: `vim --version | head -1 | tr 'IM' 'im' | awk '{print $1" "$5 }'`
my_hdr X-Operating-System: `uname -rms`
my_hdr X-Mailer: `mutt -v | head -1`
my_hdr X-PGP-Fingerprint: CBD3 C468 64B4 6517 E8FB B90F B6BC 2EC5 52BE 43BA
my_hdr OpenPGP: id=52BE43BA\; url=https://codevoid.de/0/gpg\; preference=signencrypt
set text_flowed = no
set indent_string = "> "
set imap_delim_chars='/'
set spoolfile = imaps://mail.codevoid.de/INBOX
set folder = imaps://mail.codevoid.de
set postponed = imaps://mail.codevoid.de/Drafts
set record = imaps://mail.codevoid.de/Sent
set trash = imaps://mail.codevoid.de/Trash
set realname = "Stefan Hagen"
source "pass Local/mutt-private |"
set signature = "$HOME/.mutt/signature"
set sendmail = "msmtp -a private"
set ssl_starttls = yes
set ssl_force_tls = yes
set mail_check = 120
set timeout = 15
macro index <f5> "<change-folder> =INBOX<enter>" "INBOX"
macro index <f6> "<change-folder> =Mailboxes/codevoid.de/sh+openbsd-ports<enter><last-entry>" "ports"
macro index <f7> "<change-folder> =Mailboxes/codevoid.de/sh+openbsd-tech<enter><last-entry>" "tech"
macro index <f8> "<change-folder> =Mailboxes/codevoid.de/sh+openbsd-hackers<enter><last-entry>" "hackers"
macro index <f9> "<change-folder> =Mailboxes/codevoid.de/sh+openbsd-ports-cvs<enter><last-entry>" "ports-cvs"
mailboxes -nopoll -label Codevoid "imaps://mail.codevoid.de"

319
.mutt/rc-common Normal file
View File

@ -0,0 +1,319 @@
# CACHE
set mailcap_path = "$HOME/.mutt/mailcap"
set header_cache = "$HOME/.mutt/cache/"
set message_cachedir = "$HOME/.mutt/cache/"
set header_cache_compress = yes # faster without
set message_cache_clean = yes # delete obsolete entries from cache (for outside changes)
set maildir_header_cache_verify = yes # check for changes from outside mutt
set maildir_check_cur = yes # check curr folder for new messages
set mail_check_stats = yes # calculate message statistics
set mail_check_stats_interval = 60 # stat calculation interval
# set xterm title
set ts_enabled = no
# IMAP FEATURES
set imap_condstore = yes
set imap_qresync = yes
set imap_deflate = yes
set imap_idle = no
set imap_keepalive = 180
set imap_fetch_chunk_size = 250
set imap_pipeline_depth = 0
set imap_poll_timeout = 30
set imap_check_subscribed = no
set imap_passive = yes
set mail_check = 360
set timeout = 5
set tmpdir = ~/.cache/mutt
alternates @codevoid.de|@textmail.me|@stefanhagen-fotografie.de|ptrace.org|sh@uugrn.org|stefan.hagen@uugrn.org|sdk@uugrn.org|sdk@openbsd.org
# Allow alt key
set meta_key = no
# Charset Settings
set charset = "utf-8" # terminal
set send_charset = "us-ascii:utf-8"
set config_charset = "utf-8"
set attach_charset = "utf-8" # attachment view
set assumed_charset = "utf-8"
set use_8bitmime = no # only for weird sendmails
set allow_ansi = no # no escape characters please
set allow_8bit = yes
unlists *
lists misc ports tech hackers uugrn intern vorstand
# Display Header
ignore *
unignore To Cc Subject Reply-To Mail-Followup-To Message-ID
#unignore From To Cc Subject Reply-To
#unignore Date Sender List-Unsubscribe
#unignore Message-ID
unignore X-Editor X-Mailer X-GPG X-PGP
unignore X-Gnupg PGP GPG Gnupg
unignore X-Spam:
set imap_headers = "X-Spam X-Spam-DNSBL X-Label"
spam "X-Spam: Yes" "spam"
hdr_order Date From To Cc Subject Reply-To
hdr_order Sender List-Unsubscribe
hdr_order X-Editor X-Mailer X-GPG X-PGP
hdr_order X-Gnupg PGP GPG Gnupg
#set text_flowed
set sleep_time = 0
set attribution = "%n wrote (%D):"
# TOFU filter
# set my_tprot='t-prot -aelmtS -c --bigq -Mmutt --spass --pgp-move --pgp-short'
# set display_filter=$my_tprot
set display_filter=~/.mutt/scripts/display-filter
subscribe ports@openbsd.org
send-hook '~C ^ports@openbsd\.org$' 'my_hdr From: sh+openbsd-ports@codevoid.de'
send-hook '~C ^ports@openbsd\.org$' 'unset signature'
subscribe misc@openbsd.org
send-hook '~C ^misc@openbsd\.org$' 'my_hdr From: sh+openbsd-misc@codevoid.de'
send-hook '~C ^misc@openbsd\.org$' 'unset signature'
subscribe tech@openbsd.org
send-hook '~C ^tech@openbsd\.org$' 'my_hdr From: sh+openbsd-tech@codevoid.de'
send-hook '~C ^tech@openbsd\.org$' 'unset signature'
subscribe hackers@openbsd.org
send-hook '~C ^hackers@openbsd\.org$' 'my_hdr From: sh+openbsd-hackers@codevoid.de'
send-hook '~C ^hackers@openbsd\.org$' 'unset signature'
subscribe uugrn@uugrn.org
send-hook '~C ^uugrn@uugrn\.org$' 'my_hdr From: sh@uugrn.org'
send-hook '~C ^uugrn@uugrn\.org$' 'unset signature'
subscribe vorstand@uugrn.org
send-hook '~C ^vorstand@uugrn\.org$' 'my_hdr From: sh@uugrn.org'
send-hook '~C ^vorstand@uugrn\.org$' 'unset signature'
subscribe mutt-users@mutt.org
send-hook '~C ^mutt-users@mutt\.org$' 'my_hdr From: sh+mutt-users@codevoid.de'
send-hook '~C ^mutt-users@mutt\.org$' 'unset signature'
subscribe intern@lists.ccc.de
send-hook '~C ^intern@lists.ccc\.de$' 'my_hdr From: Stefan Hagen <ccc-intern@textmail.me>'
send-hook '~C ^intern@lists.ccc\.de$' 'unset signature'
# account hooks
send2-hook '~f ^.*@uugrn.org' 'set sendmail = "msmtp -a uugrn"'
send2-hook '~f ^.*@codevoid.de' 'set sendmail = "msmtp -a private"'
send2-hook '~f ^.*@textmail.me' 'set sendmail = "msmtp -a private"'
send2-hook '~f ^.*@ptrace.org' 'set sendmail = "msmtp -a private"'
send2-hook '~f ^.*@codevoid.de' 'set sendmail = "msmtp -a private"'
send2-hook '~f ^.*@mailbox.org' 'set sendmail = "msmtp -a mboxorg"'
send2-hook '~f ^.*@mailbox.org' 'set sendmail = "msmtp -a mboxorg"'
set help = no
# Complete address via <tab>
set use_from = yes
set use_envelope_from = yes
set query_command = "mu cfind --format=mutt-ab '%s'"
macro index S "<shell-escape>~/.mutt/scripts/mu-find.sh<enter><change-folder-readonly>~/.cache/mu/results<enter>" "mu search"
bind editor <Tab> complete-query
bind editor ^T complete
# Format
set pager_format = "From: %f %* %d %P"
set date_format = "%Y-%m-%d %H:%M %Z"
set index_format = "%Z : %-18.18F : %s %* \ %?y?[%y] ?%[%H:%M %d.%m.%y]"
set forward_format = "Fw: %s"
set attach_format = "%u%D%I %t%4n %6T Size: %s, Type: %m/%M %d %F %> [ %C %e ] "
set folder_format = "%t %2C %d %f %> %s Bytes "
set status_format = '%f All:%m New:%u Mark:%t Del:%d %?V?Limit:%V/%ML? %> %P%'
# Composing
set editor = "vim -c 'set syntax=mail ft=mail'" # set mail editor
set print_command = "muttprint"
#set editor = "nvi"
set fast_reply = yes # do not ask for subject etc.
set autoedit = no # go directly to the editor. send_to has to be entered to hdr directly
set askcc = no # do not ask for cc address
set askbcc = no # do not ask for cc address
set reply_self = yes # strip own address from reply addresses
set ignore_list_reply_to = no # ignore reply_to set by mailing lists (use the list-reply then)
set bounce_delivered = no # include Delivered-To headers when bouncing messages
set reverse_name = yes # use the recieving address as From address
set edit_headers = yes # show headers in editor
set header = no # insert header into reply text
# Sending
set mime_forward = ask-no # forward as mime or text?
set reply_to = ask-yes # Reply to reply-to?
set include = yes # include message in replies
set fcc_clear = yes # save message unencrypted. (security issue!)
set hidden_host = no # skip the first part of $hostname (does not affect msg ids)
set save_address = no # take senders full name as default for saving the message
set save_empty = yes # delete mbox if empty (does not work with maildir/imap etc)
set save_name = no # mutt searches for a mailbox with the senders name and saves the mail there instead of record.
set encode_from = yes # quoted-printable if line contains "From ". Avoids address trash
set quote_regexp = '^([ \t]*[|>}])+'
set forward_decode = yes # decode complex mails to text/plain when forwarding
set forward_decrypt = yes # strip pgp
set forward_quote = no # format forwarded message text like a reply, with quote string etc.
set followup_to = yes # generates follow up header if replying to a list
set honor_followup_to = yes # take Mail-Followup-To header into account, whean group-replying
# File stuff
set mask = "." # show also dotfiles in file browser
set move = no # do not move mail from spool to mbox
set copy = yes # copy the sent messages to $record etc.
set fcc_attach = yes # save attachments in $record etc.
# Layout
set pager_index_lines = 0 # show a few lines from index above msg
set pager_stop = yes # pgdown does not wrap to next message
set markers = no # Don't add "+" on wrapped lines (hard to copy)
set smart_wrap = yes # wrap entire words
set sort = threads # sorting the mails in threads
set duplicate_threads = yes # groups messages with identical message id
set sort_aux = last-date-received # sorting the threads
set abort_nosubject = yes # abort if message has no subject
set reverse_alias = yes # use username in index instead of email address (if available)
set status_on_top = yes # moves the bottom statusbar to the top
set mark_old = no # mark old unread messages with an o
set arrow_cursor = no # use arrow curser instead of a colored line
set tilde = no # show ~ if mail ends and theres still space on the screen
set menu_scroll = yes # scroll the screen instead of using pages
set sig_dashes = no # set signature dashes "-- "
set sig_on_top = no
set ascii_chars = no # allow only ASCII chars for UI building
# Thread handling
set strict_threads = yes # thread only by In-Reply-To/References or by Subject.
set sort_re = no # use subject for thread building
set collapse_unread = no # do not hide unread messages in compressed threads
set uncollapse_jump = no # jump to the first unread message after expanding a thread
# Attachments
set implicit_autoview = yes # discover viewing app via mailcap entry
set attach_split = yes # process attachments one by one. this is for saving, printing, piping.
set mailcap_sanitize = yes # !DO NOT CHANGE! it checks mailcap for bad characters
unalternative_order *
alternative_order text/plain text/enriched text/html
auto_view text/html text/enriched text/calendar
# Preview HTML
macro pager  "<pipe-message>cat - > /tmp/mutt.html && luakit /tmp/mutt.html<return>"
#macro pager  "<pipe-message>~/.mutt/scripts/search-msgid.sh<enter>"
macro pager,attach  "<pipe-message>cat > /tmp/muttpatch.diff<enter><shell-escape>~/.mutt/scripts/portpatch2.sh /tmp/muttpatch.diff<enter>"
# Save Patch
#macro pager  "<shell-escape>rm -f /tmp/mutt-patch.diff<enter><copy-message>/tmp/mutt-patch.diff<enter><enter-command>echo 'Saved as /tmp/mutt-patch.diff'<enter><shell-escape>~/.mutt/scripts/portpatch.sh /tmp/mutt-patch.diff<enter>"
# pipe-message
set pipe_decode_weed = no
set pipe_decode = yes # when piping via pipe-message command, strip headers and decode
set pipe_split = yes # if several msgs are tagged, do the pipe-message command for each
set prompt_after = no # promt if external pager exits
set wait_key = no # wait for a key-press after performing shell/external commands
set beep_new = no # beep if new message arrives
set check_new = no # check for new mails, while the mailbox is open
set auto_tag = yes # function will applied to all tagged messages in the index
set use_domain = no # do not autoqualify messages without hostname
set read_only = no # open folders in read-only mode
set score = no # use the scoring system
set suspend = no # allow mutt to be suspended
set wrap_search = yes # search the mailbox around
# push V # show version at startup
push * # go to last entry
# save to folder
macro index s "<save-message>?<toggle-mailboxes>" "move a message to a mailbox"
macro pager s "<save-message>?<toggle-mailboxes>" "move a message to a mailbox"
bind index x sync-mailbox
# POS1 and END navigation
bind index,browser home first-entry
bind index,browser end last-entry
bind pager <home> top
bind pager <end> bottom
bind pager k previous-line
bind pager j next-line
# general navigation
bind index,pager up previous-entry
bind index,pager down next-entry
bind browser up previous-line
bind browser down next-line
bind index,pager d delete-message
bind index,pager u undelete-message
bind index,pager G group-chat-reply
bind browser d delete-mailbox
bind browser q exit
# Index keys
bind index Q quit
bind index q noop
bind index c change-folder
bind index v display-message
bind index ' ' next-page
bind index,pager y edit-label
bind index e edit
bind index $ sort-mailbox
bind index a tag-prefix
macro index M "<tag-pattern>~N<enter><tag-prefix><clear-flag>N<untag-pattern>.<enter>" "Mark all new as read"
macro index I "<limit>!~x.~$<enter>"
# Pager keys
bind pager ' ' next-page
bind pager c mail
bind pager / search
bind pager \n noop
bind pager g group-reply
bind pager h display-toggle-weed
# Compose keys
bind compose \cx send-message
bind pager,index ,S save-message
# urlview
macro pager \cb "<pipe-entry>'urlview'<enter>" 'Follow links with urlview'
# TOFU settings
# macro pager T ":unset display_filter<enter><exit><display-message>:set display_filter='$my_tprot'<enter>" 'TOFU protection'
# TOFU colors
color body brightmagenta black "^\\[---.*"
color body green black "^#v[-+]"
# SSL Settings
set ssl_verify_host = no
# GPG Settings (new style crypto - does not support inline gpg)
set crypt_use_gpgme = yes # use the new gpgme method (disabling cumbersome gpg commands below)
set crypt_replyencrypt = yes # encrypt, if original mail was encrypted
set crypt_replysign = yes # sign, if original mail was signed
set crypt_verify_sig = no # verify sig, if sig is available
set crypt_autosign = no # sign mails per default
set crypt_use_pka = yes # http://www.g10code.de/docs/pka-intro.de.pdf
set crypt_autosmime = no
set crypt_protected_headers_save = yes
set crypt_protected_headers_write = yes
set crypt_protected_headers_subject = "..."
set crypt_opportunistic_encrypt = yes # encrypt when key can be found
set autocrypt = no
set pgp_use_gpg_agent = yes
source ~/.mutt/colors/codevoid
source ~/.mutt/colors/devcolors

200
.mutt/scripts/MIMEmbellish Executable file
View File

@ -0,0 +1,200 @@
#!/usr/bin/env python3
import re
import sys
import email
import shlex
import mimetypes
import subprocess
import os.path
from copy import copy
from hashlib import md5
from email import charset
from email import encoders
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.nonmultipart import MIMENonMultipart
from os.path import basename, splitext
charset.add_charset('utf-8', charset.SHORTEST, '8bit')
command = os.path.expanduser('~/.mutt/scripts/htmlize.sh ')
def make_alternative(message, part):
alternative = convert(part, 'html', command)
alternative.set_payload(alternative.get_payload())
return alternative
def make_replacement(message, part):
return convert(part, 'plain', command)
def convert(part, to_subtype, command):
payload = part.get_payload()
if isinstance(payload, str):
payload = payload.encode('utf-8')
else:
payload = part.get_payload(None, True)
if not isinstance(payload, bytes):
payload = payload.encode('utf-8')
process = subprocess.run(
shlex.split(command),
input=payload, stdout=subprocess.PIPE, check=True)
return MIMEText(process.stdout, to_subtype, 'utf-8')
def with_alternative(parent, part, from_signed,
make_alternative=make_alternative,
make_replacement=None):
try:
alternative = make_alternative(parent or part, from_signed or part)
replacement = (make_replacement(parent or part, part)
if from_signed is None and make_replacement is not None
else part)
except:
return parent or part
envelope = MIMEMultipart('alternative')
if parent is None:
for k, v in part.items():
if (k.lower() != 'mime-version'
and not k.lower().startswith('content-')):
envelope.add_header(k, v)
del part[k]
envelope.attach(replacement)
envelope.attach(alternative)
if parent is None:
return envelope
payload = parent.get_payload()
payload[payload.index(part)] = envelope
return parent
def tag_attachments(message):
if message.get_content_type() == 'multipart/mixed':
for part in message.get_payload():
if (part.get_content_maintype() in ['image']
and 'Content-ID' not in part):
filename = part.get_param('filename',
header='Content-Disposition')
if isinstance(filename, tuple):
filename = str(filename[2], filename[0] or 'us-ascii')
if filename:
filename = splitext(basename(filename))[0]
if filename:
part.add_header('Content-ID', '<{}>'.format(filename))
return message
def attachment_from_file_path(attachment_path):
try:
mime, encoding = mimetypes.guess_type(attachment_path, strict=False)
maintype, subtype = mime.split('/')
with open(attachment_path, 'rb') as payload:
attachment = MIMENonMultipart(maintype, subtype)
attachment.set_payload(payload.read())
encoders.encode_base64(attachment)
if encoding:
attachment.add_header('Content-Encoding', encoding)
return attachment
except:
return None
attachment_path_pattern = re.compile(r'\]\s*\(\s*file://(/[^)]*\S)\s*\)|'
r'\]\s*:\s*file://(/.*\S)\s*$',
re.MULTILINE)
def link_attachments(payload):
attached = []
attachments = []
def on_match(match):
if match.group(1):
attachment_path = match.group(1)
cid_fmt = '](cid:{})'
else:
attachment_path = match.group(2)
cid_fmt = ']: cid:{}'
attachment_id = md5(attachment_path.encode()).hexdigest()
if attachment_id in attached:
return cid_fmt.format(attachment_id)
attachment = attachment_from_file_path(attachment_path)
if attachment:
attachment.add_header('Content-ID', '<{}>'.format(attachment_id))
attachments.append(attachment)
attached.append(attachment_id)
return cid_fmt.format(attachment_id)
return match.group()
return attachments, attachment_path_pattern.sub(on_match, payload)
def with_local_attachments(parent, part, from_signed,
link_attachments=link_attachments):
if from_signed is None:
attachments, payload = link_attachments(part.get_payload())
part.set_payload(payload)
else:
attachments, payload = link_attachments(from_signed.get_payload())
from_signed = copy(from_signed)
from_signed.set_payload(payload)
if not attachments:
return parent, part, from_signed
if parent is None:
parent = MIMEMultipart('mixed')
for k, v in part.items():
if (k.lower() != 'mime-version'
and not k.lower().startswith('content-')):
parent.add_header(k, v)
del part[k]
parent.attach(part)
for attachment in attachments:
parent.attach(attachment)
return parent, part, from_signed
def is_target(part, target_subtypes):
return (part.get('Content-Disposition', 'inline') == 'inline'
and part.get_content_maintype() == 'text'
and part.get_content_subtype() in target_subtypes)
def pick_from_signed(part, target_subtypes):
for from_signed in part.get_payload():
if is_target(from_signed, target_subtypes):
return from_signed
def seek_target(message, target_subtypes=['plain', 'markdown']):
if message.is_multipart():
if message.get_content_type() == 'multipart/signed':
part = pick_from_signed(message, target_subtypes)
if part is not None:
return None, message, part
elif message.get_content_type() == 'multipart/mixed':
for part in message.get_payload():
if part.is_multipart():
if part.get_content_type() == 'multipart/signed':
from_signed = pick_from_signed(part, target_subtypes)
if from_signed is not None:
return message, part, from_signed
elif is_target(part, target_subtypes):
return message, part, None
else:
if is_target(message, target_subtypes):
return None, message, None
return None, None, None
def main():
try:
message = email.message_from_file(sys.stdin)
parent, part, from_signed = seek_target(message)
if (parent, part, from_signed) == (None, None, None):
return message
tag_attachments(message)
print(with_alternative(
*with_local_attachments(parent, part, from_signed)))
except (BrokenPipeError, KeyboardInterrupt):
pass
if __name__ == '__main__':
main()

8
.mutt/scripts/display-filter Executable file
View File

@ -0,0 +1,8 @@
#!/bin/sh
cat - \
| sed 's|\[--\(.*unsupported.*\)--\]$|## Attachment:\1|g' \
| egrep -v '\[-- Attachment #1 --\]$' \
| egrep -v '\[-- Type.* --\]$' \
| fgrep -v "WARNING: We have NO indication" \
| cat -s

40
.mutt/scripts/htmlize.sh Executable file
View File

@ -0,0 +1,40 @@
#!/bin/sh
# read stdin
content=$(cat)
content_safe=$(echo "$content"| sed -E 's/^(>+)/\1 /g ;
s/^(>+) /\1 /g ;
s|<|\&lt;|g ;
s|>|\&gt;|g ;
s|^\&gt;\&gt;\&gt;\&gt;\&gt;\&gt;|\&gt;\&gt;\&gt;\&gt;\&gt;</span><span style="color: x">\&gt;</span>|g ;
s|^\&gt;\&gt;\&gt;\&gt;\&gt;|\&gt;\&gt;\&gt;\&gt;</span><span style="color: gray">\&gt;</span>|g ;
s|^\&gt;\&gt;\&gt;\&gt;|\&gt;\&gt;\&gt;</span><span style="color: brown">\&gt;</span>|g ;
s|^\&gt;\&gt;\&gt;|\&gt;\&gt;</span><span style="color: green">\&gt;</span>|g ;
s|^\&gt;\&gt;|\&gt;<span style="color: orange">\&gt;</span>|g ;
s|^\&gt;|<span style="color: blue">\&gt;</span>|g ;
s|^----------.*|<span style="color: gray">&</span>| ;
s|^Sender: |<b>&</b>| ;
s|^Date: |<b>&</b>| ;
s|^To: |<b>&</b>| ;
s|^Cc: |<b>&</b>| ;
s|^Subject: |<b>&</b>| ;
s|^-- $|</font><font face="Arial" size="0.75" color="gray">--\&nbsp;|g ;
s|^Stefan Hagen$|<b>&</b>|g ;
s|^SAP SE Germany, Walldorf$|<b>&</b>|g')
# wrap html
echo '<html>'
echo ' <head>'
echo ' <meta charset="utf-8">'
echo ' <meta name="viewport" content="width=device-width, initial-scale=1">'
echo ' <meta http-equiv="Content-Type" content="text/html; charset=utf-8">'
echo ' <meta http-equiv="X-UA-Compatible" content="IE=edge">'
echo ' <title></title>'
echo ' </head>'
echo ' <body style="min-width: 74ch; color: black; font-size: 11; line-height: 1.6; font: 11, \"Calibri\"">'
echo ' <pre>'
echo ' <font size="3" face="Calibri">'
echo "$content_safe"
echo '</font>'
echo '</pre>'
echo '</body>'
echo '</html>'

5
.mutt/scripts/mu-find.sh Executable file
View File

@ -0,0 +1,5 @@
#!/bin/ksh
printf "MU Seach: "
read -r term
mu find --clearlinks --format=links --linksdir=~/.cache/mu/results $term

223
.mutt/scripts/mutt-ical.py Executable file
View File

@ -0,0 +1,223 @@
#!/usr/bin/env python
# -*- coding: utf8 -*-
"""
This script is meant as a simple way to reply to ical invitations from mutt.
See README for instructions and LICENSE for licensing information.
"""
from __future__ import with_statement
__author__="Martin Sander"
__license__="MIT"
from tzlocal import get_localzone
import pytz
import vobject
import tempfile, time
import os, sys
import warnings
from datetime import date, datetime
from subprocess import Popen, PIPE
from getopt import gnu_getopt as getopt
timezone = get_localzone()
mutt="mutt"
usage="""
usage:
%s [OPTIONS] -e your@email.address filename.ics
OPTIONS:
-i interactive
-a accept
-d decline
-t tentatively accept
-c mutt_command
(accept is default, last one wins)
""" % sys.argv[0]
def del_if_present(dic, key):
if dic.has_key(key):
del dic[key]
def set_accept_state(attendees, state):
for attendee in attendees:
attendee.params['PARTSTAT'] = [unicode(state)]
for i in ["RSVP","ROLE","X-NUM-GUESTS","CUTYPE"]:
del_if_present(attendee.params,i)
return attendees
def get_accept_decline():
while True:
sys.stdout.write("\nAccept Invitation? [y/n/t/q]")
ans = sys.stdin.readline()
if ans.lower() == 'y\n':
return 'ACCEPTED'
elif ans.lower() == 'n\n':
return 'DECLINED'
elif ans.lower() == 't\n':
return 'TENTATIVE'
elif ans.lower() == 'q\n':
return ''
def get_answer(invitation):
# create
ans = vobject.newFromBehavior('vcalendar')
ans.add('method')
ans.method.value = "REPLY"
ans.add('vevent')
# just copy from invitation
for i in ["uid", "summary", "dtstart", "dtend", "organizer"]:
if invitation.vevent.contents.has_key(i):
ans.vevent.add( invitation.vevent.contents[i][0] )
# new timestamp
ans.vevent.add('dtstamp')
ans.vevent.dtstamp.value = datetime.utcnow().replace(
tzinfo = invitation.vevent.dtstamp.value.tzinfo)
return ans
def write_to_tempfile(ical):
tempdir = tempfile.mkdtemp()
icsfile = tempdir+"/event-reply.ics"
with open(icsfile,"w") as f:
f.write(ical.serialize())
return icsfile, tempdir
def get_mutt_command(ical, email_address, accept_decline, icsfile):
accept_decline = accept_decline.capitalize()
if ical.vevent.contents.has_key('organizer'):
if hasattr(ical.vevent.organizer,'EMAIL_param'):
sender = ical.vevent.organizer.EMAIL_param
else:
sender = ical.vevent.organizer.value.split(':')[1] #workaround for MS
else:
sender = "NO SENDER"
summary = ical.vevent.contents['summary'][0].value.encode()
command = [mutt, "-e", "my_hdr From: %s" % email_address, "-a", icsfile,
"-s", "%s: %s" % (accept_decline, summary), "--", sender]
#Uncomment the below line, and move it above the -s line to enable the wrapper
#"-e", 'set sendmail=\'ical_reply_sendmail_wrapper.sh\'',
return command
def execute(command, mailtext):
process = Popen(command, stdin=PIPE)
process.stdin.write(mailtext)
process.stdin.close()
result = None
while result is None:
result = process.poll()
time.sleep(.1)
if result != 0:
print "unable to send reply, subprocess exited with\
exit code %d\nPress return to continue" % result
sys.stdin.readline()
def openics(invitation_file):
with open(invitation_file) as f:
try:
with warnings.catch_warnings(): #vobject uses deprecated Exception stuff
warnings.simplefilter("ignore")
invitation = vobject.readOne(f, ignoreUnreadable=True)
except AttributeError:
invitation = vobject.readOne(f, ignoreUnreadable=True)
return invitation
def display(ical):
summary = ical.vevent.contents['summary'][0].value.encode()
if ical.vevent.contents.has_key('organizer'):
if hasattr(ical.vevent.organizer,'EMAIL_param'):
sender = ical.vevent.organizer.EMAIL_param
else:
sender = ical.vevent.organizer.value.split(':')[1] #workaround for MS
else:
sender = "NO SENDER"
if ical.vevent.contents.has_key('description'):
description = ical.vevent.contents['description'][0].value
else:
description = "NO DESCRIPTION"
if ical.vevent.contents.has_key('attendee'):
attendees = ical.vevent.contents['attendee']
else:
attendees = ""
sys.stdout.write("Start:\t" + ical.vevent.dtstart.value.astimezone(timezone).strftime('%Y-%m-%d %I:%M %p %Z') + "\n")
sys.stdout.write("End:\t" + ical.vevent.dtend.value.astimezone(timezone).strftime('%Y-%m-%d %I:%M %p %Z') + "\n")
sys.stdout.write("From:\t" + sender + "\n")
sys.stdout.write("Title:\t" + summary + "\n")
sys.stdout.write("To:\t")
for attendee in attendees:
if hasattr(attendee,'EMAIL_param'):
sys.stdout.write(attendee.CN_param + " <" + attendee.EMAIL_param + ">, ")
else:
sys.stdout.write(attendee.CN_param + " <" + attendee.value.split(':')[1] + ">, ") #workaround for MS
sys.stdout.write("\n\n")
sys.stdout.write(description + "\n")
if __name__=="__main__":
email_address = None
email_addresses = []
accept_decline = ''
opts, args=getopt(sys.argv[1:],"e:aidtc:")
if len(args) < 1:
sys.stderr.write(usage)
sys.exit(1)
invitation = openics(args[0])
#print(invitation)
display(invitation)
for opt,arg in opts:
if opt == '-e':
email_addresses = arg.split(',')
if opt == '-i':
accept_decline = get_accept_decline()
if opt == '-a':
accept_decline = 'ACCEPTED'
if opt == '-d':
accept_decline = 'DECLINED'
if opt == '-t':
accept_decline = 'TENTATIVE'
if opt == '-c':
mutt = arg
if accept_decline == '':
sys.exit(0)
ans = get_answer(invitation)
if invitation.vevent.contents.has_key('attendee'):
attendees = invitation.vevent.contents['attendee']
else:
attendees = ""
set_accept_state(attendees,accept_decline)
ans.vevent.add('attendee')
ans.vevent.attendee_list.pop()
flag = 1
for attendee in attendees:
if hasattr(attendee,'EMAIL_param'):
if attendee.EMAIL_param in email_addresses:
ans.vevent.attendee_list.append(attendee)
email_address = attendee.EMAIL_param
flag = 0
else:
if attendee.value.split(':')[1] in email_addresses:
ans.vevent.attendee_list.append(attendee)
email_address = attendee.value.split(':')[1]
flag = 0
if flag:
sys.stderr.write("Seems like you have not been invited to this event!\n")
sys.exit(1)
icsfile, tempdir = write_to_tempfile(ans)
mutt_command = get_mutt_command(ans, email_address, accept_decline, icsfile)
mailtext = "From: %s\n\n%s has %s" % (email_address, email_address, accept_decline.lower())
execute(mutt_command, mailtext)
os.remove(icsfile)
os.rmdir(tempdir)

20
.mutt/scripts/portpatch.sh Executable file
View File

@ -0,0 +1,20 @@
#!/bin/sh
strip=0
clear
printf '\n---------------------------------------------------------------------\n'
egrep '^Index|^RCS|^diff --git|^file +' "$1" | sed 's,/cvs,/usr,g'
printf '---------------------------------------------------------------------\n\n'
printf "Path for patch [/usr/ports]? "
read _path
[ -z "$_path" ] && _path=/usr/ports
egrep -q '^diff --git a/' "$1" && strip=1
#print "Trying to apply patch"
#qprint -d "$1" "$1.out"
doas patch -Ep"$strip" -d $_path < "$1"
cd $_path && ksh

26
.mutt/scripts/portpatch2.sh Executable file
View File

@ -0,0 +1,26 @@
#!/bin/sh
# needs converters/qprint
# mutt: macro pager,attach ^S "<pipe-message>cat > /tmp/muttpatch.diff<enter><shell-escape>~/.mutt/scripts/portpatch2.sh /tmp/muttpatch.diff<enter>"
clear
printf '\n---------------------------------------------------------------------\n'
grep -E 'Subject: |^Index|^RCS|^diff --git|^file +|^[-+]{3} ' "${1}"
printf '---------------------------------------------------------------------\n\n'
printf "Apply patch on path [defaults to /usr/ports]? "
read -r _path
printf "Fix quoted-printable mangeled patch? [y/N]: "
read -r _qprint
case ${_qprint} in
[y|Y]) _catcmd="qprint -d"; ;;
*) _catcmd="cat"; ;;
esac
printf "Strip? [0]: "
read -r _strip
${_catcmd} "${1}" | doas patch -Ep${_strip:=0} -d ${_path:=/usr/ports}
cd ${_path} && doas su

2
.mutt/scripts/search-msgid.sh Executable file
View File

@ -0,0 +1,2 @@
#!/bin/sh
luakit "https://marc.info/?i=$(cat - | sed -n 's/^Message-ID: <\(.*\)>/\1/p')"

View File

@ -0,0 +1,2 @@
#!/bin/sh
ssh sdk@mail.codevoid.de "/usr/sbin/sendmail -F 'Stefan Hagen' -f sh@codevoid.de -t"

View File

@ -0,0 +1,2 @@
#!/bin/sh
ssh sdk@cvs.openbsd.org "/usr/sbin/sendmail -F 'Stefan Hagen' -f sdk@openbsd.org -t"

89
.mutt/scripts/vcal2text.pl Executable file
View File

@ -0,0 +1,89 @@
#!/usr/bin/perl
# from: http://dollyfish.net.nz/projects/mutt-filters
# vcalendar-filter is a simple filter to give plain text representations of vcards
# Copyright (C) 2008 Martyn Smith
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# This script takes a simple VCALENDAR file as input on STDIN and produces a
# human readable text/plain representation of it on STDOUT
#
# It has been designed for use with mutt's auto_view config option, see the
# README file for more details
use strict;
use warnings;
use Data::ICal;
use Text::Autoformat;
my $body = eval { local $/ = undef; <> };
my $calendar = Data::ICal->new(data => $body);
# If parsing failed, try parsing as version 1.0
$calendar = Data::ICal->new(data => $body, vcal10 => 1) unless $calendar;
# If parsing failed, give up :-(
unless ( $calendar ) {
print "Unable to parse vcalendar: ", $calendar->error_message, "\n";
print $body;
exit 1;
}
foreach my $entry ( @{$calendar->{entries}} ) {
my $properties;
foreach my $property ( keys %{$entry->properties} ) {
next unless defined $entry->property($property);
$properties->{$property} = join(', ', map { $_->decoded_value } @{$entry->property($property)});
if ( $property eq 'description' ) {
$properties->{$property} = eval qq{"$properties->{$property}"};
$properties->{$property} = autoformat $properties->{$property}, {
all => 1,
left => 15,
};
$properties->{$property} =~ s/^\s*// if defined $properties->{$property};
}
elsif ( $property =~ m{ \A dt (?: start | end ) \z }xms ) {
if ( $properties->{$property} =~ m{ (\d\d\d\d)(\d\d)(\d\d)T(\d\d)(\d\d)(\d\d) }xms ) {
$properties->{$property} = "$1-$2-$3 $4:$5";
}
}
}
if ( $entry->ical_entry_type eq 'VTIMEZONE' ) {
unless ( defined $properties->{tzid} and $properties->{tzid} =~ m{Pacific/Auckland} ) {
print "Timezone : ", $properties->{tzid}, "\n";
print "\n";
}
}
elsif ( $entry->ical_entry_type eq 'VEVENT' ) {
print '-' x 72, "\n";
foreach my $key ( qw(summary BR description BR location organizer dtstart dtend) ) {
if ( $key eq 'BR' ) {
print "\n";
next;
}
next unless defined $properties->{$key};
printf "%-12s: %s\n", ucfirst $key, $properties->{$key};
}
}
else {
print "WARNING: Unknown entry type: ", $entry->ical_entry_type, "\n";
}
}

0
.mutt/signature Normal file
View File