Skip to content
pages.py 9.4 KiB
Newer Older
# 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/>.

hydrargyrum's avatar
hydrargyrum committed
from __future__ import unicode_literals

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
Kitof's avatar
Kitof committed
from weboob.browser.filters.standard import CleanText, Regexp
# Ugly array to avoid the use of french locale
Nicolas Gattolin's avatar
Nicolas Gattolin committed
FRENCH_MONTHS = ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre']
class AmeliBasePage(HTMLPage):
Nicolas Gattolin's avatar
Nicolas Gattolin committed
        if self.doc.xpath('//a[contains(text(), "Déconnexion")]'):
            logged = True
        self.logger.debug('logged: %s' % (logged))
        return logged
Florent's avatar
Florent committed

    def is_error(self):
Nicolas Gattolin's avatar
Nicolas Gattolin committed
        errors = self.doc.xpath('//*[@id="r_errors"]')
        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)

Florent's avatar
Florent committed
class HomePage(AmeliBasePage):
class AccountPage(AmeliBasePage):
    def iter_subscription_list(self):
Kitof's avatar
Kitof committed
        names_list = self.doc.xpath('//span[@class="NomEtPrenomLabel"]')
        fullname = CleanText(newlines=True).filter(names_list[0])
Laurent Bachelier's avatar
Laurent Bachelier committed
        number = re.sub(r'[^\d]+', '', CleanText('//span[@class="blocNumSecu"]', replace=[(' ', '')])(self.doc))
        sub = Subscription(number)
        sub._id = number
hydrargyrum's avatar
hydrargyrum committed
        sub.label = fullname
Kitof's avatar
Kitof committed
        firstname = CleanText('//span[@class="prenom-titulaire"]')(self.doc)
hydrargyrum's avatar
hydrargyrum committed
        sub.subscriber = firstname
Kitof's avatar
Kitof committed
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=')
Kitof's avatar
Kitof committed
        return url

class LastPaymentsPage(LoggedPage, AmeliBasePage):
    def iter_last_payments(self):
Kitof's avatar
Kitof committed
        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(',')
Kitof's avatar
Kitof committed
            yield "/PortailAS/paiements.do?actionEvt=chargerDetailPaiements&idPaiement=" + items[0] + "&naturePaiement=" + items[1] + "&indexGroupe=" + items[2] + "&indexPaiement=" + items[3]
Kitof's avatar
Kitof committed
    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:
Laurent Bachelier's avatar
Laurent Bachelier committed
                continue
Kitof's avatar
Kitof committed
            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
Nicolas Gattolin's avatar
Nicolas Gattolin committed
            bil.format = 'pdf'
            bil.type = 'bill'
            bil.label = date.strftime("%Y%m%d")
            bil.url = '/PortailAS/PDFServletReleveMensuel.dopdf?PDF.moisRecherche=' + date.strftime("%m%Y")
Kitof's avatar
Kitof committed
            yield bil

    def get_document(self, bill):
        self.location(bill.url, params=bill._args)
Florent's avatar
Florent committed
class PaymentDetailsPage(AmeliBasePage):
    def iter_payment_details(self, sub):
Kitof's avatar
Kitof committed
        id_str = self.doc.xpath('//div[@class="entete container"]/h2')[0].text.strip()
Nicolas Gattolin's avatar
Nicolas Gattolin committed
        m = re.match(r'.*le (.*) pour un montant de.*', id_str)
Kitof's avatar
Kitof committed
        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")
Kitof's avatar
Kitof committed
                table = blocs_prestas[i].xpath('.//tr')
Florent's avatar
Florent committed
                last_date = None
Florent's avatar
Florent committed
                    tds = tr.xpath('.//td')
Kitof's avatar
Kitof committed
                    # TO TEST : Indemnités journalières : Pas pu tester de cas de figure similaire dans la nouvelle mouture du site
Kitof's avatar
Kitof committed
                    if len(tds) == 4:
                        date_str = Regexp(pattern=r'.*<br/>(\d+/\d+/\d+)\).*').filter(tds[0].text)
hydrargyrum's avatar
hydrargyrum committed
                        det.label = tds[0].xpath('.//span')[0].text.strip()
Kitof's avatar
Kitof committed
                        jours = tds[1].text
                        if jours is None:
                            jours = '0'

                        montant = tds[2].text
Kitof's avatar
Kitof committed
                        price = tds[3].text
                        if price is None:
                            price = '0'

                        if date_str is None or date_str == '':
Nicolas Gattolin's avatar
Nicolas Gattolin committed
                            det.infos = ''
Nicolas Gattolin's avatar
Nicolas Gattolin committed
                            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
Nicolas Gattolin's avatar
Nicolas Gattolin committed
                        det.price = Decimal(re.sub(r'[^\d,-]+', '', price).replace(',', '.'))
Kitof's avatar
Kitof committed
                    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()))
Nicolas Gattolin's avatar
Nicolas Gattolin committed
                        det.label = bene + ' - ' + tds[0].xpath('.//span')[0].text.strip()
Kitof's avatar
Kitof committed
                        paye = tds[1].text
Kitof's avatar
Kitof committed
                        base = tds[2].text
Kitof's avatar
Kitof committed
                        tdtaux = tds[3].xpath('.//span')[0].text
                        if tdtaux is None:
Kitof's avatar
Kitof committed
                        else:
                            taux = tdtaux.strip()
Kitof's avatar
Kitof committed
                        tdprice = tds[4].xpath('.//span')[0].text
                        if tdprice is None:
Kitof's avatar
Kitof committed
                        else:
                            price = tdprice.strip()

                        if date_str is None or date_str == '':
Nicolas Gattolin's avatar
Nicolas Gattolin committed
                            det.infos = ''
Nicolas Gattolin's avatar
Nicolas Gattolin committed
                            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
Nicolas Gattolin's avatar
Nicolas Gattolin committed
                        det.price = Decimal(re.sub(r'[^\d,-]+', '', price).replace(',', '.'))
class Raw(LoggedPage, RawPage):
    pass