Initial poivy import

This commit is contained in:
Florent 2013-09-12 13:20:28 +02:00
commit 4ff5007f36
4 changed files with 284 additions and 0 deletions

23
modules/poivy/__init__.py Normal file
View file

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
# Copyright(C) 2013 Florent Fourcot
#
# 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 .backend import PoivyBackend
__all__ = ['PoivyBackend']

80
modules/poivy/backend.py Normal file
View file

@ -0,0 +1,80 @@
# -*- coding: utf-8 -*-
# Copyright(C) 2013 Florent Fourcot
#
# 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.capabilities.bill import ICapBill, Subscription, SubscriptionNotFound, Detail
from weboob.capabilities.base import Currency
from weboob.tools.backend import BaseBackend, BackendConfig
from weboob.tools.value import ValueBackendPassword
from .browser import PoivyBrowser
__all__ = ['PoivyBackend']
class PoivyBackend(BaseBackend, ICapBill):
NAME = 'poivy'
MAINTAINER = u'Florent Fourcot'
EMAIL = 'weboob@flo.fourcot.fr'
VERSION = '0.h'
LICENSE = 'AGPLv3+'
DESCRIPTION = 'Poivy website'
CONFIG = BackendConfig(ValueBackendPassword('login',
label='login',
masked=False),
ValueBackendPassword('password',
label='Password')
)
BROWSER = PoivyBrowser
def create_default_browser(self):
return self.create_browser(self.config['login'].get(),
self.config['password'].get())
def iter_subscription(self):
for subscription in self.browser.get_subscription_list():
yield subscription
def get_subscription(self, _id):
with self.browser:
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
# No details on the website
def get_details(self, subscription):
raise NotImplementedError()
def get_balance(self, subscription):
if not isinstance(subscription, Subscription):
subscription = self.get_subscription(subscription)
balance = Detail()
balance.id = "%s-balance" % subscription.id
balance.price = subscription._balance
balance.label = u"Balance %s" % subscription.id
balance.currency = Currency.CUR_EUR
return balance

90
modules/poivy/browser.py Normal file
View file

@ -0,0 +1,90 @@
# -*- coding: utf-8 -*-
# Copyright(C) 2013 Fourcot Florent
#
# 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.browser import BaseBrowser, BrowserIncorrectPassword
from .pages import HomePage, LoginPage, HistoryPage, BillsPage
__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
}
def __init__(self, *args, **kwargs):
BaseBrowser.__init__(self, *args, **kwargs)
def home(self):
self.location('/login')
def is_logged(self):
return not self.is_on_page(LoginPage)
def login(self):
assert isinstance(self.username, basestring)
assert isinstance(self.password, basestring)
if not self.is_on_page(LoginPage):
self.location('/login')
self.page.login(self.username, self.password)
if self.is_on_page(LoginPage):
raise BrowserIncorrectPassword()
def get_subscription_list(self):
if not self.is_on_page(HomePage):
self.location('/buy_credit')
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:
return a
return None
def get_history(self):
if not self.is_on_page(HistoryPage):
self.location('/recent_calls')
return self.page.get_calls()
def iter_bills(self, parentid):
if not self.is_on_page(BillsPage):
self.location('/purchases')
return self.page.date_bills()
def get_bill(self, id):
assert isinstance(id, basestring)
l = self.iter_bills(id)
for a in l:
if a.id == id:
return a

91
modules/poivy/pages.py Normal file
View file

@ -0,0 +1,91 @@
# -*- coding: utf-8 -*-
# Copyright(C) 2013 Florent Fourcot
#
# 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.browser import BasePage
from weboob.capabilities.base import Currency
from weboob.capabilities.bill import Subscription, Detail
from decimal import Decimal
from datetime import datetime, date, time
import re
__all__ = ['LoginPage', 'HomePage', 'HistoryPage', 'BillsPage']
class LoginPage(BasePage):
def on_loaded(self):
pass
def login(self, login, password):
# Form without name
self.browser.select_form(nr=1)
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.submit(nologin=True)
class HomePage(BasePage):
def on_loaded(self):
pass
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()
subscription = Subscription(owner)
subscription.label = u"Poivy - %s - %s" % (owner, credit)
subscription._balance = Decimal(re.sub(u'[^\d\-\.]', '', credit))
return [subscription]
class HistoryPage(BasePage):
months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
def on_loaded(self):
pass
def get_calls(self):
table = self.document.xpath('//table/tbody')[0]
for tr in table.xpath('tr'):
tds = tr.xpath('td')
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)
detail.price = Decimal(price)
detail.currency = Currency.CUR_EUR
yield detail
class BillsPage(BasePage):
def on_loaded(self):
pass