madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

rewrite processing of postponed messages
authormartin f. krafft <madduck@madduck.net>
Tue, 4 Mar 2008 18:30:57 +0000 (19:30 +0100)
committermartin f. krafft <madduck@madduck.net>
Tue, 4 Mar 2008 18:30:57 +0000 (19:30 +0100)
bin/list-postponed-messages [new file with mode: 0755]
bin/process-delayed-queue [deleted file]
bin/process-tickler [deleted file]
bin/release-delayed-messages
bin/resubmit
bin/resubmit-postponed-messages [new file with mode: 0755]

diff --git a/bin/list-postponed-messages b/bin/list-postponed-messages
new file mode 100755 (executable)
index 0000000..d0ee1af
--- /dev/null
@@ -0,0 +1,73 @@
+#!/bin/sh
+set -eu
+
+ME="${0##*/}"
+
+about()
+{
+  echo "$ME -- list postponed messages which have expired"
+  echo "Copyright © martin f. krafft <madduck@madduck.net>"
+  echo "Released under the terms of the Artistic Licence 2.0"
+}   
+    
+usage()
+{
+  echo "Usage: $ME [options] <Maildir> [<Maildir> ...]"
+  echo
+  echo "Valid options are:"
+  cat <<-_eof | column -s\& -t
+       -V|--version & show version information.
+       -h|--help & show this output.
+       -a|--all & list all postponed messages, not only expired ones
+       -s|--stamp & include the time stamp *before* the filename
+       _eof
+}
+
+SHORTOPTS=Vhas
+LONGOPTS=version,help,all,stamp
+
+maildirs=
+listall=0
+timestamp=0
+
+for opt in $(getopt -n $ME -o $SHORTOPTS -l $LONGOPTS -u -- "$@"); do
+  case "$opt" in
+    -V|--version) about; exit 0;;
+    -h|--help) about; echo; usage; exit 0;;
+    -a|--all) listall=1;;
+    -s|--stamp) timestamp=1;;
+    --) :;;
+    *)
+      if [ -d "$opt/cur" ] && [ -d "$opt/new" ] && [ -d "$opt/tmp" ]; then
+        maildirs="$maildirs $opt"
+      else
+        echo "E: unknown argument: $opt" >&2
+        exit 1
+      fi
+      ;;
+  esac
+done
+
+if [ -z "$maildirs" ]; then
+  echo "E: no Maildirs specified." >&2
+  exit 2
+fi
+
+NOW=$(date +%s)
+
+for i in $maildirs; do
+  d="${i%/}"
+  echo "$d/new/"
+  echo "$d/cur/"
+done \
+  | xargs -I {} find {} -type f \
+  | xargs grep '^X-Postponed:' \
+  | while read i; do
+      f="${i%:X-Postponed:*}"
+      ts="${i#*:X-Postponed: }"; ts="${ts%% *}"
+
+      if [ $listall -eq 1 ] || [ $ts -le $NOW ]; then
+        [ $timestamp -eq 1 ] && echo -n "$ts "
+        echo "$f"
+      fi
+    done
diff --git a/bin/process-delayed-queue b/bin/process-delayed-queue
deleted file mode 100755 (executable)
index 826a346..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/bin/sh
-set -eu
-
-MAILDIR=$HOME/.maildir
-
-SQLITE=/usr/bin/sqlite3
-RESUBMIT=$HOME/.etc/mailfilter/bin/resubmit
-
-DELAYED_QUEUE_DB=$HOME/.var/procmail/delayed-queue.sqlite
-
-QUERY='select * from messages where release_ts <= strftime("%s", "now")'
-
-$SQLITE -list -separator ' ' $DELAYED_QUEUE_DB "$QUERY" \
-  | while read msgid basefile ts; do
-
-    file="$MAILDIR/$basefile"
-    files="$file ${file}:2,"
-
-    basename="${file##*/}"
-    dirname="${file%/*}"
-    case "${dirname##*/}" in
-      cur)
-        files="$files ${file}:2,S ${file}:2,R ${file}:2,RS"
-        file="${dirname%/cur}/new/$basename"
-        files="$files $file ${file}:2, ${file}:2,R ${file}:2,RS"
-        ;;
-      new)
-        file="${dirname%/new}/cur/$basename"
-        files="$files ${file}:2, ${file}:2,S"
-        ;;
-    esac
-
-    found=0
-    for file in $files; do
-      if [ -f "$file" ]; then
-        $RESUBMIT "$file"
-        echo "I: resubmitted $msgid"
-        found=1
-        break
-      fi
-    done
-
-    $SQLITE $DELAYED_QUEUE_DB "delete from messages where msgid = '$msgid'"
-
-    if [ $found -eq 0 ]; then
-      echo "E: message $msgid not found in $basefile" >&2
-    fi
-
-done
diff --git a/bin/process-tickler b/bin/process-tickler
deleted file mode 100755 (executable)
index 28b6c5e..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/usr/bin/python2.5
-# -*- coding: utf-8 -*-
-#
-# process-tickler – process message in tickler maildir
-#
-# Copyright © martin f. krafft <madduck@debian.org>
-# Released under the terms of the Artistic Licence 2.0
-#
-
-import mailbox
-import os
-import sys
-import time
-
-HOME = os.getenv('HOME')
-MAILDIR = os.path.join(HOME, '.maildir')
-TICKLER_DIR = os.path.join(MAILDIR, '.tickler')
-DEST_DIR = os.path.join(MAILDIR, '.resubmit')
-
-tmd = mailbox.Maildir(TICKLER_DIR)
-dmd = mailbox.Maildir(DEST_DIR)
-msgids = dict()
-
-def resubmit(key):
-    msg = tmd.get_message(key)
-    print >>sys.stdout, 'I: resubmit message %s' % key
-    if msg.has_key('X-Tickle-Delivered'):
-        msg.replace_header('X-Tickle-Delivered', time.strftime('%c'))
-    else:
-        msg.add_header('X-Tickle-Delivered', time.strftime('%c'))
-    dmd.add(msg)
-    tmd.discard(key)
-
-for key, msg in tmd.iteritems():
-    msgid = msg.get('Message-Id')
-    if msgid is None:
-        print >>sys.stderr, 'W: message without ID: ' + key
-        resubmit(key)
-
-    tickle = msg.get('X-Tickle')
-    if tickle is None:
-        print >>sys.stderr, 'W: message without tickle information: ' + msgid
-        resubmit(key)
-
-    if msgids.get(msgid, None) is None:
-        msgids[msgid] = list()
-    msgids[msgid].append((int(tickle.split(' ', 1)[0]), key, msg))
-
-for msgid, msgs in msgids.iteritems():
-    msgs.sort()
-    prev_tickle = None
-    for tickle, key, msg in msgs:
-        if tickle == prev_tickle:
-            print >>sys.stderr, 'I: discarding duplicate %s of message %s' % (key, msgid)
-            tmd.discard(key)
-            continue
-        prev_tickle = tickle
-
-        t = time.time()
-        if t >= tickle:
-            resubmit(key)
-        else:
-            print >>sys.stdout, 'I: message %s still has %d seconds' % (key,
-                    int(tickle - t))
index fd381d37fd550112bd4d4922908feab2799085a2..61abd85bc6b310229009acd3e124152a27c67d6f 100755 (executable)
@@ -1,12 +1,9 @@
 #!/bin/sh
 set -eu
 
-MAILDIR=$HOME/.maildir
+DELAYED_QUEUE=$HOME/.maildir/.delayed
 
-SQLITE=/usr/bin/sqlite3
-DELAYED_QUEUE_DB=$HOME/.var/procmail/delayed-queue.sqlite
+DIR="${0%/*}"
 
-QUERY="update messages set release_ts = strftime('%s', 'now') where filename like '.delayed/%'"
-
-$SQLITE $DELAYED_QUEUE_DB "$QUERY"
-exec $HOME/.etc/mailfilter/bin/process-delayed-queue
+"$DIR"/list-postponed-messages --all "$DELAYED_QUEUE" \
+  | exec xargs "$DIR"/resubmit --list
index 17888f9b8694c22a979b283b759f5e3d4891cc50..6bf8819bbae656dfc4ee9ac7bce5002908a47ebd 100755 (executable)
@@ -1,17 +1,60 @@
 #!/bin/sh
 set -eu
 
+ME="${0##*/}"
+
+about()
+{
+  echo "$ME -- resubmit messages to the mail filter"
+  echo "Copyright © martin f. krafft <madduck@madduck.net>"
+  echo "Released under the terms of the Artistic Licence 2.0"
+}
+
+usage()
+{
+  echo "Usage: $ME [options] <Maildir> [<Maildir> ...]"
+  echo
+  echo "Valid options are:"
+  cat <<-_eof | column -s\& -t
+       -V|--version & show version information.
+       -h|--help & show this output.
+       -l|--list & process the argument list (even if empty), never stdin
+       _eof
+}
+
+SHORTOPTS=Vhl
+LONGOPTS=version,help,list
+
+list=0
+files=
+
+for opt in $(getopt -n $ME -o $SHORTOPTS -l $LONGOPTS -u -- "$@"); do
+  case "$opt" in
+    -V|--version) about; exit 0;;
+    -h|--help) about; echo; usage; exit 0;;
+    -l|--list) list=1;;
+    --) :;;
+    *)
+      if [ -f "$opt" ] && [ -r "$opt" ]; then
+        files="$files $opt"
+      else
+        echo "E: unknown argument: $opt" >&2
+        exit 1
+      fi
+      ;;
+  esac
+done
+
 PROCMAIL=$HOME/.etc/mailfilter/procmail/procmailrc
-FORMAIL="/usr/bin/formail -I'X-Resubmitted: $(date -R)'"
+# execute the date -R only during the eval, not immediately
+FILTER='/usr/bin/formail -I"X-Resubmitted: $(date -R)"'
 
-if [ -z "${1:-}" ]; then
-  eval $FORMAIL | exec $PROCMAIL
+if [ -z "${1:-}" ] && [ $list -eq 0 ]; then
+  eval $FILTER | exec $PROCMAIL
 else
-  if [ ! -f "$1" ]; then
-    echo "E: no such file: $1" >&2
-    exit 1
-  fi
-  eval $FORMAIL < "$1" | $PROCMAIL && rm -f "$1"
+  for f in $files; do
+    eval $FILTER < "$f" | $PROCMAIL && rm -f "$f"
+  done
 fi
 
 exit 0
diff --git a/bin/resubmit-postponed-messages b/bin/resubmit-postponed-messages
new file mode 100755 (executable)
index 0000000..1ea3100
--- /dev/null
@@ -0,0 +1,10 @@
+#!/bin/sh
+set -eu
+
+DELAYED_QUEUE=$HOME/.maildir/.delayed
+TICKLER_QUEUE=$HOME/.maildir/.store
+
+DIR="${0%/*}"
+
+"$DIR"/list-postponed-messages "$TICKLER_QUEUE" "$DELAYED_QUEUE" \
+  | exec xargs "$DIR"/resubmit --list