From 3177ba26421b730bdf475fc2e991eef9ab9ef067 Mon Sep 17 00:00:00 2001 From: "James E. Blair" Date: Sun, 9 Jun 2019 10:05:11 -0700 Subject: Add support for Delta Also add an undocumented mailbox driver for a directory of files for ease of testing (this could probably become a maildir driver with a bit more work). Remove unecessary decode calls from the message traversal. --- email_assistant/plugins/delta.py | 115 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 email_assistant/plugins/delta.py (limited to 'email_assistant/plugins/delta.py') diff --git a/email_assistant/plugins/delta.py b/email_assistant/plugins/delta.py new file mode 100644 index 0000000..50da506 --- /dev/null +++ b/email_assistant/plugins/delta.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python3 + +# Copyright (C) 2019 James E. Blair +# +# This file is part of Email-assistant. +# +# Email-assistant is free software: you can redistribute it and/or +# modify it under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of +# the License, or (at your option) any later version. +# +# Email-assistant is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Email-assistant. If not, see +# . + +import re +import logging +import hashlib + +from bs4 import BeautifulSoup +import dateutil.parser +import dateutil.tz +import inscriptis +import vobject + +from email_assistant import iata +from email_assistant import plugin + +def parse_dep_arr(dep_date, flight_date, flight_time, code): + flight_year = dep_date.year + tz = iata.tzmap[code] + flight_time = dateutil.parser.parse(flight_date + ' ' + flight_time) + if flight_time.year < flight_year: + flight_time.replace(year=flight_year) + flight_time = flight_time.replace(tzinfo=dateutil.tz.gettz(tz)) + return flight_time + +class Plugin(plugin.Plugin): + name = 'delta' + + def match(self, msg): + if ('DeltaAirLines@e.delta.com' in msg['From'] and + 'Your Flight Receipt' in msg['Subject']): + return True + + def get_events(self, msg): + events = [] + for part in msg.walk(): + if part.get_content_type() == 'text/html': + soup = BeautifulSoup(part.get_payload(decode=True), 'html.parser') + flights = [] + flight = None + dep_date = None + start = soup.find(string=re.compile('FLIGHT INFO STARTS')) + for row in start.parent.find_all('tr', recursive=False): + row = [x.strip() for x in row.strings if x.strip()] + if len(row) == 3 and row[1:] == ['DEPART', 'ARRIVE']: + dep_date = row[0] + continue + if dep_date is None: continue + f = { + 'dep_date': dep_date, + #'num': row[0], + #'cabin': row[1], + 'dep_city': row[2], + 'dep_time': row[3], + 'arr_city': row[4], + 'arr_time': row[5]} + if len(row) > 6: + f['arr_date'] = row[6].replace('*', '').strip() + else: + f['arr_date'] = dep_date + flights.append(f) + start = soup.find(string=re.compile('Checked Bag Allowance')) + while start.name != 'table': start = start.parent + start = start.parent + while start.name != 'table': start = start.parent + index = 0 + for row in start.find_all('tr', recursive=False): + row = [x.strip() for x in row.strings if x.strip()] + if len(row) != 3: continue + try: + dep_date = dateutil.parser.parse(row[0]) + except Exception: + continue + f = flights[index] + f['dep_code'] = row[1].split()[-1].strip() + f['arr_code'] = row[2].split()[-1].strip() + f['dep_dt'] = parse_dep_arr( + dep_date, f['dep_date'], f['dep_time'], f['dep_code']) + f['arr_dt'] = parse_dep_arr( + dep_date, f['arr_date'], f['arr_time'], f['arr_code']) + index += 1 + for f in flights: + self.log.debug('%s %s %s %s', + f['dep_dt'], f['arr_dt'], f['dep_code'], f['arr_code']) + cal = vobject.iCalendar() + event = cal.add('vevent') + event.add('dtstart').value = f['dep_dt'] + event.add('dtend').value = f['arr_dt'] + summary = "Flight from %s to %s" % (f['dep_code'], f['arr_code']) + event.add('summary').value = summary + text = inscriptis.get_text(str(soup)) + text = re.sub(r'([^ ]+)\s*\n', '\\1\n', text) + event.add('description').value = text + event.add('location').value = "%s airport" % (f['dep_code'],) + uid = hashlib.sha1((str(f['dep_time']) + summary).encode('utf8')).hexdigest() + event.add('uid').value = uid + events.append(cal) + return events -- cgit v1.2.3