comparison roundup/scripts/roundup_mailgw.py @ 601:912029653c1c config-0-4-0-branch

[[Metadata associated with this commit was garbled during conversion from CVS to Subversion. The actual author of these changes was probably either Richard Jones or Titus Brown.]]
author No Author <no-author@users.sourceforge.net>
date Wed, 06 Feb 2002 03:47:17 +0000
parents
children 986354c4b1fb
comparison
equal deleted inserted replaced
482:fdee2ff82b40 601:912029653c1c
1 #! /usr/bin/python
2 #
3 # Copyright (c) 2001 Bizar Software Pty Ltd (http://www.bizarsoftware.com.au/)
4 # This module is free software, and you may redistribute it and/or modify
5 # under the same terms as Python, so long as this copyright message and
6 # disclaimer are retained in their original form.
7 #
8 # IN NO EVENT SHALL BIZAR SOFTWARE PTY LTD BE LIABLE TO ANY PARTY FOR
9 # DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING
10 # OUT OF THE USE OF THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE
11 # POSSIBILITY OF SUCH DAMAGE.
12 #
13 # BIZAR SOFTWARE PTY LTD SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
14 # BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
15 # FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS"
16 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
17 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
18 #
19 # $Id: roundup_mailgw.py,v 1.2 2002-01-29 20:07:15 jhermann Exp $
20
21 # python version check
22 from roundup import version_check
23
24 import sys, os, re, cStringIO
25
26 from roundup.mailgw import Message
27 from roundup.i18n import _
28
29 def do_pipe(handler):
30 '''Read a message from standard input and pass it to the mail handler.
31 '''
32 handler.main(sys.stdin)
33 return 0
34
35 def do_mailbox(handler, filename):
36 '''Read a series of messages from the specified unix mailbox file and
37 pass each to the mail handler.
38 '''
39 # open the spool file and lock it
40 import fcntl, FCNTL
41 f = open(filename, 'r+')
42 fcntl.flock(f.fileno(), FCNTL.LOCK_EX)
43
44 # handle and clear the mailbox
45 try:
46 from mailbox import UnixMailbox
47 mailbox = UnixMailbox(f, factory=Message)
48 # grab one message
49 message = mailbox.next()
50 while message:
51 # call the instance mail handler
52 handler.handle_Message(message)
53 message = mailbox.next()
54 # nuke the file contents
55 os.ftruncate(f.fileno(), 0)
56 except:
57 import traceback
58 traceback.print_exc()
59 return 1
60 fcntl.flock(f.fileno(), FCNTL.LOCK_UN)
61 return 0
62
63 def do_pop(handler, server, user='', password=''):
64 '''Read a series of messages from the specified POP server.
65 '''
66 import getpass, poplib, socket
67 try:
68 if not user:
69 user = raw_input(_('User: '))
70 if not password:
71 password = getpass.getpass()
72 except (KeyboardInterrupt, EOFError):
73 # Ctrl C or D maybe also Ctrl Z under Windows.
74 print "\nAborted by user."
75 return 1
76
77 # open a connection to the server and retrieve all messages
78 try:
79 server = poplib.POP3(server)
80 except socket.error, message:
81 print "POP server error:", message
82 return 1
83 server.user(user)
84 server.pass_(password)
85 numMessages = len(server.list()[1])
86 for i in range(1, numMessages+1):
87 # retr: returns
88 # [ pop response e.g. '+OK 459 octets',
89 # [ array of message lines ],
90 # number of octets ]
91 lines = server.retr(i)[1]
92 s = cStringIO.StringIO('\n'.join(lines))
93 s.seek(0)
94 handler.handle_Message(Message(s))
95 # delete the message
96 server.dele(i)
97
98 # quit the server to commit changes.
99 server.quit()
100 return 0
101
102 def usage(args, message=None):
103 if message is not None:
104 print message
105 print _('Usage: %(program)s <instance home> [source spec]')%{'program': args[0]}
106 print _('''
107 The roundup mail gateway may be called in one of two ways:
108 . with an instance home as the only argument,
109 . with both an instance home and a mail spool file, or
110 . with both an instance home and a pop server account.
111
112 PIPE:
113 In the first case, the mail gateway reads a single message from the
114 standard input and submits the message to the roundup.mailgw module.
115
116 UNIX mailbox:
117 In the second case, the gateway reads all messages from the mail spool
118 file and submits each in turn to the roundup.mailgw module. The file is
119 emptied once all messages have been successfully handled. The file is
120 specified as:
121 mailbox /path/to/mailbox
122
123 POP:
124 In the third case, the gateway reads all messages from the POP server
125 specified and submits each in turn to the roundup.mailgw module. The
126 server is specified as:
127 pop username:password@server
128 The username and password may be omitted:
129 pop username@server
130 pop server
131 are both valid. The username and/or password will be prompted for if
132 not supplied on the command-line.
133 ''')
134 return 1
135
136 def main(args):
137 '''Handle the arguments to the program and initialise environment.
138 '''
139 # figure the instance home
140 if len(args) > 1:
141 instance_home = args[1]
142 else:
143 instance_home = os.environ.get('ROUNDUP_INSTANCE', '')
144 if not instance_home:
145 return usage(args)
146
147 # get the instance
148 import roundup.instance
149 instance = roundup.instance.open(instance_home)
150
151 # get a mail handler
152 db = instance.open('admin')
153 handler = instance.MailGW(instance, db)
154
155 # if there's no more arguments, read a single message from stdin
156 if len(args) == 2:
157 return do_pipe(handler)
158
159 # otherwise, figure what sort of mail source to handle
160 if len(args) < 4:
161 return usage(args, _('Error: not enough source specification information'))
162 source, specification = args[2:]
163 if source == 'mailbox':
164 return do_mailbox(handler, specification)
165 elif source == 'pop':
166 m = re.match(r'((?P<user>[^:]+)(:(?P<pass>.+))?@)?(?P<server>.+)',
167 specification)
168 if m:
169 return do_pop(handler, m.group('server'), m.group('user'),
170 m.group('pass'))
171 return usage(args, _('Error: pop specification not valid'))
172
173 return usage(args, _('Error: The source must be either "mailbox" or "pop"'))
174
175 def run():
176 sys.exit(main(sys.argv))
177
178 # call main
179 if __name__ == '__main__':
180 run()
181
182 #
183 # $Log: not supported by cvs2svn $
184 # Revision 1.1 2002/01/29 19:53:08 jhermann
185 # Moved scripts from top-level dir to roundup.scripts subpackage
186 #
187 # Revision 1.21 2002/01/11 07:02:29 grubert
188 # put an exception around: do_pop user and password entry to catch ctrl-c/d.
189 #
190 # Revision 1.20 2002/01/07 10:43:48 richard
191 # #500329 ] exception on server not reachable-patch
192 #
193 # Revision 1.19 2002/01/05 02:19:03 richard
194 # i18n'ification
195 #
196 # Revision 1.18 2001/12/13 00:20:01 richard
197 # . Centralised the python version check code, bumped version to 2.1.1 (really
198 # needs to be 2.1.2, but that isn't released yet :)
199 #
200 # Revision 1.17 2001/12/02 05:06:16 richard
201 # . We now use weakrefs in the Classes to keep the database reference, so
202 # the close() method on the database is no longer needed.
203 # I bumped the minimum python requirement up to 2.1 accordingly.
204 # . #487480 ] roundup-server
205 # . #487476 ] INSTALL.txt
206 #
207 # I also cleaned up the change message / post-edit stuff in the cgi client.
208 # There's now a clearly marked "TODO: append the change note" where I believe
209 # the change note should be added there. The "changes" list will obviously
210 # have to be modified to be a dict of the changes, or somesuch.
211 #
212 # More testing needed.
213 #
214 # Revision 1.16 2001/11/30 18:23:55 jhermann
215 # Cleaned up strange import (less pollution, too)
216 #
217 # Revision 1.15 2001/11/30 13:16:37 rochecompaan
218 # Fixed bug. Mail gateway was not using the extended Message class
219 # resulting in failed submissions when mails were processed from a Unix
220 # mailbox
221 #
222 # Revision 1.14 2001/11/13 21:44:44 richard
223 # . re-open the database as the author in mail handling
224 #
225 # Revision 1.13 2001/11/09 01:05:55 richard
226 # Fixed bug #479511 ] mailgw to pop once engelbert gruber tested the POP
227 # gateway.
228 #
229 # Revision 1.12 2001/11/08 05:16:55 richard
230 # Rolled roundup-popgw into roundup-mailgw. Cleaned mailgw up significantly,
231 # tested unix mailbox some more. POP still untested.
232 #
233 # Revision 1.11 2001/11/07 05:32:58 richard
234 # More roundup-mailgw usage help.
235 #
236 # Revision 1.10 2001/11/07 05:30:11 richard
237 # Nicer usage message.
238 #
239 # Revision 1.9 2001/11/07 05:29:26 richard
240 # Modified roundup-mailgw so it can read e-mails from a local mail spool
241 # file. Truncates the spool file after parsing.
242 # Fixed a couple of small bugs introduced in roundup.mailgw when I started
243 # the popgw.
244 #
245 # Revision 1.8 2001/11/01 22:04:37 richard
246 # Started work on supporting a pop3-fetching server
247 # Fixed bugs:
248 # . bug #477104 ] HTML tag error in roundup-server
249 # . bug #477107 ] HTTP header problem
250 #
251 # Revision 1.7 2001/08/07 00:24:42 richard
252 # stupid typo
253 #
254 # Revision 1.6 2001/08/07 00:15:51 richard
255 # Added the copyright/license notice to (nearly) all files at request of
256 # Bizar Software.
257 #
258 # Revision 1.5 2001/08/05 07:44:25 richard
259 # Instances are now opened by a special function that generates a unique
260 # module name for the instances on import time.
261 #
262 # Revision 1.4 2001/08/03 01:28:33 richard
263 # Used the much nicer load_package, pointed out by Steve Majewski.
264 #
265 # Revision 1.3 2001/08/03 00:59:34 richard
266 # Instance import now imports the instance using imp.load_module so that
267 # we can have instance homes of "roundup" or other existing python package
268 # names.
269 #
270 # Revision 1.2 2001/07/29 07:01:39 richard
271 # Added vim command to all source so that we don't get no steenkin' tabs :)
272 #
273 # Revision 1.1 2001/07/23 03:46:48 richard
274 # moving the bin files to facilitate out-of-the-boxness
275 #
276 # Revision 1.1 2001/07/22 11:15:45 richard
277 # More Grande Splite stuff
278 #
279 #
280 # vim: set filetype=python ts=4 sw=4 et si

Roundup Issue Tracker: http://roundup-tracker.org/