Convert poivy to Browser2

This commit is contained in:
Florent 2014-03-20 15:07:10 +01:00
commit 8ec4f24c9a
4 changed files with 93 additions and 114 deletions

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright(C) 2013 Florent Fourcot
# Copyright(C) 2013-2014 Florent Fourcot
#
# This file is part of weboob.
#

View file

@ -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

View file

@ -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 <http://www.gnu.org/licenses/>.
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)

View file

@ -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 <http://www.gnu.org/licenses/>.
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