Browse Source

added support for ikea

Fabian Peter Hammerle 8 years ago
parent
commit
a2f174b969
6 changed files with 126 additions and 0 deletions
  1. 16 0
      dingguo/__init__.py
  2. 2 0
      dingguo/parser/__init__.py
  3. 71 0
      dingguo/parser/ikea.py
  4. 1 0
      tests/test_parser.py
  5. 24 0
      tests/test_parser_ikea.py
  6. 12 0
      tests/test_yaml.py

+ 16 - 0
dingguo/__init__.py

@@ -287,6 +287,9 @@ class Article(Item):
             authors = None,
             color = None,
             delivery_date = None,
+            depth = None,
+            height  = None,
+            maximum_load = None,
             option = None,
             product_id = None,
             quantity = None,
@@ -294,6 +297,7 @@ class Article(Item):
             shipper = None,
             size = None,
             state = None,
+            width = None,
             **kwargs
             ):
         super(Article, self).__init__(**kwargs)
@@ -325,6 +329,18 @@ class Article(Item):
         if size is not None:
             assert type(size) is unicode
             self.size = size
+        if width is not None:
+            assert type(width) is ScalarFigure
+            self.width = width
+        if depth is not None:
+            assert type(depth) is ScalarFigure
+            self.depth = depth
+        if height is not None:
+            assert type(height) is ScalarFigure
+            self.height = height
+        if maximum_load is not None:
+            assert type(maximum_load) is ScalarFigure
+            self.maximum_load = maximum_load
         assert delivery_date is None or type(delivery_date) is datetime.date
         self.delivery_date = delivery_date
 

+ 2 - 0
dingguo/parser/__init__.py

@@ -6,6 +6,7 @@ import traceback
 import amazon
 import banggood
 import hm
+import ikea
 import ingdiba
 import lieferservice
 import mytaxi
@@ -17,6 +18,7 @@ order_confirmation_parsers = [
     amazon.parse_order_confirmation_mail,
     banggood.parse_order_confirmation_mail,
     hm.parse_order_confirmation_mail,
+    ikea.parse_order_confirmation_mail,
     lieferservice.parse_order_confirmation_mail,
     mytaxi.parse_order_confirmation_mail,
     oebb.parse_order_confirmation_mail,

+ 71 - 0
dingguo/parser/ikea.py

@@ -0,0 +1,71 @@
+# -*- coding: utf-8 -*-
+
+import datetime
+import dingguo
+import email
+import re
+
+def parse_order_confirmation_mail(mail):
+
+    assert isinstance(mail, email.message.Message)
+
+    mail_text = mail.get_payload()[0].get_payload(decode = True).decode('iso-8859-1')
+
+    if not u'Danke für deine Bestellung bei IKEA' in mail_text:
+        raise Exception('no ikea order confirmation')
+
+    order = dingguo.Order(
+        order_id = re.search(ur'Bestellnummer:\s+(\d+)', mail_text).group(1),
+        order_date = datetime.datetime.strptime(
+                re.search(ur'Bestelldatum:\s+(\d\d-\d\d-\d{4})', mail_text).group(1),
+                '%d-%m-%Y',
+                ).date(),
+        platform = u'ikea',
+        )
+
+    # Menge  1
+    # Produkt KOMPLEMENT
+    #  Bügel, ausziehbar , dunkelgrau
+    #  Tiefe: 58 cm
+    #  Max Belastung: 4 kg
+    # Artikelnummer: 202.624.87
+    # Einzelpreis ? 10,-
+    # Gesamtpreis ? 10,-
+
+    # Menge  1
+    # Produkt ÄPPLARÖ
+    #  Hocker/außen , braun faltbar braun las.
+    #  Breite: 40 cm
+    #  Tiefe: 38 cm
+    #  Höhe: 42 cm
+    # Artikelnummer: 202.049.25
+    # Einzelpreis ? 19,99
+    # Gesamtpreis ? 19,99
+
+    for article_text in re.findall(ur'Menge[\W\w]+?Gesamtpreis', mail_text):
+        article_attr = re.match(
+                ur'Menge\s+(?P<quantity>\d+)\s+'
+                    + ur'Produkt\s+(?P<name>.+)\s+'
+                    + ur'(?P<label>.+)\s+'
+                    + ur'(Breite: (?P<width>\d+) (?P<width_unit>[^\s]+)\s+)?'
+                    + ur'(Tiefe: (?P<depth>\d+) (?P<depth_unit>[^\s]+)\s+)?'
+                    + ur'(Höhe: (?P<height>\d+) (?P<height_unit>[^\s]+)\s+)?'
+                    + ur'(Max Belastung: (?P<maximum_load>\d+) (?P<maximum_load_unit>[^\s]+)\s+)?'
+                    + ur'Artikelnummer: (?P<product_id>[\d\.]+)\s+'
+                    + ur'Einzelpreis \? (?P<price>\d+,\d*)-?\s+'
+                    + ur'Gesamtpreis',
+                article_text,
+                re.UNICODE,
+                ).groupdict()
+        order.items.append(dingguo.Article(
+            depth = dingguo.ScalarFigure(float(article_attr['depth']), article_attr['depth_unit']) if article_attr['depth'] else None,
+            height = dingguo.ScalarFigure(float(article_attr['height']), article_attr['height_unit']) if article_attr['height'] else None,
+            maximum_load = dingguo.ScalarFigure(float(article_attr['maximum_load']), article_attr['maximum_load_unit']) if article_attr['maximum_load'] else None,
+            name = u'%s %s' % (article_attr['name'].strip(), article_attr['label'].strip().replace(' , ', ', ')),
+            price_brutto = dingguo.Sum(float(article_attr['price'].replace(',', '.')), u'EUR'),
+            product_id = article_attr['product_id'],
+            quantity = int(article_attr['quantity']),
+            width = dingguo.ScalarFigure(float(article_attr['width']), article_attr['width_unit']) if article_attr['width'] else None,
+            ))
+
+    return [order]

+ 1 - 0
tests/test_parser.py

@@ -13,6 +13,7 @@ test_data_path = os.path.join(project_root_path, 'tests', 'data')
     ('amazon.de', os.path.join(test_data_path, 'amazon', 'mail_1.eml')),
     ('banggood', os.path.join(test_data_path, 'banggood', '1.eml')),
     ('hm', os.path.join(test_data_path, 'hm', '1.eml')),
+    ('ikea', os.path.join(test_data_path, 'ikea', '1.eml')),
     ('lieferservice.at', os.path.join(test_data_path, 'lieferservice.at', 'mail_1.eml')),
     ('mytaxi', os.path.join(test_data_path, 'mytaxi', 'mail_1.eml')),
     ('oebb', os.path.join(test_data_path, 'oebb', 'mail_1.eml')),

+ 24 - 0
tests/test_parser_ikea.py

@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+
+import pytest
+
+import dingguo.parser.ikea
+import email
+import glob
+import os
+import test_yaml
+import yaml
+
+project_root_path = os.path.realpath(os.path.join(__file__, '..', '..'))
+test_data_path = os.path.join(project_root_path, 'tests', 'data', 'ikea')
+
+@pytest.mark.parametrize('mail_path', glob.glob(os.path.join(test_data_path, '*.eml')))
+def test_parse_confirmation_mail(mail_path):
+    with open(mail_path) as mail:
+        parsed_orders = dingguo.parser.ikea.parse_order_confirmation_mail(
+                email.message_from_file(mail)
+                )
+    with open(mail_path.replace('.eml', '.yml')) as yaml_file:
+        expected_orders = yaml.load(yaml_file.read())
+    assert expected_orders == parsed_orders, \
+            test_yaml.yaml_diff(expected_orders, parsed_orders)

+ 12 - 0
tests/test_yaml.py

@@ -42,6 +42,10 @@ def get_article():
             reseller = u'seller',
             shipper = u'shipper',
             state = u'goood',
+            width = dingguo.ScalarFigure(1.23, u'm'),
+            depth = dingguo.ScalarFigure(12.3, u'dm'),
+            height = dingguo.ScalarFigure(123., u'cm'),
+            maximum_load = dingguo.ScalarFigure(40., u'kg'),
             )
 
 def get_transportation():
@@ -279,6 +283,9 @@ authors:
 - a
 - b
 delivery_date: null
+depth: !scalar '12.3 dm'
+height: !scalar '123.0 cm'
+maximum_load: !scalar '40.0 kg'
 name: article name
 price_brutto: !sum '1.23 EUR'
 product_id: 0815
@@ -286,6 +293,7 @@ quantity: 1
 reseller: seller
 shipper: shipper
 state: goood
+width: !scalar '1.23 m'
 """
 
 def test_article_from_yaml():
@@ -301,6 +309,10 @@ quantity: 1
 reseller: seller
 shipper: shipper
 state: goood
+depth: !scalar 12.3 dm
+height: !scalar 123.0 cm
+maximum_load: !scalar 40.0 kg
+width: !scalar 1.23 m
 """)
 
 def test_transportation_to_yaml():