diff --git a/data/interfaces/default/newsletter_config.html b/data/interfaces/default/newsletter_config.html index 75df94cd..ab773af8 100644 --- a/data/interfaces/default/newsletter_config.html +++ b/data/interfaces/default/newsletter_config.html @@ -218,6 +218,13 @@
+
+ +

Enable to group this newsletter together in a single Email thread. Disable to send a new Email for each newsletter.

+ +
diff --git a/plexpy/__init__.py b/plexpy/__init__.py index 5a0a31a7..8ae982a2 100644 --- a/plexpy/__init__.py +++ b/plexpy/__init__.py @@ -668,7 +668,8 @@ def dbcheck(): 'CREATE TABLE IF NOT EXISTS newsletter_log (id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp INTEGER, ' 'newsletter_id INTEGER, agent_id INTEGER, agent_name TEXT, notify_action TEXT, ' 'subject_text TEXT, body_text TEXT, message_text TEXT, start_date TEXT, end_date TEXT, ' - 'start_time INTEGER, end_time INTEGER, uuid TEXT UNIQUE, filename TEXT, success INTEGER DEFAULT 0)' + 'start_time INTEGER, end_time INTEGER, uuid TEXT UNIQUE, filename TEXT, email_msg_id TEXT, ' + 'success INTEGER DEFAULT 0)' ) # recently_added table :: This table keeps record of recently added items @@ -1563,6 +1564,15 @@ def dbcheck(): 'ALTER TABLE newsletter_log ADD COLUMN filename TEXT' ) + # Upgrade newsletter_log table from earlier versions + try: + c_db.execute('SELECT email_msg_id FROM newsletter_log') + except sqlite3.OperationalError: + logger.debug(u"Altering database. Updating database table newsletter_log.") + c_db.execute( + 'ALTER TABLE newsletter_log ADD COLUMN email_msg_id TEXT' + ) + # Upgrade newsletters table from earlier versions try: c_db.execute('SELECT id_name FROM newsletters') diff --git a/plexpy/newsletter_handler.py b/plexpy/newsletter_handler.py index 3ff0db8c..2d25cbe0 100644 --- a/plexpy/newsletter_handler.py +++ b/plexpy/newsletter_handler.py @@ -18,6 +18,7 @@ import time from apscheduler.schedulers.background import BackgroundScheduler from apscheduler.triggers.cron import CronTrigger +import email.utils import plexpy import database @@ -86,6 +87,9 @@ def notify(newsletter_id=None, notify_action=None, **kwargs): body = newsletter_config['body'] message = newsletter_config['message'] + email_msg_id = email.utils.make_msgid() + email_reply_msg_id = get_last_newsletter_email_msg_id(newsletter_id=newsletter_id, notify_action=notify_action) + newsletter_agent = newsletters.get_agent_class(newsletter_id=newsletter_id, newsletter_id_name=newsletter_config['id_name'], agent_id=newsletter_config['agent_id'], @@ -93,7 +97,9 @@ def notify(newsletter_id=None, notify_action=None, **kwargs): email_config=newsletter_config['email_config'], subject=subject, body=body, - message=message + message=message, + email_msg_id=email_msg_id, + email_reply_msg_id=email_reply_msg_id ) # Set the newsletter state in the db @@ -107,7 +113,8 @@ def notify(newsletter_id=None, notify_action=None, **kwargs): end_date=newsletter_agent.end_date.format('YYYY-MM-DD'), start_time=newsletter_agent.start_time, end_time=newsletter_agent.end_time, - newsletter_uuid=newsletter_agent.uuid) + newsletter_uuid=newsletter_agent.uuid, + email_msg_id=email_msg_id) # Send the notification success = newsletter_agent.send() @@ -118,7 +125,7 @@ def notify(newsletter_id=None, notify_action=None, **kwargs): def set_notify_state(newsletter, notify_action, subject, body, message, filename, - start_date, end_date, start_time, end_time, newsletter_uuid): + start_date, end_date, start_time, end_time, newsletter_uuid, email_msg_id): if newsletter and notify_action: db = database.MonitorDatabase() @@ -137,6 +144,7 @@ def set_notify_state(newsletter, notify_action, subject, body, message, filename 'end_date': end_date, 'start_time': start_time, 'end_time': end_time, + 'email_msg_id': email_msg_id, 'filename': filename} db.upsert(table_name='newsletter_log', key_dict=keys, value_dict=values) @@ -153,6 +161,16 @@ def set_notify_success(newsletter_log_id): db.upsert(table_name='newsletter_log', key_dict=keys, value_dict=values) +def get_last_newsletter_email_msg_id(newsletter_id, notify_action): + db = database.MonitorDatabase() + + result = db.select_single('SELECT email_msg_id FROM newsletter_log ' + 'WHERE newsletter_id = ? AND notify_action = ? AND success = 1 ' + 'ORDER BY timestamp DESC LIMIT 1', [newsletter_id, notify_action]) + + return result.get('email_msg_id') + + def get_newsletter(newsletter_uuid=None, newsletter_id_name=None): db = database.MonitorDatabase() diff --git a/plexpy/newsletters.py b/plexpy/newsletters.py index 6485ce84..5e3ef1b9 100644 --- a/plexpy/newsletters.py +++ b/plexpy/newsletters.py @@ -65,7 +65,8 @@ def available_notification_actions(): def get_agent_class(newsletter_id=None, newsletter_id_name=None, agent_id=None, config=None, email_config=None, - start_date=None, end_date=None, subject=None, body=None, message=None): + start_date=None, end_date=None, subject=None, body=None, message=None, + email_msg_id=None, email_reply_msg_id=None): if str(agent_id).isdigit(): agent_id = int(agent_id) @@ -77,7 +78,9 @@ def get_agent_class(newsletter_id=None, newsletter_id_name=None, agent_id=None, 'end_date': end_date, 'subject': subject, 'body': body, - 'message': message} + 'message': message, + 'email_msg_id': email_msg_id, + 'email_reply_msg_id': email_reply_msg_id} if agent_id == 0: return RecentlyAdded(**kwargs) @@ -326,6 +329,7 @@ class Newsletter(object): 'time_frame': 7, 'time_frame_units': 'days', 'formatted': 1, + 'threaded': 0, 'notifier_id': 0, 'filename': '', 'save_only': 0} @@ -339,11 +343,15 @@ class Newsletter(object): _TEMPLATE = '' def __init__(self, newsletter_id=None, newsletter_id_name=None, config=None, email_config=None, - start_date=None, end_date=None, subject=None, body=None, message=None): + start_date=None, end_date=None, subject=None, body=None, message=None, + email_msg_id=None, email_reply_msg_id=None): self.config = self.set_config(config=config, default=self._DEFAULT_CONFIG) self.email_config = self.set_config(config=email_config, default=self._DEFAULT_EMAIL_CONFIG) self.uuid = generate_newsletter_uuid() + self.email_msg_id = email_msg_id + self.email_reply_msg_id = email_reply_msg_id + self.newsletter_id = newsletter_id self.newsletter_id_name = newsletter_id_name or '' self.start_date = None @@ -516,12 +524,16 @@ class Newsletter(object): if plexpy.CONFIG.NEWSLETTER_SELF_HOSTED and plexpy.CONFIG.HTTP_BASE_URL: plaintext += self._DEFAULT_BODY.format(**self.parameters) + email_reply_msg_id = self.email_reply_msg_id if self.config['threaded'] else None + if self.email_config['notifier_id']: return send_notification( notifier_id=self.email_config['notifier_id'], subject=self.subject_formatted, body=newsletter_stripped, - plaintext=plaintext + plaintext=plaintext, + msg_id=self.email_msg_id, + reply_msg_id=email_reply_msg_id ) else: @@ -529,7 +541,9 @@ class Newsletter(object): return email.notify( subject=self.subject_formatted, body=newsletter_stripped, - plaintext=plaintext + plaintext=plaintext, + msg_id=self.email_msg_id, + reply_msg_id=email_reply_msg_id ) elif self.config['notifier_id']: return send_notification( diff --git a/plexpy/notifiers.py b/plexpy/notifiers.py index 7300ed74..cde7fbe7 100644 --- a/plexpy/notifiers.py +++ b/plexpy/notifiers.py @@ -1302,13 +1302,20 @@ class EMAIL(Notifier): msg.replace_header('Content-Transfer-Encoding', 'quoted-printable') msg.set_payload(body, 'utf-8') - msg['Message-ID'] = email.utils.make_msgid() + msg_id = kwargs.get('msg_id', email.utils.make_msgid()) + reply_msg_id = kwargs.get('reply_msg_id') + + msg['Message-ID'] = msg_id msg['Date'] = email.utils.formatdate(localtime=True) msg['Subject'] = subject msg['From'] = email.utils.formataddr((self.config['from_name'], self.config['from'])) msg['To'] = ','.join(self.config['to']) msg['CC'] = ','.join(self.config['cc']) + if reply_msg_id: + msg["In-Reply-To"] = reply_msg_id + msg["References"] = reply_msg_id + recipients = self.config['to'] + self.config['cc'] + self.config['bcc'] mailserver = None