Procházet zdrojové kódy

moved class definitions to module

Fabian Peter Hammerle před 9 roky
rodič
revize
957beb3a83
2 změnil soubory, kde provedl 188 přidání a 186 odebrání
  1. 168 0
      dingguo/__init__.py
  2. 20 186
      scripts/order-confirmation-mail-parser

+ 168 - 0
dingguo/__init__.py

@@ -1,5 +1,7 @@
 # -*- coding: utf-8 -*-
+
 import yaml
+import datetime
 
 class Figure(object):
 
@@ -70,3 +72,169 @@ class Sum(Figure):
 
     """ use property() instead of decorator to enable overriding """
     unit = property(get_unit, set_unit)
+
+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 Order(object):
+
+    def __init__(self, platform, order_id, order_date, customer_id = None):
+        assert type(platform) is unicode
+        self.platform = platform
+        assert type(order_id) is unicode
+        self.order_id = order_id
+        if type(order_date) is datetime.datetime:
+            order_date = order_date.date()
+        assert type(order_date) is datetime.date
+        self.order_date = order_date
+        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,
+            }.items() if v is not None}
+
+yaml.SafeDumper.add_representer(Order, lambda dumper, order: dumper.represent_dict(order.dict_repr()))
+
+class Item(object):
+
+    def __init__(
+            self,
+            name = None,
+            price_brutto = None,
+            ):
+        assert type(name) is unicode
+        self.name = name
+        assert type(price_brutto) is Sum
+        self.price_brutto = price_brutto
+
+    def dict_repr(self):
+        return {
+            'name': self.name,
+            '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()))
+
+class Article(Item):
+
+    def __init__(
+            self,
+            quantity = None,
+            authors = [],
+            state = None,
+            reseller = None,
+            shipper = None,
+            **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
+        self.state = state
+        assert reseller is None or type(reseller) is unicode
+        self.reseller = reseller
+        assert shipper is None or type(shipper) is unicode
+        self.shipper = shipper
+        self.delivery_date = None
+
+    def dict_repr(self):
+        attr = super(Article, self).dict_repr()
+        attr.update({
+            'delivery_date': self.delivery_date,
+            'quantity': self.quantity,
+            'reseller': self.reseller,
+            'shipper': self.shipper,
+            'state': self.state,
+            })
+        if len(self.authors) > 0:
+            attr['authors'] = self.authors
+        return attr
+
+yaml.SafeDumper.add_representer(Article, lambda dumper, article: dumper.represent_dict(article.dict_repr()))
+
+class Transportation(Item):
+
+    def __init__(
+            self,
+            departure_point = None,
+            destination_point = None,
+            distance = None,
+            route_map = None,
+            **kwargs
+            ):
+        super(Transportation, self).__init__(**kwargs)
+        assert type(departure_point) is unicode
+        self.departure_point = departure_point
+        assert type(destination_point) is unicode
+        self.destination_point = destination_point
+        assert distance is None or type(distance) is Distance
+        self.distance = distance
+        assert route_map is None or type(route_map) is str
+        self.route_map = route_map
+
+    def dict_repr(self):
+        attr = super(Transportation, self).dict_repr()
+        attr.update({
+            'departure_point': self.departure_point,
+            'destination_point': self.destination_point,
+            'distance_metres': self.distance.metres if self.distance else None,
+            'route_map': self.route_map,
+            })
+        return attr
+
+yaml.SafeDumper.add_representer(Transportation, lambda dumper, transportation: dumper.represent_dict(transportation.dict_repr()))
+
+class TaxiRide(Transportation):
+
+    def __init__(self, name = None, driver = None, arrival_time = None, departure_time = None, **kwargs):
+        if name is None:
+            name = u'Taxi Ride'
+        super(TaxiRide, self).__init__(name = name, **kwargs)
+        assert type(driver) is unicode
+        self.driver = driver
+        assert arrival_time is None or type(arrival_time) is datetime.datetime
+        self.arrival_time = arrival_time
+        assert departure_time is None or type(departure_time) is datetime.datetime
+        self.departure_time = departure_time
+
+    def dict_repr(self):
+        attr = super(TaxiRide, self).dict_repr()
+        attr.update({
+            'arrival_time': self.arrival_time.strftime('%Y-%m-%d %H:%M') if self.arrival_time else None,
+            'departure_time': self.departure_time.strftime('%Y-%m-%d %H:%M') if self.departure_time else None,
+            'driver': self.driver,
+            })
+        return attr
+
+yaml.SafeDumper.add_representer(TaxiRide, lambda dumper, taxi_ride: dumper.represent_dict(taxi_ride.dict_repr()))

+ 20 - 186
scripts/order-confirmation-mail-parser

@@ -20,172 +20,6 @@ import HTMLParser
 import argcomplete
 import BeautifulSoup
 
-class Order(object):
-
-    def __init__(self, platform, order_id, order_date, customer_id = None):
-        assert type(platform) is unicode
-        self.platform = platform
-        assert type(order_id) is unicode
-        self.order_id = order_id
-        if type(order_date) is datetime.datetime:
-            order_date = order_date.date()
-        assert type(order_date) is datetime.date
-        self.order_date = order_date
-        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,
-            }.items() if v is not None}
-
-yaml.SafeDumper.add_representer(Order, lambda dumper, order: dumper.represent_dict(order.dict_repr()))
-
-class Discount(object):
-
-    def __init__(
-            self,
-            name = None,
-            amount = None,
-            ):
-        assert type(name) is unicode
-        self.name = name
-        assert type(amount) is dingguo.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,
-            ):
-        assert type(name) is unicode
-        self.name = name
-        assert type(price_brutto) is dingguo.Sum
-        self.price_brutto = price_brutto
-
-    def dict_repr(self):
-        return {
-            'name': self.name,
-            '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()))
-
-class Article(Item):
-
-    def __init__(
-            self,
-            quantity = None,
-            authors = [],
-            state = None,
-            reseller = None,
-            shipper = None,
-            **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
-        self.state = state
-        assert reseller is None or type(reseller) is unicode
-        self.reseller = reseller
-        assert shipper is None or type(shipper) is unicode
-        self.shipper = shipper
-        self.delivery_date = None
-
-    def dict_repr(self):
-        attr = Item.dict_repr(self)
-        attr.update({
-            'delivery_date': self.delivery_date,
-            'quantity': self.quantity,
-            'reseller': self.reseller,
-            'shipper': self.shipper,
-            'state': self.state,
-            })
-        if len(self.authors) > 0:
-            attr['authors'] = self.authors
-        return attr
-
-yaml.SafeDumper.add_representer(Article, lambda dumper, article: dumper.represent_dict(article.dict_repr()))
-
-class Transportation(Item):
-
-    def __init__(
-            self,
-            departure_point = None,
-            destination_point = None,
-            distance = None,
-            route_map = None,
-            **kwargs
-            ):
-        super(Transportation, self).__init__(**kwargs)
-        assert type(departure_point) is unicode
-        self.departure_point = departure_point
-        assert type(destination_point) is unicode
-        self.destination_point = destination_point
-        assert distance is None or type(distance) is dingguo.Distance
-        self.distance = distance
-        assert route_map is None or type(route_map) is str
-        self.route_map = route_map
-
-    def dict_repr(self):
-        attr = Item.dict_repr(self)
-        attr.update({
-            'departure_point': self.departure_point,
-            'destination_point': self.destination_point,
-            'distance_metres': self.distance.metres if self.distance else None,
-            'route_map': self.route_map,
-            })
-        return attr
-
-yaml.SafeDumper.add_representer(Transportation, lambda dumper, transportation: dumper.represent_dict(transportation.dict_repr()))
-
-class TaxiRide(Transportation):
-
-    def __init__(self, name = None, driver = None, arrival_time = None, departure_time = None, **kwargs):
-        if name is None:
-            name = u'Taxi Ride'
-        super(TaxiRide, self).__init__(name = name, **kwargs)
-        assert type(driver) is unicode
-        self.driver = driver
-        assert arrival_time is None or type(arrival_time) is datetime.datetime
-        self.arrival_time = arrival_time
-        assert departure_time is None or type(departure_time) is datetime.datetime
-        self.departure_time = departure_time
-
-    def dict_repr(self):
-        attr = Transportation.dict_repr(self)
-        attr.update({
-            'arrival_time': self.arrival_time.strftime('%Y-%m-%d %H:%M') if self.arrival_time else None,
-            'departure_time': self.departure_time.strftime('%Y-%m-%d %H:%M') if self.departure_time else None,
-            'driver': self.driver,
-            })
-        return attr
-
-yaml.SafeDumper.add_representer(TaxiRide, lambda dumper, taxi_ride: dumper.represent_dict(taxi_ride.dict_repr()))
-
 def parse_amazon(msg):
 
     msg_text = msg.get_payload()[0].get_payload(decode = True).decode('utf-8')
@@ -203,7 +37,7 @@ def parse_amazon(msg):
         locale.setlocale(locale.LC_ALL, 'de_DE.UTF-8')
         order_date = datetime.datetime.strptime(order_date_formatted.encode('utf-8'), '%d. %B %Y')
 
-        order = Order(
+        order = dingguo.Order(
             u'amazon.de',
             order_id,
             order_date
@@ -225,7 +59,7 @@ def parse_amazon(msg):
                 sys.stderr.write(repr(article_text) + '\n')
                 raise Exception('could not match article')
             article = article_match.groupdict()
-            order.items.append(Article(
+            order.items.append(dingguo.Article(
                 name = article['name'],
                 price_brutto = dingguo.Sum(
                     float(article['price_brutto'].replace(',', '.')),
@@ -267,7 +101,7 @@ def parse_oebb(msg):
         '%b %d, %Y'
         )
 
-    order = Order(
+    order = dingguo.Order(
         u'oebb',
         order_match_groups['order_id'],
         order_date,
@@ -283,7 +117,7 @@ def parse_oebb(msg):
         re.MULTILINE | re.UNICODE
         )
     item = item_match.groupdict()
-    order.items.append(Transportation(
+    order.items.append(dingguo.Transportation(
         name = u'Train Ticket',
         price_brutto = dingguo.Sum(
             float(item['price_brutto']),
@@ -344,13 +178,13 @@ def parse_mytaxi(msg):
         '%d.%m.%y %H:%M'
         )
 
-    order = Order(
+    order = dingguo.Order(
         u'mytaxi',
         order_id,
         arrival_time,
         )
     locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
-    order.items.append(TaxiRide(
+    order.items.append(dingguo.TaxiRide(
         price_brutto = dingguo.Sum(
             float(ride_match_groups['price_brutto'].replace(',', '.')),
             # why 0x80 ?
@@ -388,7 +222,7 @@ def parse_uber(msg):
         ur'[\da-f\-]{36}',
         doc.find(text = 'Visit the trip page').parent['href'],
         ).group(0)
-    order = Order(
+    order = dingguo.Order(
         u'uber',
         trip_id,
         datetime.datetime.strptime(
@@ -416,7 +250,7 @@ def parse_uber(msg):
 
     fare = doc.find(attrs = {'class': 'header-price'}).find(attrs = {'class': 'header-fare text-pad'}).text
 
-    order.items.append(TaxiRide(
+    order.items.append(dingguo.TaxiRide(
         name = doc.find(text = 'CAR').parent.parent.find(attrs = {'class': 'data'}).text + ' Ride',
         price_brutto = dingguo.Sum(float(fare[1:]), fare[0]),
         arrival_time = datetime.datetime.combine(order.order_date, arrival_time),
@@ -447,7 +281,7 @@ def parse_yipbee(msg):
         re.UNICODE
         ).groupdict()
 
-    order = Order(
+    order = dingguo.Order(
         u'yipbee',
         order_match_groups['order_id'],
         datetime.datetime.strptime(order_match_groups['order_time'], '%d.%m.%Y %H:%M:%S'),
@@ -464,7 +298,7 @@ def parse_yipbee(msg):
         total_price_2 = float(article_match_groups['total_price_2'].replace(',', '.'))
         assert abs(total_price - total_price_2) < 0.01, 'expected %f, received %f' % (total_price, total_price_2)
         quantity = int(article_match_groups['quantity'])
-        order.items.append(Article(
+        order.items.append(dingguo.Article(
             name = article_match_groups['name'],
             price_brutto = dingguo.Sum(round(total_price / quantity, 2), u'EUR'),
             quantity = quantity,
@@ -482,14 +316,14 @@ def parse_yipbee(msg):
     if discount_tag:
         name_tag, value_tag = discount_tag.findAll('td', recursive = False)
         value, currency = value_tag.text.split(' ')
-        order.discounts.append(Discount(
+        order.discounts.append(dingguo.Discount(
             name = name_tag.text,
             amount = dingguo.Sum(float(value.replace(',', '.')) * -1, currency),
             ))
 
     delivery_price = order_match_groups['summary_text'].split('VERSAND')[1].split('STEUERN')[0].strip()
     delivery_price_value, delivery_price_currency = delivery_price.split(' ')
-    order.items.append(Item(
+    order.items.append(dingguo.Item(
         name = u'Delivery',
         price_brutto = dingguo.Sum(float(delivery_price_value.replace(',', '.')), delivery_price_currency),
         ))
@@ -512,7 +346,7 @@ def parse_yipbee_html(msg):
         re.UNICODE
         ).groupdict()
 
-    order = Order(
+    order = dingguo.Order(
         u'yipbee',
         order_match_groups['order_id'],
         datetime.datetime.strptime(order_match_groups['order_time'], '%d.%m.%Y %H:%M:%S'),
@@ -522,7 +356,7 @@ def parse_yipbee_html(msg):
     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(
+        order.items.append(dingguo.Article(
             name = article_columns[1].text,
             price_brutto = dingguo.Sum(float(price), currency),
             quantity = int(article_columns[3].text),
@@ -533,14 +367,14 @@ def parse_yipbee_html(msg):
     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(
+    order.discounts.append(dingguo.Discount(
         name = discount_name,
         amount = dingguo.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(
+    order.items.append(dingguo.Item(
         name = u'Delivery',
         price_brutto = dingguo.Sum(float(shipping_price), shipping_currency),
         ))
@@ -574,7 +408,7 @@ def parse_lieferservice(msg):
             time.mktime(email.utils.parsedate(msg['Date']))
             )
 
-    order = Order(
+    order = dingguo.Order(
         u'lieferservice.at',
         order_match_groups['order_id'].strip(),
         order_date
@@ -597,12 +431,12 @@ def parse_lieferservice(msg):
             )
         if price.value < 0:
             price.value *= -1
-            order.discounts.append(Discount(
+            order.discounts.append(dingguo.Discount(
                 name = name,
                 amount = price,
                 ))
         else:
-            order.items.append(Article(
+            order.items.append(dingguo.Article(
                 name = name,
                 quantity = 1,
                 price_brutto = price,
@@ -612,7 +446,7 @@ def parse_lieferservice(msg):
 
     delivery_costs = order_match_groups['delivery_costs'].strip()
     assert delivery_costs == 'FREE'
-    order.items.append(Item(
+    order.items.append(dingguo.Item(
         name = u'Delivery',
         price_brutto = dingguo.Sum(float('0'.replace(',', '.')), u'EUR'),
         ))