#!/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(flight_date, flight_time, flight_loc): code = re.compile('^.*\((...)\)$').match(flight_loc).group(1) tz = iata.tzmap[code] flight_time = dateutil.parser.parse(flight_date + ' ' + flight_time) flight_time = flight_time.replace(tzinfo=dateutil.tz.gettz(tz)) return (code, flight_time) class Plugin(plugin.Plugin): name = 'united' def match(self, msg): if ('Receipts@united.com' in msg['From'] and 'Itinerary and 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') index = 0 while True: index += 1 info = soup.find(string=re.compile('Flight %s of' % index)) if not info: break while info.name != 'table': info = info.parent row = info.find('tr') cols = row.find_all('td') cols = [x.strip() for x in row.strings if x.strip()] flight_num, flight_class = cols row = row.nextSibling cols = row.find_all('td') cols = [x.strip() for x in row.strings if x.strip()] dep_date, arr_date = cols row = row.nextSibling cols = row.find_all('td') cols = [x.strip() for x in row.strings if x.strip()] dep_time, arr_time = cols row = row.nextSibling cols = row.find_all('td') cols = [x.strip() for x in row.strings if x.strip()] dep_loc, arr_loc = cols flight_num = flight_num.split()[-1] dep_code, dep_time = parse_dep_arr(dep_date, dep_time, dep_loc) arr_code, arr_time = parse_dep_arr(arr_date, arr_time, arr_loc) self.log.debug("dep: %s %s", dep_code, dep_time) self.log.debug("arr: %s %s", arr_code, arr_time) cal = vobject.iCalendar() event = cal.add('vevent') event.add('dtstart').value = dep_time event.add('dtend').value = arr_time summary = "Flight %s from %s to %s" % (flight_num, dep_code, 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" % (dep_code,) uid = hashlib.sha1((str(dep_time) + summary).encode('utf8')).hexdigest() event.add('uid').value = uid events.append(cal) return events