def test_create_multipart_string_from_files(self): files = [] values = [] for i in range(3): _, filename = tempfile.mkstemp() files.append(('plain', filename)) with open(filename, 'wb') as f: value = "value-%d" % i f.write(value) values.append(value) result = Util.create_multipart_string_from_files(files) for mime, f in files: os.remove(f) with closing(StringIO(result)) as buf: parser = Parser() msg = parser.parse(buf) for part in msg.walk(): if msg.is_multipart(): i = 0 for msg in part.get_payload(): self.assertEqual(values[i], msg.get_payload()) i += 1
def __parse_revision_logs(self, fqrevlist, update=True): changesets = [] logparser = Parser() c = ExternalCommand(cwd=self.repository.basedir, command=self.repository.command("cat-archive-log")) for fqrev in fqrevlist: out, err = c.execute(fqrev, stdout=PIPE, stderr=PIPE) if c.exit_status: raise GetUpstreamChangesetsFailure( "%s returned status %d saying\n%s" % (str(c), c.exit_status, err.read())) err = None try: msg = logparser.parse(out) except Exception, err: pass if not err and msg.is_multipart(): err = "unable to parse log description" if not err and update and msg.has_key('Continuation-of'): err = "in-version continuations not supported" if err: raise GetUpstreamChangesetsFailure(str(err)) date = self.__parse_date(msg['Date'], msg['Standard-date']) author = msg['Creator'] revision = fqrev logmsg = [msg['Summary']] s = msg.get('Keywords', "").strip() if s: logmsg.append('Keywords: ' + s) s = msg.get_payload().strip() if s: logmsg.append(s) logmsg = '\n'.join(logmsg) changesets.append(Changeset(revision, date, author, logmsg))
def __parse_revision_logs(self, fqrevlist, update=True): changesets = [] logparser = Parser() c = ExternalCommand(cwd=self.repository.basedir, command=self.repository.command("cat-archive-log")) for fqrev in fqrevlist: out, err = c.execute(fqrev, stdout=PIPE, stderr=PIPE) if c.exit_status: raise GetUpstreamChangesetsFailure( "%s returned status %d saying\n%s" % (str(c), c.exit_status, err.read())) err = None try: msg = logparser.parse(out) except Exception, err: pass if not err and msg.is_multipart(): err = "unable to parse log description" if not err and update and msg.has_key('Continuation-of'): err = "in-version continuations not supported" if err: raise GetUpstreamChangesetsFailure(str(err)) date = self.__parse_date(msg['Date'], msg['Standard-date']) author = msg['Creator'] revision = fqrev logmsg = [msg['Summary']] s = msg.get('Keywords', "").strip() if s: logmsg.append('Keywords: ' + s) s = msg.get_payload().strip() if s: logmsg.append(s) logmsg = '\n'.join(logmsg) changesets.append(Changeset(revision, date, author, logmsg))
def parse(content): """ Eメールのコンテンツを受け取りparse,encodeして返す """ p = EmailParser() msgobj = p.parse(content) attachments = [] return parse2(msgobj, attachments)
def parse(content): """ Eメールのコンテンツを受け取りparse,encodeして返す """ p = EmailParser() msgobj = p.parse(content) attachments = [] return parse2(msgobj, attachments)
def parse(content): p = EmailParser() if type(content) == str: msgobj = p.parsestr(content) else: msgobj = p.parse(content) attachments = [] return _parse2(msgobj, attachments)
def parse(content): p = EmailParser() if type(content) == str: msgobj = p.parsestr(content) else: msgobj = p.parse(content) attachments = [] return _parse2(msgobj, attachments)
def parse(content): """ Eメールのコンテンツを受け取りparse,encodeして返す """ p = EmailParser() msgobj = p.parse(content) if msgobj['Subject'] is not None: decodefrag = decode_header(msgobj['Subject']) subj_fragments = [] for s , enc in decodefrag: if enc: s = str(s , enc).encode('utf8','replace') subj_fragments.append(s) subject = ''.join(subj_fragments) else: subject = None attachments = [] body = None html = None for part in msgobj.walk(): attachment = parse_attachment(part) if attachment: attachments.append(attachment) elif part.get_content_type() == "text/plain": if body is None: body = "" body += str( part.get_payload(decode=True), part.get_content_charset(), 'replace' ).encode('utf8','replace') elif part.get_content_type() == "text/html": if html is None: html = "" html += str( part.get_payload(decode=True), part.get_content_charset(), 'replace' ).encode('utf8','replace') return { 'subject' : subject, 'body' : body, 'html' : html, 'from' : parseaddr(msgobj.get('From'))[1], # 名前は除いてメールアドレスのみ抽出 'to' : parseaddr(msgobj.get('To'))[1], # 名前は除いてメールアドレスのみ抽出 'attachments': attachments, }
def parse(content): """ Eメールのコンテンツを受け取りparse,encodeして返す """ p = EmailParser() msgobj = p.parse(content) if msgobj['Subject'] is not None: decodefrag = decode_header(msgobj['Subject']) subj_fragments = [] for s, enc in decodefrag: if enc: s = unicode(s, enc).encode('utf8', 'replace') subj_fragments.append(s) subject = ''.join(subj_fragments) else: subject = None attachments = [] body = None html = None for part in msgobj.walk(): attachment = parse_attachment(part) if attachment: attachments.append(attachment) elif part.get_content_type() == "text/plain": if body is None: body = "" body += unicode(part.get_payload(decode=True), part.get_content_charset(), 'replace').encode('utf8', 'replace') elif part.get_content_type() == "text/html": if html is None: html = "" html += unicode(part.get_payload(decode=True), part.get_content_charset(), 'replace').encode('utf8', 'replace') return { 'subject': subject, 'body': body, 'html': html, 'from': parseaddr(msgobj.get('From'))[1], # 名前は除いてメールアドレスのみ抽出 'to': parseaddr(msgobj.get('To'))[1], # 名前は除いてメールアドレスのみ抽出 'attachments': attachments, }
def addMessage(self, msg, flags=None, date=None): #print "Add Message: %s :: %s" % (msg, flags) # passes a file handler here, need to cache fetchBodyFile so I can find the message id. # list of uids # uids[sequence_number] = msg_uid # add new uid # rpush[msg_uid] parse = Parser() email_obj = parse.parse(msg) fp = StringIO() g = Generator(fp, mangle_from_=False, maxheaderlen=60) g.flatten(email_obj) body = fp.getvalue() msg_uid = self.conn.incr("%s:mailboxes:%s:uidnext" % (self.user, self.folder)) - 1; self.conn.zadd("%s:mailboxes:%s:uidlist"% (self.user, self.folder), msg_uid, msg_uid) self.seqlist.append((msg_uid, ['\Recent'])) seq_number = len(self.seqlist) if flags: self.conn.sadd("%s:mailboxes:%s:mail:%s:flags" % (self.user, self.folder, msg_uid), *flags) self.conn.set("%s:mailboxes:%s:mail:%s:date" % (self.user, self.folder, msg_uid), rfc822date()) self.conn.incr("%s:mailboxes:%s:count" % (self.user, self.folder)) self.conn.set("%s:mailboxes:%s:mail:%s:size" % (self.user, self.folder, msg_uid), len(body)) self.conn.set("%s:mailboxes:%s:mail:%s:body" % (self.user, self.folder, msg_uid), body) self.conn.sadd("%s:mailboxes:%s:mail:%s:headers" % (self.user, self.folder, msg_uid), *(email_obj.keys())) #print email_obj.keys() for header in email_obj.keys(): self.conn.set("%s:mailboxes:%s:mail:%s:header:%s" % (self.user, self.folder, msg_uid, header.lower()), email_obj[header]) #print header, msg_uid, self.folder, self.user self.conn.incr("%s:mailboxes:%s:recent" % (self.user, self.folder)) self.recent_count += 1 self.conn.publish("%s:mailboxes:%s:channel" % (self.user, self.folder), "count %d" % (msg_uid)) return defer.succeed(seq_number)
def test_create_multipart_string(self): files = [] values = [] for i in range(3): value = "value-%d" % i values.append(value) files.append(('plain', value)) result = Util.create_multipart_string(files) with closing(StringIO(result)) as buf: parser = Parser() msg = parser.parse(buf) for part in msg.walk(): if msg.is_multipart(): i = 0 for msg in part.get_payload(): self.assertEqual(values[i], msg.get_payload()) i += 1
class HTTPParser(object): def __init__(self, message): self._parser = Parser() self.requests = [] self.responses = [] if isinstance(message, basestring): self._parsestr(message) else: self._parse(message) def _parse_subrequest(self, subrequest): payload = subrequest.get_payload() if payload is None: raise ParserError("Missing payload in subrequest") content_type = subrequest.get("content-transfer-encoding", "").lower() if content_type == "quoted-printable": payload = quopri.decodestring(payload) elif content_type == "base64": payload = bdecode(payload) return payload def _parse(self, fp): msg = self._parser.parse(fp) for subrequest in msg.walk(): type = subrequest.get_content_maintype() request_id = subrequest.get("multipart-request-id", None) if type == "multipart": continue # walk will descend into child messages if type == "application": payload = self._parse_subrequest(subrequest) subtype = subrequest.get_content_subtype() if subtype == "http-request": self.requests.append(HTTPRequest(payload, request_id=request_id)) elif subtype == "http-response": self.responses.append(HTTPResponse(payload)) else: raise ParserError("Unrecognized message type: '%s'" % subrequest.get_content_type()) def _parsestr(self, text): self._parse(StringIO(text))
def handle(self, *args, **options): p = Parser() #Parse the email from standard input if args: sample_email_filename = args[0] sample_email_file = open(sample_email_filename) email = p.parse(sample_email_file) else: email = p.parse(sys.stdin) #f = open('/out.txt','w') #print >>f, email #Here are the relevant details. subject = email['subject'] original_recipient_address = email['X-Original-To'] email_logger.info('Got email to %s.' % original_recipient_address) body = get_first_text_part( email ) + "\n\n This message was handled by Justin's Django Email handler (replace with some meaningful message)." sender = email['from'] sender_info = email_utils.parseaddr(sender) sender_name = sender_info[0] sender_email = sender_info[1] #First of all, we're curious about whether this is a message sent to an object, in which case we're going to do something entirely different. subdomain = original_recipient_address.split('@')[1].split('.')[0] #There may be a drier way to confirm that the user has an account. #They do need one to send to blast or objects. if subdomain == 'blasts' or subdomain == 'objects': try: sender_user = User.objects.get(email=sender_email) except User.DoesNotExist: #This wasn't anybody's primary email. Let's see if it's an additional email. try: additional_email = AdditionalEmail.objects.get( email=sender_email) sender_user = additional_email.contact_info.userprofile.user except AdditionalEmail.DoesNotExist: #If the use doesn't exist, we have no idea as whom to post the message. We'll just have to tell them so. recipients = [] subject = 'No dice.' body = "It seems that your email address, %s, is not associated with a username. Thus, you can't post a message." % ( sender_email) sender = '*****@*****.**' recipients.append(sender_email) recipients.append('*****@*****.**' ) #Send to Justin for debugging for recipient in recipients: send_mail( subject, body, sender, [recipient], fail_silently=False ) #, connection=smtp.EmailBackend()) #To test smtp backend return False if subdomain == 'blasts': blast_info = original_recipient_address.split('@')[0] group_name_with_underscores = blast_info.split('__')[0] group_name = group_name_with_underscores.replace('_', ' ') role_name = blast_info.split('__')[1] try: role_in_group = RoleInGroup.objects.get( group__name=group_name, role__name=role_name) blast_message = BlastMessage.objects.create( subject=subject, message=body, role=role_in_group.role, group=role_in_group.group, creator=sender_user) blast_message.prepare() blast_message.send_blast() except RoleInGroup.DoesNotExist: recipients = [] subject = 'No dice.' body = "There is no role called %s and / or group called %s." % ( role_name, group_name) sender = '*****@*****.**' recipients.append(email['sender']) recipients.append('*****@*****.**' ) #Send to Justin for debugging for recipient in recipients: send_mail(subject, body, sender, [recipient], fail_silently=False) if subdomain == "objects": object_info = original_recipient_address.split('@')[0] #Well, we seem to have found a sender_user, so we are going to go ahead with this shindig here. #Before we do, let's parse the message and get rid of any old replies or signatures. message_lines = body.split('\n') message_text = "" #Start an empty string which we'll fill with the message text. for line in message_lines: if line[:2] == "--" or line[:1] == ">" or re.search( ".*On.*(\\r\\n)?wrote:", line ): #Let's see if the first two characters of the line are hyphens. #If so, we're going to ignore anything after this line. break #Since we have already found the end of the message, there's no need to keep iterating. else: #We haven't hit the hyphens yet, so we'll add this line to the message. message_text += line + "\n" app_name = object_info.split('.')[0] model_name = object_info.split('.')[1] object_id = object_info.split('.')[2] Model = ContentType.objects.get( app_label=app_name, model=model_name.lower()).model_class() target_object = Model.objects.get(id=object_id) TopLevelMessage.objects.create(content_object=target_object, creator=sender_user, message=message_text) else: #Nope, this is just a message to a user / group / handler (ie, not directly to an object). #Who is this email to? recipient_name = original_recipient_address.split('@')[0] recipients = [] try: user = User.objects.get( userprofile__email_prefix__iexact=recipient_name) recipients.append(user.email) except User.DoesNotExist: #We don't need a MultipleObjectsReturned case because username is constrained unique. email_logger.info('User did not exist. Looking for handler.') try: handler = MailHandler.objects.get(address=recipient_name) #TODO: Put amazing, mind-blowing shit here. for user in handler.users.all(): recipients.append(user.email) except MailHandler.DoesNotExist: email_logger.info( 'No match found at all - sending bounce.') subject = 'No dice.' body = "We don't know " + email[ 'to'] + ". If you want to introduce us, send a message to [email protected] + \n Headers Follow: \n " + str( email) sender = '*****@*****.**' recipients.append(email['sender']) recipients.append('*****@*****.**' ) #Send to Justin for debugging for recipient in recipients: email_logger.info('Sending to %s.' % recipient) send_mail(subject, body, sender, [recipient], fail_silently=False) #Last of all - assuming the database is up, we'll save the message object now. if not subject: subject = "No Subject." mail = MailMessage(subject=subject, body=body, recipient=original_recipient_address, sender=sender) try: mail.save() except: #TODO: Add reasonable and sane logging. pass #Well, you know. F**k.
def handle(self, *args, **options): p = Parser() #Parse the email from standard input if args: sample_email_filename = args[0] sample_email_file = open(sample_email_filename) email = p.parse(sample_email_file) else: email = p.parse(sys.stdin) #f = open('/out.txt','w') #print >>f, email #Here are the relevant details. subject = email['subject'] original_recipient_address = email['X-Original-To'] email_logger.info('Got email to %s.' % original_recipient_address) body = get_first_text_part(email) + "\n\n This message was handled by Justin's Django Email handler (replace with some meaningful message)." sender = email['from'] sender_info = email_utils.parseaddr(sender) sender_name = sender_info[0] sender_email = sender_info[1] #First of all, we're curious about whether this is a message sent to an object, in which case we're going to do something entirely different. subdomain=original_recipient_address.split('@')[1].split('.')[0] #There may be a drier way to confirm that the user has an account. #They do need one to send to blast or objects. if subdomain == 'blasts' or subdomain == 'objects': try: sender_user = User.objects.get(email = sender_email) except User.DoesNotExist: #This wasn't anybody's primary email. Let's see if it's an additional email. try: additional_email = AdditionalEmail.objects.get(email=sender_email) sender_user = additional_email.contact_info.userprofile.user except AdditionalEmail.DoesNotExist: #If the use doesn't exist, we have no idea as whom to post the message. We'll just have to tell them so. recipients = [] subject = 'No dice.' body = "It seems that your email address, %s, is not associated with a username. Thus, you can't post a message." % (sender_email) sender = '*****@*****.**' recipients.append(sender_email) recipients.append('*****@*****.**') #Send to Justin for debugging for recipient in recipients: send_mail(subject, body, sender, [recipient], fail_silently=False)#, connection=smtp.EmailBackend()) #To test smtp backend return False if subdomain == 'blasts': blast_info = original_recipient_address.split('@')[0] group_name_with_underscores = blast_info.split('__')[0] group_name = group_name_with_underscores.replace('_', ' ') role_name = blast_info.split('__')[1] try: role_in_group = RoleInGroup.objects.get(group__name=group_name, role__name=role_name) blast_message = BlastMessage.objects.create(subject=subject, message=body, role=role_in_group.role, group=role_in_group.group, creator=sender_user) blast_message.prepare() blast_message.send_blast() except RoleInGroup.DoesNotExist: recipients = [] subject = 'No dice.' body = "There is no role called %s and / or group called %s." % (role_name, group_name) sender = '*****@*****.**' recipients.append(email['sender']) recipients.append('*****@*****.**') #Send to Justin for debugging for recipient in recipients: send_mail(subject, body, sender, [recipient], fail_silently=False) if subdomain == "objects": object_info = original_recipient_address.split('@')[0] #Well, we seem to have found a sender_user, so we are going to go ahead with this shindig here. #Before we do, let's parse the message and get rid of any old replies or signatures. message_lines = body.split('\n') message_text = "" #Start an empty string which we'll fill with the message text. for line in message_lines: if line[:2] == "--" or line[:1] == ">" or re.search(".*On.*(\\r\\n)?wrote:", line): #Let's see if the first two characters of the line are hyphens. #If so, we're going to ignore anything after this line. break #Since we have already found the end of the message, there's no need to keep iterating. else: #We haven't hit the hyphens yet, so we'll add this line to the message. message_text += line + "\n" app_name = object_info.split('.')[0] model_name = object_info.split('.')[1] object_id = object_info.split('.')[2] Model=ContentType.objects.get(app_label=app_name, model=model_name.lower()).model_class() target_object = Model.objects.get(id=object_id) TopLevelMessage.objects.create(content_object = target_object, creator=sender_user, message=message_text) else: #Nope, this is just a message to a user / group / handler (ie, not directly to an object). #Who is this email to? recipient_name=original_recipient_address.split('@')[0] recipients = [] try: user = User.objects.get(userprofile__email_prefix__iexact=recipient_name) recipients.append(user.email) except User.DoesNotExist: #We don't need a MultipleObjectsReturned case because username is constrained unique. email_logger.info('User did not exist. Looking for handler.') try: handler = MailHandler.objects.get(address=recipient_name) #TODO: Put amazing, mind-blowing shit here. for user in handler.users.all(): recipients.append(user.email) except MailHandler.DoesNotExist: email_logger.info('No match found at all - sending bounce.') subject = 'No dice.' body = "We don't know " + email['to'] + ". If you want to introduce us, send a message to [email protected] + \n Headers Follow: \n " + str(email) sender = '*****@*****.**' recipients.append(email['sender']) recipients.append('*****@*****.**') #Send to Justin for debugging for recipient in recipients: email_logger.info('Sending to %s.' % recipient) send_mail(subject, body, sender, [recipient], fail_silently=False) #Last of all - assuming the database is up, we'll save the message object now. if not subject: subject="No Subject." mail = MailMessage(subject=subject, body=body, recipient=original_recipient_address, sender=sender) try: mail.save() except: #TODO: Add reasonable and sane logging. pass #Well, you know. F**k.
""" import os from repoze.sendmail.queue import QueueProcessor from base64 import b64decode from email.Parser import Parser as EmailParser mailer = None queue_path = 'var/mail_queue' qp = QueueProcessor(mailer, queue_path) if os.listdir("%s/new" % qp.maildir.path): parser = EmailParser() print "Parsing mail" print for filename in qp.maildir: mail_file = open(filename) message = parser.parse(mail_file) print "#" * 72 print for header, value in message.items(): print "%s: %s" % (header, value) print print b64decode(message._payload) print print "#" * 72 mail_file.close() os.remove(filename) print print print "Done parsing and removing emails" else: