aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVosjedev <vosje@vosjedev.net>2025-11-06 16:51:14 +0100
committerVosjedev <vosje@vosjedev.net>2025-11-06 16:51:14 +0100
commit644e0e701b00dac372ae63e8b8245c04b7838057 (patch)
treeae961b3e7641e88cd4b68a078a47d16633096cc6
parentdb8829ff7aa50de9a22e83c112d1e6f734b2a643 (diff)
downloadacit-644e0e701b00dac372ae63e8b8245c04b7838057.tar.gz
acit-644e0e701b00dac372ae63e8b8245c04b7838057.tar.bz2
acit-644e0e701b00dac372ae63e8b8245c04b7838057.tar.xz
imapplugin: implement subscribing/unsubscribing
-rw-r--r--src/acit/imapplugin.py67
1 files changed, 60 insertions, 7 deletions
diff --git a/src/acit/imapplugin.py b/src/acit/imapplugin.py
index de13e6d..a73a2de 100644
--- a/src/acit/imapplugin.py
+++ b/src/acit/imapplugin.py
@@ -208,16 +208,17 @@ class ImapPlugin(plugins.SimplePlugin):
for msg in mailbox.fetch():
try:
target=self.handle_email(mailbox,msg)
+
+ if target:
+ proj,bug=target
+ refreshable.setdefault(proj,[]).append(bug)
+
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)
-
# block: update all webpages that received new mail
for proj,bugs in refreshable.items():
# project page needs to be regenerated too (counters)
@@ -229,6 +230,16 @@ class ImapPlugin(plugins.SimplePlugin):
if refreshable:
self.update_index([proj,bug] for bug in bugs for proj,bugs in refreshable.items())
+
+ def get_newest_from_mailbox(self,mailbox,proj,bug):
+ folder=mailbox.folder.get()
+ mailbox.folder.set(self.get_bug_folder(mailbox,proj,bug),True)
+ for m in mailbox.fetch(limit=1,reverse=True):
+ break
+ if folder:
+ mailbox.folder.set(folder)
+ return m
+
def handle_email(self,mailbox:MailBox,msg:MailMessage):
self.mlog("Processing email with subject '%s'"%msg.subject)
@@ -254,6 +265,44 @@ class ImapPlugin(plugins.SimplePlugin):
proj=None
bug=None
+ if msg.subject.startswith("SUBSCRIBE"):
+ from_=self.format_emailaddr(project=proj,bugid=bug)
+
+ if not proj:
+ self.smtp.sendmail(
+ replyto=msg,
+ from_=from_,
+ body="Could not subscribe you, please specify a project and optionally a bug in the target address"
+ )
+ self.mlog("")
+ mailbox.delete([msg.uid])
+ return
+
+ self.mlog("Subscribing",msg.from_,"to",proj,bug)
+ with self.dbpool.get_connection() as conn, conn.cursor() as cur:
+ cur.execute("INSERT INTO subscribers (tracker,bugid,email) VALUES (?,?,?)",(proj,bug,msg.from_))
+
+ if not bug:
+ bug="all bugs"
+ else:
+ bug="bug "+bug
+
+ self.smtp.sendmail(
+ replyto=msg,
+ from_=from_,
+ body="Subscribed to "+bug+" "+proj+"\nTo unsubscribe, send an email with subjectline `UNSUBSCRIBE` to "+from_
+ )
+ mailbox.delete([msg.uid])
+
+ return
+
+ if msg.subject.startswith("UNSUBSCRIBE"):
+ self.mlog("Unsubscribing",msg.from_,"from",proj,bug)
+ with self.dbpool.get_connection() as conn, conn.cursor() as cur:
+ cur.execute("DELETE FROM subscribers WHERE tracker=? AND bugid=? AND email=?)",(proj,bug,msg.from_))
+ mailbox.delete([msg.uid])
+ return
+
if "in-reply-to" in msg.headers:
self.mlog("Using In-Reply-To header to figure out meta")
replyid=msg.headers["in-reply-to"]
@@ -330,7 +379,10 @@ class ImapPlugin(plugins.SimplePlugin):
if not msg.from_ in bugobj.subscribers:
bugobj.addsubscriber(msg.from_)
- self.fwd_to_list(msg,bugobj)
+ if not "in-reply-to" in msg.headers:
+ replyto=self.get_newest_from_mailbox(mailbox,proj,bug)
+
+ self.fwd_to_list(msg,bugobj,replyto=replyto)
except Exception:
self.mlog("Error processing email '%s' for %s/%d"%(msg.subject,proj,bug),traceback=True)
self.move_errored_mail(mailbox,msg)
@@ -376,7 +428,7 @@ class ImapPlugin(plugins.SimplePlugin):
return mailbox.move(msg.uid,target)
- def fwd_to_list(self,msg:MailMessage,bug:Bug):
+ def fwd_to_list(self,msg:MailMessage,bug:Bug,replyto:MailMessage=None):
tracker=self.site.gettracker(bug.tracker)
bcc=bug.subscribers + tracker.subscribers
@@ -385,7 +437,8 @@ class ImapPlugin(plugins.SimplePlugin):
self.smtp.sendmail(
from_=self.format_emailaddr(bug.tracker,bug.bugid),
bcc=bcc,
- tosend=msg
+ tosend=msg,
+ replyto=replyto
)
def stop(self):