namecheap.py 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. # -*- coding: utf-8 -*-
  2. import BeautifulSoup
  3. import datetime
  4. import dateutil.parser
  5. import dingguo
  6. import email.message
  7. import ioex.datetimeex
  8. import re
  9. def parse_order_confirmation_mail(mail):
  10. assert isinstance(mail, email.message.Message)
  11. html = mail.get_payload()[1].get_payload(decode = True).decode('utf-8')
  12. if not 'Namecheap' in html:
  13. raise Exception()
  14. doc = BeautifulSoup.BeautifulSoup(html)
  15. email_date = dateutil.parser.parse(mail['date'])
  16. order_date = dateutil.parser.parse(
  17. doc.find(text = re.compile('Order Date:')).findNext(text = re.compile('\d+'))
  18. ).replace(tzinfo = email_date.tzinfo)
  19. # ensure timezone is correct
  20. assert (email_date - order_date) < datetime.timedelta(minutes = 30)
  21. order = dingguo.Order(
  22. platform = u'namecheap',
  23. order_id = doc.find(text = re.compile('Order Number:')).findNext().findNext().text,
  24. order_date = order_date,
  25. customer_id = doc.find(text = re.compile('User Name:')).findNext().findNext().text,
  26. )
  27. for item_row_tag in doc.find(text = re.compile('TITLE')).findParent('table').findAll('tr')[1:-2]:
  28. title_tag, quantity_tag, duration_tag, price_tag, subtotal_tag = item_row_tag.findAll('td')
  29. assert int(quantity_tag.text.replace('&nbsp;', '')) == 1
  30. item = dingguo.Service(
  31. name = title_tag.text.replace('\r\n', '').replace('&nbsp;', '').strip(),
  32. price_brutto = dingguo.Sum.parse_text(price_tag.text.replace('&nbsp;', '')),
  33. duration = ioex.datetimeex.Duration(
  34. years = int(duration_tag.text.replace(' year&nbsp;', '')),
  35. ),
  36. )
  37. order.items.append(item)
  38. fee_tag = subtotal_tag.find('small')
  39. if fee_tag:
  40. fee_name, fee_price = fee_tag.text.split(' ')
  41. order.items.append(dingguo.Service(
  42. name = '%s %s' % (item.name, fee_name),
  43. price_brutto = dingguo.Sum.parse_text(fee_price),
  44. duration = item.duration,
  45. ))
  46. total_price = dingguo.Sum.parse_text(
  47. doc.find(text = re.compile('^TOTAL$')).findNext('strong').text
  48. )
  49. assert total_price.value == sum([i.price_brutto.value for i in order.items])
  50. return [order]