diff --git a/modules/poivy/__init__.py b/modules/poivy/__init__.py
index 9fccbea1..ab467ddb 100644
--- a/modules/poivy/__init__.py
+++ b/modules/poivy/__init__.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# Copyright(C) 2013 Florent Fourcot
+# Copyright(C) 2013-2014 Florent Fourcot
#
# This file is part of weboob.
#
diff --git a/modules/poivy/backend.py b/modules/poivy/backend.py
index fe376441..fd618948 100644
--- a/modules/poivy/backend.py
+++ b/modules/poivy/backend.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# Copyright(C) 2013 Florent Fourcot
+# Copyright(C) 2013-2014 Florent Fourcot
#
# This file is part of weboob.
#
@@ -52,17 +52,14 @@ class PoivyBackend(BaseBackend, ICapBill):
yield subscription
def get_subscription(self, _id):
- with self.browser:
- subscription = self.browser.get_subscription(_id)
+ subscription = self.browser.get_subscription(_id)
if subscription:
return subscription
else:
raise SubscriptionNotFound()
def iter_bills_history(self, subscription):
- with self.browser:
- for history in self.browser.get_history():
- yield history
+ return self.browser.get_history()
# No details on the website
def get_details(self, subscription):
@@ -75,5 +72,5 @@ class PoivyBackend(BaseBackend, ICapBill):
balance.id = "%s-balance" % subscription.id
balance.price = subscription._balance
balance.label = u"Balance %s" % subscription.id
- balance.currency = 'EUR'
+ balance.currency = u'EUR'
return balance
diff --git a/modules/poivy/browser.py b/modules/poivy/browser.py
index a0767260..339a5534 100644
--- a/modules/poivy/browser.py
+++ b/modules/poivy/browser.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# Copyright(C) 2013 Fourcot Florent
+# Copyright(C) 2013-2014 Fourcot Florent
#
# This file is part of weboob.
#
@@ -18,75 +18,55 @@
# along with weboob. If not, see .
-from weboob.tools.browser import BaseBrowser, BrowserIncorrectPassword, BrowserBanned
+from weboob.tools.browser2 import LoginBrowser, URL, need_login
from .pages import HomePage, LoginPage, HistoryPage, BillsPage, ErrorPage
__all__ = ['PoivyBrowser']
-class PoivyBrowser(BaseBrowser):
- DOMAIN = 'www.poivy.com'
- PROTOCOL = 'https'
- ENCODING = None # refer to the HTML encoding
- PAGES = {'.*login': LoginPage,
- '.*buy_credit.*': HomePage,
- '.*/recent_calls': HistoryPage,
- '.*purchases': BillsPage,
- '.*warning.*': ErrorPage
- }
+class PoivyBrowser(LoginBrowser):
+ BASEURL = 'https://www.poivy.com'
- def __init__(self, *args, **kwargs):
- BaseBrowser.__init__(self, *args, **kwargs)
+ login = URL('/login', LoginPage)
+ homepage = URL('/buy_credit.*', HomePage)
+ history = URL('/recent_calls', HistoryPage)
+ bills = URL('/purchases', BillsPage)
+ warning = URL('/warning.*', ErrorPage)
- def home(self):
- self.location('/login')
-
- def is_logged(self):
- return not self.is_on_page(LoginPage)
-
- def login(self):
+ def do_login(self):
assert isinstance(self.username, basestring)
assert isinstance(self.password, basestring)
- if not self.is_on_page(LoginPage):
- self.location('/login')
+ self.login.stay_or_go()
if not self.page.login(self.username, self.password):
raise BrowserBanned('Too many connections from you IP address: captcha enabled')
- if self.is_on_page(LoginPage) or self.is_on_page(ErrorPage):
+ if self.login.is_here() or self.warning.is_here():
raise BrowserIncorrectPassword()
+ @need_login
def get_subscription_list(self):
- if not self.is_on_page(HomePage):
- self.location('/buy_credit')
+ return self.homepage.stay_or_go().get_list()
- return self.page.get_list()
-
- def get_subscription(self, id):
- assert isinstance(id, basestring)
-
- l = self.get_subscription_list()
- for a in l:
- if a.id == id:
+ def _find_id_list(self, mylist, _id):
+ for a in mylist:
+ if a.id == _id:
return a
-
return None
+ @need_login
+ def get_subscription(self, _id):
+ return self._find_id_list(self.get_subscription_list(), _id)
+
+ @need_login
def get_history(self):
- if not self.is_on_page(HistoryPage):
- self.location('/recent_calls')
- return self.page.get_calls()
+ return self.history.stay_or_go().get_calls()
+ @need_login
def iter_bills(self, parentid):
- if not self.is_on_page(BillsPage):
- self.location('/purchases')
- return self.page.date_bills()
+ return self.bills.stay_or_go().get_bills()
+ @need_login
def get_bill(self, id):
- assert isinstance(id, basestring)
-
- l = self.iter_bills(id)
- for a in l:
- if a.id == id:
- return a
+ return self._find_id_list(self.iter_bills(), _id)
diff --git a/modules/poivy/pages.py b/modules/poivy/pages.py
index 2e916bb5..21d0b916 100644
--- a/modules/poivy/pages.py
+++ b/modules/poivy/pages.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# Copyright(C) 2013 Florent Fourcot
+# Copyright(C) 2013-2014 Florent Fourcot
#
# This file is part of weboob.
#
@@ -17,7 +17,8 @@
# You should have received a copy of the GNU Affero General Public License
# along with weboob. If not, see .
-from weboob.tools.browser import BasePage
+from weboob.tools.browser2.page import HTMLPage, LoggedPage, method, ListElement, ItemElement
+from weboob.tools.browser2.filters import Env, CleanText, CleanDecimal, Field, Attr, Filter, Time, Date
from weboob.capabilities.bill import Subscription, Detail
from decimal import Decimal, InvalidOperation
from datetime import datetime, date, time
@@ -27,15 +28,11 @@ import re
__all__ = ['LoginPage', 'HomePage', 'HistoryPage', 'BillsPage', 'ErrorPage']
-class ErrorPage(BasePage):
- def on_loaded(self):
+class ErrorPage(HTMLPage):
pass
-class LoginPage(BasePage):
- def on_loaded(self):
- pass
-
+class LoginPage(HTMLPage):
def _predicate_form(self, form):
try:
return form.attrs['class'] == "form-detail"
@@ -43,73 +40,78 @@ class LoginPage(BasePage):
return False
def login(self, login, password):
- captcha = self.document.xpath('//label[@class="label_captcha_input"]')
+ captcha = self.doc.xpath('//label[@class="label_captcha_input"]')
if len(captcha) > 0:
return False
- form_newsletter = self.document.xpath('//form[@id="newsletter_form"]')[0]
- hidden_input = form_newsletter.xpath('./input[@type="hidden"]')[0]
- hidden_id = hidden_input.attrib["value"]
- hidden_name = hidden_input.attrib["name"]
+ xpath_hidden = '//form[@id="newsletter_form"]/input[@type="hidden"]'
+ hidden_id = Attr(xpath_hidden, "value")(self.doc)
+ hidden_name = Attr(xpath_hidden, "name")(self.doc)
- # Form without name
- self.browser.select_form(predicate=self._predicate_form)
- self.browser.set_all_readonly(False)
- self.browser['login[username]'] = login.encode('iso-8859-1')
- self.browser['login[password]'] = password.encode('iso-8859-1')
- self.browser[hidden_name] = hidden_id
- self.browser.submit(nologin=True)
+ form = self.get_form(xpath="//form[@class='form-detail']")
+ form['login[username]'] = login.encode('iso-8859-1')
+ form['login[password]'] = password.encode('iso-8859-1')
+ form[hidden_name] = hidden_id
+ form.submit()
return True
-class HomePage(BasePage):
- def on_loaded(self):
- pass
+class Insert2(Filter):
+ """
+ Insert two Filters inside a string
+ """
+ def __init__(self, selector, selector2, string):
+ super(Insert2, self).__init__(selector)
+ self.string = string
+ self.selector2 = selector2
- def get_list(self):
- spanabo = self.document.xpath('//span[@class="welcome-text"]/b')[0]
- owner = spanabo.text_content()
- credit = self.document.xpath('//span[@class="balance"]')[0].text_content()
+ def __call__(self, item):
+ value = self.selector(item)
+ value2 = self.selector2(item)
+ return self.filter(value, value2)
- subscription = Subscription(owner)
- subscription.label = u"Poivy - %s - %s" % (owner, credit)
- subscription._balance = Decimal(re.sub(u'[^\d\-\.]', '', credit))
-
- return [subscription]
+ def filter(self, txt, txt2):
+ return self.string % (txt, txt2)
-class HistoryPage(BasePage):
- months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
+class HomePage(LoggedPage, HTMLPage):
- def on_loaded(self):
- pass
+ @method
+ class get_list(ListElement):
+ item_xpath = '.'
- def get_calls(self):
- table = self.document.xpath('//table/tbody')[0]
- for tr in table.xpath('tr'):
- tds = tr.xpath('td')
+ class item(ItemElement):
+ klass = Subscription
- rawdate = tds[0].text_content()
- splitdate = rawdate.split('-')
- month_no = self.months.index(splitdate[1]) + 1
- mydate = date(int(splitdate[2]), month_no, int(splitdate[0]))
-
- rawtime = tds[1].text_content()
- mytime = time(*[int(x) for x in rawtime.split(":")])
-
- price = re.sub(u'[^\d\-\.]', '', tds[6].text)
- detail = Detail()
- detail.datetime = datetime.combine(mydate, mytime)
- detail.label = u"%s from %s to %s - %s" % (tds[2].text, tds[3].text, tds[4].text, tds[5].text)
- try:
- detail.price = Decimal(price)
- except InvalidOperation:
- detail.price = Decimal(0) # free calls
- detail.currency = 'EUR'
-
- yield detail
+ obj_id = CleanText('//span[@class="welcome-text"]/b')
+ obj__balance = CleanDecimal(CleanText('//span[@class="balance"]'), replace_dots=False)
+ obj_label = Insert2(Field('id'), Field('_balance'), u"Poivy - %s - %s €")
-class BillsPage(BasePage):
- def on_loaded(self):
- pass
+class HistoryPage(LoggedPage, HTMLPage):
+
+ @method
+ class get_calls(ListElement):
+ item_xpath = '//table/tbody/tr'
+
+ class item(ItemElement):
+ klass = Detail
+
+ obj_datetime = Env('datetime')
+ obj_price = CleanDecimal('td[7]', replace_dots=False)
+ obj_currency = u'EUR'
+ obj_label = Env('label')
+
+ def parse(self, el):
+ tds = el.xpath('td')
+
+ mydate = Date(CleanText('td[1]'))(el)
+ mytime = Time(CleanText('td[2]'))(el)
+
+ self.env['datetime'] = datetime.combine(mydate, mytime)
+ self.env['label'] = u"%s from %s to %s - %s" % (tds[2].text, tds[3].text, tds[4].text, tds[5].text)
+
+
+#TODO
+class BillsPage(HTMLPage):
+ pass