-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmonitor.py
132 lines (109 loc) · 4.37 KB
/
monitor.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import os
import argparse
import datetime
import textwrap
from django.utils import timezone
from django.core.mail import EmailMessage, get_connection
SYSTEM_NAME = 'mailhole'
URL = 'https://mail.tket.dk/'
MAX_SIZE = 10
MAX_DAYS = 2
SUBJECT = '[%s] Emails pending moderation' % SYSTEM_NAME
FROM_EMAIL = '[email protected]'
parser = argparse.ArgumentParser()
parser.add_argument('-n', '--dry-run', action='store_true')
def make_monitor_message(to, messages):
message_format = textwrap.dedent('''
Date: {date}
From: {sender}
To: {recipients}
Subject: {subject}
''').strip()
messages_text = '\n\n'.join(
message_format.format(sender=message.from_(),
recipients=message.to_as_text(),
subject=message.subject(),
date=message.parsed_headers.get('Date'))
for message in messages)
body = textwrap.dedent("""
This is {SYSTEM_NAME}. The following messages are waiting for you.
Please visit {URL} at your next convenience.
{messages_text}
""").format(SYSTEM_NAME=SYSTEM_NAME, URL=URL, messages_text=messages_text)
return EmailMessage(
subject=SUBJECT,
body=body,
from_email=FROM_EMAIL,
to=[to],
)
def main(dry_run):
from django.conf import settings
from django.contrib.auth.models import User
from mailhole.models import Message, Mailbox, MonitorMessage
if settings.NO_OUTGOING_EMAIL and not dry_run:
print("NO_OUTGOING_EMAIL is set - don't send anything")
return
inbox_by_mailbox_id = {}
for message in Message.objects.filter(status=Message.INBOX):
inbox_by_mailbox_id.setdefault(message.mailbox_id, []).append(message)
users = {}
readers = Mailbox.readers.through.objects.all()
readers = readers.filter(mailbox_id__in=inbox_by_mailbox_id)
for e in readers:
users.setdefault(e.user_id, []).append(
inbox_by_mailbox_id[e.mailbox_id])
monitor_messages = []
monitor_message_models = []
for user_id, inboxes in users.items():
inbox = [message for i in inboxes for message in i]
inbox_size = len(inbox)
oldest = min(inbox, key=lambda m: m.created_time)
age = timezone.now() - oldest.created_time
age_days = age / datetime.timedelta(1)
if inbox_size < MAX_SIZE and age_days < MAX_DAYS:
print("user_id=%s inbox_size=%s age_days=%s " %
(user_id, inbox_size, age_days) +
'No need to report anything')
continue
# Did we already send a report with the newest message?
newest = max(inbox, key=lambda m: m.created_time)
already_reported = MonitorMessage.objects.filter(
user_id=user_id, created_time__gt=newest.created_time)
if already_reported.exists():
print("user_id=%s inbox_size=%s age_days=%s " %
(user_id, inbox_size, age_days) +
'Already sent a report')
continue
monitor_message_model = MonitorMessage(
inbox_size=inbox_size, age_days=age_days)
monitor_message_model.user_id = user_id
user = User.objects.get(id=user_id)
if not user.email:
print("user_id=%s inbox_size=%s age_days=%s " %
(user_id, inbox_size, age_days) +
'User has no email address!')
continue
monitor_message = make_monitor_message(user.email, inbox)
monitor_message_model.body = monitor_message.body
monitor_messages.append(monitor_message)
monitor_message_models.append(monitor_message_model)
print("user_id=%s inbox_size=%s age_days=%s " %
(user_id, inbox_size, age_days) +
'Send report')
if dry_run:
print('--dry-run: Want to send %s message(s)' % len(monitor_messages))
for e in monitor_messages:
print(e)
else:
if monitor_messages:
get_connection().send_messages(monitor_messages)
MonitorMessage.objects.bulk_create(
monitor_message_models)
if __name__ == '__main__':
# Parse args before calling Django setup.
# This makes --help much faster.
_args = parser.parse_args()
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mailhole.settings')
from django import setup as _s
_s()
main(**vars(_args))