[Ameli]&[Amelipro] Update after sites changes, and upgrade to new browser

This commit is contained in:
Kitof 2013-12-17 22:22:52 +01:00 committed by Romain Bignon
commit 10c5abc3d4
7 changed files with 251 additions and 229 deletions

90
modules/amelipro/browser.py Normal file → Executable file
View file

@ -18,65 +18,60 @@
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
import urllib
from weboob.deprecated.browser import Browser, BrowserIncorrectPassword
from weboob.browser import LoginBrowser, URL, need_login
from weboob.exceptions import BrowserIncorrectPassword
from weboob.capabilities.bill import Detail
from decimal import Decimal
from .pages import LoginPage, HomePage, AccountPage, HistoryPage, BillsPage
from .pages import LoginPage, HomePage, AccountPage, HistoryPage, BillsPage, SearchPage
__all__ = ['AmeliProBrowser']
class AmeliProBrowser(LoginBrowser):
BASEURL = 'https://espacepro.ameli.fr:443'
class AmeliProBrowser(Browser):
PROTOCOL = 'https'
DOMAIN = 'espacepro.ameli.fr'
ENCODING = None
loginp = URL('/PortailPS/appmanager/portailps/professionnelsante\?_nfpb=true&_pageLabel=vp_login_page', LoginPage)
homep = URL('/PortailPS/appmanager/portailps/professionnelsante\?_nfpb=true&_pageLabel=vp_accueil_page', HomePage)
accountp = URL('/PortailPS/appmanager/portailps/professionnelsante\?_nfpb=true&_pageLabel=vp_coordonnees_infos_perso_page', AccountPage)
billsp = URL('/PortailPS/appmanager/portailps/professionnelsante\?_nfpb=true&_pageLabel=vp_releves_mensuels_page', BillsPage)
searchp = URL('/PortailPS/appmanager/portailps/professionnelsante\?_nfpb=true&_pageLabel=vp_recherche_par_date_paiements_page', SearchPage)
historyp = URL('/PortailPS/appmanager/portailps/professionnelsante\?_nfpb=true&_windowLabel=vp_recherche_paiement_tiers_payant_portlet_1&vp_recherche_paiement_tiers_payant_portlet_1_actionOverride=%2Fportlets%2Fpaiements%2Frecherche&_pageLabel=vp_recherche_par_date_paiements_page', HistoryPage)
PAGES = {'.*_pageLabel=vp_login_page.*': LoginPage,
'.*_pageLabel=vp_accueil.*': HomePage,
'.*_pageLabel=vp_coordonnees_infos_perso_page.*': AccountPage,
'.*_pageLabel=vp_recherche_par_date_paiements_page.*': HistoryPage,
'.*_pageLabel=vp_releves_mensuels_page.*': BillsPage,
}
logged = False
loginp = '/PortailPS/appmanager/portailps/professionnelsante?_nfpb=true&_pageLabel=vp_login_page'
homep = '/PortailPS/appmanager/portailps/professionnelsante?_nfpb=true&_pageLabel=vp_accueil_book'
accountp = '/PortailPS/appmanager/portailps/professionnelsante?_nfpb=true&_pageLabel=vp_coordonnees_infos_perso_page'
billsp = '/PortailPS/appmanager/portailps/professionnelsante?_nfpb=true&_pageLabel=vp_releves_mensuels_page'
searchp = '/PortailPS/appmanager/portailps/professionnelsante?_nfpb=true&_pageLabel=vp_recherche_par_date_paiements_page'
historyp = '/PortailPS/appmanager/portailps/professionnelsante?_nfpb=true&_windowLabel=vp_recherche_paiement_tiers_payant_portlet_1&vp_recherche_paiement_tiers_payant_portlet_1_actionOverride=%2Fportlets%2Fpaiements%2Frecherche&_pageLabel=vp_recherche_par_date_paiements_page'
def do_login(self):
self.logger.debug('call Browser.do_login')
if self.logged:
return True
def home(self):
self.location(self.homep)
self.loginp.stay_or_go()
if self.homep.is_here():
self.logged = True
return True
def is_logged(self):
if self.is_on_page(LoginPage):
return False
return True
def login(self):
assert isinstance(self.username, basestring)
assert isinstance(self.password, basestring)
if not self.is_on_page(LoginPage):
self.location(self.loginp)
self.page.login(self.username, self.password)
if self.is_on_page(LoginPage):
if not self.homep.is_here():
raise BrowserIncorrectPassword()
def get_subscription_list(self):
if not self.is_on_page(AccountPage):
self.location(self.accountp)
return self.page.get_subscription_list()
self.logged = True
@need_login
def get_subscription_list(self):
self.logger.debug('call Browser.get_subscription_list')
self.accountp.stay_or_go()
return self.page.iter_subscription_list()
@need_login
def get_subscription(self, id):
assert isinstance(id, basestring)
return self.get_subscription_list()
@need_login
def iter_history(self, subscription):
if not self.is_on_page(HistoryPage):
self.location(self.searchp)
self.searchp.stay_or_go()
date_deb = self.page.document.xpath('//input[@name="vp_recherche_paiement_tiers_payant_portlet_1dateDebutRecherche"]')[0].value
date_fin = self.page.document.xpath('//input[@name="vp_recherche_paiement_tiers_payant_portlet_1dateFinRecherche"]')[0].value
date_deb = self.page.doc.xpath('//input[@name="vp_recherche_paiement_tiers_payant_portlet_1dateDebutRecherche"]')[0].value
date_fin = self.page.doc.xpath('//input[@name="vp_recherche_paiement_tiers_payant_portlet_1dateFinRecherche"]')[0].value
data = {'vp_recherche_paiement_tiers_payant_portlet_1dateDebutRecherche': date_deb,
'vp_recherche_paiement_tiers_payant_portlet_1dateFinRecherche': date_fin,
@ -85,9 +80,12 @@ class AmeliProBrowser(Browser):
'vp_recherche_paiement_tiers_payant_portlet_1codeRegime': '01',
}
self.location(self.historyp, urllib.urlencode(data))
return self.page.iter_history()
self.session.headers.update({'Content-Type': 'application/x-www-form-urlencoded'})
self.historyp.go(data=urllib.urlencode(data))
if self.historyp.is_here():
return self.page.iter_history()
@need_login
def get_details(self, sub):
det = Detail()
det.id = sub.id
@ -96,14 +94,20 @@ class AmeliProBrowser(Browser):
det.price = Decimal('0.0')
return det
@need_login
def iter_bills(self):
if not self.is_on_page(BillsPage):
self.location(self.billsp)
self.billsp.stay_or_go()
return self.page.iter_bills()
@need_login
def get_bill(self, id):
assert isinstance(id, basestring)
for b in self.iter_bills():
if id == b.id:
return b
return None
@need_login
def download_bill(self, bill):
request = self.open(bill._url, data=bill._data, stream=True)
return request.content

22
modules/amelipro/module.py Normal file → Executable file
View file

@ -17,7 +17,6 @@
# You should have received a copy of the GNU Affero General Public License
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
import urllib
from weboob.capabilities.bill import CapBill, SubscriptionNotFound, BillNotFound, Subscription, Bill
from weboob.tools.backend import Module, BackendConfig
from weboob.tools.value import ValueBackendPassword
@ -25,7 +24,6 @@ from .browser import AmeliProBrowser
__all__ = ['AmeliProModule']
class AmeliProModule(Module, CapBill):
NAME = 'amelipro'
DESCRIPTION = u'Ameli website: French Health Insurance for Professionals'
@ -41,9 +39,9 @@ class AmeliProModule(Module, CapBill):
label='Password',
masked=True)
)
BROWSER = AmeliProBrowser
def create_default_browser(self):
self.logger.settings['save_responses'] = False # Set to True to help debugging
return self.create_browser(self.config['login'].get(),
self.config['password'].get())
@ -53,8 +51,7 @@ class AmeliProModule(Module, CapBill):
def get_subscription(self, _id):
if not _id.isdigit():
raise SubscriptionNotFound()
with self.browser:
subscription = self.browser.get_subscription(_id)
subscription = self.browser.get_subscription(_id)
if not subscription:
raise SubscriptionNotFound()
else:
@ -63,24 +60,20 @@ class AmeliProModule(Module, CapBill):
def iter_bills_history(self, subscription):
if not isinstance(subscription, Subscription):
subscription = self.get_subscription(subscription)
with self.browser:
return self.browser.iter_history(subscription)
return self.browser.iter_history(subscription)
def get_details(self, subscription):
if not isinstance(subscription, Subscription):
subscription = self.get_subscription(subscription)
with self.browser:
return self.browser.get_details(subscription)
return self.browser.get_details(subscription)
def iter_bills(self, subscription):
if not isinstance(subscription, Subscription):
subscription = self.get_subscription(subscription)
with self.browser:
return self.browser.iter_bills()
return self.browser.iter_bills()
def get_bill(self, id):
with self.browser:
bill = self.browser.get_bill(id)
bill = self.browser.get_bill(id)
if not bill:
raise BillNotFound()
else:
@ -89,5 +82,4 @@ class AmeliProModule(Module, CapBill):
def download_bill(self, bill):
if not isinstance(bill, Bill):
bill = self.get_bill(bill)
with self.browser:
return self.browser.readurl(bill._url, urllib.urlencode(bill._args))
return self.browser.download_bill(bill)

98
modules/amelipro/pages.py Normal file → Executable file
View file

@ -19,10 +19,9 @@
from datetime import datetime
from decimal import Decimal
import re
import urllib
from weboob.deprecated.browser import Page
from decimal import Decimal
from weboob.browser.pages import HTMLPage
from weboob.capabilities.bill import Subscription, Detail, Bill
@ -30,25 +29,25 @@ from weboob.capabilities.bill import Subscription, Detail, Bill
FRENCH_MONTHS = [u'janvier', u'février', u'mars', u'avril', u'mai', u'juin', u'juillet', u'août', u'septembre', u'octobre', u'novembre', u'décembre']
class LoginPage(Page):
class LoginPage(HTMLPage):
def login(self, login, password):
self.browser.select_form('connexionCompteForm')
self.browser["vp_connexion_portlet_1numPS"] = login.encode('utf8')
self.browser["vp_connexion_portlet_1password"] = password.encode('utf8')
self.browser.submit()
class HomePage(Page):
form = self.get_form('//form[@name="connexionCompteForm"]')
form['vp_connexion_portlet_1numPS'] = login.encode('utf8')
form['vp_connexion_portlet_1password'] = password.encode('utf8')
form.submit()
class HomePage(HTMLPage):
def on_loaded(self):
pass
class SearchPage(HTMLPage):
def on_loaded(self):
pass
class AccountPage(Page):
def get_subscription_list(self):
ident = self.document.xpath('//div[@id="identification"]')[0]
prof = self.document.xpath('//div[@id="profession"]')[0]
class AccountPage(HTMLPage):
def iter_subscription_list(self):
ident = self.doc.xpath('//div[@id="identification"]')[0]
prof = self.doc.xpath('//div[@id="profession"]')[0]
name = ident.xpath('//p/b')[0].text.replace('&nbsp;', ' ').strip()
number = ident.xpath('//p')[1].text.replace('Cabinet', '').strip()
label = prof.xpath('//div[@class="zoneTexte"]')[0].text.strip()
@ -59,34 +58,38 @@ class AccountPage(Page):
return sub
class HistoryPage(Page):
class HistoryPage(HTMLPage):
def iter_history(self):
table = self.document.xpath('//table[contains(concat(" ", @class, " "), " cTableauTriable ")]')[0].xpath('.//tr')
for tr in table:
list_a = tr.xpath('.//a')
if len(list_a) == 0:
continue
date = tr.xpath('.//td')[0].text.strip()
lot = list_a[0].text
factures = tr.xpath('.//div[@class="cAlignGauche"]/a')
factures_lbl = ''
for a in factures:
factures_lbl = factures_lbl + a.text + ' '
montant = tr.xpath('.//div[@class="cAlignDroite"]')[0].text.strip()
det = Detail()
det.id = lot
det.label = lot
det.infos = factures_lbl
det.datetime = datetime.strptime(date, "%d/%m/%Y").date()
det.price = Decimal(montant.replace(',', '.'))
yield det
tables = self.doc.xpath('//table[contains(concat(" ", @class, " "), " cTableauTriable ")]')
if len(tables) > 0:
lines = tables[0].xpath('.//tr')
sno = 0
for tr in lines:
list_a = tr.xpath('.//a')
if len(list_a) == 0:
continue
date = tr.xpath('.//td')[0].text.strip()
lot = list_a[0].text.replace('(*)', '').strip()
if lot == 'SNL':
sno = sno + 1
lot = lot + str(sno)
factures = tr.xpath('.//div[@class="cAlignGauche"]/a')
factures_lbl = ''
for a in factures:
factures_lbl = factures_lbl + a.text.replace('(**)', '').strip() + ' '
montant = tr.xpath('.//div[@class="cAlignDroite"]')[0].text.strip()
det = Detail()
det.id = u''+lot
det.label = u''+lot
det.infos = u''+factures_lbl
det.datetime = datetime.strptime(date, "%d/%m/%Y").date()
det.price = Decimal(montant.replace(',', '.'))
yield det
class BillsPage(Page):
class BillsPage(HTMLPage):
def iter_bills(self):
table = self.document.xpath('//table[@id="releveCompteMensuel"]')[0].xpath('.//tr')
table = self.doc.xpath('//table[@id="releveCompteMensuel"]')[0].xpath('.//tr')
for tr in table:
list_tds = tr.xpath('.//td')
if len(list_tds) == 0:
@ -96,19 +99,18 @@ class BillsPage(Page):
month_str = date_str.split()[0]
date = datetime.strptime(re.sub(month_str, str(FRENCH_MONTHS.index(month_str) + 1), date_str), "%m %Y").date()
amount = tr.xpath('.//td[@class="cAlignDroite"]')[0].text
amount = re.sub('[^\d,-]+', '', amount)
for format in ('CSV', 'PDF'):
bil = Bill()
bil.id = date.strftime("%Y%m") + format
bil.date = date
bil.label = u''+amount.strip()
bil.price = Decimal('-'+amount.strip().replace(',','.'))
bil.label = u''+date.strftime("%Y%m%d")
bil.format = u''+format
filedate = date.strftime("%m%Y")
bil._url = '/PortailPS/fichier.do'
bil._args = {'FICHIER.type': format.lower() + '.releveCompteMensuel',
'dateReleve': filedate,
'FICHIER.titre': '',
}
bil._data = {'FICHIER.type': format.lower()+'.releveCompteMensuel',
'dateReleve': filedate,
'FICHIER.titre': 'Releve' + filedate
}
yield bil
def get_bill(self, bill):
self.location(bill._url, urllib.urlencode(bill._args))