aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVosjedev <vosje@vosjedev.net>2025-11-06 15:39:06 +0100
committerVosjedev <vosje@vosjedev.net>2025-11-06 15:39:06 +0100
commitf5186251a27e3dbe2df8fc7835e5f3ab27f485f5 (patch)
tree4290eb56d088f28158ea942185cccd34702b9409
parent113005e39085a5bb3c6d53fa2964388c3eb0a395 (diff)
downloadacit-f5186251a27e3dbe2df8fc7835e5f3ab27f485f5.tar.gz
acit-f5186251a27e3dbe2df8fc7835e5f3ab27f485f5.tar.bz2
acit-f5186251a27e3dbe2df8fc7835e5f3ab27f485f5.tar.xz
smtpplugin: start mailinglisting and actually sending errors
plus some small fixes
-rw-r--r--src/acit/imapplugin.py75
1 files changed, 62 insertions, 13 deletions
diff --git a/src/acit/imapplugin.py b/src/acit/imapplugin.py
index b38f77c..de13e6d 100644
--- a/src/acit/imapplugin.py
+++ b/src/acit/imapplugin.py
@@ -136,9 +136,10 @@ class ImapPlugin(plugins.SimplePlugin):
cur.execute("SELECT tracker,bugid FROM msgindex WHERE messageid=? LIMIT 1",(messageid,))
return cur.fetchone()
- def format_emailaddr(self,project,bugid=None,subject=None):
+ def format_emailaddr(self,project=None,bugid=None,subject=None):
email=self.addr_format.format(proj=project, bug=bugid)
email=email.replace("#None",'')
+ email=email.replace("+None",'')
if subject:
from urllib.parse import quote as quote
email+='?subject='
@@ -205,7 +206,14 @@ class ImapPlugin(plugins.SimplePlugin):
if mailbox.folder.status()["MESSAGES"]>0:
for msg in mailbox.fetch():
- target=self.handle_email(mailbox,msg)
+ try:
+ target=self.handle_email(mailbox,msg)
+ except Exception:
+ import traceback
+ self.mlog("Error processing email: ",traceback.format_exc())
+ self.mlog("Moving mail to INBOX/Errors.")
+ self.move_errored_mail(mailbox,msg)
+
if target:
proj,bug=target
refreshable.setdefault(proj,[]).append(bug)
@@ -225,6 +233,18 @@ class ImapPlugin(plugins.SimplePlugin):
def handle_email(self,mailbox:MailBox,msg:MailMessage):
self.mlog("Processing email with subject '%s'"%msg.subject)
+ if "x-acit-delete-when-sender" in msg.headers and "sender" in msg.headers:
+ if msg.headers["x-acit-delete-when-sender"]==msg.headers["sender"]:
+ self.mlog("Header requested deletion, deleting email")
+ mailbox.delete([msg.uid])
+ return
+
+ if "x-acit-is-outgoing" in msg.headers and "sender" in msg.headers:
+ if msg.headers["x-acit-is-outgoing"]==msg.headers["sender"]:
+ self.mlog("Header indicated this is Sent mail, moving")
+ mailbox.move([msg.uid],self.ensurefolder(mailbox,"Sent"))
+ return
+
for addr in msg.to + msg.cc + msg.bcc + msg.reply_to:
if re.fullmatch(self.addr_regex,addr):
@@ -273,7 +293,7 @@ class ImapPlugin(plugins.SimplePlugin):
proj=proj_matches[0]
# end block
- # block: parse bug id
+ # block: make new bug if needed
if not bug:
if re.match(r"^\[PATCH.*\]",msg.subject):
bugtype="PATCH"
@@ -281,18 +301,21 @@ class ImapPlugin(plugins.SimplePlugin):
bugtype="DISCUS"
else:
bugtype="BUG"
- bug=self.site.newbug(proj,bugtype=bugtype)
- bug.subject=msg.subject[:1024]
- bug.description=\
+ bugobj=self.site.newbug(proj,bugtype=bugtype)
+ bugobj.subject=msg.subject[:1024]
+ bugobj.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
+ self.mlog("Assigned new bugnr %d to '%s'"%(bugobj.bugid,msg.subject))
+ bug=bugobj.bugid
+ else:
+ bugobj=self.site.getbug(proj,bug)
+ # end block
+ # parse bug id to make sure it's an int
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
@@ -303,8 +326,14 @@ class ImapPlugin(plugins.SimplePlugin):
try:
path=self.get_bug_folder(mailbox,proj,bug)
mailbox.move([msg.uid], path)
+
+ if not msg.from_ in bugobj.subscribers:
+ bugobj.addsubscriber(msg.from_)
+
+ self.fwd_to_list(msg,bugobj)
except Exception:
self.mlog("Error processing email '%s' for %s/%d"%(msg.subject,proj,bug),traceback=True)
+ self.move_errored_mail(mailbox,msg)
# end block
return (proj,bug)
@@ -328,16 +357,36 @@ class ImapPlugin(plugins.SimplePlugin):
self.mlog("IMAP monitor thread stopped.")
def mail_error(self,msg:MailMessage,notice:str=None,exception:Exception=None):
- pass
+ from_=self.format_emailaddr()
+ self.mlog("Sending error report.")
+
+ body="An error occured while processing your email with subject:\n"
+ body+="> "+msg.subject
+ if notice:
+ body+="\n\nThe mail worker reports:\n> "+notice.replace("\n","\n> ")
+ if exception:
+ body+="\n\nThe following error was included:\n> "+repr(exception).replace("\n","\n> ")
+ body+="\n\nIf you think this is a bug, please report it (mail to acit@bugs.vosjedev.net).\n"
+ body+="Make sure to attach both this email and the email that triggered this bug."
+
+ self.smtp.sendmail(replyto=msg,from_=from_,body=body)
def move_errored_mail(self,mailbox:MailBox,msg:MailMessage,):
target=self.ensurefolder(mailbox,"INBOX","Errors")
return mailbox.move(msg.uid,target)
-
+
+ def fwd_to_list(self,msg:MailMessage,bug:Bug):
+ tracker=self.site.gettracker(bug.tracker)
+ bcc=bug.subscribers + tracker.subscribers
- def smtp_loop(self):
- pass
+ self.mlog("Bcc:",bcc)
+
+ self.smtp.sendmail(
+ from_=self.format_emailaddr(bug.tracker,bug.bugid),
+ bcc=bcc,
+ tosend=msg
+ )
def stop(self):
"Sets stopping signal, waits for all threads to stop"