diff --git a/modules/ups/__init__.py b/modules/ups/__init__.py
new file mode 100644
index 00000000..dd5379d5
--- /dev/null
+++ b/modules/ups/__init__.py
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+
+# Copyright(C) 2013 Romain Bignon
+#
+# 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 .
+
+
+from .backend import UpsBackend
+
+
+__all__ = ['UpsBackend']
diff --git a/modules/ups/backend.py b/modules/ups/backend.py
new file mode 100644
index 00000000..1f1c84dd
--- /dev/null
+++ b/modules/ups/backend.py
@@ -0,0 +1,41 @@
+# -*- coding: utf-8 -*-
+
+# Copyright(C) 2013 Romain Bignon
+#
+# 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 .
+
+
+from weboob.capabilities.tracking import ICapPackageTracking
+from weboob.tools.backend import BaseBackend
+
+from .browser import UpsBrowser
+
+
+__all__ = ['UpsBackend']
+
+
+class UpsBackend(BaseBackend, ICapPackageTracking):
+ NAME = 'ups'
+ DESCRIPTION = u'UPS website'
+ MAINTAINER = u'Romain Bignon'
+ EMAIL = 'romain@weboob.org'
+ VERSION = '0.g'
+
+ BROWSER = UpsBrowser
+
+ def track_package(self, id):
+ with self.browser:
+ return self.browser.get_tracking_info(id)
diff --git a/modules/ups/browser.py b/modules/ups/browser.py
new file mode 100644
index 00000000..752159b9
--- /dev/null
+++ b/modules/ups/browser.py
@@ -0,0 +1,49 @@
+# -*- coding: utf-8 -*-
+
+# Copyright(C) 2013 Romain Bignon
+#
+# 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 .
+
+import urllib
+
+from weboob.tools.browser import BaseBrowser
+
+from .pages import TrackPage
+
+
+__all__ = ['UpsBrowser']
+
+
+class UpsBrowser(BaseBrowser):
+ PROTOCOL = 'http'
+ DOMAIN = 'wwwapps.ups.com'
+ ENCODING = None
+
+ PAGES = {
+ 'http://wwwapps.ups.com/WebTracking/track': TrackPage,
+ }
+
+ def get_tracking_info(self, _id):
+ data = {'HTMLVersion': '5.0',
+ 'USER_HISTORY_LIST': '',
+ 'loc': 'en_US',
+ 'track.x': 'Track',
+ 'trackNums': _id.encode('utf-8'),
+ }
+ self.location('http://wwwapps.ups.com/WebTracking/track', urllib.urlencode(data))
+ assert self.is_on_page(TrackPage)
+
+ return self.page.get_info(_id)
diff --git a/modules/ups/pages.py b/modules/ups/pages.py
new file mode 100644
index 00000000..c8fd6503
--- /dev/null
+++ b/modules/ups/pages.py
@@ -0,0 +1,57 @@
+# -*- coding: utf-8 -*-
+
+# Copyright(C) 2013 Romain Bignon
+#
+# 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 .
+
+
+import re
+from dateutil.parser import parse as parse_date
+
+from weboob.capabilities.tracking import Package, Location
+from weboob.tools.browser import BasePage
+
+
+__all__ = ['TrackPage']
+
+
+class TrackPage(BasePage):
+ def get_info(self, id):
+ p = Package(id)
+ for dl in self.document.xpath('//dl'):
+ dt = dl.find('dt')
+ dd = dl.find('dd')
+ if dt is None or dd is None:
+ continue
+ label = self.parser.tocleanstring(dt)
+ if label == 'Scheduled Delivery:' or label == 'Delivered On':
+ m = re.search('(\d+/\d+/\d+)', dd.text)
+ if m:
+ p.arrival = parse_date(m.group(1))
+
+ p.history = []
+ for i, tr in enumerate(self.document.xpath('//table[@class="dataTable"]//tr')):
+ tds = tr.findall('td')
+ if len(tds) < 4:
+ continue
+
+ loc = Location(i)
+ loc.name = self.parser.tocleanstring(tds[0])
+ loc.activity = self.parser.tocleanstring(tds[-1])
+ loc.date = parse_date('%s %s' % (tds[1].text, tds[2].text))
+ p.history.append(loc)
+
+ return p
diff --git a/modules/ups/test.py b/modules/ups/test.py
new file mode 100644
index 00000000..9540e4e0
--- /dev/null
+++ b/modules/ups/test.py
@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+
+# Copyright(C) 2013 Romain Bignon
+#
+# 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 .
+
+
+from weboob.tools.test import BackendTest
+
+
+class UpsTest(BackendTest):
+ BACKEND = 'ups'
+
+ def test_ups(self):
+ raise NotImplementedError()