def find_content(project, mail): patchbuf = None commentbuf = '' pullurl = None for part in mail.walk(): if part.get_content_maintype() != 'text': continue payload = part.get_payload(decode=True) charset = part.get_content_charset() subtype = part.get_content_subtype() # if we don't have a charset, assume utf-8 if charset is None: charset = 'utf-8' if not isinstance(payload, unicode): payload = unicode(payload, charset) if subtype in ['x-patch', 'x-diff']: patchbuf = payload elif subtype == 'plain': c = payload if not patchbuf: (patchbuf, c) = parse_patch(payload) if not pullurl: pullurl = find_pull_request(payload) if c is not None: commentbuf += c.strip() + '\n' patch = None comment = None if pullurl or patchbuf: name = clean_subject(mail.get('Subject'), [project.linkname]) patch = Patch(name = name, pull_url = pullurl, content = patchbuf, date = mail_date(mail), headers = mail_headers(mail)) if commentbuf: if patch: cpatch = patch else: cpatch = find_patch_for_comment(project, mail) if not cpatch: return (None, None) comment = Comment(patch = cpatch, date = mail_date(mail), content = clean_content(commentbuf), headers = mail_headers(mail)) return (patch, comment)
def find_content(project, mail): patchbuf = None commentbuf = '' for part in mail.walk(): if part.get_content_maintype() != 'text': continue payload = part.get_payload(decode=True) subtype = part.get_content_subtype() if not isinstance(payload, six.text_type): charset = part.get_content_charset() # Check that we have a charset that we understand. Otherwise, # ignore it and fallback to our standard set. if charset is not None: try: codecs.lookup(charset) except LookupError: charset = None # If there is no charset or if it is unknown, then try some common # charsets before we fail. if charset is None: try_charsets = ['utf-8', 'windows-1252', 'iso-8859-1'] else: try_charsets = [charset] for cset in try_charsets: try: payload = six.text_type(payload, cset) break except UnicodeDecodeError: payload = None # Could not find a valid decoded payload. Fail. if payload is None: return None, None if subtype in ['x-patch', 'x-diff']: patchbuf = payload elif subtype == 'plain': c = payload if not patchbuf: patchbuf, c = parse_patch(payload) if c is not None: commentbuf += c.strip() + '\n' commentbuf = clean_content(commentbuf) return patchbuf, commentbuf
def find_content(project, mail): patchbuf = None commentbuf = '' pullurl = None is_attachment = False for part in mail.walk(): if part.get_content_maintype() != 'text': continue payload = part.get_payload(decode=True) subtype = part.get_content_subtype() if not isinstance(payload, six.text_type): charset = part.get_content_charset() # Check that we have a charset that we understand. Otherwise, # ignore it and fallback to our standard set. if charset is not None: try: codecs.lookup(charset) except LookupError: charset = None # If there is no charset or if it is unknown, then try some common # charsets before we fail. if charset is None: try_charsets = ['utf-8', 'windows-1252', 'iso-8859-1'] else: try_charsets = [charset] for cset in try_charsets: decoded_payload = try_decode(payload, cset) if decoded_payload is not None: break payload = decoded_payload # Could not find a valid decoded payload. Fail. if payload is None: return None if subtype in ['x-patch', 'x-diff']: is_attachment = True patchbuf = payload elif subtype == 'plain': c = payload if not patchbuf: (patchbuf, c) = parse_patch(payload) if not pullurl: pullurl = find_pull_request(payload) if c is not None: commentbuf += c.strip() + '\n' ret = MailContent() drop_prefixes = [project.linkname] + project.get_subject_prefix_tags() (name, prefixes) = clean_subject(mail.get('Subject'), drop_prefixes) (x, n) = parse_series_marker(prefixes) refs = build_references_list(mail) is_root = refs == [] is_cover_letter = is_root and x == 0 patch_prefix = re.match('(\s*\[[^]]*\]\s*)*\[\s*PATCH', mail.get('Subject')) is_patch = patchbuf is not None and patch_prefix drop_patch = not is_attachment and \ project.git_send_email_only and not is_git_send_email(mail) if pullurl or (is_patch and not drop_patch): if project.git_send_email_only or not is_cover_letter: ret.patch_order = x or 1 ret.patch = Patch(name=name, pull_url=pullurl, content=patchbuf, date=mail_date(mail), headers=mail_headers(mail)) if patchbuf: ret.filenames = patch_get_filenames(patchbuf) # Create/update the Series and SeriesRevision objects if is_cover_letter or is_patch: msgid = mail.get('Message-Id').strip() # check if msgid already exists in db ex_msgid=get_object_by_msgid(Patch, msgid) if not ex_msgid: ex_msgid=get_object_by_msgid(Comment, msgid) if ex_msgid and ex_msgid.content: # modify msgid to allow processing new message only if it # contains different content than existing Patch or Comment if patchbuf and patchbuf!=ex_msgid.content: refs.append(msgid) msgid=datetime.datetime.now().isoformat() + '-' + msgid ret.msgid=msgid # Series get a generic name when they don't start by a cover letter or # when they haven't received the root message yet. Except when it's # only 1 patch, then the series takes the patch subject as name. series_name = None if is_cover_letter or n is None: series_name = strip_prefixes(name) (ret.series, ret.revision, ret.patch_order, n) = \ find_series_for_mail(project, series_name, msgid, is_patch, ret.patch_order, n, refs) ret.revision.n_patches = n or 1 date = mail_date(mail) if not ret.series.submitted or date < ret.series.submitted: ret.series.submitted = date if is_cover_letter: ret.revision.cover_letter = clean_content(commentbuf) return ret if commentbuf: # If this is a new patch, we defer setting comment.patch until # patch has been saved by the caller if ret.patch: ret.comment = Comment(date=mail_date(mail), content=clean_content(commentbuf), headers=mail_headers(mail)) else: cpatch = find_patch_for_comment(project, refs) if not cpatch: return ret ret.comment = Comment(patch=cpatch, date=mail_date(mail), content=clean_content(commentbuf), headers=mail_headers(mail)) # make sure we always have a valid (series,revision) tuple if we have a # patch. We don't consider pull requests a series. if ret.patch and not pullurl and (not ret.series or not ret.revision): raise Exception("Could not find series for: %s" % name) return ret
def find_content(project, mail): patchbuf = None commentbuf = '' pullurl = None is_attachment = False for part in mail.walk(): if part.get_content_maintype() != 'text': continue payload = part.get_payload(decode=True) subtype = part.get_content_subtype() if not isinstance(payload, unicode): charset = part.get_content_charset() # Check that we have a charset that we understand. Otherwise, # ignore it and fallback to our standard set. if charset is not None: try: codecs.lookup(charset) except LookupError: charset = None # If there is no charset or if it is unknown, then try some common # charsets before we fail. if charset is None: try_charsets = ['utf-8', 'windows-1252', 'iso-8859-1'] else: try_charsets = [charset] for cset in try_charsets: decoded_payload = try_decode(payload, cset) if decoded_payload is not None: break payload = decoded_payload # Could not find a valid decoded payload. Fail. if payload is None: return None if subtype in ['x-patch', 'x-diff']: is_attachment = True patchbuf = payload elif subtype == 'plain': c = payload if not patchbuf: (patchbuf, c) = parse_patch(payload) if not pullurl: pullurl = find_pull_request(payload) if c is not None: commentbuf += c.strip() + '\n' ret = MailContent() drop_prefixes = [project.linkname] + project.get_subject_prefix_tags() (name, prefixes) = clean_subject(mail.get('Subject'), drop_prefixes) (x, n) = parse_series_marker(prefixes) refs = build_references_list(mail) is_root = refs == [] is_cover_letter = is_root and x == 0 is_patch = patchbuf is not None is_git_send_email = mail.get('X-Mailer', '').startswith('git-send-email ') drop_patch = not is_attachment and \ project.git_send_email_only and not is_git_send_email if pullurl or (is_patch and not drop_patch): ret.patch_order = x or 1 ret.patch = Patch(name=name, pull_url=pullurl, content=patchbuf, date=mail_date(mail), headers=mail_headers(mail)) # Create/update the Series and SeriesRevision objects if is_cover_letter or is_patch: msgid = mail.get('Message-Id').strip() # Series get a generic name when they don't start by a cover letter or # when they haven't received the root message yet. Except when it's # only 1 patch, then the series takes the patch subject as name. series_name = None if is_cover_letter or n is None: series_name = strip_prefixes(name) (ret.series, ret.revision, ret.patch_order) = \ find_series_for_mail(project, series_name, msgid, is_patch, ret.patch_order, refs) ret.series.n_patches = n or 1 date = mail_date(mail) if not ret.series.submitted or date < ret.series.submitted: ret.series.submitted = date if is_cover_letter: ret.revision.cover_letter = clean_content(commentbuf) return ret if commentbuf: # If this is a new patch, we defer setting comment.patch until # patch has been saved by the caller if ret.patch: ret.comment = Comment(date=mail_date(mail), content=clean_content(commentbuf), headers=mail_headers(mail)) else: cpatch = find_patch_for_comment(project, refs) if not cpatch: return ret ret.comment = Comment(patch=cpatch, date=mail_date(mail), content=clean_content(commentbuf), headers=mail_headers(mail)) # make sure we always have a valid (series,revision) tuple if we have a # patch. We don't consider pull requests a series. if ret.patch and not pullurl and (not ret.series or not ret.revision): raise Exception("Could not find series for: %s" % name) return ret
def find_content(project, mail): patchbuf = None commentbuf = '' pullurl = None for part in mail.walk(): if part.get_content_maintype() != 'text': continue payload = part.get_payload(decode=True) subtype = part.get_content_subtype() if not isinstance(payload, unicode): charset = part.get_content_charset() # Check that we have a charset that we understand. Otherwise, # ignore it and fallback to our standard set. if charset is not None: try: codec = codecs.lookup(charset) except LookupError: charset = None # If there is no charset or if it is unknown, then try some common # charsets before we fail. if charset is None: try_charsets = ['utf-8', 'windows-1252', 'iso-8859-1'] else: try_charsets = [charset] for cset in try_charsets: decoded_payload = try_decode(payload, cset) if decoded_payload is not None: break payload = decoded_payload # Could not find a valid decoded payload. Fail. if payload is None: return (None, None) if subtype in ['x-patch', 'x-diff']: patchbuf = payload elif subtype == 'plain': c = payload if not patchbuf: (patchbuf, c) = parse_patch(payload) if not pullurl: pullurl = find_pull_request(payload) if c is not None: commentbuf += c.strip() + '\n' patch = None comment = None if pullurl or patchbuf: name = clean_subject(mail.get('Subject'), [project.linkname]) patch = Patch(name = name, pull_url = pullurl, content = patchbuf, date = mail_date(mail), headers = mail_headers(mail)) if commentbuf: if patch: cpatch = patch else: cpatch = find_patch_for_comment(project, mail) if not cpatch: return (None, None) comment = Comment(patch = cpatch, date = mail_date(mail), content = clean_content(commentbuf), headers = mail_headers(mail)) return (patch, comment)