~ubuntu-branches/ubuntu/hoary/mailman/hoary-security

« back to all changes in this revision

Viewing changes to bin/withlist

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2004-10-11 02:02:43 UTC
  • Revision ID: james.westby@ubuntu.com-20041011020243-ukiishnhlkmsoh21
Tags: upstream-2.1.5
ImportĀ upstreamĀ versionĀ 2.1.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#! @PYTHON@
 
2
#
 
3
# Copyright (C) 1998-2003 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
"""General framework for interacting with a mailing list object.
 
20
 
 
21
There are two ways to use this script: interactively or programmatically.
 
22
Using it interactively allows you to play with, examine and modify a MailList
 
23
object from Python's interactive interpreter.  When running interactively, a
 
24
MailList object called `m' will be available in the global namespace.  It also
 
25
loads the class MailList into the global namespace.
 
26
 
 
27
Programmatically, you can write a function to operate on a MailList object,
 
28
and this script will take care of the housekeeping (see below for examples).
 
29
In that case, the general usage syntax is:
 
30
 
 
31
%% bin/withlist [options] listname [args ...]
 
32
 
 
33
Options:
 
34
 
 
35
    -l / --lock
 
36
        Lock the list when opening.  Normally the list is opened unlocked
 
37
        (e.g. for read-only operations).  You can always lock the file after
 
38
        the fact by typing `m.Lock()'
 
39
 
 
40
        Note that if you use this option, you should explicitly call m.Save()
 
41
        before exiting, since the interpreter's clean up procedure will not
 
42
        automatically save changes to the MailList object (but it will unlock
 
43
        the list).
 
44
 
 
45
    -i / --interactive
 
46
        Leaves you at an interactive prompt after all other processing is
 
47
        complete.  This is the default unless the -r option is given.
 
48
 
 
49
    --run [module.]callable
 
50
    -r [module.]callable
 
51
        This can be used to run a script with the opened MailList object.
 
52
        This works by attempting to import `module' (which must already be
 
53
        accessible on your sys.path), and then calling `callable' from the
 
54
        module.  callable can be a class or function; it is called with the
 
55
        MailList object as the first argument.  If additional args are given
 
56
        on the command line, they are passed as subsequent positional args to
 
57
        the callable.
 
58
 
 
59
        Note that `module.' is optional; if it is omitted then a module with
 
60
        the name `callable' will be imported.
 
61
 
 
62
        The global variable `r' will be set to the results of this call.
 
63
 
 
64
    --all / -a
 
65
        This option only works with the -r option.  Use this if you want to
 
66
        execute the script on all mailing lists.  When you use -a you should
 
67
        not include a listname argument on the command line.  The variable `r'
 
68
        will be a list of all the results.
 
69
 
 
70
    --quiet / -q
 
71
        Suppress all status messages.
 
72
 
 
73
    --help / -h
 
74
        Print this message and exit
 
75
 
 
76
 
 
77
Here's an example of how to use the -r option.  Say you have a file in the
 
78
Mailman installation directory called `listaddr.py', with the following
 
79
two functions:
 
80
 
 
81
def listaddr(mlist):
 
82
    print mlist.GetListEmail()
 
83
 
 
84
def requestaddr(mlist):
 
85
    print mlist.GetRequestEmail()
 
86
 
 
87
Now, from the command line you can print the list's posting address by running
 
88
the following from the command line:
 
89
 
 
90
%% bin/withlist -r listaddr mylist
 
91
Loading list: mylist (unlocked)
 
92
Importing listaddr ...
 
93
Running listaddr.listaddr() ...
 
94
mylist@myhost.com
 
95
 
 
96
And you can print the list's request address by running:
 
97
 
 
98
%% bin/withlist -r listaddr.requestaddr mylist
 
99
Loading list: mylist (unlocked)
 
100
Importing listaddr ...
 
101
Running listaddr.requestaddr() ...
 
102
mylist-request@myhost.com
 
103
 
 
104
As another example, say you wanted to change the password for a particular
 
105
user on a particular list.  You could put the following function in a file
 
106
called `changepw.py':
 
107
 
 
108
from Mailman.Errors import NotAMemberError
 
109
 
 
110
def changepw(mlist, addr, newpasswd):
 
111
    try:
 
112
        mlist.setMemberPassword(addr, newpasswd)
 
113
        mlist.Save()
 
114
    except NotAMemberError:
 
115
        print 'No address matched:', addr
 
116
 
 
117
and run this from the command line:
 
118
%% bin/withlist -l -r changepw mylist somebody@somewhere.org foobar
 
119
"""
 
120
 
 
121
import sys
 
122
import getopt
 
123
import code
 
124
 
 
125
import paths
 
126
from Mailman import Utils
 
127
from Mailman import MailList
 
128
from Mailman import Errors
 
129
from Mailman.i18n import _
 
130
 
 
131
# `m' will be the MailList object and `r' will be the results of the callable
 
132
m = None
 
133
r = None
 
134
VERBOSE = 1
 
135
LOCK = 0
 
136
 
 
137
 
 
138
 
 
139
def usage(code, msg=''):
 
140
    if code:
 
141
        fd = sys.stderr
 
142
    else:
 
143
        fd = sys.stdout
 
144
    print >> fd, _(__doc__)
 
145
    if msg:
 
146
        print >> fd, msg
 
147
    sys.exit(code)
 
148
 
 
149
 
 
150
def atexit():
 
151
    """Unlock a locked list, but do not implicitly Save() it.
 
152
 
 
153
    This does not get run if the interpreter exits because of a signal, or if
 
154
    os._exit() is called.  It will get called if an exception occurs though.
 
155
    """
 
156
    global m
 
157
    if not m:
 
158
        return
 
159
    if m.Locked():
 
160
        if VERBOSE:
 
161
            listname = m.internal_name()
 
162
            print >> sys.stderr, _(
 
163
                'Unlocking (but not saving) list: %(listname)s')
 
164
        m.Unlock()
 
165
    if VERBOSE:
 
166
        print >> sys.stderr, _('Finalizing')
 
167
    del m
 
168
 
 
169
 
 
170
 
 
171
def do_list(listname, args, func):
 
172
    global m
 
173
    # first try to open mailing list
 
174
    if VERBOSE:
 
175
        print >> sys.stderr, _('Loading list %(listname)s'),
 
176
        if LOCK:
 
177
            print >> sys.stderr, _('(locked)')
 
178
        else:
 
179
            print >> sys.stderr, _('(unlocked)')
 
180
 
 
181
    try:
 
182
        m = MailList.MailList(listname, lock=LOCK)
 
183
    except Errors.MMUnknownListError:
 
184
        print >> sys.stderr, _('Unknown list: %(listname)s')
 
185
        m = None
 
186
 
 
187
    # try to import the module and run the callable
 
188
    if func:
 
189
        return func(m, *args)
 
190
    return None
 
191
 
 
192
 
 
193
 
 
194
def main():
 
195
    global VERBOSE
 
196
    global LOCK
 
197
    global r
 
198
    try:
 
199
        opts, args = getopt.getopt(
 
200
            sys.argv[1:], 'hlr:qia',
 
201
            ['help', 'lock', 'run=', 'quiet', 'interactive', 'all'])
 
202
    except getopt.error, msg:
 
203
        usage(1, msg)
 
204
 
 
205
    run = None
 
206
    interact = None
 
207
    all = 0
 
208
    for opt, arg in opts:
 
209
        if opt in ('-h', '--help'):
 
210
            usage(0)
 
211
        elif opt in ('-l', '--lock'):
 
212
            LOCK = 1
 
213
        elif opt in ('-r', '--run'):
 
214
            run = arg
 
215
        elif opt in ('-q', '--quiet'):
 
216
            VERBOSE = 0
 
217
        elif opt in ('-i', '--interactive'):
 
218
            interact = 1
 
219
        elif opt in ('-a', '--all'):
 
220
            all = 1
 
221
 
 
222
    if len(args) < 1 and not all:
 
223
        usage(1, _('No list name supplied.'))
 
224
 
 
225
    if all and not run:
 
226
        usage(1, _('--all requires --run'))
 
227
 
 
228
    # The default for interact is 1 unless -r was given
 
229
    if interact is None:
 
230
        if run is None:
 
231
            interact = 1
 
232
        else:
 
233
            interact = 0
 
234
 
 
235
    # try to import the module for the callable
 
236
    func = None
 
237
    if run:
 
238
        i = run.find('.')
 
239
        if i < 0:
 
240
            module = run
 
241
            callable = run
 
242
        else:
 
243
            module = run[:i]
 
244
            callable = run[i+1:]
 
245
        if VERBOSE:
 
246
            print >> sys.stderr, _('Importing %(module)s...')
 
247
        mod = __import__(module)
 
248
        if VERBOSE:
 
249
            print >> sys.stderr, _('Running %(module)s.%(callable)s()...')
 
250
        func = getattr(mod, callable)
 
251
 
 
252
    if all:
 
253
        r = [do_list(listname, args, func) for listname in Utils.list_names()]
 
254
    else:
 
255
        listname = args.pop(0).lower().strip()
 
256
        r = do_list(listname, args, func)
 
257
 
 
258
    # Now go to interactive mode, perhaps
 
259
    if interact:
 
260
        # Attempt to import the readline module, so we emulate the interactive
 
261
        # console as closely as possible.  Don't worry if it doesn't import.
 
262
        # readline works by side-effect.
 
263
        try:
 
264
            import readline
 
265
        except ImportError:
 
266
            pass
 
267
        namespace = globals().copy()
 
268
        namespace.update(locals())
 
269
        code.InteractiveConsole(namespace).interact(
 
270
            _("The variable `m' is the %(listname)s MailList instance"))
 
271
 
 
272
 
 
273
 
 
274
sys.exitfunc = atexit
 
275
main()