~futatuki/mailman/2.1-forbid-subscription

« back to all changes in this revision

Viewing changes to bin/arch

  • Committer:
  • Date: 2003-01-02 05:25:50 UTC
  • Revision ID: vcs-imports@canonical.com-20030102052550-qqbl1i96tzg3bach
This commit was manufactured by cvs2svn to create branch
'Release_2_1-maint'.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#! @PYTHON@
 
2
#
 
3
# Copyright (C) 1998,1999,2000,2001,2002 by the Free Software Foundation, Inc.
 
4
#
 
5
# This program is free software; you can redistribute it and/or
 
6
# modify it under the terms of the GNU General Public License
 
7
# as published by the Free Software Foundation; either version 2
 
8
# of the License, or (at your option) any later version.
 
9
#
 
10
# This program is distributed in the hope that it will be useful,
 
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
# GNU General Public License for more details.
 
14
#
 
15
# You should have received a copy of the GNU General Public License
 
16
# along with this program; if not, write to the Free Software
 
17
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
18
 
 
19
"""Rebuild a list's archive.
 
20
 
 
21
Use this command to rebuild the archives for a mailing list.  You may want to
 
22
do this if you edit some messages in an archive, or remove some messages from
 
23
an archive.
 
24
 
 
25
Usage: %(PROGRAM)s [options] <listname> [<mbox>]
 
26
 
 
27
Where options are:
 
28
    -h / --help
 
29
        Print this help message and exit.
 
30
 
 
31
    -q / --quiet
 
32
        Make the archiver output less verbose.
 
33
 
 
34
    --wipe
 
35
        First wipe out the original archive before regenerating.  You usually
 
36
        want to specify this argument unless you're generating the archive in
 
37
        chunks.
 
38
 
 
39
    -s N
 
40
    --start=N
 
41
        Start indexing at article N, where article 0 is the first in the mbox.
 
42
        Defaults to 0.
 
43
 
 
44
    -e M
 
45
    --end=M
 
46
        End indexing at article M.  This script is not very efficient with
 
47
        respect to memory management, and for large archives, it may not be
 
48
        possible to index the mbox entirely.  For that reason, you can specify
 
49
        the start and end article numbers.
 
50
 
 
51
Where <mbox> is the path to a list's complete mbox archive.  Usually this will
 
52
be some path in the archives/private directory.  For example:
 
53
 
 
54
%% bin/arch mylist archives/private/mylist.mbox/mylist.mbox
 
55
 
 
56
<mbox> is optional.  If it is missing, it is calculated.
 
57
"""
 
58
 
 
59
import os
 
60
import sys
 
61
import getopt
 
62
import shutil
 
63
 
 
64
import paths
 
65
from Mailman import mm_cfg
 
66
from Mailman import Errors
 
67
 
 
68
from Mailman.MailList import MailList
 
69
from Mailman.Archiver.HyperArch import HyperArchive
 
70
from Mailman.LockFile import LockFile
 
71
from Mailman import i18n
 
72
 
 
73
_ = i18n._
 
74
 
 
75
PROGRAM = sys.argv[0]
 
76
i18n.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)
 
77
 
 
78
 
 
79
 
 
80
def usage(code, msg=''):
 
81
    if code:
 
82
        fd = sys.stderr
 
83
    else:
 
84
        fd = sys.stdout
 
85
    print >> fd, _(__doc__)
 
86
    if msg:
 
87
        print >> fd, msg
 
88
    sys.exit(code)
 
89
 
 
90
 
 
91
 
 
92
def main():
 
93
    # get command line arguments
 
94
    try:
 
95
        opts, args = getopt.getopt(
 
96
            sys.argv[1:], 'hs:e:q',
 
97
            ['help', 'start', 'end', 'quiet', 'wipe'])
 
98
    except getopt.error, msg:
 
99
        usage(1, msg)
 
100
 
 
101
    start = None
 
102
    end = None
 
103
    verbose = 1
 
104
    wipe = 0
 
105
    for opt, arg in opts:
 
106
        if opt in ('-h', '--help'):
 
107
            usage(0)
 
108
        elif opt in ('-s', '--start'):
 
109
            try:
 
110
                start = int(arg)
 
111
            except ValueError:
 
112
                usage(1)
 
113
        elif opt in ('-e', '--end'):
 
114
            try:
 
115
                end = int(arg)
 
116
            except ValueError:
 
117
                usage(1)
 
118
        elif opt in ('-q', '--quiet'):
 
119
            verbose = 0
 
120
        elif opt == '--wipe':
 
121
            wipe = 1
 
122
 
 
123
    # grok arguments
 
124
    if len(args) < 1:
 
125
        usage(1, _('listname is required'))
 
126
    listname = args[0].lower().strip()
 
127
 
 
128
    if len(args) < 2:
 
129
        mbox = None
 
130
    else:
 
131
        mbox = args[1]
 
132
 
 
133
    if len(args) > 2:
 
134
        usage(1)
 
135
 
 
136
    # open the mailing list object
 
137
    mlist = None
 
138
    lock = None
 
139
    try:
 
140
        try:
 
141
            mlist = MailList(listname)
 
142
        except Errors.MMListError, e:
 
143
            usage(2, _('No such list "%(listname)s"\n%(e)s'))
 
144
        if mbox is None:
 
145
            mbox = mlist.ArchiveFileName()
 
146
 
 
147
        i18n.set_language(mlist.preferred_language)
 
148
        # lay claim to the archive's lock file.  this is so no other post can
 
149
        # mess up the archive while we're glomming it.  we pick a suitably
 
150
        # long period of time for the lock lifetime, however we really don't
 
151
        # know how long it will take.
 
152
        #
 
153
        # XXX: processUnixMailbox() should refresh the lock.
 
154
        #
 
155
        # XXX: this may not be necessary because I think we lay claim to the
 
156
        # list lock up above, although that may be too short to be of use (and
 
157
        # maybe we don't really want to lock the list anyway).
 
158
        #
 
159
        lockfile = os.path.join(mm_cfg.LOCK_DIR, mlist._internal_name) + \
 
160
                   '.archiver.lock'
 
161
        # set the lock lifetime to 3 hours.  XXX is this reasonable???
 
162
        lock = LockFile(lockfile, lifetime=3*60*60)
 
163
        lock.lock()
 
164
        # Maybe wipe the old archives
 
165
        if wipe:
 
166
            shutil.rmtree(mlist.archive_dir())
 
167
        try:
 
168
            fp = open(mbox)
 
169
        except IOError, msg:
 
170
            usage(3, _('Cannot open mbox file %(mbox)s: %(msg)s'))
 
171
 
 
172
        archiver = HyperArchive(mlist)
 
173
        archiver.VERBOSE = verbose
 
174
        try:
 
175
            archiver.processUnixMailbox(fp, start, end)
 
176
        finally:
 
177
            archiver.close()
 
178
        fp.close()
 
179
    finally:
 
180
        if lock:
 
181
            lock.unlock()
 
182
        if mlist:
 
183
            mlist.Unlock()
 
184
 
 
185
 
 
186
if __name__ == '__main__':
 
187
    main()