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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 #

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