|
@@ -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]))
|
|
|
|