Newer
Older
# -*- coding: utf-8 -*-
# Copyright(C) 2013-2015 Christophe Lampin
#
# 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 datetime import datetime
import re
from decimal import Decimal
from weboob.browser.filters.html import Attr, XPathNotFound
from weboob.browser.pages import HTMLPage, RawPage, LoggedPage
from weboob.capabilities.bill import Subscription, Detail, Bill
from weboob.browser.filters.standard import CleanText, Regexp
# Ugly array to avoid the use of french locale
FRENCH_MONTHS = ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre']
class AmeliBasePage(HTMLPage):
@property
def logged(self):
if self.doc.xpath('//a[contains(text(), "Déconnexion")]'):
else:
logged = False
self.logger.debug('logged: %s' % (logged))
return logged
if errors:
return errors[0].text_content()
errors = CleanText('//p[@class="msg_erreur"]', default='')(self.doc)
if errors:
return errors
errors = CleanText('//div[@class="zone-alerte"]/span')(self.doc)
if errors:
return errors
class LoginPage(AmeliBasePage):
def login(self, login, password):
form = self.get_form('//form[@name="connexionCompteForm"]')
form['connexioncompte_2numSecuriteSociale'] = login.encode('utf8')
form['connexioncompte_2codeConfidentiel'] = password.encode('utf8')
form.submit()
def locate_to_cgu_page(self):
try:
# they've put a head tag inside body, yes i know...
url = Regexp(Attr('//div[@id="connexioncompte_2"]//meta', 'content'), r'url=(.*)')(self.doc)
except XPathNotFound:
# no cgu to validate
return
self.browser.location(url)
class CguPage(AmeliBasePage):
def get_cgu(self):
return CleanText('//div[@class="page_nouvelles_cgus"]/p[1]')(self.doc)
class AccountPage(AmeliBasePage):
def iter_subscription_list(self):
names_list = self.doc.xpath('//span[@class="NomEtPrenomLabel"]')
fullname = CleanText(newlines=True).filter(names_list[0])
number = re.sub(r'[^\d]+', '', CleanText('//span[@class="blocNumSecu"]', replace=[(' ', '')])(self.doc))
sub = Subscription(number)
sub._id = number
firstname = CleanText('//span[@class="prenom-titulaire"]')(self.doc)
yield sub
class PaymentsPage(AmeliBasePage):
def get_last_payments_url(self):
begin_date = self.doc.xpath('//input[@id="paiements_1dateDebut"]/@data-mindate')[0]
end_date = self.doc.xpath('//input[@id="paiements_1dateFin"]/@data-maxdate')[0]
url = ('/PortailAS/paiements.do?actionEvt=afficherPaiementsComplementaires&DateDebut='
+ begin_date + '&DateFin=' + end_date +
'&Beneficiaire=tout_selectionner&afficherReleves=false&afficherIJ=false&afficherInva=false'
'&afficherRentes=false&afficherRS=false&indexPaiement=&idNotif=')
class LastPaymentsPage(LoggedPage, AmeliBasePage):
def iter_last_payments(self):
elts = self.doc.xpath('//li[@class="rowitem remboursement"]')
for elt in elts:
items = Regexp(CleanText('./@onclick'), r".*ajaxCallRemoteChargerDetailPaiement \('(\w+={0,2})', '(\w+)', '(\d+)', '(\d+)'\).*", '\\1,\\2,\\3,\\4')(elt).split(',')
yield "/PortailAS/paiements.do?actionEvt=chargerDetailPaiements&idPaiement=" + items[0] + "&naturePaiement=" + items[1] + "&indexGroupe=" + items[2] + "&indexPaiement=" + items[3]
def iter_documents(self, sub):
elts = self.doc.xpath('//li[@class="rowdate"]')
for elt in elts:
try:
elt.xpath('.//a[contains(@id,"lienPDFReleve")]')[0]
except IndexError:
date_str = elt.xpath('.//span[contains(@id,"moisEnCours")]')[0].text
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()
bil = Bill()
bil.id = sub._id + "." + date.strftime("%Y%m")
bil.date = date
bil.format = 'pdf'
bil.type = 'bill'
bil.label = date.strftime("%Y%m%d")
bil.url = '/PortailAS/PDFServletReleveMensuel.dopdf?PDF.moisRecherche=' + date.strftime("%m%Y")
yield bil
def get_document(self, bill):
self.location(bill.url, params=bill._args)
def iter_payment_details(self, sub):
id_str = self.doc.xpath('//div[@class="entete container"]/h2')[0].text.strip()
m = re.match(r'.*le (.*) pour un montant de.*', id_str)
if m:
blocs_benes = self.doc.xpath('//span[contains(@id,"nomBeneficiaire")]')
blocs_prestas = self.doc.xpath('//table[@id="tableauPrestation"]')
i = 0
last_bloc = len(blocs_benes)
for i in range(0, last_bloc):
bene = blocs_benes[i].text
id_str = m.group(1)
id_date = datetime.strptime(id_str, '%d/%m/%Y').date()
id = sub._id + "." + datetime.strftime(id_date, "%Y%m%d")
for tr in table:
if len(tds) == 0:
continue
det = Detail()
# TO TEST : Indemnités journalières : Pas pu tester de cas de figure similaire dans la nouvelle mouture du site
date_str = Regexp(pattern=r'.*<br/>(\d+/\d+/\d+)\).*').filter(tds[0].text)
det.id = id + "." + str(line)
det.label = tds[0].xpath('.//span')[0].text.strip()
jours = tds[1].text
if jours is None:
jours = '0'
montant = tds[2].text
if montant is None:
montant = '0'
if price is None:
price = '0'
if date_str is None or date_str == '':
det.datetime = last_date
else:
det.infos = date_str + ' (' + re.sub(r'[^\d,-]+', '', jours) + 'j) * ' + re.sub(r'[^\d,-]+', '', montant) + '€'
det.datetime = datetime.strptime(date_str.split(' ')[3], '%d/%m/%Y').date()
last_date = det.datetime
det.price = Decimal(re.sub(r'[^\d,-]+', '', price).replace(',', '.'))
if len(tds) == 5:
date_str = Regexp(pattern=r'\w*(\d{2})/(\d{2})/(\d{4}).*', template='\\1/\\2/\\3', default="").filter("".join(tds[0].itertext()))
det.id = id + "." + str(line)
det.label = bene + ' - ' + tds[0].xpath('.//span')[0].text.strip()
if paye is None:
paye = '0'
if base is None:
base = '0'
tdtaux = tds[3].xpath('.//span')[0].text
if tdtaux is None:
taux = '0'
tdprice = tds[4].xpath('.//span')[0].text
if tdprice is None:
price = '0'
if date_str is None or date_str == '':
det.datetime = last_date
else:
det.infos = ' Payé ' + re.sub(r'[^\d,-]+', '', paye) + '€ / Base ' + re.sub(r'[^\d,-]+', '', base) + '€ / Taux ' + re.sub(r'[^\d,-]+', '', taux) + '%'
det.datetime = datetime.strptime(date_str, '%d/%m/%Y').date()
last_date = det.datetime
det.price = Decimal(re.sub(r'[^\d,-]+', '', price).replace(',', '.'))
line = line + 1
yield det
class Raw(LoggedPage, RawPage):
pass