From 9e232c55a2681a2a3231d71cae2627c7bcba1ea8 Mon Sep 17 00:00:00 2001 From: Liz Fong-Jones Date: Sun, 16 Dec 2012 04:18:30 -0500 Subject: [PATCH] add ability for users to get structure notifications as well as regular mail --- evelink/char.py | 2 +- index.html | 11 +++++++ main.py | 86 +++++++++++++++++++++++++++++++++++++++++++++++-- models.py | 8 +++++ 4 files changed, 104 insertions(+), 3 deletions(-) diff --git a/evelink/char.py b/evelink/char.py index ccbd58b..b67adec 100644 --- a/evelink/char.py +++ b/evelink/char.py @@ -143,7 +143,7 @@ def notifications(self): notification_id = int(a['notificationID']) result[notification_id] = { 'id': notification_id, - 'type_id': a['typeID'], + 'type_id': int(a['typeID']), 'sender_id': int(a['senderID']), 'timestamp': api.parse_ts(a['sentDate']), 'read': a['read'] == '1', diff --git a/index.html b/index.html index eedd286..88a879f 100644 --- a/index.html +++ b/index.html @@ -13,6 +13,17 @@

EVEMail-Email Relay Configuration

(ID or Name)
Recipient Organization #2 From Which to Relay EVEMail (Optional)
(ID or Name)
+
Types of Notifications To Relay
+
Destination Email Address
diff --git a/main.py b/main.py index fcd2b93..4808ebe 100644 --- a/main.py +++ b/main.py @@ -1,4 +1,5 @@ import datetime +import logging import os import re @@ -10,7 +11,7 @@ import evelink from evelink import appengine as elink_appengine -from models import Configuration, SeenMail +from models import Configuration, SeenMail, SeenNotification, NotificationTypes jinja_environment = jinja2.Environment( loader=jinja2.FileSystemLoader(os.path.dirname(__file__))) @@ -19,6 +20,8 @@ class HomeHandler(webapp2.RequestHandler): def get(self): config = memcache.get('config') or Configuration.all().get() + notify_descriptions = (memcache.get('ndesc') or + NotificationTypes.all()) if config: template_values = { @@ -28,6 +31,8 @@ def get(self): 'rcpt_org': config.rcpt_org, 'rcpt_org2': config.rcpt_org2 or '', 'dest_email': config.dest_email, + 'notify_types': config.notify_types, + 'notify_descriptions': notify_descriptions, } else: template_values = { @@ -37,6 +42,8 @@ def get(self): 'rcpt_org': '', 'rcpt_org2': '', 'dest_email': '', + 'notify_types': [], + 'notify_descriptions': notify_descriptions, } template = jinja_environment.get_template('index.html') @@ -48,6 +55,7 @@ def post(self): rcpt_char = self.request.get('rcpt_char') rcpt_org = self.request.get('rcpt_org') rcpt_org2 = self.request.get('rcpt_org2') + notify_types = [int(x) for x in self.request.get_all('notify_types')] dest_email = self.request.get('dest_email') if not (key_id and vcode and rcpt_org and dest_email): @@ -92,6 +100,7 @@ def post(self): rcpt_char=rcpt_char, rcpt_org=rcpt_org, rcpt_org2=rcpt_org2, + notify_types=notify_types, dest_email=dest_email, ) else: @@ -101,6 +110,7 @@ def post(self): config.rcpt_org = rcpt_org if rcpt_org2: config.rcpt_org2 = rcpt_org2 + config.notify_types = notify_types config.dest_email = dest_email config.put() @@ -125,6 +135,9 @@ class CronHandler(webapp2.RequestHandler): def get(self): config = memcache.get('config') or Configuration.all().get() + notify_descriptions = (memcache.get('ndesc') or + NotificationTypes.all()) + if not config: # We haven't set up our configuration yet, so don't try to do anything return @@ -133,6 +146,12 @@ def get(self): elink_char = evelink.char.Char(config.rcpt_char, api=elink_api) elink_eve = evelink.eve.EVE(api=elink_api) + self.send_emails(config, elink_api, elink_char, elink_eve) + self.send_notifications(config, elink_api, elink_char, elink_eve, + notify_descriptions) + + def send_emails(self, config, elink_api, elink_char, elink_eve): + recips = set([config.rcpt_org]) if config.rcpt_org2: recips.add(config.rcpt_org2) @@ -154,7 +173,7 @@ def get(self): memcache.set('seen-%s' % m_id, True) if not message_ids_to_relay: - self.response.out.write("No pending messages.") + self.response.out.write("No pending messages.
") return bodies = elink_char.message_bodies(message_ids_to_relay) @@ -175,12 +194,75 @@ def get(self): return + def send_notifications(self, config, elink_api, elink_char, elink_eve, + notify_descriptions): + + headers = elink_char.notifications() + message_ids = set(headers[h]['id'] for h in headers + if headers[h]['type_id'] in config.notify_types ) + + headers = dict((headers[h]['id'], headers[h]) for h in headers) + + message_ids_to_relay = set() + sender_ids = set() + + for m_id in message_ids: + seen = (memcache.get('nseen-%s' % m_id) or + SeenNotification.gql("WHERE notify_id = :1", m_id).get()) + if not seen: + message_ids_to_relay.add(m_id) + sender_ids.add(headers[m_id]['sender_id']) + else: + memcache.set('nseen-%s' % m_id, True) + + if not message_ids_to_relay: + self.response.out.write("No pending notifications.
") + return + + bodies = elink_char.notification_texts(message_ids_to_relay) + senders = elink_eve.character_names_from_ids(sender_ids) + + e = EmailMessage() + e.to = config.dest_email + e.sender = 'no-reply@evemail-bridge.appspotmail.com' + for m_id in message_ids_to_relay: + sender = senders[headers[m_id]['sender_id']] + timestamp = headers[m_id]['timestamp'] + e.subject = ('[EVE Notify] %s' % + notify_descriptions.filter( + "type_id = ", headers[m_id]['type_id']).get().description) + e.html = self.format_notification(bodies[m_id], timestamp, sender, + elink_eve) + e.send() + SeenNotification(notification_id=m_id).put() + memcache.set('nseen-%s' % m_id, True) + self.response.out.write("Processed notification ID %s.
\n" % m_id) + + return + def format_message(self, body, timestamp, sender): mtime = datetime.datetime.fromtimestamp(timestamp) body = re.sub(r'', r'', body) body = "

Sent by %s at %s EVE Time

%s" % (sender, mtime, body) return body + def format_notification(self, data, timestamp, sender, elink_eve): + mtime = datetime.datetime.fromtimestamp(timestamp) + body = ("Attack by %s <%s> [%s] against %s located at " + + "moon %s in system %s. Health is %f/%f/%f.") % ( + data['aggressorID'], + data['aggressorCorpID'], + data['aggressorAllianceID'], + data['typeID'], + data['moonID'], + data['solarSystemID'], + data['shieldValue'], + data['armorValue'], + data['hullValue'], + ) + body = "

Sent by %s at %s EVE Time

%s" % (sender, mtime, body) + return body + class NullHandler(webapp2.RequestHandler): def get(self): pass diff --git a/models.py b/models.py index 958ad0d..33910da 100644 --- a/models.py +++ b/models.py @@ -7,6 +7,14 @@ class Configuration(db.Model): rcpt_org = db.IntegerProperty(required=True) rcpt_org2 = db.IntegerProperty() dest_email = db.EmailProperty(required=True) + notify_types = db.ListProperty(int, required=True) + +class NotificationTypes(db.Model): + type_id = db.IntegerProperty(required=True) + description = db.StringProperty(required=True) class SeenMail(db.Model): mail_id = db.IntegerProperty(required=True) + +class SeenNotification(db.Model): + notification_id = db.IntegerProperty(required=True)