# -*- coding: utf-8 -*- import BeautifulSoup import datetime import dateutil.parser import dingguo import email.message import ioex.datetimeex import re def parse_order_confirmation_mail(mail): assert isinstance(mail, email.message.Message) html = mail.get_payload()[1].get_payload(decode = True).decode('utf-8') if not 'Namecheap' in html: raise Exception() doc = BeautifulSoup.BeautifulSoup(html) email_date = dateutil.parser.parse(mail['date']) order_date = dateutil.parser.parse( doc.find(text = re.compile('Order Date:')).findNext(text = re.compile('\d+')) ).replace(tzinfo = email_date.tzinfo) # ensure timezone is correct assert (email_date - order_date) < datetime.timedelta(minutes = 30) order = dingguo.Order( platform = u'namecheap', order_id = doc.find(text = re.compile('Order Number:')).findNext().findNext().text, order_date = order_date, customer_id = doc.find(text = re.compile('User Name:')).findNext().findNext().text, ) for item_row_tag in doc.find(text = re.compile('TITLE')).findParent('table').findAll('tr')[1:-2]: title_tag, quantity_tag, duration_tag, price_tag, subtotal_tag = item_row_tag.findAll('td') assert int(quantity_tag.text.replace(' ', '')) == 1 item = dingguo.Service( name = title_tag.text.replace('\r\n', '').replace(' ', '').strip(), price_brutto = dingguo.Sum.parse_text(price_tag.text.replace(' ', '')), duration = ioex.datetimeex.Duration( years = int(duration_tag.text.replace(' year ', '')), ), ) order.items.append(item) fee_tag = subtotal_tag.find('small') if fee_tag: fee_name, fee_price = fee_tag.text.split(' ') order.items.append(dingguo.Service( name = '%s %s' % (item.name, fee_name), price_brutto = dingguo.Sum.parse_text(fee_price), duration = item.duration, )) total_price = dingguo.Sum.parse_text( doc.find(text = re.compile('^TOTAL$')).findNext('strong').text ) assert total_price.value == sum([i.price_brutto.value for i in order.items]) return [order]