[weboob] [PATCH 3/4] Added module dpd

Matthieu Weber mweber+weboob at free.fr
Wed May 13 20:16:08 CEST 2015


This module enables parceloob to track parcels sent with DPD.

Signed-off-by: Matthieu Weber <mweber+weboob at free.fr>
---
 modules/dpd/__init__.py |   24 +++++++++++++++++
 modules/dpd/browser.py  |   32 +++++++++++++++++++++++
 modules/dpd/favicon.png |  Bin 0 -> 508 bytes
 modules/dpd/module.py   |   49 +++++++++++++++++++++++++++++++++++
 modules/dpd/pages.py    |   65 +++++++++++++++++++++++++++++++++++++++++++++++
 modules/dpd/test.py     |   29 +++++++++++++++++++++
 6 files changed, 199 insertions(+)
 create mode 100644 modules/dpd/__init__.py
 create mode 100644 modules/dpd/browser.py
 create mode 100644 modules/dpd/favicon.png
 create mode 100644 modules/dpd/module.py
 create mode 100644 modules/dpd/pages.py
 create mode 100644 modules/dpd/test.py

diff --git a/modules/dpd/__init__.py b/modules/dpd/__init__.py
new file mode 100644
index 0000000..84d284f
--- /dev/null
+++ b/modules/dpd/__init__.py
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+
+# Copyright(C) 2015      Matthieu Weber
+#
+# This file is part of weboob.
+#
+# weboob is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# weboob is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with weboob. If not, see <http://www.gnu.org/licenses/>.
+
+
+from .module import DPDModule
+
+
+__all__ = ['DPDModule']
diff --git a/modules/dpd/browser.py b/modules/dpd/browser.py
new file mode 100644
index 0000000..0f8221e
--- /dev/null
+++ b/modules/dpd/browser.py
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+
+# Copyright(C) 2015      Matthieu Weber
+#
+# This file is part of weboob.
+#
+# weboob is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# weboob is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with weboob. If not, see <http://www.gnu.org/licenses/>.
+
+
+from weboob.browser import PagesBrowser, URL
+
+from .pages import SearchPage
+
+
+class DPDBrowser(PagesBrowser):
+    BASEURL = 'https://tracking.dpd.de/'
+
+    search_page = URL('/cgi-bin/simpleTracking.cgi\?parcelNr=(?P<id>.+)&locale=en_D2&type=1', SearchPage)
+
+    def get_tracking_info(self, _id):
+        return self.search_page.go(id=_id).get_info(_id)
diff --git a/modules/dpd/favicon.png b/modules/dpd/favicon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ad68b69b31edc02bb6bcf69326adbf4f14c1f111
GIT binary patch
literal 508
zcmeAS at N?(olHy`uVBq!ia0vp^4j|0I1SD0tpLGH$&H|6fVg?3oVGw3ym^DWND9B#o
z>FdgVpOsBWRLS0f1tcU{;u=xnoS&PUnpeW$T$GwvlA5AWo>`Ki;O^-g5Z=fq&cMJ}
z=IP=Xl5y|tth;>83OsH{Yu^7qb@%L at KhBNcnkP+JeO9O7+?p**)C40dl$X9|zooTc
z@%#NkCJyfE*$afNe3 at e}a!N at w<gIE<eBmY~(X;N_fr`AjY%&YYGY`mCEoGatNId(1
zX;mYennV4S112vddsR-~Nlv}~dd)^gb<2yt`<E)e6?0l{{UG=;U(t7-n8hdh-R8ah
zBv5_1;_=BhPI4xvB;>YV43si`E%u~wp48WDQFWtjZm<7LojGIS!r7ZwPT6p2!wmO8
z?#yZ1cTawmv`*}(6-V!?i$Xf*%o3vfo(s&hmUw9MA!cUubAelp%ff#t&p%NowdKiP
zzq&;{jRG79w39XEnOHl=ztG<?vCH1pAOCqNhPQ9F+3NJ(-5JL(``emZ#IgLz*z?v<
zW9}j6=EZ>v_Pd=u*EeltwV6c^YlYO>pCY$ZC3*Y&n5uZYwb-UHF32p{(wFl8(|1qj
uCk02Vb{?s!-n-=B!(TQEMGDJA-^zRJ-d!DZGd&a-O$?r{elF{r5}E*G^V1yw

literal 0
HcmV?d00001

diff --git a/modules/dpd/module.py b/modules/dpd/module.py
new file mode 100644
index 0000000..97b25b7
--- /dev/null
+++ b/modules/dpd/module.py
@@ -0,0 +1,49 @@
+# -*- coding: utf-8 -*-
+
+# Copyright(C) 2015      Matthieu Weber
+#
+# This file is part of weboob.
+#
+# weboob is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# weboob is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with weboob. If not, see <http://www.gnu.org/licenses/>.
+
+
+from weboob.tools.backend import Module
+from weboob.capabilities.parcel import CapParcel
+
+from .browser import DPDBrowser
+
+
+__all__ = ['DPDModule']
+
+
+class DPDModule(Module, CapParcel):
+    NAME = 'dpd'
+    DESCRIPTION = u'DPD website'
+    MAINTAINER = u'Matthieu Weber'
+    EMAIL = 'mweber+weboob at free.fr'
+    LICENSE = 'AGPLv3+'
+    VERSION = '1.1'
+
+    BROWSER = DPDBrowser
+
+    def get_parcel_tracking(self, id):
+        """
+        Get information abouut a parcel.
+
+        :param id: ID of the parcel
+        :type id: :class:`str`
+        :rtype: :class:`Parcel`
+        :raises: :class:`ParcelNotFound`
+        """
+        return self.browser.get_tracking_info(id)
diff --git a/modules/dpd/pages.py b/modules/dpd/pages.py
new file mode 100644
index 0000000..b830aad
--- /dev/null
+++ b/modules/dpd/pages.py
@@ -0,0 +1,65 @@
+# -*- coding: utf-8 -*-
+
+# Copyright(C) 2015      Matthieu Weber
+#
+# This file is part of weboob.
+#
+# weboob is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# weboob is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with weboob. If not, see <http://www.gnu.org/licenses/>.
+
+from dateutil.parser import parse as parse_date
+
+from weboob.browser.pages import JsonPage
+from weboob.capabilities.parcel import Parcel, Event, ParcelNotFound
+
+STATUSES = {
+    1: Parcel.STATUS_PLANNED,
+    2: Parcel.STATUS_IN_TRANSIT,
+    3: Parcel.STATUS_IN_TRANSIT,
+    4: Parcel.STATUS_IN_TRANSIT,
+    5: Parcel.STATUS_ARRIVED,
+}
+
+
+class SearchPage(JsonPage):
+    def build_doc(self, text):
+        from weboob.tools.json import json
+        return json.loads(text[1:-1])
+
+    def get_info(self, _id):
+        result_id = self.doc.get("TrackingStatusJSON", {}).get("shipmentInfo", {}).get("parcelNumber", None)
+        if not result_id:
+            raise ParcelNotFound("No such ID: %s" % _id)
+        if not _id.startswith(result_id):
+            raise ParcelNotFound("ID mismatch: expecting %s, got %s" % (_id, result_id))
+
+        p = Parcel(_id)
+        events = self.doc.get("TrackingStatusJSON", {}).get("statusInfos", [])
+        p.history = [self.build_event(i, data) for i, data in enumerate(events)]
+        p.status = self.guess_status(
+            self.doc.get("TrackingStatusJSON", {}).
+            get("shipmentInfo", {}).
+            get("deliveryStatus"))
+        p.info = p.history[-1].activity
+        return p
+
+    def guess_status(self, status_code):
+        return STATUSES.get(status_code, Parcel.STATUS_UNKNOWN)
+
+    def build_event(self, index, data):
+        event = Event(index)
+        date = "%s %s" % (data["date"], data["time"])
+        event.date = parse_date(date, dayfirst=False)
+        event.location = unicode(data["city"])
+        event.activity = unicode(", ".join([_["label"] for _ in data["contents"]]))
+        return event
diff --git a/modules/dpd/test.py b/modules/dpd/test.py
new file mode 100644
index 0000000..ffb24d8
--- /dev/null
+++ b/modules/dpd/test.py
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+
+# Copyright(C) 2015      Matthieu Weber
+#
+# This file is part of weboob.
+#
+# weboob is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# weboob is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with weboob. If not, see <http://www.gnu.org/licenses/>.
+
+
+from weboob.tools.test import BackendTest
+from weboob.capabilities.parcel import ParcelNotFound
+
+
+class DPDTest(BackendTest):
+    MODULE = 'dpd'
+
+    def test_dpd(self):
+        self.assertRaises(ParcelNotFound, self.backend.get_parcel_tracking, "foo")
-- 
1.7.10.4



More information about the weboob mailing list