summaryrefslogtreecommitdiffstats
path: root/roles/lists/files/usr/local/bin/mhonarc-scan.sh
blob: d0ea2af6fc3477d33026ecb9b2d1a03b23bc1b1e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#!/bin/sh

# Convert a list archive into HTML.
#
# Copyright © 2014 Guilhem Moulin <guilhem@fripost.org>
#
# 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/>.

set -ue

fail () {
    echo Error: "$@" >&2
    exit 1
}

[ $# -eq 1 ] || { echo "Usage: $0 listdir"; exit; }
listdir="${1%/}"
[ -d "$listdir" ] || fail "No such directory: $listdir"

localpart="${listdir##*/}"
domainpart="${listdir%/$localpart}"
domainpart="${domainpart##*/}"

# Determine the rotation period
rotation=
[ -s "$listdir/control/archiverotate" ] && read rotation <"$listdir/control/archiverotate"

# Subdir format (/!\ shouldn't be empty, and shouldn't contain spaces!),
# and archive date format.
case "${rotation:-month}" in
    '')    subdirf='/'         listpage='./';        archivef=;;
    year)  subdirf="%Y";       listpage='../';       archivef="for %Y";;
    month) subdirf="%Y/%m";    listpage='../../';    archivef="for %B %Y";;
    day)   subdirf="%Y/%m/%d"; listpage='../../../'; archivef="for %a, %d %b %Y";;
    *)     fail "$rotation: unknown rotation period"
esac

# Look up for the send date in an email. Fall back to the creation date
# if not found.
printDate () {
    local filename date
    while read filename; do
        if ! [ "$rotation" ]; then
            # don't bother looking for a date
            date=0
        else
            # stop as soon as the header is over
            date=$(sed -nr '/^Date:\s*(\S.*)$/I {s//\1/p;q}; /^([^[:cntrl:][:space:]]+:|\s)/ !q' \
                           "$filename")
            [ "$date" ] || date=@$(stat -c '%Y' "$filename")
        fi
        echo $(date -d "$date" +"%s $subdirf") "$filename"
    done
}

# Process a (single) subdirectory
process () {
    local list="$1" subdir="$2" date="$3"
    [ -s "$list" ] || return 0

    [ -d "$listdir/webarchive/$subdir" ] || mkdir -p "$listdir/webarchive/$subdir"
    # TODO: add a line to the index file
    xargs -a"$list" mhonarc -definevar ListName="'$localpart'" \
                            -definevar ListPage="'${listpage}index.html'" \
                            -definevar DirDate="'$date'" \
                            -rcfile /etc/mhonarc.rc \
                            -add \
                            -quiet \
                            -outdir "$listdir/webarchive/$subdir" \
    || exit 1
    # empty the list
    echo -n >"$list"
}

# Process all found emails
processM () {
    local cursubdir= date=
    local timestamp subdir filename

    while read timestamp subdir filename; do
        if [ "$cursubdir" != "$subdir" ]; then
            process "$list" "$cursubdir" "$date"
            cursubdir="$subdir"
            date="$(date -d "@$timestamp" +"$archivef")"
        fi
        echo "$filename" >>"$list"
    done
    process "$list" "$cursubdir" "$date"
}

# The span of emails we'll touch during the current instance
now=$(date +'%s')
list=$(mktemp) || exit 1
trap 'rm -f "$list"' EXIT

from=0
if [ -s "$listdir/.webarchive.date" ]; then
    read from <"$listdir/.webarchive.date"
    from=$(( $from - 30 )) # remove 30s to fight race conditions
fi

find "$listdir/archive/" -type f -a -newermt @"$from" | printDate | sort -n -k1,1 | processM
echo "$now" > "$listdir/.webarchive.date"