diff options
| author | Vosjedev <vosje@vosjedev.net> | 2025-11-02 15:41:45 +0100 |
|---|---|---|
| committer | Vosjedev <vosje@vosjedev.net> | 2025-11-02 15:41:45 +0100 |
| commit | 8bcffee40c893a8b4a46ba17275f89d7d55ed9ab (patch) | |
| tree | afd2aa3ac0b0eec3a0c068731182eabbecd4ff14 | |
| parent | 82ec0feb048511f8c48648d42f251bdada372b39 (diff) | |
| download | acit-8bcffee40c893a8b4a46ba17275f89d7d55ed9ab.tar.gz acit-8bcffee40c893a8b4a46ba17275f89d7d55ed9ab.tar.bz2 acit-8bcffee40c893a8b4a46ba17275f89d7d55ed9ab.tar.xz | |
imapplugin.py: Move handling email to own function
| -rw-r--r-- | src/acit/imapplugin.py | 168 |
1 files changed, 89 insertions, 79 deletions
diff --git a/src/acit/imapplugin.py b/src/acit/imapplugin.py index 454904d..6bee54b 100644 --- a/src/acit/imapplugin.py +++ b/src/acit/imapplugin.py @@ -204,99 +204,109 @@ class ImapPlugin(plugins.SimplePlugin): if mailbox.folder.status()["MESSAGES"]>0: for msg in mailbox.fetch(): - self.mlog("Processing email with subject '%s'"%msg.subject) + target=self.handle_email(mailbox,msg) + if target: + proj,bug=target + refreshable.setdefault(proj,[]).append(bug) + # block: update all webpages that received new mail + for proj,bugs in refreshable.items(): + # project page needs to be regenerated too (counters) + cherrypy.engine.publish("regen",proj,None) + for bug in bugs: + cherrypy.engine.publish("regen",proj,bug) - for addr in msg.to + msg.cc + msg.bcc + msg.reply_to: - if re.fullmatch(self.addr_regex,addr): - proj,bug=self.stripInfoFromMailAddr(addr) - break - else: - proj=None - bug=None + # end block - if "in-reply-to" in msg.headers: - self.mlog("Using In-Reply-To header to figure out meta") - replyid=msg.headers["in-reply-to"] - data=self.find_in_reply_to(replyid) - if data: - proj,bug=data + if refreshable: + self.update_index([proj,bug] for bug in bugs for proj,bugs in refreshable.items()) - # block: make sure a project was specified - if not proj: - self.mlog("No project specified.") - self.mail_error(msg,"Please specify a project by mailing to:\n "+\ - ("" if self.uses_aliases else self.emailname+"+")+"PROJECT@"+self.emaildomain+\ - "\nwhere PROJECT is the name of your target project") - self.move_errored_mail(mailbox,msg) - continue - # end block + def handle_email(self,mailbox:MailBox,msg:MailMessage): + self.mlog("Processing email with subject '%s'"%msg.subject) - # block: make sure project exists - proj_matches=self.get_full_projectname(proj) - if not proj_matches: - self.mlog("Received email for nonexistent project %s"%proj) - self.mail_error(msg,notice="Project '%s' doesn't exist"%proj) - self.move_errored_mail(mailbox,msg) - continue - # end block - # block: make sure only 1 project matches - if len(proj_matches)>1: - self.mlog("Conficting projectname. Sending projectlist.") - self.mail_error(msg,notice="Multiple projects found to match your query. Please specify. Options:\n%s"%"\n".join(proj_matches)) - self.move_errored_mail(mailbox,msg) - continue + for addr in msg.to + msg.cc + msg.bcc + msg.reply_to: + if re.fullmatch(self.addr_regex,addr): + proj,bug=self.stripInfoFromMailAddr(addr) + break + else: + proj=None + bug=None - proj=proj_matches[0] - # end block + if "in-reply-to" in msg.headers: + self.mlog("Using In-Reply-To header to figure out meta") + replyid=msg.headers["in-reply-to"] + data=self.find_in_reply_to(replyid) + if data: + proj,bug=data + else: # try again later, maybe we need to index first or handle some other email first + self.mlog("Message-ID not in index, trying again next round") + return - # block: parse bug id - if not bug: - if re.match(r"^\[PATCH.*\]",msg.subject): - bugtype="PATCH" - elif re.match(r"^\[DISCUSSION.*\]",msg.subject): - bugtype="DISCUS" - else: - bugtype="BUG" - bug=self.site.newbug(proj,bugtype=bugtype) - bug.subject=msg.subject[:1024] - bug.description=\ - 'No description written.\nFirst email in thread:\n\n'+msg.text[:65535] # TODO: don't thruncate silently, send error to user. - self.mlog("Assigned new bugnr %d to '%s'"%(bug.bugid,msg.subject)) - bug=bug.bugid + # block: make sure a project was specified + if not proj: + self.mlog("No project specified.") + self.mail_error(msg,"Please specify a project by mailing to:\n "+\ + ("" if self.uses_aliases else self.emailname+"+")+"PROJECT@"+self.emaildomain+\ + "\nwhere PROJECT is the name of your target project") + self.move_errored_mail(mailbox,msg) + return + # end block - try: - bug=int(bug) - except ValueError as e: - self.mlog("Error decoding value to int:",e,traceback=True) + # block: make sure project exists + proj_matches=self.get_full_projectname(proj) + if not proj_matches: + self.mlog("Received email for nonexistent project %s"%proj) + self.mail_error(msg,notice="Project '%s' doesn't exist"%proj) + self.move_errored_mail(mailbox,msg) + return + # end block - self.mail_error(msg,notice="Exception while trying to convert bug number to integer",exception=e) - self.move_errored_mail(mailbox,msg) - continue - # end block - - # block: move mail to folder specific for this project/bug - try: - path=self.get_bug_folder(mailbox,proj,bug) - mailbox.move([msg.uid], path) - refreshable.setdefault(proj,[]).append(bug) - except Exception: - self.mlog("Error processing email '%s' for %s/%d"%(msg.subject,proj,bug),traceback=True) - # end block + # block: make sure only 1 project matches + if len(proj_matches)>1: + self.mlog("Conficting projectname. Sending projectlist.") + self.mail_error(msg,notice="Multiple projects found to match your query. Please specify. Options:\n%s"%"\n".join(proj_matches)) + self.move_errored_mail(mailbox,msg) + return - # block: update all webpages that received new mail - for proj,bugs in refreshable.items(): - # project page needs to be regenerated too (counters) - cherrypy.engine.publish("regen",proj,None) - for bug in bugs: - cherrypy.engine.publish("regen",proj,bug) + proj=proj_matches[0] + # end block - # end block + # block: parse bug id + if not bug: + if re.match(r"^\[PATCH.*\]",msg.subject): + bugtype="PATCH" + elif re.match(r"^\[DISCUSSION.*\]",msg.subject): + bugtype="DISCUS" + else: + bugtype="BUG" + bug=self.site.newbug(proj,bugtype=bugtype) + bug.subject=msg.subject[:1024] + bug.description=\ + 'No description written.\nFirst email in thread:\n\n'+msg.text[:65535] # TODO: don't thruncate silently, send error to user. + self.mlog("Assigned new bugnr %d to '%s'"%(bug.bugid,msg.subject)) + bug=bug.bugid - if refreshable: - self.update_index([proj,bug] for bug in bugs for proj,bugs in refreshable.items()) + try: + bug=int(bug) + except ValueError as e: + self.mlog("Error decoding value to int:",e,traceback=True) + self.mail_error(msg,notice="Exception while trying to convert bug number to integer",exception=e) + self.move_errored_mail(mailbox,msg) + return + # end block + + # block: move mail to folder specific for this project/bug + self.mlog("Email '%s' into %s/%d"%(msg.subject,proj,bug)) + try: + path=self.get_bug_folder(mailbox,proj,bug) + mailbox.move([msg.uid], path) + except Exception: + self.mlog("Error processing email '%s' for %s/%d"%(msg.subject,proj,bug),traceback=True) + # end block + + return (proj,bug) def imap_loop_controller(self): "Responsible for running imap_magic() repeatedly, and handling its errors." |
