Mercurial > p > roundup > code
annotate roundup/mailgw.py @ 103:381016730332
Fixed some non-string node ids.
| author | Richard Jones <richard@users.sourceforge.net> |
|---|---|
| date | Sat, 28 Jul 2001 00:34:34 +0000 |
| parents | c7c14960f413 |
| children | 19686b60e410 |
| rev | line source |
|---|---|
|
25
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
1 ''' |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
2 Incoming messages are examined for multiple parts. In a multipart/mixed |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
3 message or part, each subpart is extracted and examined. In a |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
4 multipart/alternative message or part, we look for a text/plain subpart and |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
5 ignore the other parts. The text/plain subparts are assembled to form the |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
6 textual body of the message, to be stored in the file associated with a |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
7 "msg" class node. Any parts of other types are each stored in separate |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
8 files and given "file" class nodes that are linked to the "msg" node. |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
9 |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
10 The "summary" property on message nodes is taken from the first non-quoting |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
11 section in the message body. The message body is divided into sections by |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
12 blank lines. Sections where the second and all subsequent lines begin with |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
13 a ">" or "|" character are considered "quoting sections". The first line of |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
14 the first non-quoting section becomes the summary of the message. |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
15 |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
16 All of the addresses in the To: and Cc: headers of the incoming message are |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
17 looked up among the user nodes, and the corresponding users are placed in |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
18 the "recipients" property on the new "msg" node. The address in the From: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
19 header similarly determines the "author" property of the new "msg" |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
20 node. The default handling for addresses that don't have corresponding |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
21 users is to create new users with no passwords and a username equal to the |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
22 address. (The web interface does not permit logins for users with no |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
23 passwords.) If we prefer to reject mail from outside sources, we can simply |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
24 register an auditor on the "user" class that prevents the creation of user |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
25 nodes with no passwords. |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
26 |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
27 The subject line of the incoming message is examined to determine whether |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
28 the message is an attempt to create a new item or to discuss an existing |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
29 item. A designator enclosed in square brackets is sought as the first thing |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
30 on the subject line (after skipping any "Fwd:" or "Re:" prefixes). |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
31 |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
32 If an item designator (class name and id number) is found there, the newly |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
33 created "msg" node is added to the "messages" property for that item, and |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
34 any new "file" nodes are added to the "files" property for the item. |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
35 |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
36 If just an item class name is found there, we attempt to create a new item |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
37 of that class with its "messages" property initialized to contain the new |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
38 "msg" node and its "files" property initialized to contain any new "file" |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
39 nodes. |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
40 |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
41 Both cases may trigger detectors (in the first case we are calling the |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
42 set() method to add the message to the item's spool; in the second case we |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
43 are calling the create() method to create a new node). If an auditor raises |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
44 an exception, the original message is bounced back to the sender with the |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
45 explanatory message given in the exception. |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
46 |
|
103
381016730332
Fixed some non-string node ids.
Richard Jones <richard@users.sourceforge.net>
parents:
26
diff
changeset
|
47 $Id: mailgw.py,v 1.3 2001-07-28 00:34:34 richard Exp $ |
|
25
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
48 ''' |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
49 |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
50 |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
51 import string, re, os, mimetools, StringIO, smtplib, socket, binascii, quopri |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
52 import traceback |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
53 import date |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
54 |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
55 def getPart(fp, boundary): |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
56 line = '' |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
57 s = StringIO.StringIO() |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
58 while 1: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
59 line_n = fp.readline() |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
60 if not line_n: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
61 break |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
62 line = line_n.strip() |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
63 if line == '--'+boundary+'--': |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
64 break |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
65 if line == '--'+boundary: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
66 break |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
67 s.write(line_n) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
68 if not s.getvalue().strip(): |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
69 return None |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
70 return s |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
71 |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
72 subject_re = re.compile(r'(\[?(fwd|re):\s*)*' |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
73 r'(\[(?P<classname>[^\d]+)(?P<nodeid>\d+)?\])' |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
74 r'(?P<title>[^\[]+)(\[(?P<args>.+?)\])?', re.I) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
75 |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
76 class MailGW: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
77 def __init__(self, db): |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
78 self.db = db |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
79 |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
80 def main(self, fp): |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
81 # ok, figure the subject, author, recipients and content-type |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
82 message = mimetools.Message(fp) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
83 try: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
84 self.handle_message(message) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
85 except: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
86 # bounce the message back to the sender with the error message |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
87 sendto = [message.getaddrlist('from')[0][1]] |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
88 m = ['Subject: failed issue tracker submission'] |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
89 m.append('') |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
90 # TODO as attachments? |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
91 m.append('---- traceback of failure ----') |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
92 s = StringIO.StringIO() |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
93 import traceback |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
94 traceback.print_exc(None, s) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
95 m.append(s.getvalue()) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
96 m.append('---- failed message follows ----') |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
97 try: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
98 fp.seek(0) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
99 except: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
100 pass |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
101 m.append(fp.read()) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
102 try: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
103 smtp = smtplib.SMTP(self.MAILHOST) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
104 smtp.sendmail(self.ADMIN_EMAIL, sendto, '\n'.join(m)) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
105 except socket.error, value: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
106 return "Couldn't send confirmation email: mailhost %s"%value |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
107 except smtplib.SMTPException, value: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
108 return "Couldn't send confirmation email: %s"%value |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
109 |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
110 def handle_message(self, message): |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
111 # handle the subject line |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
112 m = subject_re.match(message.getheader('subject')) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
113 if not m: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
114 raise ValueError, 'No [designator] found in subject "%s"' |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
115 classname = m.group('classname') |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
116 nodeid = m.group('nodeid') |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
117 title = m.group('title').strip() |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
118 subject_args = m.group('args') |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
119 cl = self.db.getclass(classname) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
120 properties = cl.getprops() |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
121 props = {} |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
122 args = m.group('args') |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
123 if args: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
124 for prop in string.split(m.group('args'), ';'): |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
125 try: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
126 key, value = prop.split('=') |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
127 except ValueError, message: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
128 raise ValueError, 'Args list not of form [arg=value,value,...;arg=value,value,value..] (specific exception message was "%s")'%message |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
129 type = properties[key] |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
130 if type.isStringType: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
131 props[key] = value |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
132 elif type.isDateType: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
133 props[key] = date.Date(value) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
134 elif type.isIntervalType: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
135 props[key] = date.Interval(value) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
136 elif type.isLinkType: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
137 props[key] = value |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
138 elif type.isMultilinkType: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
139 props[key] = value.split(',') |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
140 |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
141 # handle the users |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
142 author = self.db.uidFromAddress(message.getaddrlist('from')[0]) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
143 recipients = [] |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
144 for recipient in message.getaddrlist('to') + message.getaddrlist('cc'): |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
145 if recipient[1].strip().lower() == self.ISSUE_TRACKER_EMAIL: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
146 continue |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
147 recipients.append(self.db.uidFromAddress(recipient)) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
148 |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
149 # now handle the body - find the message |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
150 content_type = message.gettype() |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
151 attachments = [] |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
152 if content_type == 'multipart/mixed': |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
153 boundary = message.getparam('boundary') |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
154 # skip over the intro to the first boundary |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
155 part = getPart(message.fp, boundary) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
156 content = None |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
157 while 1: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
158 # get the next part |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
159 part = getPart(message.fp, boundary) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
160 if part is None: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
161 break |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
162 # parse it |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
163 part.seek(0) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
164 submessage = mimetools.Message(part) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
165 subtype = submessage.gettype() |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
166 if subtype == 'text/plain' and not content: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
167 # this one's our content |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
168 content = part.read() |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
169 elif subtype == 'message/rfc822': |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
170 i = part.tell() |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
171 subsubmess = mimetools.Message(part) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
172 name = subsubmess.getheader('subject') |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
173 part.seek(i) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
174 attachments.append((name, 'message/rfc822', part.read())) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
175 else: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
176 # try name on Content-Type |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
177 name = submessage.getparam('name') |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
178 # this is just an attachment |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
179 data = part.read() |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
180 encoding = submessage.getencoding() |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
181 if encoding == 'base64': |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
182 data = binascii.a2b_base64(data) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
183 elif encoding == 'quoted-printable': |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
184 data = quopri.decode(data) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
185 elif encoding == 'uuencoded': |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
186 data = binascii.a2b_uu(data) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
187 attachments.append((name, submessage.gettype(), data)) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
188 if content is None: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
189 raise ValueError, 'No text/plain part found' |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
190 |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
191 elif content_type[:10] == 'multipart/': |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
192 boundary = message.getparam('boundary') |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
193 # skip over the intro to the first boundary |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
194 getPart(message.fp, boundary) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
195 content = None |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
196 while 1: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
197 # get the next part |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
198 part = getPart(message.fp, boundary) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
199 if part is None: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
200 break |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
201 # parse it |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
202 part.seek(0) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
203 submessage = mimetools.Message(part) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
204 if submessage.gettype() == 'text/plain' and not content: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
205 # this one's our content |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
206 content = part.read() |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
207 if content is None: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
208 raise ValueError, 'No text/plain part found' |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
209 |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
210 elif content_type != 'text/plain': |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
211 raise ValueError, 'No text/plain part found' |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
212 |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
213 else: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
214 content = message.fp.read() |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
215 |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
216 # extract out the summary from the message |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
217 summary = [] |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
218 for line in content.split('\n'): |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
219 line = line.strip() |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
220 if summary and not line: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
221 break |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
222 if not line: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
223 summary.append('') |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
224 elif line[0] not in '>|': |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
225 summary.append(line) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
226 summary = '\n'.join(summary) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
227 |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
228 # handle the files |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
229 files = [] |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
230 for (name, type, data) in attachments: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
231 files.append(self.db.file.create(type=type, name=name, content=data)) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
232 |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
233 # now handle the db stuff |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
234 if nodeid: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
235 # If an item designator (class name and id number) is found there, the |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
236 # newly created "msg" node is added to the "messages" property for |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
237 # that item, and any new "file" nodes are added to the "files" |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
238 # property for the item. |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
239 message_id = self.db.msg.create(author=author, recipients=recipients, |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
240 date=date.Date('.'), summary=summary, content=content, |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
241 files=files) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
242 messages = cl.get(nodeid, 'messages') |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
243 messages.append(message_id) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
244 props['messages'] = messages |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
245 apply(cl.set, (nodeid, ), props) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
246 else: |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
247 # If just an item class name is found there, we attempt to create a |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
248 # new item of that class with its "messages" property initialized to |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
249 # contain the new "msg" node and its "files" property initialized to |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
250 # contain any new "file" nodes. |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
251 message_id = self.db.msg.create(author=author, recipients=recipients, |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
252 date=date.Date('.'), summary=summary, content=content, |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
253 files=files) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
254 if not props.has_key('assignedto'): |
|
103
381016730332
Fixed some non-string node ids.
Richard Jones <richard@users.sourceforge.net>
parents:
26
diff
changeset
|
255 props['assignedto'] = '1' # "admin" |
|
25
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
256 if not props.has_key('priority'): |
|
103
381016730332
Fixed some non-string node ids.
Richard Jones <richard@users.sourceforge.net>
parents:
26
diff
changeset
|
257 props['priority'] = '1' # "bug-fatal" |
|
25
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
258 if not props.has_key('status'): |
|
103
381016730332
Fixed some non-string node ids.
Richard Jones <richard@users.sourceforge.net>
parents:
26
diff
changeset
|
259 props['status'] = '1' # "unread" |
|
25
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
260 if not props.has_key('title'): |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
261 props['title'] = title |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
262 props['messages'] = [message_id] |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
263 props['nosy'] = recipients[:] |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
264 props['nosy'].append(author) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
265 props['nosy'].sort() |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
266 nodeid = cl.create(**props) |
|
4cf1daf2f2eb
More Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
diff
changeset
|
267 |
|
26
c7c14960f413
Final commit of Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
25
diff
changeset
|
268 # |
|
c7c14960f413
Final commit of Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
25
diff
changeset
|
269 # $Log: not supported by cvs2svn $ |
|
103
381016730332
Fixed some non-string node ids.
Richard Jones <richard@users.sourceforge.net>
parents:
26
diff
changeset
|
270 # Revision 1.2 2001/07/22 12:09:32 richard |
|
381016730332
Fixed some non-string node ids.
Richard Jones <richard@users.sourceforge.net>
parents:
26
diff
changeset
|
271 # Final commit of Grande Splite |
|
26
c7c14960f413
Final commit of Grande Splite
Richard Jones <richard@users.sourceforge.net>
parents:
25
diff
changeset
|
272 # |
|
103
381016730332
Fixed some non-string node ids.
Richard Jones <richard@users.sourceforge.net>
parents:
26
diff
changeset
|
273 # |
