From 99a2e554e8dfbb6579228dba44187a0cc3cb1f54 Mon Sep 17 00:00:00 2001 From: Florent Date: Wed, 14 Mar 2012 00:02:07 +0100 Subject: [PATCH] Download bill on freemobile --- modules/freemobile/backend.py | 18 +++++++++---- modules/freemobile/browser.py | 18 ++++++++++++- modules/freemobile/pages/history.py | 5 +++- weboob/applications/boobill/boobill.py | 37 +++++++++++++++++++++++++- weboob/capabilities/bill.py | 13 ++++++++- 5 files changed, 82 insertions(+), 9 deletions(-) diff --git a/modules/freemobile/backend.py b/modules/freemobile/backend.py index 20f8fc4d..9bd359ca 100644 --- a/modules/freemobile/backend.py +++ b/modules/freemobile/backend.py @@ -19,7 +19,7 @@ from __future__ import with_statement -from weboob.capabilities.bill import ICapBill, SubscriptionNotFound +from weboob.capabilities.bill import ICapBill, SubscriptionNotFound, BillNotFound from weboob.tools.backend import BaseBackend, BackendConfig from weboob.tools.value import ValueBackendPassword @@ -68,14 +68,18 @@ class FreeMobileBackend(BaseBackend, ICapBill): for history in self.browser.get_history(): yield history - def get_bill(self, subscription, id): - raise NotImplementedError() + def get_bill(self, id): + with self.browser: + bill = self.browser.get_bill(id) + if bill: + return bill + else: + raise BillNotFound() def iter_bills(self, subscription): with self.browser: sub = self.get_subscription(subscription) - for bill in self.browser.iter_bills(): - bill.idparent = sub.id + for bill in self.browser.iter_bills(sub.id): yield bill # The subscription is actually useless, but maybe for the futur... @@ -83,3 +87,7 @@ class FreeMobileBackend(BaseBackend, ICapBill): with self.browser: for detail in self.browser.get_details(): yield detail + + def download_bill(self, id): + with self.browser: + return self.browser.download_bill(id) diff --git a/modules/freemobile/browser.py b/modules/freemobile/browser.py index 873c641e..db0df2ad 100644 --- a/modules/freemobile/browser.py +++ b/modules/freemobile/browser.py @@ -85,7 +85,23 @@ class Freemobile(BaseBrowser): self.location('/moncompte/index.php?page=suiviconso') return self.page.get_details() - def iter_bills(self): + def iter_bills(self, parentid): if not self.is_on_page(DetailsPage): self.location('/moncompte/index.php?page=suiviconso') return self.page.date_bills() + + def get_bill(self, id): + assert isinstance(id, basestring) + + if not self.is_on_page(DetailsPage): + self.location('/moncompte/index.php?page=suiviconso') + l = self.page.date_bills() + for a in l: + if a.id == id: + return a + + def download_bill(self, id): + assert isinstance(id, basestring) + date = id.split('.')[1] + + return self.readurl('/moncompte/ajax.php?page=facture&mode=html&date=' + date) diff --git a/modules/freemobile/pages/history.py b/modules/freemobile/pages/history.py index 1e3c2c29..519f5b3c 100644 --- a/modules/freemobile/pages/history.py +++ b/modules/freemobile/pages/history.py @@ -41,6 +41,8 @@ class DetailsPage(BasePage): def on_loaded(self): + num = self.document.xpath('//div[@class="infosLigneDetail"]')[0].text + num = num.split("-")[2].strip() divnat = self.document.xpath('//div[@class="national"]')[0] divs = divnat.xpath('div[@class="detail"]') divvoice = divs.pop(0) @@ -62,6 +64,7 @@ class DetailsPage(BasePage): mydate = trbill.find('td/input').attrib['onclick'].split("'")[1] bill = Bill() bill.label = mydate + bill.id = num + "." + mydate bill.date = date(int(mydate[0:4]), int(mydate[4:6]), int(mydate[6:8])) bill.format = 'html' self.datebills.append(bill) @@ -78,7 +81,7 @@ class DetailsPage(BasePage): self.details.append(detail) - def get_details(self): + def get_details(self, parentid): return self.details def date_bills(self): diff --git a/weboob/applications/boobill/boobill.py b/weboob/applications/boobill/boobill.py index aec315cd..1dea165b 100644 --- a/weboob/applications/boobill/boobill.py +++ b/weboob/applications/boobill/boobill.py @@ -129,7 +129,8 @@ class Boobill(ReplApplication): """ bills Id - Get the list of bills documents + Get the list of bills documents for subscription + id is the identifier of the backend """ id, backend_name = self.parse_id(id) @@ -144,3 +145,37 @@ class Boobill(ReplApplication): for backend, date in self.do(do, backends=names): self.format(date) self.flush() + + def do_download(self, line): + """ + download Id [FILENAME] + + download the bill + id is the identifier of the bill (hint: try bills command) + FILENAME is where to write the file. If FILENAME is '-', + the file is written to stdout. + """ + id, dest = self.parse_command_args(line, 2, 1) + id, backend_name = self.parse_id(id) + if not id: + print >>sys.stderr, 'Error: please give an subscription ID (hint: use subscriptions command)' + return 2 + names = (backend_name,) if backend_name is not None else None + + if dest is None: + dest = id + + for backend, buf in self.do('download_bill', id, backends=names): + if buf: + if dest == "-": + print buf + else: + try: + with open(dest, 'w') as f: + f.write(buf) + except IOError, e: + print >>sys.stderr, 'Unable to write bill in "%s": %s' % (dest, e) + return 1 + return + + diff --git a/weboob/capabilities/bill.py b/weboob/capabilities/bill.py index cb1ed357..98918ebf 100644 --- a/weboob/capabilities/bill.py +++ b/weboob/capabilities/bill.py @@ -31,6 +31,14 @@ class SubscriptionNotFound(Exception): msg = 'Subscription not found' Exception.__init__(self, msg) + +class BillNotFound(Exception): + def __init__(self, msg=None): + if msg is None: + msg = 'Bill not found' + Exception.__init__(self, msg) + + class Detail(CapBaseObject): def __init__(self): CapBaseObject.__init__(self, 0) @@ -69,7 +77,10 @@ class ICapBill(ICapCollection): def iter_history(self, subscription): raise NotImplementedError() - def get_bill(self, subscription, id): + def get_bill(self, id): + raise NotImplementedError() + + def download_bill(self, id): raise NotImplementedError() def iter_bills(self, subscription):