Prechádzať zdrojové kódy

added support for yipbee

Fabian Peter Hammerle 9 rokov pred
rodič
commit
ea6851ea09
1 zmenil súbory, kde vykonal 115 pridanie a 19 odobranie
  1. 115 19
      order-confirmation-mail-parser

+ 115 - 19
order-confirmation-mail-parser

@@ -16,6 +16,7 @@ import traceback
 import subprocess
 import HTMLParser
 import argcomplete
+import BeautifulSoup
 
 class Order(object):
 
@@ -29,11 +30,13 @@ class Order(object):
         assert customer_id is None or type(customer_id) is unicode
         self.customer_id = customer_id
         self.items = []
+        self.discounts = []
 
     def dict_repr(self):
         return {k: v for (k, v) in {
             'articles': self.items,
             'customer_id': self.customer_id,
+            'discounts': self.discounts,
             'order_date': self.order_date.strftime('%Y-%m-%d'),
             'order_id': self.order_id,
             'platform': self.platform,
@@ -41,29 +44,56 @@ class Order(object):
 
 yaml.SafeDumper.add_representer(Order, lambda dumper, order: dumper.represent_dict(order.dict_repr()))
 
+class Sum(object):
+
+    def __init__(self, value, currency):
+        assert type(value) is float
+        self.value = value
+        if currency == u'€':
+            currency = u'EUR'
+        assert type(currency) is unicode
+        assert currency in [u'EUR']
+        self.currency = currency
+
+class Discount(object):
+
+    def __init__(
+            self,
+            name = None,
+            amount = None,
+            ):
+        assert type(name) is unicode
+        self.name = name
+        assert type(amount) is Sum
+        assert amount.value >= 0
+        self.amount = amount
+
+    def dict_repr(self):
+        return {
+            'name': self.name,
+            'value': self.amount.value,
+            'value_currency': self.amount.currency,
+            }
+
+yaml.SafeDumper.add_representer(Discount, lambda dumper, discount: dumper.represent_dict(discount.dict_repr()))
+
 class Item(object):
 
     def __init__(
             self,
             name = None,
             price_brutto = None,
-            price_brutto_currency = None,
             ):
         assert type(name) is unicode
         self.name = name
-        assert type(price_brutto) is float
+        assert type(price_brutto) is Sum
         self.price_brutto = price_brutto
-        if price_brutto_currency == u'€':
-            price_brutto_currency = u'EUR'
-        assert type(price_brutto_currency) is unicode
-        assert price_brutto_currency in [u'EUR']
-        self.price_brutto_currency = price_brutto_currency
 
     def dict_repr(self):
         return {
             'name': self.name,
-            'price_brutto': self.price_brutto,
-            'price_brutto_currency': self.price_brutto_currency,
+            'price_brutto': self.price_brutto.value,
+            'price_brutto_currency': self.price_brutto.currency,
             }
 
 yaml.SafeDumper.add_representer(Item, lambda dumper, item: dumper.represent_dict(item.dict_repr()))
@@ -72,6 +102,7 @@ class Article(Item):
 
     def __init__(
             self,
+            quantity = None,
             authors = [],
             state = None,
             reseller = None,
@@ -79,6 +110,8 @@ class Article(Item):
             **kwargs
             ):
         super(Article, self).__init__(**kwargs)
+        assert type(quantity) is int
+        self.quantity = quantity
         assert type(authors) is list
         self.authors = authors
         assert state is None or type(state) is unicode
@@ -91,9 +124,10 @@ class Article(Item):
     def dict_repr(self):
         attr = Item.dict_repr(self)
         attr.update({
-            'state': self.state,
+            'quantity': self.quantity,
             'reseller': self.reseller,
             'shipper': self.shipper,
+            'state': self.state,
             })
         if len(self.authors) > 0:
             attr['authors'] = self.authors
@@ -173,8 +207,11 @@ def parse_amazon(msg):
         article = article_match.groupdict()
         order.items.append(Article(
             name = article['name'],
-            price_brutto = float(article['price_brutto'].replace(',', '.')),
-            price_brutto_currency = article['price_brutto_currency'],
+            price_brutto = Sum(
+                float(article['price_brutto'].replace(',', '.')),
+                article['price_brutto_currency']
+                ),
+            quantity = 1,
             authors = article['authors'].split(',') if article['authors'] else [],
             state = article['state'],
             reseller = article['reseller'],
@@ -226,8 +263,10 @@ def parse_oebb(msg):
     item = item_match.groupdict()
     order.items.append(Transportation(
         name = u'Train Ticket',
-        price_brutto = float(item['price_brutto']),
-        price_brutto_currency = item['price_brutto_currency'],
+        price_brutto = Sum(
+            float(item['price_brutto']),
+            item['price_brutto_currency'],
+            ),
         departure_point = item['departure_point'],
         destination_point = item['destination_point'],
         ))
@@ -290,11 +329,12 @@ def parse_mytaxi(msg):
         )
     locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
     order.items.append(TaxiRide(
-        price_brutto = float(ride_match_groups['price_brutto'].replace(',', '.')),
-        # why 0x80 ?
-        price_brutto_currency = u'EUR'
-            if (ride_match_groups['price_brutto_currency'] == u'\x80')
-            else ride_match_groups['price_brutto_currency'],
+        price_brutto = Sum(
+            float(ride_match_groups['price_brutto'].replace(',', '.')),
+            # why 0x80 ?
+            u'EUR' if (ride_match_groups['price_brutto_currency'] == u'\x80')
+                else ride_match_groups['price_brutto_currency'],
+            ),
         departure_point = ride_match_groups['departure_point'],
         destination_point = ride_match_groups['destination_point'],
         driver = ride_match_groups['driver'],
@@ -302,6 +342,57 @@ def parse_mytaxi(msg):
         ))
     return order
 
+def parse_yipbee(msg):
+
+    html = msg.get_payload()[0].get_payload()[1].get_payload(decode = True)
+
+    if not 'yipbee' in html:
+        raise Exception('no yipbee confirmation')
+
+    doc = BeautifulSoup.BeautifulSoup(html, convertEntities = BeautifulSoup.BeautifulSoup.HTML_ENTITIES)
+    content_table = doc.find('table')
+
+    order_match_groups = re.search(
+        ur'Bestellung:(?P<order_id>\w+) vom (?P<order_time>\d\d.\d\d.\d{4} \d\d:\d\d:\d\d)',
+        content_table.find('table').findAll('tr')[3].text,
+        re.UNICODE
+        ).groupdict()
+
+    order = Order(
+        u'yipbee',
+        order_match_groups['order_id'],
+        datetime.datetime.strptime(order_match_groups['order_time'], '%d.%m.%Y %H:%M:%S'),
+        )
+
+    articles_table = content_table.find('table').find('tbody').findAll('tr', recursive = False)[4].find('table')
+    for article_row in articles_table.find('tbody').findAll('tr', recursive = False)[1:]:
+        article_columns = article_row.findAll('td', recursive = False)
+        (price, currency) = re.sub(ur'\s+', ' ', article_columns[2].text.replace(u',', u'.')).split(' ')
+        order.items.append(Article(
+            name = article_columns[1].text,
+            price_brutto = Sum(float(price), currency),
+            quantity = int(article_columns[3].text),
+            reseller = u'yipbee',
+            shipper = u'yipbee',
+            ))
+
+    discount_row = content_table.find('table').find('tbody').findAll('tr', recursive = False)[6]
+    (discount_name, discount_value_with_currency) = [c.text for c in discount_row.findAll('td', recursive = False)]
+    (discount_value, discount_currency) = discount_value_with_currency.split(' ')
+    order.discounts.append(Discount(
+        name = discount_name,
+        amount = Sum(float(discount_value.replace(',', '.')) * -1, discount_currency)
+        ))
+
+    shipping_costs_table = content_table.find('tbody').findAll('tr', recursive = False)[3].findAll('table')[1]
+    (shipping_price, shipping_currency) = shipping_costs_table.text.replace(',', '.').split(' ')
+    order.items.append(Item(
+        name = u'Delivery',
+        price_brutto = Sum(float(shipping_price), shipping_currency),
+        ))
+
+    return order
+
 def parse(msg):
 
     tracebacks = {}
@@ -321,6 +412,11 @@ def parse(msg):
     except:
         tracebacks['mytaxi'] = traceback.format_exc()
 
+    try:
+        return parse_yipbee(msg)
+    except:
+        tracebacks['yipbee'] = traceback.format_exc()
+
     for parser_name in tracebacks:
         sys.stderr.write('%s parser: \n%s\n' % (parser_name, tracebacks[parser_name]))