Commit 545c5172 authored by Benjamin Graillot's avatar Benjamin Graillot

Utilise une seule connexion imap pour toutes les sources

parent dbbb3b64
......@@ -3,15 +3,18 @@ import socket
import config
# Sources
import source
import github
import wiki
import news
import phabricator
import ml
SOURCES = [wiki.Wiki(), news.News(), phabricator.Phabricator()]
MAIL_SOURCES = [wiki.Wiki(), phabricator.Phabricator(), ml.Ml(), github.Github()]
SOURCES = [source.MailSources(MAIL_SOURCES), news.News()]
if __name__ == "__main__":
with open(config.socket_path, 'w') as fifo:
fifo.write('SOURCES ' + ','.join([source.name for source in SOURCES]))
[ source.thread.join() for source in SOURCES ]
\ No newline at end of file
fifo.write('SOURCES ' + ','.join([source.name for source in SOURCES + MAIL_SOURCES if source.name]))
[ source.thread.join() for source in SOURCES ]
......@@ -26,49 +26,31 @@ class Phabricator(source.Source):
def __init__(self):
source.Source.__init__(self, 'phabricator', 'noreply@phabricator.crans.org')
def loop(self):
print('phabricator: connecting to', secrets.host)
while True:
try:
imap_client = imaplib.IMAP4_SSL(host=secrets.host)
imap_client.login(secrets.user, secrets.password)
imap_client.select()
print('phabricator: Running...')
while True:
for uid, msg in imap_client.idle():
if msg == b'EXISTS':
fetcher = imaplib.IMAP4_SSL(host=secrets.host)
fetcher.login(secrets.user, secrets.password)
fetcher.select()
mail = fetcher.fetch(uid.decode('ascii'), '(RFC822)')
fetcher.close()
fetcher.logout()
mail = email.message_from_bytes(mail[1][0][1])
sender = decode_header(mail['From'])
if self.address not in sender:
continue
try:
projects = [project.strip()[2:-1] for project in mail['X-Phabricator-Projects'].split(',')]
except:
projects = []
subject = decode_header(mail['Subject'])
tags = []
for m in re.finditer(r'\[(?P<tag>[^]]*)\]', subject):
tags.append(m.group('tag'))
m = re.search(r'(?P<task>T\d+):\s+(?P<name>.*)$', subject)
if m is None:
print("No task")
continue
task = m.group('task')
if projects:
task = projects[0] + '/' + task
task_name = m.group('name')
m = re.search(r'"?(?P<author>[^"<]*)"?\s*<', sender)
if m is None:
print("No author:", sender)
continue
author = m.group('author')
self.push_update(task, '\x0310{task}\x03 \x033{author}\x03 \x02{tag}\x02\x03 \x0315{name}\x03'.format(task=task, author=author, tag=tags[1], name=task_name))
except Exception as e:
raise e
def parse_mail(self, mail):
sender = decode_header(mail['From'])
if self.address not in sender:
return
try:
projects = [decode_header(project) for project in mail['X-Phabricator-Projects'].split(',')]
projects = [project.strip()[2:-1] for project in projects]
except:
projects = []
subject = decode_header(mail['Subject'])
tags = []
for m in re.finditer(r'\[(?P<tag>[^]]*)\]', subject):
tags.append(m.group('tag'))
m = re.search(r'(?P<task>T\d+):\s+(?P<name>.*)$', subject)
if m is None:
print("No task")
return
task_id = task = m.group('task')
if projects:
print(projects[0])
task = projects[0] + '/' + task
task_name = m.group('name')
m = re.search(r'"?(?P<author>[^"<]*)"?\s*<', sender)
if m is None:
print("No author:", sender)
return
author = m.group('author')
self.push_update(task, '\x0310{task}\x03 \x033{author}\x03 \x02{tag}\x02\x03 \x0315{name}\x03'.format(task=task_id, author=author, tag=tags[1], name=task_name))
import email
import email.header
import json
import quopri
import threading
from imapidle import imaplib
import config
import secrets
class Source:
......@@ -16,4 +23,40 @@ class Source:
fifo.write(json.dumps({'source': self.name, 'page': page, 'message': message}, separators=(',', ':')))
def loop(self, *args, **kwargs):
return
\ No newline at end of file
return
class MailSources:
def __init__(self, sources=None):
self.name = ''
self.sources = sources if sources else []
self.thread = threading.Thread(target=self.loop)
self.thread.start()
def loop(self):
while True:
try:
imap_client = imaplib.IMAP4_SSL(host=secrets.host)
imap_client.login(secrets.user, secrets.password)
imap_client.select()
print('email: Running...')
while True:
for uid, msg in imap_client.idle():
if msg == b'EXISTS':
fetcher = imaplib.IMAP4_SSL(host=secrets.host)
fetcher.login(secrets.user, secrets.password)
fetcher.select()
mail = fetcher.fetch(uid.decode('ascii'), '(RFC822)')
fetcher.close()
fetcher.logout()
mail = email.message_from_bytes(mail[1][0][1])
try: print('Received new mail from', mail['From'])
except: pass
for source in self.sources:
try:
source.parse_mail(mail)
except Exception as e:
print(e)
continue
except Exception as e:
print(e)
continue
......@@ -89,44 +89,29 @@ class Wiki(source.Source):
def __init__(self):
source.Source.__init__(self, 'wiki', 'wiki@crans.org')
def loop(self):
print('wiki: connecting to', secrets.host)
while True:
try:
imap_client = imaplib.IMAP4_SSL(host=secrets.host)
imap_client.login(secrets.user, secrets.password)
imap_client.select()
print('Running...')
while True:
for uid, msg in imap_client.idle():
if msg == b'EXISTS':
fetcher = imaplib.IMAP4_SSL(host=secrets.host)
fetcher.login(secrets.user, secrets.password)
fetcher.select()
mail = fetcher.fetch(uid.decode('ascii'), '(RFC822)')
fetcher.logout()
mail = email.message_from_bytes(mail[1][0][1])
sender = mail['From']
preprocessor, updates = UPDATES
body = preprocessor(mail)
for update in updates:
next_update = False
message, page, regexps = updates[update]
kwargs = {}
for info, groups, regexp in regexps:
m = re.search(regexp, body)
if info == Information.required and not m:
next_update = True
break
elif m:
for group in groups:
kwargs[group] = m.group(group)
else:
for group in groups:
kwargs[group] = None
if next_update: continue
message = message(**kwargs)
page = kwargs[page]
self.push_update(page, message)
except:
continue
\ No newline at end of file
def parse_mail(self, mail):
sender = mail['From']
preprocessor, updates = UPDATES
try:
body = preprocessor(mail)
except:
return
for update in updates:
next_update = False
message, page, regexps = updates[update]
kwargs = {}
for info, groups, regexp in regexps:
m = re.search(regexp, body)
if info == Information.required and not m:
next_update = True
break
elif m:
for group in groups:
kwargs[group] = m.group(group)
else:
for group in groups:
kwargs[group] = None
if next_update: continue
message = message(**kwargs)
page = kwargs[page]
self.push_update(page, message)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment