# -*- coding: utf-8 -*- import datetime import dateutil.parser import dingguo import email import email.utils import ioex import pytz import re class UtcOffsetTimezone(datetime.tzinfo): def __init__(self, seconds): assert type(seconds) is int self.seconds = seconds def utcoffset(self, dt): return datetime.timedelta(seconds = self.seconds) def dst(self, dt): return None def tzname(self, dt): return self.__class__.__name__ + '(seconds = %d)' % self.seconds def parse_order_confirmation_mail(mail): assert isinstance(mail, email.message.Message) msg_text = mail.get_payload(decode = True).decode('utf8') if not 'Wiener Linien' in msg_text: raise Exception() order_match = re.search( r'(?P.*Ticket.*)\s+' + r'Valid from: (?P\d{1,2} \w+ \d{4} \d{1,2}:\d{2})\s+' + r'(Valid until: (?P\d{1,2} \w+ \d{4} \d{1,2}:\d{2})\s+)?' + r'Type: (?P.* ticket)\s+' + r'For\:\s+' + r'(?PFabian Peter)\s+' + r'(?PHammerle)\s+' + ur'Price: (?P€)(?P\d+.\d{2})\s+' + r'Quantity: (?P1)\s+' , msg_text, re.MULTILINE | re.UNICODE ) if not order_match: print(repr(msg_text)) order_match_groups = order_match.groupdict() email_recipient_address = mail['delivered-to'].decode('utf8') email_date = dateutil.parser.parse(mail['date']) order = dingguo.Order( platform = u'wiener_linien', order_id = '%s-%sZ' % ( email_recipient_address, email_date.astimezone(pytz.utc).replace(tzinfo = None).isoformat(), ), order_date = email_date, customer_id = email_recipient_address, ) assert int(order_match_groups['quantity']) == 1 ticket_url_match = re.search( ur'following link:\s+(http[^\s]+)', msg_text, re.MULTILINE | re.UNICODE, ) with ioex.setlocale('en_US.UTF-8'): timezone = UtcOffsetTimezone(email.utils.parsedate_tz(mail['date'])[9]) order.items.append(dingguo.Transportation( name = order_match_groups['name'], price_brutto = dingguo.Sum( float(order_match_groups['price']), order_match_groups['currency'], ), passenger = dingguo.Person( first_name = order_match_groups['passenger_first_name'], last_name = order_match_groups['passenger_last_name'], ), valid_from = datetime.datetime.strptime(order_match_groups['valid_from'], '%d %B %Y %H:%M') .replace(tzinfo = timezone), valid_until = datetime.datetime.strptime(order_match_groups['valid_until'], '%d %B %Y %H:%M') .replace(tzinfo = timezone) if order_match_groups['valid_until'] else None, ticket_url = ticket_url_match.group(1) if ticket_url_match else None, )) return [order]