1515# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717#
18- # vim: ts=4 sw=4 expandtab
19- #
2018
2119"""An e-mail gateway for Roundup.
2220
2523 examined. The text/plain subparts are assembled to form the textual
2624 body of the message, to be stored in the file associated with a "msg"
2725 class node. Any parts of other types are each stored in separate files
28- and given "file" class nodes that are linked to the "msg" node.
26+ and given "file" class nodes that are linked to the "msg" node.
2927 . In a multipart/alternative message or part, we look for a text/plain
3028 subpart and ignore the other parts.
3129
@@ -35,7 +33,7 @@ class node. Any parts of other types are each stored in separate files
3533section in the message body. The message body is divided into sections by
3634blank lines. Sections where the second and all subsequent lines begin with
3735a ">" or "|" character are considered "quoting sections". The first line of
38- the first non-quoting section becomes the summary of the message.
36+ the first non-quoting section becomes the summary of the message.
3937
4038Addresses
4139---------
@@ -48,33 +46,33 @@ class node. Any parts of other types are each stored in separate files
4846address. (The web interface does not permit logins for users with no
4947passwords.) If we prefer to reject mail from outside sources, we can simply
5048register an auditor on the "user" class that prevents the creation of user
51- nodes with no passwords.
49+ nodes with no passwords.
5250
5351Actions
5452-------
5553The subject line of the incoming message is examined to determine whether
5654the message is an attempt to create a new item or to discuss an existing
5755item. A designator enclosed in square brackets is sought as the first thing
58- on the subject line (after skipping any "Fwd:" or "Re:" prefixes).
56+ on the subject line (after skipping any "Fwd:" or "Re:" prefixes).
5957
6058If an item designator (class name and id number) is found there, the newly
6159created "msg" node is added to the "messages" property for that item, and
62- any new "file" nodes are added to the "files" property for the item.
60+ any new "file" nodes are added to the "files" property for the item.
6361
6462If just an item class name is found there, we attempt to create a new item
6563of that class with its "messages" property initialized to contain the new
6664"msg" node and its "files" property initialized to contain any new "file"
67- nodes.
65+ nodes.
6866
6967Triggers
7068--------
7169Both cases may trigger detectors (in the first case we are calling the
7270set() method to add the message to the item's spool; in the second case we
7371are calling the create() method to create a new node). If an auditor raises
7472an exception, the original message is bounced back to the sender with the
75- explanatory message given in the exception.
73+ explanatory message given in the exception.
7674
77- $Id: mailgw.py,v 1.149.2.2 2004-09-14 22:03:42 richard Exp $
75+ $Id: mailgw.py,v 1.149.2.3 2004-09-29 08:47:59 a1s Exp $
7876"""
7977__docformat__ = 'restructuredtext'
8078
@@ -211,7 +209,7 @@ def getbody(self):
211209 data = None
212210 if encoding == 'base64' :
213211 # BUG: is base64 really used for text encoding or
214- # are we inserting zip files here.
212+ # are we inserting zip files here.
215213 data = binascii .a2b_base64 (self .fp .read ())
216214 elif encoding == 'quoted-printable' :
217215 # the quopri module wants to work with files
@@ -223,7 +221,7 @@ def getbody(self):
223221 else :
224222 # take it as text
225223 data = self .fp .read ()
226-
224+
227225 # Encode message to unicode
228226 charset = rfc2822 .unaliasCharset (self .getparam ("charset" ))
229227 if charset :
@@ -234,19 +232,19 @@ def getbody(self):
234232 else :
235233 # Leave message content as is
236234 edata = data
237-
235+
238236 return edata
239237
240238 # General multipart handling:
241- # Take the first text/plain part, anything else is considered an
239+ # Take the first text/plain part, anything else is considered an
242240 # attachment.
243241 # multipart/mixed: multiple "unrelated" parts.
244- # multipart/signed (rfc 1847):
245- # The control information is carried in the second of the two
242+ # multipart/signed (rfc 1847):
243+ # The control information is carried in the second of the two
246244 # required body parts.
247245 # ACTION: Default, so if content is text/plain we get it.
248- # multipart/encrypted (rfc 1847):
249- # The control information is carried in the first of the two
246+ # multipart/encrypted (rfc 1847):
247+ # The control information is carried in the first of the two
250248 # required body parts.
251249 # ACTION: Not handleable as the content is encrypted.
252250 # multipart/related (rfc 1872, 2112, 2387):
@@ -259,7 +257,7 @@ def getbody(self):
259257 # only in "related" ?
260258 # multipart/report (rfc 1892):
261259 # e.g. mail system delivery status reports.
262- # ACTION: Default. Could be ignored or used for Delivery Notification
260+ # ACTION: Default. Could be ignored or used for Delivery Notification
263261 # flagging.
264262 # multipart/form-data:
265263 # For web forms only.
@@ -269,7 +267,7 @@ def extract_content(self, parent_type=None):
269267 content_type = self .gettype ()
270268 content = None
271269 attachments = []
272-
270+
273271 if content_type == 'text/plain' :
274272 content = self .getbody ()
275273 elif content_type [:10 ] == 'multipart/' :
@@ -282,7 +280,7 @@ def extract_content(self, parent_type=None):
282280 content = new_content
283281 elif new_content :
284282 attachments .append (part .as_attachment ())
285-
283+
286284 attachments .extend (new_attach )
287285 elif (parent_type == 'multipart/signed' and
288286 content_type == 'application/pgp-signature' ):
@@ -306,7 +304,7 @@ class MailGW:
306304 (\[(?P<classname>[^\d\s]+) # [issue..
307305 (?P<nodeid>\d+)? # ..1234]
308306 \])?\s*
309- (?P<title>[^[]+)? # issue title
307+ (?P<title>[^[]+)? # issue title
310308 "? # Trailing "
311309 (\[(?P<args>.+?)\])? # [prop=value]
312310 ''' , re .IGNORECASE | re .VERBOSE )
@@ -476,7 +474,7 @@ def do_pop(self, server, user='', password='', apop=0):
476474 server .pass_ (password )
477475 numMessages = len (server .list ()[1 ])
478476 for i in range (1 , numMessages + 1 ):
479- # retr: returns
477+ # retr: returns
480478 # [ pop response e.g. '+OK 459 octets',
481479 # [ array of message lines ],
482480 # number of octets ]
@@ -514,7 +512,7 @@ def handle_Message(self, message):
514512 if not sendto :
515513 # very bad-looking message - we don't even know who sent it
516514 # XXX we should use a log file here...
517-
515+
518516 sendto = [self .instance .config .ADMIN_EMAIL ]
519517
520518 m = ['Subject: badly formed message from mail gateway' ]
@@ -636,7 +634,7 @@ def handle_message(self, message):
636634 subject = 'Your registration to %s is complete' % \
637635 self .instance .config .TRACKER_NAME
638636 sendto = [from_list [0 ][1 ]]
639- self .mailer .standard_message (sendto , subject , '' )
637+ self .mailer .standard_message (sendto , subject , '' )
640638 return
641639 elif self .default_class :
642640 classname = self .default_class
@@ -865,19 +863,19 @@ def handle_message(self, message):
865863Roundup requires the submission to be plain text. The message parser could
866864not find a text/plain part to use.
867865'''
868-
866+
869867 # figure how much we should muck around with the email body
870868 keep_citations = getattr (self .instance .config , 'EMAIL_KEEP_QUOTED_TEXT' ,
871869 'no' ) == 'yes'
872870 keep_body = getattr (self .instance .config , 'EMAIL_LEAVE_BODY_UNCHANGED' ,
873871 'no' ) == 'yes'
874872
875873 # parse the body of the message, stripping out bits as appropriate
876- summary , content = parseContent (content , keep_citations ,
874+ summary , content = parseContent (content , keep_citations ,
877875 keep_body )
878876 content = content .strip ()
879877
880- #
878+ #
881879 # handle the attachments
882880 #
883881 if properties .has_key ('files' ):
@@ -902,7 +900,7 @@ def handle_message(self, message):
902900 # pre-load the files list
903901 props ['files' ] = files
904902
905- #
903+ #
906904 # create the message if there's a message body (content)
907905 #
908906 if (content and properties .has_key ('messages' )):
@@ -916,15 +914,15 @@ def handle_message(self, message):
916914Mail message was rejected by a detector.
917915%s
918916''' % error
919- # attach the message to the node
920- if nodeid :
921- # add the message to the node's list
922- messages = cl .get (nodeid , 'messages' )
923- messages .append (message_id )
924- props ['messages' ] = messages
925- else :
926- # pre-load the messages list
927- props ['messages' ] = [message_id ]
917+ # attach the message to the node
918+ if nodeid :
919+ # add the message to the node's list
920+ messages = cl .get (nodeid , 'messages' )
921+ messages .append (message_id )
922+ props ['messages' ] = messages
923+ else :
924+ # pre-load the messages list
925+ props ['messages' ] = [message_id ]
928926
929927 #
930928 # perform the node change / create
@@ -951,7 +949,7 @@ def handle_message(self, message):
951949
952950 return nodeid
953951
954-
952+
955953def setPropArrayFromString (self , cl , propString , nodeid = None ):
956954 ''' takes string of form prop=value,value;prop2=value
957955 and returns (error, prop[..])
@@ -1051,13 +1049,13 @@ def uidFromAddress(db, address, create=1, **user_props):
10511049
10521050def parseContent (content , keep_citations , keep_body ,
10531051 blank_line = re .compile (r'[\r\n]+\s*[\r\n]+' ),
1054- eol = re .compile (r'[\r\n]+' ),
1052+ eol = re .compile (r'[\r\n]+' ),
10551053 signature = re .compile (r'^[>|\s]*-- ?$' ),
10561054 original_msg = re .compile (r'^[>|\s]*-----\s?Original Message\s?-----$' )):
10571055 ''' The message body is divided into sections by blank lines.
10581056 Sections where the second and all subsequent lines begin with a ">"
10591057 or "|" character are considered "quoting sections". The first line of
1060- the first non-quoting section becomes the summary of the message.
1058+ the first non-quoting section becomes the summary of the message.
10611059
10621060 If keep_citations is true, then we keep the "quoting sections" in the
10631061 content.
@@ -1131,4 +1129,4 @@ def parseContent(content, keep_citations, keep_body,
11311129
11321130 return summary , content
11331131
1134- # vim: set filetype=python ts =4 sw=4 et si
1132+ # vim: set filetype=python sts =4 sw=4 et si :
0 commit comments