# -*- coding: utf-8 -*- import datetime import dateutil import dateutil.tz import dingguo import email import ioex import re def parse_order_confirmation_mail(mail): assert isinstance(mail, email.message.Message) msg_text = mail.get_payload()[0].get_payload(decode = True).decode('utf-8') if not u'Amazon.de Bestellbestätigung' in msg_text: raise Exception('no amazon order confirmation') orders = [] for order_text in re.split(ur'={32,}', msg_text)[1:-1]: order_id = re.search(r'Bestellnummer #(.+)', order_text).group(1) order_date_formatted = re.search(ur'Aufgegeben am (.+)', order_text, re.UNICODE).group(1) mail_date = dateutil.parser.parse(mail['date']) with ioex.setlocale('de_DE.UTF-8'): order_date = datetime.datetime.strptime( order_date_formatted.encode('utf-8'), '%d. %B %Y', ) assert order_date.date() == mail_date.date() order = dingguo.Order( u'amazon.de', order_id, order_date.date(), ) for articles_text in re.findall( ur'Bestellte\(r\) Artikel:\s+' + ur'([\W\w]+?)\s+' + ur'(Lieferung \d|_{10,})', order_text, re.UNICODE, ): for article_text in re.split(ur'\n\t*\n', articles_text[0]): article_match = re.match( ur' *((?P\d+) x )?(?P.*)\n' + ur'( *von (?P.*)\n)?' + ur' *(?P[A-Z]+) (?P\d+,\d+)\n' + ur'( *Zustand: (?P.*)\n)?' + ur' *Verkauft von: (?P.*)' + ur'(\n *Versand durch (?P.*))?', article_text, re.MULTILINE | re.UNICODE ) assert article_match is not None, repr(article_text) article = article_match.groupdict() order.items.append(dingguo.Article( name = article['name'], price_brutto = dingguo.Sum( float(article['price_brutto'].replace(',', '.')), article['price_brutto_currency'] ), quantity = int(article['quantity']) if article['quantity'] else 1, authors = article['authors'].split(',') if article['authors'] else None, state = article['state'], reseller = article['reseller'], shipper = article['shipper'], )) assert re.search( ur'Verpackung und Versand: \w+ (\d+,\d+)', order_text, ).group(1) == '0,00' shipping_match = re.finditer( ur'Zustellung:\s+(?P[\W\w]+?)\s+' + ur'Versandart', order_text, re.UNICODE, ) for shipping_attr in [m.groupdict() for m in shipping_match]: with ioex.setlocale('de_AT.UTF-8'): s = datetime.datetime.strptime( shipping_attr['t'].encode('utf8'), '%A, %d. %B', ).replace( year = order.order_date.year, tzinfo = dateutil.tz.gettz('Europe/Berlin'), ) assert s.date() > order.order_date e = s + datetime.timedelta(days = 1) order.items.append(dingguo.Shipping( price_brutto = dingguo.Sum(0.0, u'EUR'), estimated_arrival_time = ioex.datetimeex.Period(start = s, end = e), )) orders.append(order) return orders