From b1515657d4754327e62760f55ec7c6fc873f6fe9 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Mon, 15 May 2017 15:33:32 -0400 Subject: bash: don't warn if ~/.config/dir_colors doesn't exist --- .config/bash/rc.d/10_aliases.sh | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.config/bash/rc.d/10_aliases.sh b/.config/bash/rc.d/10_aliases.sh index c3766da..9505271 100644 --- a/.config/bash/rc.d/10_aliases.sh +++ b/.config/bash/rc.d/10_aliases.sh @@ -3,9 +3,15 @@ ###################################################################### # Set up colors and settings for all the things # ###################################################################### -if [ -x "`which dircolors`" ]; then - eval "$(dircolors -p | cat - "${XDG_CONFIG_HOME}/dir_colors" | - dircolors -b -)" +if type dircolors &>/dev/null; then + eval "$( + { + dircolors -p + if [[ -f "${XDG_CONFIG_HOME}/dir_colors" ]]; then + cat "${XDG_CONFIG_HOME}/dir_colors" + fi + } | dircolors -b - + )" alias ls='ls -1v --color=auto' alias dir='dir -v --color=auto' alias vdir='vdir -v --color=auto' -- cgit v1.1-4-g5e80 From 898449d60e0f9966db1fe223998f7ad1e5eb45ad Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Mon, 15 May 2017 15:33:51 -0400 Subject: login: load config-path better --- .config/login.d/00_path.sh | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/.config/login.d/00_path.sh b/.config/login.d/00_path.sh index ae2e8db..dda528a 100644 --- a/.config/login.d/00_path.sh +++ b/.config/login.d/00_path.sh @@ -1,12 +1,7 @@ #!/hint/sh -eval "$( if type config-path &>/dev/null; then - config_path=config-path -else + eval "$(config-path | sed 's/^/export //')" +elif [[ -x "$HOME/.local/bin/config-path"; then # Bootstrap finding config-path - config_path="$HOME/.local/bin/config-path" + eval "$("$HOME/.local/bin/config-path" | sed 's/^/export //')" fi -IFS=$'\n' -lines=($("$config_path")) -printf -- 'export %s\n' "${lines[@]}" -)" -- cgit v1.1-4-g5e80 From 6023f67b634c0a3f4dca214b45dd76c6d2116059 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Mon, 15 May 2017 15:40:23 -0400 Subject: aliases: check for colordiff existance for the 'diff' alias --- .config/bash/rc.d/10_aliases.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.config/bash/rc.d/10_aliases.sh b/.config/bash/rc.d/10_aliases.sh index 9505271..9d008e2 100644 --- a/.config/bash/rc.d/10_aliases.sh +++ b/.config/bash/rc.d/10_aliases.sh @@ -69,7 +69,7 @@ if type dircolors &>/dev/null; then } diff() { - if [[ -t 1 ]]; then + if [[ -t 1 ]] && type colordiff &>/dev/null; then ( set -o pipefail command diff "$@" | colordiff -- cgit v1.1-4-g5e80 From 2644226e08f429467f79007be853ebc7b66c395b Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Mon, 15 May 2017 15:44:05 -0400 Subject: oops --- .config/login.d/00_path.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.config/login.d/00_path.sh b/.config/login.d/00_path.sh index dda528a..8b3484f 100644 --- a/.config/login.d/00_path.sh +++ b/.config/login.d/00_path.sh @@ -1,7 +1,7 @@ #!/hint/sh if type config-path &>/dev/null; then eval "$(config-path | sed 's/^/export //')" -elif [[ -x "$HOME/.local/bin/config-path"; then +elif [[ -x "$HOME/.local/bin/config-path" ]]; then # Bootstrap finding config-path eval "$("$HOME/.local/bin/config-path" | sed 's/^/export //')" fi -- cgit v1.1-4-g5e80 From 9fe48ff5cc04adf81496cc6f39e9c0c2a8668b79 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Mon, 15 May 2017 15:44:50 -0400 Subject: oops --- .config/login.d/00_path.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.config/login.d/00_path.sh b/.config/login.d/00_path.sh index 8b3484f..aa62f75 100644 --- a/.config/login.d/00_path.sh +++ b/.config/login.d/00_path.sh @@ -1,7 +1,7 @@ #!/hint/sh if type config-path &>/dev/null; then - eval "$(config-path | sed 's/^/export //')" + eval "$(config-path | sed 's/^/export /')" elif [[ -x "$HOME/.local/bin/config-path" ]]; then # Bootstrap finding config-path - eval "$("$HOME/.local/bin/config-path" | sed 's/^/export //')" + eval "$("$HOME/.local/bin/config-path" | sed 's/^/export /')" fi -- cgit v1.1-4-g5e80 From a945e25fffd7ae2499e1744e0309ecd4b19135a1 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sat, 15 Apr 2017 16:41:13 -0400 Subject: emacs: pull things out of custom.el --- .config/emacs/custom.el | 16 ---------------- .config/emacs/init.el | 11 ++++++++++- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/.config/emacs/custom.el b/.config/emacs/custom.el index ac20ba1..f5d9860 100644 --- a/.config/emacs/custom.el +++ b/.config/emacs/custom.el @@ -6,11 +6,7 @@ '(ansi-color-names-vector ["#212526" "#ff4b4b" "#b4fa70" "#fce94f" "#729fcf" "#e090d7" "#8cc4ff" "#eeeeec"]) '(custom-enabled-themes (quote (tsdh-dark))) - '(custom-safe-themes - (quote - ("9f443833deb3412a34d2d2c912247349d4bd1b09e0f5eaba11a3ea7872892000" "bb08c73af94ee74453c90422485b29e5643b73b05e8de029a6909af6a3fb3f58" "82d2cac368ccdec2fcc7573f24c3f79654b78bf133096f9b40c20d97ec1d8016" "1b8d67b43ff1723960eb5e0cba512a2c7a2ad544ddb2533a90101fd1852b426e" "628278136f88aa1a151bb2d6c8a86bf2b7631fbea5f0f76cba2a0079cd910f7d" "06f0b439b62164c6f8f84fdda32b62fb50b6d00e8b01c2208e55543a6337433a" "1e7e097ec8cb1f8c3a912d7e1e0331caeed49fef6cff220be63bd2a6ba4cc365" "71b172ea4aad108801421cc5251edb6c792f3adbaecfa1c52e94e3d99634dee7" "fc5fcb6f1f1c1bc01305694c59a1a861b008c534cae8d0e48e4d5e81ad718bc6" default))) '(erc-nick "lukeshu") - '(explicit-shell-file-name "/bin/bash") '(graphviz-dot-auto-indent-on-semi nil) '(org-latex-default-packages-alist (quote @@ -32,12 +28,6 @@ '(org-latex-pdf-process (quote ("xelatex -interaction nonstopmode -output-directory %o %f" "xelatex -interaction nonstopmode -output-directory %o %f" "xelatex -interaction nonstopmode -output-directory %o %f"))) - '(org-src-fontify-natively t) - '(package-selected-packages - (quote - (wanderlust yaml-mode scss-mode nginx-mode markdown-mode less-css-mode haml-mode graphviz-dot-mode go-mode glsl-mode php-mode php-mode-improved coffee-mode bison-mode smart-tabs-mode page-break-lines dtrt-indent))) - '(ruby-deep-arglist nil) - '(ruby-deep-indent-paren nil) '(safe-local-variable-values (quote ((Fill-Column . 64) @@ -60,12 +50,6 @@ (Nginx-indent-level . 4) (Nginx-indent-level . 8) (c-set-style . "K&R")))) - '(scroll-bar-mode nil) - '(send-mail-function (quote smtpmail-send-it)) - '(smtpmail-smtp-server "plus.smtp.mail.yahoo.com") - '(smtpmail-smtp-service 587) - '(tramp-use-ssh-controlmaster-options nil) - '(uniquify-buffer-name-style (quote post-forward-angle-brackets) nil (uniquify)) '(use-package-verbose (quote debug))) (custom-set-faces ;; custom-set-faces was added by Custom. diff --git a/.config/emacs/init.el b/.config/emacs/init.el index 200daad..1a5d719 100644 --- a/.config/emacs/init.el +++ b/.config/emacs/init.el @@ -90,6 +90,12 @@ (set (make-local-variable 'tab-width) 2) (set (make-local-variable 'indent-tabs-mode) nil) ))) +(use-package graphviz-dot-mode + :mode ("\\.dot\\'" "\\.gv\\'") + :config (add-hook 'graphviz-dot-mode-hook + '(lambda () + (set (make-local-variable 'graphviz-dot-auto-indent-on-semi) nil) + ))) ;;(use-package php-mode-improved ;; :mode (("\\.php[s34]?\\'" . php-mode) ;; ("\\.phtml\\'" . php-mode) @@ -101,7 +107,6 @@ (use-package cmake-mode :mode ("CMakeLists\\.txt\\'" "\\.cmake\\'")) (use-package glsl-mode :mode ("\\.vert\\'" "\\.frag\\'" "\\.geom\\'" "\\.glsl\\'")) (use-package go-mode :mode "\\.go\\'") -(use-package graphviz-dot-mode :mode ("\\.dot\\'" "\\.gv\\'")) (use-package haml-mode :mode "\\.haml\\'") (use-package less-css-mode :mode "\\.less\\'") (use-package markdown-mode :mode ("\\.markdown\\'" "\\.md\\'" "\\.ronn\\'")) @@ -128,6 +133,7 @@ ;; Misc. crap (when (fboundp 'tool-bar-mode) (tool-bar-mode -1)) +(when (fboundp 'scroll-bar-mode) (scroll-bar-mode -1)) (setq inhibit-startup-screen t) (setq-default truncate-lines t) @@ -311,4 +317,7 @@ sh-script.el is broken." (add-to-list 'auto-mode-alist '("\\.mak\\'" . makefile-gmake-mode)) (add-to-list 'auto-mode-alist '("\\.jad\\'" . java-mode)) + +;; Anything that gets magically appended ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + (put 'downcase-region 'disabled nil) -- cgit v1.1-4-g5e80 From fc4ed81f7d2991eaebabcf0cc90003d0fd793c31 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Wed, 8 Nov 2017 14:02:33 -0500 Subject: login: enable ccache by default --- .config/login.d/10_ccache.sh | 4 ++++ .git.info.exclude.in | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .config/login.d/10_ccache.sh diff --git a/.config/login.d/10_ccache.sh b/.config/login.d/10_ccache.sh new file mode 100644 index 0000000..b9721c0 --- /dev/null +++ b/.config/login.d/10_ccache.sh @@ -0,0 +1,4 @@ +#!/hint/sh +if test -d /usr/lib/ccache/bin; then + PATH="/usr/lib/ccache/bin:$PATH" +fi diff --git a/.git.info.exclude.in b/.git.info.exclude.in index 2d09032..a5facd1 100644 --- a/.git.info.exclude.in +++ b/.git.info.exclude.in @@ -39,7 +39,8 @@ lock *.bak *authority -*cache* +*.cache* +*_cache* # Ignore files left by editors *~ -- cgit v1.1-4-g5e80 From a774bcf62efe5de4195add1ce1cddc70e50d5dec Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Wed, 8 Nov 2017 14:04:44 -0500 Subject: .config/Makefile: place all state info in ${XDG_CACHE_HOME}/config --- .config/Makefile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.config/Makefile b/.config/Makefile index 3b7ebb1..4e8166e 100644 --- a/.config/Makefile +++ b/.config/Makefile @@ -7,11 +7,12 @@ else SHELL = /bin/bash -o pipefail GIT_DIR = ${HOME}/.git +STATEDIR = ${XDG_CACHE_HOME}/config targets = \ ${GIT_DIR}/info/exclude \ - ${XDG_CACHE_HOME}/config-symlinks/cookie \ - $(if $(shell crontab -l),${XDG_CACHE_HOME}/cron/cookie) \ + ${STATEDIR}/symlinks.stamp \ + $(if $(shell crontab -l),${STATEDIR}/crontab.stamp) \ $(if $(wildcard ${HOME}/Maildir),${HOME}/.folders) \ $(if $(wildcard ${XDG_CONFIG_HOME}/dconf/user),${XDG_CONFIG_HOME}/dconf/user.txt) @@ -28,12 +29,12 @@ ${GIT_DIR}/info/exclude: ${HOME}/.git.info.exclude.in $(shell echo .??*/) ${XDG_CONFIG_HOME}/dconf/user.txt: ${XDG_CONFIG_HOME}/dconf/user dconf dump / > $@ -${XDG_CACHE_HOME}/cron/cookie: ${XDG_CONFIG_HOME}/cron +${STATEDIR}/crontab.stamp: ${XDG_CONFIG_HOME}/cron -(cat $^/*; echo) | crontab - 2>/dev/null mkdir -p '$(@D)' date > '$@' -${XDG_CACHE_HOME}/config-symlinks/cookie: ${XDG_CONFIG_HOME}/symlinks +${STATEDIR}/symlinks.stamp: ${XDG_CONFIG_HOME}/symlinks config-symlinks mkdir -p '$(@D)' date > '$@' -- cgit v1.1-4-g5e80 From de7c79283f79ae823d7d286922503e173e461a91 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Wed, 8 Nov 2017 14:07:26 -0500 Subject: Update offlineimap systemd setup *grumble about upstream offlineimap breaking me so frequently* --- .config/systemd/user/default.target.wants/mail.target | 1 - .config/systemd/user/default.target.wants/offlineimap-oneshot.timer | 1 + .config/systemd/user/mail.target.wants/offlineimap.service | 1 - .config/systemd/user/mail.target.wants/offlineimap.timer | 1 - .config/systemd/user/offlineimap-oneshot.timer.d/length.conf | 2 ++ .config/systemd/user/offlineimap.timer.d/length.conf | 2 -- 6 files changed, 3 insertions(+), 5 deletions(-) delete mode 120000 .config/systemd/user/default.target.wants/mail.target create mode 120000 .config/systemd/user/default.target.wants/offlineimap-oneshot.timer delete mode 120000 .config/systemd/user/mail.target.wants/offlineimap.service delete mode 120000 .config/systemd/user/mail.target.wants/offlineimap.timer create mode 100644 .config/systemd/user/offlineimap-oneshot.timer.d/length.conf delete mode 100644 .config/systemd/user/offlineimap.timer.d/length.conf diff --git a/.config/systemd/user/default.target.wants/mail.target b/.config/systemd/user/default.target.wants/mail.target deleted file mode 120000 index 40ca36d..0000000 --- a/.config/systemd/user/default.target.wants/mail.target +++ /dev/null @@ -1 +0,0 @@ -/usr/lib/systemd/user/mail.target \ No newline at end of file diff --git a/.config/systemd/user/default.target.wants/offlineimap-oneshot.timer b/.config/systemd/user/default.target.wants/offlineimap-oneshot.timer new file mode 120000 index 0000000..9fb06ea --- /dev/null +++ b/.config/systemd/user/default.target.wants/offlineimap-oneshot.timer @@ -0,0 +1 @@ +/usr/lib/systemd/user/offlineimap-oneshot.timer \ No newline at end of file diff --git a/.config/systemd/user/mail.target.wants/offlineimap.service b/.config/systemd/user/mail.target.wants/offlineimap.service deleted file mode 120000 index aacc641..0000000 --- a/.config/systemd/user/mail.target.wants/offlineimap.service +++ /dev/null @@ -1 +0,0 @@ -/usr/lib/systemd/user/offlineimap.service \ No newline at end of file diff --git a/.config/systemd/user/mail.target.wants/offlineimap.timer b/.config/systemd/user/mail.target.wants/offlineimap.timer deleted file mode 120000 index 0644e30..0000000 --- a/.config/systemd/user/mail.target.wants/offlineimap.timer +++ /dev/null @@ -1 +0,0 @@ -/usr/lib/systemd/user/offlineimap.timer \ No newline at end of file diff --git a/.config/systemd/user/offlineimap-oneshot.timer.d/length.conf b/.config/systemd/user/offlineimap-oneshot.timer.d/length.conf new file mode 100644 index 0000000..5945ce8 --- /dev/null +++ b/.config/systemd/user/offlineimap-oneshot.timer.d/length.conf @@ -0,0 +1,2 @@ +[Timer] +OnUnitInactiveSec=1m diff --git a/.config/systemd/user/offlineimap.timer.d/length.conf b/.config/systemd/user/offlineimap.timer.d/length.conf deleted file mode 100644 index c010b38..0000000 --- a/.config/systemd/user/offlineimap.timer.d/length.conf +++ /dev/null @@ -1,2 +0,0 @@ -[Timer] -OnUnitInactiveSec=5m -- cgit v1.1-4-g5e80 From c3dec27c4819b3b825423e5774dc044412d29222 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Wed, 8 Nov 2017 14:12:45 -0500 Subject: config-path: use %q to avoid complexity --- .local/bin/config-path | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/.local/bin/config-path b/.local/bin/config-path index cbecc95..eb88092 100755 --- a/.local/bin/config-path +++ b/.local/bin/config-path @@ -40,15 +40,14 @@ var_add() { } var_done() { - eval "$1=\"\${ary_$1[*]}\"" - declare -p $1 + local var=$1 + local valref="ary_${var}[*]" + printf '%s=%q\n' "${var}" "${!valref}" } main() { - export LC_ALL=C # Work around brokenly slow Unicode handling - # in Bash - IFS=: + # Import existing values var_init PATH var_init LD_LIBRARY_PATH @@ -66,12 +65,9 @@ main() { done # Finally, print the values - lines=() for var in PATH LD_LIBRARY_PATH PKG_CONFIG_PATH RUBYLIB PERL5LIB; do - lines+=("$(var_done "$var")") + var_done "$var" done - shopt -s extglob - printf -- '%s\n' "${lines[@]##declare *(-+([[:graph:]]) )}" } main "$@" -- cgit v1.1-4-g5e80 From 8e046f1b3f39bd2c5bca498965c7d082057982dd Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Wed, 8 Nov 2017 14:13:26 -0500 Subject: git: Use git-merge-changelog if available --- .config/git/attributes | 1 + .config/git/config | 3 +++ 2 files changed, 4 insertions(+) create mode 100644 .config/git/attributes diff --git a/.config/git/attributes b/.config/git/attributes new file mode 100644 index 0000000..56444aa --- /dev/null +++ b/.config/git/attributes @@ -0,0 +1 @@ +ChangeLog merge=merge-changelog diff --git a/.config/git/config b/.config/git/config index 6e5abf2..21efa65 100644 --- a/.config/git/config +++ b/.config/git/config @@ -5,6 +5,9 @@ ui = auto [push] default = matching +[merge "merge-changelog"] + name = GNU-style ChangeLog merge driver + driver =git-merge-changelog %O %A %B [alias] lg = log --graph --format='%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative hist = log --format='%h %ci -%C(yellow)%d%Creset %s %C(bold blue)<%an>%Creset' --abbrev-commit -- cgit v1.1-4-g5e80 From c5c39eb8c02c040f077b8a43999e88af40790a42 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Fri, 14 Apr 2017 12:21:50 -0400 Subject: update mail filters --- .config/maildirproc/att.rc | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/.config/maildirproc/att.rc b/.config/maildirproc/att.rc index 67335e7..f25aa09 100644 --- a/.config/maildirproc/att.rc +++ b/.config/maildirproc/att.rc @@ -15,12 +15,14 @@ def mailman_domain(mail, domain): m = mail["List-Id"].matches("^(.*<|)([^<]*)\."+re.escape(domain)) if m: return m.group(2) + ret = None for hdr in [ 'To', 'Cc', 'From' ]: m = mail[hdr].matches("((\w|-)*)@"+re.escape(domain)) if m: - if mail["Subject"].contains("["+m.group(1)+"]"): - return m.group(1) - return None + ret = m.group(1) + if mail["Subject"].contains("["+ret+"]"): + return ret + return ret def ezmlm_domain(mail, domain): """ @@ -149,17 +151,19 @@ def my_whitelist(mail): def my_filters(mail): # .software.* (GNU Mailman) - for pair in [ [ 'gnu.org', 'gnu' ], # https://lists.gnu.org/mailman/options/bug-librejs/lukeshu@sbcglobal.net - [ 'nongnu.org', 'nongnu' ], # https://lists.nongnu.org/mailman/options/libreboot/lukeshu@sbcglobal.net - [ 'gnome.org', 'gnome' ], # https://mail.gnome.org/mailman/options/networkmanager-list/lukeshu@sbcglobal.net - [ 'archlinux.org', 'archlinux' ], - [ 'lists.freedesktop.org', 'freedesktop' ], - [ 'lists.fedorahosted.org', 'fedorahosted' ], - [ 'lists.arthurdejong.org', 'arthurdejong' ], - [ 'lists.stanford.edu', 'stanford' ], - [ 'mailman.stanford.edu', 'stanford' ], - [ 'lists.parabola.nu', 'parabola' ], - [ 'parabola.nu', 'parabola' ] ]: + for pair in [ + [ 'archlinux.org' , 'archlinux' ], # @sbcglobal.net and @lukeshu.com ; problems delivering to Yahoo! + [ 'gnome.org' , 'gnome' ], # https://mail.gnome.org/mailman/options/networkmanager-list/lukeshu@lukeshu.com + [ 'gnu.org' , 'gnu' ], # https://lists.gnu.org/mailman/options/bug-librejs/lukeshu@lukeshu.com + [ 'lists.arthurdejong.org' , 'arthurdejong' ], + [ 'lists.freedesktop.org' , 'freedesktop' ], # https://lists.freedesktop.org/mailman/options/systemd-devel/lukeshu@lukeshu.com + [ 'lists.parabola.nu' , 'parabola' ], # https://lists.parabola.nu/mailman/options/dev/lukeshu@lukeshu.com + [ 'lists.reproducible-builds.org' , 'reproducible-builds' ], # https://lists.reproducible-builds.org/options/rb-general/lukeshu@lukeshu.com + [ 'nongnu.org' , 'nongnu' ], # https://lists.nongnu.org/mailman/options/gnu-linux-libre/lukeshu@lukeshu.com + [ 'redhat.com' , 'redhat' ], # https://www.redhat.com/mailman/options/pam-list/lukeshu@lukeshu.com + [ 'lists.stanford.edu', 'stanford' ], + [ 'mailman.stanford.edu', 'stanford' ], + ]: list = mailman_domain(mail, pair[0]) if list: move_ham(mail, ".software."+pair[1]+"."+list) @@ -182,6 +186,7 @@ def my_filters(mail): or is_to_or_from(mail, "parabolagnulinux.org") or is_to_or_from(mail, "parabola.nu") or is_to_or_from(mail, "kiwwwi.com.ar") + or is_to_or_from(mail, "jon@whiteheat.org.uk") ): move_ham(mail, ".software.parabola") return -- cgit v1.1-4-g5e80 From 65a5662ffb11e76b68f81ee24c37d74e49bd0d98 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Wed, 8 Nov 2017 14:10:38 -0500 Subject: Revamp mail filtering and organization --- .config/Makefile | 16 +- .config/emacs/wl.el | 12 +- .config/maildirproc/att.rc | 490 ------------------ .config/maildirproc/default.rc | 556 +++++++++++++++++++++ .config/offlineimap/config | 34 +- .../maildirproc@default.service | 1 + 6 files changed, 602 insertions(+), 507 deletions(-) delete mode 100644 .config/maildirproc/att.rc create mode 100644 .config/maildirproc/default.rc create mode 120000 .config/systemd/user/default.target.wants/maildirproc@default.service diff --git a/.config/Makefile b/.config/Makefile index 4e8166e..62c639e 100644 --- a/.config/Makefile +++ b/.config/Makefile @@ -21,8 +21,20 @@ clean: rm -f -- $(targets) .PHONY: all clean -${HOME}/.folders: ${HOME}/Maildir $(MAKEFILE_LIST) - find -L $< -mindepth 2 -maxdepth 2 \( -type f -name "maildirfolder" -o -type d -name new -o -type d -name tmp -o -type d -name cur \) -printf '%P\0' | xargs -r0 dirname -z -- | sort -zu | xargs -0 printf -- '.%s\n' > '$@' +ifneq ($(wildcard ${HOME}/Maildir),) +MAILDIRS = . +-include ${STATEDIR}/maildirs.mk +${HOME}/.folders: $(addprefix ${HOME}/Maildir/,${MAILDIRS}) + find -L $< \( -false \ + -o -type f -name maildirfolder \ + -o -type d -name new \ + -o -type d -name tmp \ + -o -type d -name cur \ + \) -printf '%P\0' | xargs -r0 dirname -z -- | sort -zu | xargs -0 printf -- '.%s\n' > '$@' +${STATEDIR}/maildirs.mk: ${HOME}/.folders + < $< sed -n 's/^\.//p' | xargs -d $$'\n' -r dirname -- | sort -u | xargs -d $$'\n' -r printf 'MAILDIRS += %s\n' > $@ +endif + ${GIT_DIR}/info/exclude: ${HOME}/.git.info.exclude.in $(shell echo .??*/) ( cat $<; find $^ -type f -name 'CACHEDIR.TAG' -printf '%h\n'|sed 's@^\./@/@' ) > $@ diff --git a/.config/emacs/wl.el b/.config/emacs/wl.el index c27c87e..08d9ec3 100644 --- a/.config/emacs/wl.el +++ b/.config/emacs/wl.el @@ -18,12 +18,12 @@ ;; note: all below are dirs (Maildirs) under elmo-maildir-folder-path ;; the '.'-prefix is for marking them as maildirs - wl-fcc ".Sent" ;; sent msgs go to the "sent"-folder - wl-default-folder ".FOLDERS.Ham" ;; my main inbox - wl-draft-folder ".Draft" ;; store drafts in 'postponed' - wl-trash-folder ".Trash" ;; put trash in 'trash' - wl-spam-folder ".FOLDERS.Spam.training" ;; put spam in 'Bulk Mail' - wl-queue-folder ".FOLDERS.Queue" ;; we don't use this + wl-default-folder ".MAIN/Ham.2017" + wl-spam-folder ".QUEUES/Spam" + wl-draft-folder ".WL/Draft" + wl-trash-folder ".WL/Trash" + wl-queue-folder ".WL/Queue" + wl-fcc ".WL/Sent" ;; check this folder periodically, and update modeline ;wl-biff-check-folder-list '(".todo") ;; check every 180 seconds diff --git a/.config/maildirproc/att.rc b/.config/maildirproc/att.rc deleted file mode 100644 index f25aa09..0000000 --- a/.config/maildirproc/att.rc +++ /dev/null @@ -1,490 +0,0 @@ -# -*- mode: python; indent-tabs-mode: t -*- - -import os -import os.path -import subprocess -import datetime -import re -# -# Mail attribute utilities - -def mailman_domain(mail, domain): - """ - Return a string that is the list-name for a mailman domain - """ - m = mail["List-Id"].matches("^(.*<|)([^<]*)\."+re.escape(domain)) - if m: - return m.group(2) - ret = None - for hdr in [ 'To', 'Cc', 'From' ]: - m = mail[hdr].matches("((\w|-)*)@"+re.escape(domain)) - if m: - ret = m.group(1) - if mail["Subject"].contains("["+ret+"]"): - return ret - return ret - -def ezmlm_domain(mail, domain): - """ - Return a string that is the list-name for a ezmlm domain - """ - m = mail["Mailing-List"].matches("^(.* )?(\w+)(-\S*)?@"+re.escape(domain)+"(;.*)?$") - if m: - return m.group(2) - for hdr in [ 'To', 'Cc', 'From' ]: - m = mail[hdr].matches("(\w)@"+re.escape(domain)) - if m: - return m.group(1) - return None - -def majordomo_domain(mail, domain): - """ - Return a string that is the list-name for a majordomo domain - """ - m = mail["List-Id"].matches("^(.*<|)([^<]*)\."+re.escape(domain)) - if m: - return m.group(2) - for hdr in [ 'To', 'Cc', 'From' ]: - m = mail[hdr].matches("((\w|-)*)@"+re.escape(domain)) - if m: - return m.group(1) - -def is_to_or_from(mail, address): - """ - Return true if [mail] is to or from an address that contains [address]. - """ - return ( - False - or mail["From"].contains(address) - or mail["Reply-To"].contains(address) - or mail.target.contains(address)) -def is_to_or_from_re(mail, address): - """ - Return true if [mail] is to or from an address that matches the - regex [address]. - """ - return ( - mail["From"].matches(address) - or mail.target.matches(address)) -# -# bogofilter utilites - -def bogofilter_auto(mail): - p = subprocess.Popen( - ["bogofilter", "-u", "-v", "-I", mail.path], - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT) - (output, _) = p.communicate() - processor.log("*** Bogofilter result: {0!r}".format(output.rstrip())) - if p.returncode not in [0, 1, 2]: - processor.log_error( - "Error running bogofilter: Return code = {0!r}".format( - p.returncode)) - return p.returncode -def bogofilter_ham(mail): - subprocess.call(["bogofilter", "-S", "-n", "-I", mail.path]) -def bogofilter_spam(mail): - subprocess.call(["bogofilter", "-N", "-s", "-I", mail.path]) -# -# The core of my filters - -def move_ham(mail, folder): - y = datetime.datetime.now().year - folder = "FOLDERS.Ham."+str(y)+folder - dir = processor.maildir_base+"/"+folder - if not os.path.isfile(dir+"/maildirfolder"): - os.makedirs(dir+"/tmp", 0o777, True) - os.makedirs(dir+"/new", 0o777, True) - os.makedirs(dir+"/cur", 0o777, True) - open(dir+"/maildirfolder", 'a').close() - mail.move(folder) - -def my_whitelist(mail): - return ( - False - or is_to_or_from(mail, "@opengroup.org") - or is_to_or_from(mail, "@purestorage.com") - or is_to_or_from(mail, "@vger.kernel.org") - or is_to_or_from(mail, "Bryan@ChankTunUnGi.onmicrosoft.com") - or is_to_or_from(mail, "cacnedcomms@gmail.com") - or is_to_or_from(mail, "fsf.org") - or is_to_or_from(mail, "gnu.org") - or is_to_or_from(mail, "parabola.nu") - or is_to_or_from(mail, "parabolagnulinux.org") - or mail["From"] == "3174451635@mms.att.net" - or mail["From"] == "MAILER-DAEMON@yahoo.com" - or mail["From"].contains("@careereco.com") - or mail["From"].contains("@ciholas.com") - or mail["From"].contains("@e.oldnational.com>") - or mail["From"].contains("@facebookmail.com>") - or mail["From"].contains("@gandi.net") - or mail["From"].contains("@github.com>") - or mail["From"].contains("@goodwillindy.org>") - or mail["From"].contains("@kickstarter.com>") - or mail["From"].contains("@list.cr.yp.to") - or mail["From"].contains("@lpi.org>") - or mail["From"].contains("@lulzbot.com>") - or mail["From"].contains("@mail.scribd.com>") - or mail["From"].contains("@massdrop.com>") - or mail["From"].contains("@msdlt.k12.in.us>") - or mail["From"].contains("@parabola.nu") - or mail["From"].contains("@post.oreilly.com>") - or mail["From"].contains("@scouting.org>") - or mail["From"].contains("@solutionsinplastic.com>") - or mail["From"].contains("@startcom.org>") - or mail["From"].contains("@usfirst.org>") - or mail["From"].contains("@vectren.com") - or mail["From"].contains("@vectrenemail.com") - or mail["From"].contains("@wolframalpha.com>") - or mail["From"].contains("Promo@email.newegg.com") - or mail["From"].contains("info@email2.mysimplemobile.com") - or mail["From"].contains("margieshu@sbcglobal.net") - or mail["From"].contains("parabolagnulinux.org") - or mail["From"].matches("@[a-z]+\.gandi\.net") - or mail["List-Id"].matches(".*\.(gnu|gnome|archlinux|parabolagnulinuxlibre|fedorahosted)\.org") - or mail["List-Id"].matches(".*\.parabola\.nu") - or mail["Subject"].contains("[Dev]") - or mail["Subject"].contains("[Maintenance]") - or mail["Subject"].contains("[PATCH") - or mail["Subject"].contains("[systemd-devel]") - ) - -def my_filters(mail): - # .software.* (GNU Mailman) - for pair in [ - [ 'archlinux.org' , 'archlinux' ], # @sbcglobal.net and @lukeshu.com ; problems delivering to Yahoo! - [ 'gnome.org' , 'gnome' ], # https://mail.gnome.org/mailman/options/networkmanager-list/lukeshu@lukeshu.com - [ 'gnu.org' , 'gnu' ], # https://lists.gnu.org/mailman/options/bug-librejs/lukeshu@lukeshu.com - [ 'lists.arthurdejong.org' , 'arthurdejong' ], - [ 'lists.freedesktop.org' , 'freedesktop' ], # https://lists.freedesktop.org/mailman/options/systemd-devel/lukeshu@lukeshu.com - [ 'lists.parabola.nu' , 'parabola' ], # https://lists.parabola.nu/mailman/options/dev/lukeshu@lukeshu.com - [ 'lists.reproducible-builds.org' , 'reproducible-builds' ], # https://lists.reproducible-builds.org/options/rb-general/lukeshu@lukeshu.com - [ 'nongnu.org' , 'nongnu' ], # https://lists.nongnu.org/mailman/options/gnu-linux-libre/lukeshu@lukeshu.com - [ 'redhat.com' , 'redhat' ], # https://www.redhat.com/mailman/options/pam-list/lukeshu@lukeshu.com - [ 'lists.stanford.edu', 'stanford' ], - [ 'mailman.stanford.edu', 'stanford' ], - ]: - list = mailman_domain(mail, pair[0]) - if list: - move_ham(mail, ".software."+pair[1]+"."+list) - return - # .software.* (EZMLM) - for pair in [ [ 'list.cr.yp.to', 'djb' ] ]: - list = ezmlm_domain(mail, pair[0]) - if list: - move_ham(mail, ".software."+pair[1]+"."+list) - return - # .software.* (Majordomo) - for pair in [ [ 'vger.kernel.org', 'kernel' ] ]: - list = majordomo_domain(mail, pair[0]) - if list: - move_ham(mail, ".software."+pair[1]+"."+list) - return - # .software.parabola - if ( - False - or is_to_or_from(mail, "parabolagnulinux.org") - or is_to_or_from(mail, "parabola.nu") - or is_to_or_from(mail, "kiwwwi.com.ar") - or is_to_or_from(mail, "jon@whiteheat.org.uk") - ): - move_ham(mail, ".software.parabola") - return - # .software.POSIX - if is_to_or_from(mail, "austin-group-l@opengroup.org"): - move_ham(mail, ".software.POSIX") - return - # .software.TravisCI - if mail["From"].contains("builds@travis-ci.org"): - move_ham(mail, ".software.TravisCI") - return - # .software - for address in [ - "@archlinux.org", - "@canonical.org", - "@cnuk.org", - "@core3.amsl.com", - "@defectivebydesign.org", - "@eff.org", - "@fedorahosted.org", - "@foocorp.net", - "@fsf.org", - "@github.com", - "@gitorious.org", - "@gnome.org", - "@gnu.org", - "@ietf.org", - "@kde.org", - "@lists.fedorahosted.org", - "@mozilla.org", - "@nongnu.org", - "@sourceforge.com", - "@thyrsus.com", - ]: - if is_to_or_from(mail, address): - move_ham(mail, ".software") - return - # .servers - if ( - False - or mail["From"].contains("@gandi.net") - or mail["From"].contains("@ramhost.us") - or mail["From"].contains("@startcom.org") - or mail["From"].contains("@startssl.com") - or mail["From"].contains("@vultr.com") - or (mail["From"].contains("@2co.com") and mail["Subject"].contains("RAM Host")) - ): - move_ham(mail, ".servers") - return - # .Social.* - if mail["From"].matches("facebook(|mail)\.com"): - move_ham(mail, ".Social.Facebook") - return - if mail["From"].matches("identi\.ca|statusnet"): - move_ham(mail, ".Social.Identica") - return - if mail["From"].matches("twitter\.com"): - move_ham(mail, ".Social.Twitter") - return - if mail["From"].matches("@xkcd\.com"): - move_ham(mail, ".Social.xkcd") - return - if is_to_or_from(mail, "linkedin.com"): - move_ham(mail, ".Social.LinkedIn") - return - # .BSA - if ( - False - or mail["List-Id"].contains("troopmailinglist.troop276.net") - or mail["Subject"].matches("troop") - or mail["Subject"].matches("merit\s*badge") - or is_to_or_from(mail, "t276_announcements@att.net") - or is_to_or_from(mail, "Bryan@ChankTunUnGi.onmicrosoft.com") - or is_to_or_from(mail, "basu@maharjan.org") - or is_to_or_from(mail, "cacnedcomms@gmail.com") - or is_to_or_from(mail, "crossroadsbsa.org") - or is_to_or_from(mail, "dhoyt@yourhomecompany.com") - or is_to_or_from(mail, "dllargent@comcast.net") - or is_to_or_from(mail, "eldredmac@comcast.net")# MacDonell - or is_to_or_from(mail, "jsting@sbcglobal.net") - or is_to_or_from(mail, "mitchprather@sbcglobal.net") - or is_to_or_from(mail, "muellerindy@yahoo.com") - or is_to_or_from(mail, "mytroop.us") - or is_to_or_from(mail, "oa_wap@yahoo.com") - or is_to_or_from(mail, "salupo_vincent_p@lilly.com") - or is_to_or_from(mail, "scouting.org") - or is_to_or_from(mail, "solorzano.luis@rocketmail.com") - or is_to_or_from(mail, "trdindy@comcast.net") - or is_to_or_from(mail, "wjensen111@aol.com") - ): - move_ham(mail, ".BSA") - return - # .FRC - for address in [ "@ni.com", "@usfirst.org", "@firstinspires.org" ]: - if is_to_or_from(mail, address): - move_ham(mail, ".FRC") - return - # .FRC.829 - if ( - False - or mail["Subject"].matches("\b829\b") - or is_to_or_from(mail, "wcxctrack829@aim.com") # Pat - or is_to_or_from(mail, "william.walk@gmail.com") - ): - move_ham(mail, ".FRC.829") - return - # .FRC.1024 - if ( - False - or mail["Subject"].matches("\b1024\b") - or mail["Subject"].matches("kil-?a-?bytes") - or is_to_or_from(mail, "BBonahoom@stanleyworks.com") - or is_to_or_from(mail, "bryanbonahoom@gmail.com") - or is_to_or_from(mail, "allison.m.babcock@gmail.com") - or is_to_or_from(mail, "cdewalt3@yahoo.com") - or is_to_or_from(mail, "dave.nelson@ecolab.com") - or is_to_or_from(mail, "dickaustin190@yahoo.com") - or is_to_or_from(mail, "djnels1@comcast.net") # Dave and Julie Nelson - or is_to_or_from(mail, "gamefreak207@gmail.com") # Brett Leedy - or is_to_or_from(mail, "jason.zielke@gmail.com") - or is_to_or_from(mail, "jeffreysmith@msdlt.k12.in.us") - or is_to_or_from(mail, "sarahlittell@comcast.net") - or is_to_or_from(mail, "silioso@gmail.com") - or is_to_or_from(mail, "skiplittell@comcast.net") - or is_to_or_from(mail, "tswilson4801@att.net") - ): - move_ham(mail, ".FRC.1024") - return - # .FRC.4272 - if ( - False - or mail["Subject"].matches("\b4272\b") - or mail["Subject"].contains("[ME297]") - or is_to_or_from(mail, "firstteam4272@gmail.com") - or is_to_or_from(mail, "@tscstudents.net") - or is_to_or_from(mail, "abenyeho@purdue.edu") - or is_to_or_from(mail, "Henry65@purdue.edu") - or is_to_or_from(mail, "chang282@purdue.edu") - ): - move_ham(mail, ".FRC.4272") - return - # .Purdue.* - if ( - False - or mail["Subject"].contains("[PASE]") - or is_to_or_from(mail, "Purduealumni@purdue.edu") - or is_to_or_from(mail, "pase@purdue.edu") - ): - move_ham(mail, ".Purdue.PASE") - return - if mail["Subject"].contains("[PLUG]"): - move_ham(mail, ".Purdue.PLUG") - return - if is_to_or_from(mail, "@cerias.purdue.edu"): - move_ham(mail, ".Purdue.CERIAS") - return - if ( - False - or is_to_or_from(mail, "purduehackers@gmail.com") - or is_to_or_from(mail, "royfu@purdue.edu") - or is_to_or_from(mail, "usmannkhan@purdue.edu") - ): - move_ham(mail, ".Purdue.Hackers") - return - if ( - False - or mail["Subject"].contains("[CS Opportunity Update]") - or mail["Subject"].contains("[CS Majors]") - ): - move_ham(mail, ".Purdue.CS") - return - if ( - False - or is_to_or_from(mail, "askcco@purdue.edu") - or is_to_or_from_re(mail, "pmx-auto-approve\+.*@purdue\.edu") - or is_to_or_from(mail, "evertrue@purdue.edu") - or is_to_or_from(mail, "college.response@purdue.edu") - or is_to_or_from(mail, "purduepresident@purdue.edu") - or is_to_or_from(mail, "@prf.org") - ): - move_ham(mail, ".Purdue.misc") - return - # .misc.* - if mail["From"].matches("schwab\.com"): - move_ham(mail, ".misc.schwab") - return - if mail["From"].matches("@ebay\.com"): - move_ham(mail, ".misc.ebay") - return - if ( - False - or is_to_or_from(mail, "margieshu@sbcglobal.net") - or is_to_or_from(mail, "3174451635@mms.att.net") - ): - move_ham(mail, ".misc.Mom") - return - for address in [ - "@lpi.org", - "@pearson.com", - "ciscotraining-notify@cisco.com", - "CompTIA", - ]: - if mail["From"].contains(address): - move_ham(mail, ".misc.CompTIA") - return - if ( - False - or mail["From"].contains("newsletter") - or mail["From"].contains("announcements") - or mail["Subject"].contains("newsletter") - or mail["Message-Id"].contains("@sailthru.com") - or False - or (mail["From"].contains("@sparkfun.com") and mail["Message-Id"].contains("rsgsv.net")) - or (mail["From"].contains("no-reply@kickstarter.com") and mail["Message-Id"].contains(".sendgrid.net")) - or (mail["From"].contains("no-reply@kickstarter.com") and ( - False - or mail["Subject"].contains("Projects We Love:") - or mail["Subject"].contains("Project Update"))) - or mail["From"].contains("Info@mailing.jamendo.com") - or mail["From"].contains("Promo@email.newegg.com") - or mail["From"].contains("auto@comicsbyemail.com") - or mail["From"].contains("info@demandprogress.org") - or mail["From"].contains("info@email2.mysimplemobile.com") - or mail["From"].contains("info@massdrop.com") - or mail["From"].contains("info@lulzbot.com") - or mail["From"].contains("oreilly.com") - or mail["From"].contains("reply-to@e.digikey.com") - or mail["From"].contains("communication@communications.bmv.in.gov") - or mail["From"].contains("sales@solutionsinplastic.com") - or mail["From"].contains("social@goodwillindy.org") - or mail["From"].contains("support@support.digitalocean.com") - or mail["From"].contains("@pardonsnowden.org") - ): - move_ham(mail, ".misc.Newsletters") - return - if ( - False - or mail["From"].matches("@localhost") - or mail["From"].matches("@[^,>]*\.local") - or mail["From"].matches("@[^,>]*\.lan") - or mail["To"].matches("luke@") - ): - move_ham(mail, ".misc.LocalSystems") - return - if ( - False - or mail["Subject"].contains("password") - or mail["Subject"].contains("account") - or mail["From"].contains("accounts") - ): - move_ham(mail, ".misc.accounts") - return - - move_ham(mail, "") -# -# call the above - -def handle_incoming_ham_training(mail): - bogofilter_ham(mail) - handle_incoming_ham(mail) -def handle_incoming_spam_training(mail): - bogofilter_spam(mail) - mail.move("FOLDERS.Spam") - -def handle_incoming_ham(mail): - my_filters(mail) -def handle_incoming_spam(mail): - mail.move("FOLDERS.Spam") - -def handle_incoming_unknown(mail): - # Whitelist - if my_whitelist(mail): - handle_incoming_ham_training(mail) - return - - spam = bogofilter_auto(mail) - if spam == 0: - handle_incoming_spam(mail) - return - elif spam == 1: - handle_incoming_ham(mail) - return - elif spam == 2: - mail.move("FOLDERS.MysteryMeat") - return - else: - mail.move("FOLDERS.BogoFail") - return - -# hook the above functions into the maildirproc processor -processor.maildir_base = "~/Maildir" -processor.auto_reload_rcfile = True -handle_mapping = { - "Inbox": handle_incoming_unknown, - "Bulk Mail": handle_incoming_unknown, # fucking Yahoo! - "FOLDERS.Spam.training": handle_incoming_spam_training, - "FOLDERS.Ham.training": handle_incoming_ham_training, - } -processor.maildirs = handle_mapping.keys() -for mail in processor: - handle_mapping[mail.maildir](mail) diff --git a/.config/maildirproc/default.rc b/.config/maildirproc/default.rc new file mode 100644 index 0000000..e264cc3 --- /dev/null +++ b/.config/maildirproc/default.rc @@ -0,0 +1,556 @@ +#!/hint/python3 +# -*- indent-tabs-mode: t -*- + +import os +import os.path +import subprocess +import datetime +import re +import email.utils +# +# Mail attribute utilities + +def parse_address(x): + return email.utils.parseaddr(str(x))[1] +def parse_addresses(x): + return [p[1] for p in email.utils.getaddresses([str(x)])] + +def match_re(x, pat): + return re.fullmatch(pat, x, re.IGNORECASE) +def match_glob(x, glob): + if '@' in glob: + if glob.startswith('@'): + return x.lower().endswith(glob.lower()) + return x.lower() == glob.lower() + else: + return x.lower().endswith('@'+glob.lower()) or x.lower().endswith('.'+glob.lower()) + +def originator_addresses(mail): + return [p[1] for p in email.utils.getaddresses([ + str(mail['From']), + str(mail['Sender']), + str(mail['Reply-To']), + ]) if p[1] != ''] + +def destination_addresses(mail): + return [p[1] for p in email.utils.getaddresses([ + str(mail['To']), + str(mail['Cc']), + str(mail['Bcc']), + ]) if p[1] != ''] +def all_addresses(mail): + return originator_addresses(mail) + destination_addresses(mail) + +def mailman_domain(mail, domain): + """ + Return a string that is the list-name for a mailman domain + """ + m = match_re(parse_address(mail["List-Id"]), "(.*)\."+re.escape(domain)) + if m: + return m.group(1) + if mail["List-Id"] != "": + return None + for addr in destination_addresses(mail): + m = match_re(addr, "(.*)@"+re.escape(domain)) + if m: + ret = m.group(1) + if mail["Subject"].contains("["+ret+"]"): + return ret + return None + +def ezmlm_domain(mail, domain): + """ + Return a string that is the list-name for a ezmlm domain + """ + m = match_re(parse_address(mail["List-Id"]), "(.*)\."+re.escape(domain)) + if m: + return m.group(1) + if mail["List-Id"] != "": + return None + ml = [s.strip() for s in str(mail["Mailing-List"]).split(";")] + if 'run by ezmlm' in ml: + contacts = [s[7:].strip() for s in ml if s.startswith('contact ')] + for contact in contacts: + m = match_re(contact, "(.+)-help@"+re.escape(domain)) + if m: + return m.group(1) + for addr in destination_addresses(mail): + m = match_re(addr, "(.*)@"+re.escape(domain)) + if m: + return m.group(1) + return None + +def majordomo_domain(mail, domain): + """ + Return a string that is the list-name for a majordomo domain + """ + m = match_re(parse_address(mail["List-Id"]), "(.*)\."+re.escape(domain)) + if m: + return m.group(1) + if mail["List-Id"] != "": + return None + for addr in destination_addresses(mail): + m = match_re(addr, "(.*)@"+re.escape(domain)) + if m: + return m.group(1) + return None + +def is_from(mail, address): + return any(match_glob(addr, address) for addr in originator_addresses(mail)) +def is_from_re(mail, address): + return any(match_re(addr, address) for addr in originator_addresses(mail)) + +def is_to_or_from(mail, address): + return any(match_glob(addr, address) for addr in all_addresses(mail)) +def is_to_or_from_re(mail, address): + return any(match_re(addr, address) for addr in all_addresses(mail)) +# +# bogofilter utilites + +def bogofilter_auto(mail): + p = subprocess.Popen( + ["bogofilter", "-u", "-v", "-I", mail.path], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + (output, _) = p.communicate() + processor.log("*** Bogofilter result: {0!r}".format(output.rstrip())) + if p.returncode not in [0, 1, 2]: + processor.log_error( + "Error running bogofilter: Return code = {0!r}".format( + p.returncode)) + return p.returncode +def bogofilter_ham(mail): + subprocess.call(["bogofilter", "-S", "-n", "-I", mail.path]) +def bogofilter_spam(mail): + subprocess.call(["bogofilter", "-N", "-s", "-I", mail.path]) +# +# The core of my filters + +def move_ham(mail, folder): + y = datetime.datetime.now().year + folder = "MAIN/Ham."+str(y)+folder + dir = processor.maildir_base+"/"+folder + if not os.path.isfile(dir+"/maildirfolder"): + os.makedirs(dir+"/tmp", 0o777, True) + os.makedirs(dir+"/new", 0o777, True) + os.makedirs(dir+"/cur", 0o777, True) + open(dir+"/maildirfolder", 'a').close() + subprocess.call(['make', '-C', os.environ['XDG_CONFIG_HOME']]) + mail.move(folder) + +def my_whitelist(mail): + return ( + False + or is_to_or_from(mail, "opengroup.org") + or is_to_or_from(mail, "purestorage.com") + or is_to_or_from(mail, "sourceware.org") + or is_to_or_from(mail, "vger.kernel.org") + or is_to_or_from(mail, "Bryan@ChankTunUnGi.onmicrosoft.com") + or is_to_or_from(mail, "cacnedcomms@gmail.com") + or is_to_or_from(mail, "fsf.org") + or is_to_or_from(mail, "gnu.org") + or is_to_or_from(mail, "parabola.nu") + or is_to_or_from(mail, "parabolagnulinux.org") + or is_from(mail, "3174451635@mms.att.net") + or is_from(mail, "MAILER-DAEMON@yahoo.com") + or is_from(mail, "careereco.com") + or is_from(mail, "ciholas.com") + or is_from(mail, "e.oldnational.com") + or is_from(mail, "facebookmail.com") + or is_from(mail, "gandi.net") + or is_from(mail, "github.com") + or is_from(mail, "goodwillindy.org") + or is_from(mail, "kickstarter.com") + or is_from(mail, "list.cr.yp.to") + or is_from(mail, "lpi.org") + or is_from(mail, "lulzbot.com") + or is_from(mail, "mail.scribd.com") + or is_from(mail, "massdrop.com") + or is_from(mail, "msdlt.k12.in.us") + or is_from(mail, "parabola.nu") + or is_from(mail, "post.oreilly.com") + or is_from(mail, "scouting.org") + or is_from(mail, "solutionsinplastic.com") + or is_from(mail, "startcom.org") + or is_from(mail, "usfirst.org") + or is_from(mail, "vectren.com") + or is_from(mail, "vectrenemail.com") + or is_from(mail, "wolframalpha.com") + or is_from(mail, "Promo@email.newegg.com") + or is_from(mail, "info@email2.mysimplemobile.com") + or is_from(mail, "margieshu@sbcglobal.net") + or is_from(mail, "parabolagnulinux.org") + or is_from(mail, "gandi.net") + or match_re(parse_address(mail["List-Id"]), ".*\.(gnu|gnome|archlinux|parabolagnulinuxlibre|fedorahosted)\.org") + or match_re(parse_address(mail["List-Id"]), ".*\.parabola\.nu") + or mail["Subject"].contains("[Dev]") + or mail["Subject"].contains("[Maintenance]") + or mail["Subject"].contains("[PATCH") + or mail["Subject"].contains("[systemd-devel]") + ) + +def my_filters(mail): + if mail["From"].contains("Parabola Website Notification "): + move_ham(mail, ".software.parabola.dev.web-notif") + return + + # .software.POSIX (custom mlm, I think) + if is_to_or_from(mail, "austin-group-l@opengroup.org"): + move_ham(mail, ".software.POSIX") + return + # .software.* (GNU Mailman) + for pair in [ + [ 'archlinux.org' , 'archlinux' ], # @sbcglobal.net and @lukeshu.com ; problems delivering to Yahoo! + [ 'gnome.org' , 'gnome' ], # https://mail.gnome.org/mailman/options/networkmanager-list/lukeshu@lukeshu.com + [ 'gnu.org' , 'gnu' ], # https://lists.gnu.org/mailman/options/bug-librejs/lukeshu@lukeshu.com + [ 'lists.arthurdejong.org' , 'arthurdejong' ], + [ 'lists.fedorahosted.org' , 'fedorahosted' ], + [ 'lists.freedesktop.org' , 'freedesktop' ], # https://lists.freedesktop.org/mailman/options/systemd-devel/lukeshu@lukeshu.com + [ 'lists.parabola.nu' , 'parabola' ], # https://lists.parabola.nu/mailman/options/dev/lukeshu@lukeshu.com + [ 'lists.reproducible-builds.org' , 'reproducible-builds' ], # https://lists.reproducible-builds.org/options/rb-general/lukeshu@lukeshu.com + [ 'nongnu.org' , 'nongnu' ], # https://lists.nongnu.org/mailman/options/gnu-linux-libre/lukeshu@lukeshu.com + [ 'redhat.com' , 'redhat' ], # https://www.redhat.com/mailman/options/pam-list/lukeshu@lukeshu.com + [ 'lists.stanford.edu' , 'stanford' ], + [ 'mailman.stanford.edu' , 'stanford' ], + + ]: + list = mailman_domain(mail, pair[0]) + if list: + move_ham(mail, ".software."+pair[1]+"."+list) + return + # .software.* (EZMLM) + for pair in [ + [ 'list.cr.yp.to', 'djb' ], + [ 'sourceware.org', 'sourceware' ], + ]: + list = ezmlm_domain(mail, pair[0]) + if list: + move_ham(mail, ".software."+pair[1]+"."+list) + return + if is_from(mail, "sourceware-bugzilla@sourceware.org"): + move_ham(mail, ".software.sourceware-bugzilla") + return + # .software.* (Majordomo) + for pair in [ [ 'vger.kernel.org', 'kernel' ] ]: + list = majordomo_domain(mail, pair[0]) + if list: + move_ham(mail, ".software."+pair[1]+"."+list) + return + # .software.parabola + if ( + False + or is_to_or_from(mail, "ceata.org") + or is_to_or_from(mail, "kiwwwi.com.ar") + or is_to_or_from(mail, "endefensadelsl.org") + or is_to_or_from(mail, "parabola.nu") + or is_to_or_from(mail, "parabolagnulinux.org") + or is_to_or_from(mail, "xylon.me.uk") + or False + or is_to_or_from(mail, "g4jc@openmailbox.org") + or is_to_or_from(mail, "jon@whiteheat.org.uk") + or is_to_or_from(mail, "srw@openmailbox.org") + or is_to_or_from(mail, "eliotime3000@openmailbox.org") + ): + move_ham(mail, ".software.parabola") + return + # .software.TravisCI + if is_from(mail, "builds@travis-ci.org"): + move_ham(mail, ".software.TravisCI") + return + # .software + for address in [ + "archlinux.org", + "canonical.org", + "cnuk.org", + "core3.amsl.com", + "defectivebydesign.org", + "eff.org", + "fedorahosted.org", + "foocorp.net", + "fsf.org", + "github.com", + "gitorious.org", + "gnome.org", + "gnu.org", + "ietf.org", + "kde.org", + "mozilla.org", + "nongnu.org", + "sourceforge.com", + "thyrsus.com", + ]: + if is_to_or_from(mail, address): + move_ham(mail, ".software") + return + # .servers + if ( + False + or is_from(mail, "gandi.net") + or is_from(mail, "ramhost.us") + or is_from(mail, "startcom.org") + or is_from(mail, "startssl.com") + or is_from(mail, "vultr.com") + or (is_from(mail, "@2co.com") and mail["Subject"].contains("RAM Host")) + or is_from(mail, "localhost") + or is_from(mail, "local") + or is_from(mail, "lan") + or is_from(mail, "lukeshu.com") + ): + move_ham(mail, ".servers") + return + # .Social.* + if is_from_re(mail, ".*[@.]facebook(|mail)\.com"): + move_ham(mail, ".Social.Facebook") + return + if is_from(mail, "identi.ca"): + move_ham(mail, ".Social.Identica") + return + if is_from(mail, "twitter.com"): + move_ham(mail, ".Social.Twitter") + return + if is_from(mail, "xkcd.com"): + move_ham(mail, ".Social.xkcd") + return + if is_from(mail, "linkedin.com"): + move_ham(mail, ".Social.LinkedIn") + return + # .jobs.* + if is_from(mail, "guru.com"): + move_ham(mail, ".jobs.Guru") + return + if is_from(mail, "glassdoor.com"): + move_ham(mail, ".jobs.Glassdoor") + return + # .BSA + if ( + False + or mail["List-Id"].contains("troopmailinglist.troop276.net") + or mail["Subject"].matches("troop") + or mail["Subject"].matches("merit\s*badge") + or is_to_or_from(mail, "t276_announcements@att.net") + or is_to_or_from(mail, "Bryan@ChankTunUnGi.onmicrosoft.com") + or is_to_or_from(mail, "basu@maharjan.org") + or is_to_or_from(mail, "cacnedcomms@gmail.com") + or is_to_or_from(mail, "crossroadsbsa.org") + or is_to_or_from(mail, "dhoyt@yourhomecompany.com") + or is_to_or_from(mail, "dllargent@comcast.net") + or is_to_or_from(mail, "eldredmac@comcast.net")# MacDonell + or is_to_or_from(mail, "jsting@sbcglobal.net") + or is_to_or_from(mail, "mitchprather@sbcglobal.net") + or is_to_or_from(mail, "muellerindy@yahoo.com") + or is_to_or_from(mail, "mytroop.us") + or is_to_or_from(mail, "oa_wap@yahoo.com") + or is_to_or_from(mail, "salupo_vincent_p@lilly.com") + or is_to_or_from(mail, "scouting.org") + or is_to_or_from(mail, "solorzano.luis@rocketmail.com") + or is_to_or_from(mail, "trdindy@comcast.net") + or is_to_or_from(mail, "wjensen111@aol.com") + ): + move_ham(mail, ".BSA") + return + # .FRC + for address in [ "ni.com", "usfirst.org", "firstinspires.org" ]: + if is_to_or_from(mail, address): + move_ham(mail, ".FRC") + return + # .FRC.829 + if ( + False + or mail["Subject"].matches("\b829\b") + or is_to_or_from(mail, "wcxctrack829@aim.com") # Pat + or is_to_or_from(mail, "william.walk@gmail.com") + ): + move_ham(mail, ".FRC.829") + return + # .FRC.1024 + if ( + False + or mail["Subject"].matches("\b1024\b") + or mail["Subject"].matches("kil-?a-?bytes") + or is_to_or_from(mail, "BBonahoom@stanleyworks.com") + or is_to_or_from(mail, "bryanbonahoom@gmail.com") + or is_to_or_from(mail, "allison.m.babcock@gmail.com") + or is_to_or_from(mail, "cdewalt3@yahoo.com") + or is_to_or_from(mail, "dave.nelson@ecolab.com") + or is_to_or_from(mail, "dickaustin190@yahoo.com") + or is_to_or_from(mail, "djnels1@comcast.net") # Dave and Julie Nelson + or is_to_or_from(mail, "gamefreak207@gmail.com") # Brett Leedy + or is_to_or_from(mail, "jason.zielke@gmail.com") + or is_to_or_from(mail, "jeffreysmith@msdlt.k12.in.us") + or is_to_or_from(mail, "sarahlittell@comcast.net") + or is_to_or_from(mail, "silioso@gmail.com") + or is_to_or_from(mail, "skiplittell@comcast.net") + or is_to_or_from(mail, "tswilson4801@att.net") + ): + move_ham(mail, ".FRC.1024") + return + # .FRC.4272 + if ( + False + or mail["Subject"].matches("\b4272\b") + or mail["Subject"].contains("[ME297]") + or is_to_or_from(mail, "firstteam4272@gmail.com") + or is_to_or_from(mail, "@tscstudents.net") + or is_to_or_from(mail, "@tsc.k12.in.us") + or is_to_or_from(mail, "ericjoelsells@gmail.com") + or is_to_or_from(mail, "abenyeho@purdue.edu") + or is_to_or_from(mail, "alexhenry@purdue.edu") + or is_to_or_from(mail, "Henry65@purdue.edu") + or is_to_or_from(mail, "chang282@purdue.edu") + ): + move_ham(mail, ".FRC.4272") + return + # .Purdue.* + if ( + False + or mail["Subject"].contains("[PASE]") + or is_to_or_from(mail, "Purduealumni@purdue.edu") + or is_to_or_from(mail, "pase@purdue.edu") + ): + move_ham(mail, ".Purdue.PASE") + return + if mail["Subject"].contains("[PLUG]"): + move_ham(mail, ".Purdue.PLUG") + return + if is_to_or_from(mail, "@cerias.purdue.edu"): + move_ham(mail, ".Purdue.CERIAS") + return + if ( + False + or is_to_or_from(mail, "purduehackers@gmail.com") + or is_to_or_from(mail, "royfu@purdue.edu") + or is_to_or_from(mail, "usmannkhan@purdue.edu") + ): + move_ham(mail, ".Purdue.Hackers") + return + if ( + False + or mail["Subject"].contains("[CS Opportunity Update]") + or mail["Subject"].contains("[CS Majors]") + ): + move_ham(mail, ".Purdue.CS") + return + if ( + False + or is_to_or_from(mail, "askcco@purdue.edu") + or is_to_or_from_re(mail, "pmx-auto-approve\+.*@purdue\.edu") + or is_to_or_from(mail, "evertrue@purdue.edu") + or is_to_or_from(mail, "college.response@purdue.edu") + or is_to_or_from(mail, "purduepresident@purdue.edu") + or is_to_or_from(mail, "@prf.org") + ): + move_ham(mail, ".Purdue.misc") + return + # .misc.* + if is_from(mail, "schwab.com"): + move_ham(mail, ".misc.schwab") + return + if is_from(mail, "ebay.com"): + move_ham(mail, ".misc.ebay") + return + if ( + False + or is_to_or_from(mail, "margieshu@sbcglobal.net") + or is_to_or_from(mail, "3174451635@mms.att.net") + ): + move_ham(mail, ".misc.Mom") + return + if is_to_or_from(mail, "freelancer.com"): + move_ham(mail, ".misc.Freelancer") + return + for address in [ + "lpi.org", + "pearson.com", + "ciscotraining-notify@cisco.com", + ]: + if is_from(mail, address): + move_ham(mail, ".misc.CompTIA") + return + if ( + False + or mail["From"].contains("newsletter") + or mail["From"].contains("announcements") + or mail["Subject"].contains("newsletter") + or mail["Message-Id"].contains("@sailthru.com") + or False + or (mail["From"].contains("@sparkfun.com") and mail["Message-Id"].contains("rsgsv.net")) + or (mail["From"].contains("no-reply@kickstarter.com") and mail["Message-Id"].contains(".sendgrid.net")) + or (mail["From"].contains("no-reply@kickstarter.com") and ( + False + or mail["Subject"].contains("Projects We Love:") + or mail["Subject"].contains("Project Update"))) + or mail["From"].contains("Info@mailing.jamendo.com") + or mail["From"].contains("Promo@email.newegg.com") + or mail["From"].contains("auto@comicsbyemail.com") + or mail["From"].contains("info@demandprogress.org") + or mail["From"].contains("info@email2.mysimplemobile.com") + or mail["From"].contains("info@massdrop.com") + or mail["From"].contains("info@lulzbot.com") + or mail["From"].contains("oreilly.com") + or mail["From"].contains("reply-to@e.digikey.com") + or mail["From"].contains("communication@communications.bmv.in.gov") + or mail["From"].contains("sales@solutionsinplastic.com") + or mail["From"].contains("social@goodwillindy.org") + or mail["From"].contains("support@support.digitalocean.com") + or mail["From"].contains("@pardonsnowden.org") + ): + move_ham(mail, ".misc.Newsletters") + return + if ( + False + or mail["Subject"].contains("password") + or mail["Subject"].contains("account") + or mail["From"].contains("accounts") + ): + move_ham(mail, ".misc.accounts") + return + + move_ham(mail, "") +# +# call the above + +def handle_incoming_ham_training(mail): + bogofilter_ham(mail) + handle_incoming_ham(mail) +def handle_incoming_spam_training(mail): + bogofilter_spam(mail) + mail.move("MAIN/Spam") + +def handle_incoming_ham(mail): + my_filters(mail) +def handle_incoming_spam(mail): + mail.move("MAIN/Spam") + +def handle_incoming_unknown(mail): + # Whitelist + if my_whitelist(mail): + handle_incoming_ham_training(mail) + return + + spam = bogofilter_auto(mail) + if spam == 0: + handle_incoming_spam(mail) + return + elif spam == 1: + handle_incoming_ham(mail) + return + elif spam == 2: + mail.move("MAIN/MysteryMeat") + return + else: + mail.move("MAIN/BogoFail") + return + +# hook the above functions into the maildirproc processor +processor.maildir_base = "~/Maildir" +processor.auto_reload_rcfile = True +handle_mapping = { + "REMOTES/ATT/Inbox": handle_incoming_unknown, + "REMOTES/ATT/Bulk Mail": handle_incoming_unknown, # fucking Yahoo! + "REMOTES/lukeshu/INBOX": handle_incoming_unknown, + "QUEUES/Spam": handle_incoming_spam_training, + "QUEUES/Ham": handle_incoming_ham_training, + } +processor.maildirs = handle_mapping.keys() +for mail in processor: + handle_mapping[mail.maildir](mail) diff --git a/.config/offlineimap/config b/.config/offlineimap/config index 2fc6ecc..b3262b2 100644 --- a/.config/offlineimap/config +++ b/.config/offlineimap/config @@ -1,26 +1,42 @@ # -*- Mode: Conf -*- [general] -accounts = ATT +accounts = ATT,lukeshu metadata = ~/.local/share/offlineimap ## AT&T ############################################################### [Account ATT] -localrepository = Local-Main -remoterepository = Remote-SBCGlobal +localrepository = Local-ATT +remoterepository = Remote-ATT -[Repository Local-Main] +[Repository Local-ATT] type = Maildir -localfolders = ~/Maildir +localfolders = ~/Maildir/REMOTES/ATT sep = . -folderfilter = lambda folder: folder in [ 'Inbox', 'Bulk Mail' ] -[Repository Remote-SBCGlobal] +[Repository Remote-ATT] type = IMAP ssl = yes sslcacertfile = /etc/ssl/certs/ca-certificates.crt auth_mechanisms = PLAIN remotehost = imap.mail.yahoo.com remoteuser = lukeshu@sbcglobal.net -folderfilter = lambda folder: folder in [ 'Inbox', 'Bulk Mail' ] -idlefolders = [ 'Inbox', 'Bulk Mail' ] + +## lukeshu.com ######################################################## + +[Account lukeshu] +localrepository = Local-lukeshu +remoterepository = Remote-lukeshu + +[Repository Local-lukeshu] +type = Maildir +localfolders = ~/Maildir/REMOTES/lukeshu +sep = . + +[Repository Remote-lukeshu] +type = IMAP +ssl = yes +sslcacertfile = /etc/ssl/certs/ca-certificates.crt +auth_mechanisms = PLAIN +remotehost = mav.lukeshu.com +remoteuser = lukeshu diff --git a/.config/systemd/user/default.target.wants/maildirproc@default.service b/.config/systemd/user/default.target.wants/maildirproc@default.service new file mode 120000 index 0000000..13e527c --- /dev/null +++ b/.config/systemd/user/default.target.wants/maildirproc@default.service @@ -0,0 +1 @@ +../maildirproc@.service \ No newline at end of file -- cgit v1.1-4-g5e80 From 32d1b9b2d9951e96e96e672b48d52498dbc7ab24 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Wed, 8 Nov 2017 14:29:02 -0500 Subject: systemd: have a separate mail.target --- .../systemd/user/default.target.wants/maildirproc@default.service | 1 - .config/systemd/user/default.target.wants/offlineimap-oneshot.timer | 1 - .config/systemd/user/mail.target | 5 +++++ .config/systemd/user/mail.target.wants/maildirproc@default.service | 1 + .config/systemd/user/mail.target.wants/offlineimap-oneshot.timer | 1 + .config/systemd/user/maildirproc@.service | 2 +- 6 files changed, 8 insertions(+), 3 deletions(-) delete mode 120000 .config/systemd/user/default.target.wants/maildirproc@default.service delete mode 120000 .config/systemd/user/default.target.wants/offlineimap-oneshot.timer create mode 100644 .config/systemd/user/mail.target create mode 120000 .config/systemd/user/mail.target.wants/maildirproc@default.service create mode 120000 .config/systemd/user/mail.target.wants/offlineimap-oneshot.timer diff --git a/.config/systemd/user/default.target.wants/maildirproc@default.service b/.config/systemd/user/default.target.wants/maildirproc@default.service deleted file mode 120000 index 13e527c..0000000 --- a/.config/systemd/user/default.target.wants/maildirproc@default.service +++ /dev/null @@ -1 +0,0 @@ -../maildirproc@.service \ No newline at end of file diff --git a/.config/systemd/user/default.target.wants/offlineimap-oneshot.timer b/.config/systemd/user/default.target.wants/offlineimap-oneshot.timer deleted file mode 120000 index 9fb06ea..0000000 --- a/.config/systemd/user/default.target.wants/offlineimap-oneshot.timer +++ /dev/null @@ -1 +0,0 @@ -/usr/lib/systemd/user/offlineimap-oneshot.timer \ No newline at end of file diff --git a/.config/systemd/user/mail.target b/.config/systemd/user/mail.target new file mode 100644 index 0000000..5a408b2 --- /dev/null +++ b/.config/systemd/user/mail.target @@ -0,0 +1,5 @@ +[Unit] +Description=Mail Target + +[Install] +WantedBy=default.target diff --git a/.config/systemd/user/mail.target.wants/maildirproc@default.service b/.config/systemd/user/mail.target.wants/maildirproc@default.service new file mode 120000 index 0000000..13e527c --- /dev/null +++ b/.config/systemd/user/mail.target.wants/maildirproc@default.service @@ -0,0 +1 @@ +../maildirproc@.service \ No newline at end of file diff --git a/.config/systemd/user/mail.target.wants/offlineimap-oneshot.timer b/.config/systemd/user/mail.target.wants/offlineimap-oneshot.timer new file mode 120000 index 0000000..9fb06ea --- /dev/null +++ b/.config/systemd/user/mail.target.wants/offlineimap-oneshot.timer @@ -0,0 +1 @@ +/usr/lib/systemd/user/offlineimap-oneshot.timer \ No newline at end of file diff --git a/.config/systemd/user/maildirproc@.service b/.config/systemd/user/maildirproc@.service index 450157f..f5a7ca5 100644 --- a/.config/systemd/user/maildirproc@.service +++ b/.config/systemd/user/maildirproc@.service @@ -7,4 +7,4 @@ ExecStart=/usr/bin/env maildirproc --rcfile=${HOME}/.config/maildirproc/%I.rc -- Restart=on-failure [Install] -WantedBy=default.target +WantedBy=mail.target -- cgit v1.1-4-g5e80