pages.py 6.37 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
# -*- coding: utf-8 -*-
# Copyright(C) 2010-2015 Bezleputh
#
# 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/>.

19
import re
20
from datetime import datetime, timedelta
21

22 23
from weboob.capabilities.messages import CantSendMessage

24
from weboob.capabilities.base import NotLoaded
25
from weboob.capabilities.bill import Bill, Subscription
cadrien's avatar
cadrien committed
26
from weboob.capabilities.profile import Profile
27
from weboob.browser.pages import HTMLPage, JsonPage, LoggedPage, PDFPage
28
from weboob.browser.filters.json import Dict
29 30 31
from weboob.browser.filters.standard import CleanDecimal, CleanText, Env, Format, Regexp
from weboob.browser.elements import DictElement, ItemElement, method

32 33

class LoginPage(HTMLPage):
34
    def login(self, login, password, lastname):
35
        form = self.get_form('//form[@id="log_data"]')
36

37 38
        form['username'] = login
        form['password'] = password
39

40 41 42
        if 'lastname' in form:
            form['lastname'] = lastname

43 44 45
        form.submit()


46
class HomePage(LoggedPage, HTMLPage):
47
    pass
48 49


50 51 52 53 54 55 56
class SubscriberPage(LoggedPage, JsonPage):
    def get_subscriber(self):
        if self.doc['type'] == 'INDIVIDU':
            sub_dict = self.doc
        else:
            sub_dict = self.doc['representantLegal']
        return "%s %s %s" % (sub_dict['civilite'], sub_dict['prenom'], sub_dict['nom'])
57

58 59
    def get_phone_list(self):
        num_tel_list = []
60
        for phone in self.doc.get('comptesAcces', []):
61 62 63 64
            num_tel_list.append(' '.join([phone[i:i + 2] for i in range(0, len(phone), 2)]))

        return ' - '.join(num_tel_list)

65 66 67 68 69

class SubscriptionPage(LoggedPage, JsonPage):
    @method
    class iter_subscriptions(DictElement):
        item_xpath = 'items'
70

71 72 73
        class item(ItemElement):
            klass = Subscription

74 75 76
            obj_id = Dict('id')
            obj_url = Dict('_links/factures/href')
            obj_subscriber = Env('subscriber')
77

78

79 80 81 82 83 84 85 86
class SubscriptionDetailPage(LoggedPage, JsonPage):
    def get_label(self):
        num_tel_list = []
        for s in self.doc['items']:
            phone = re.sub(r'^\+\d{2}', '0', s['numeroTel'])
            num_tel_list.append(' '.join([phone[i:i + 2] for i in range(0, len(phone), 2)]))

        return ' - '.join(num_tel_list)
87 88 89 90 91


class SendSMSPage(HTMLPage):
    def send_sms(self, message, receivers):
        sms_number = CleanDecimal(Regexp(CleanText('//span[@class="txt12-o"][1]/strong'), '(\d*) SMS.*'))(self.doc)
92

93 94 95 96 97 98 99
        if sms_number == 0:
            msg = CleanText('//span[@class="txt12-o"][1]')(self.doc)
            raise CantSendMessage(msg)

        form = self.get_form('//form[@name="formSMS"]')
        form["fieldMsisdn"] = receivers
        form["fieldMessage"] = message.content
100

101 102 103 104 105 106
        form.submit()


class SendSMSErrorPage(HTMLPage):
    def get_error_message(self):
        return CleanText('//span[@class="txt12-o"][1]')(self.doc)
107 108


109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
class DocumentsPage(LoggedPage, JsonPage):
    FRENCH_MONTHS = {
        1: 'Janvier',
        2: 'Février',
        3: 'Mars',
        4: 'Avril',
        5: 'Mai',
        6: 'Juin',
        7: 'Juillet',
        8: 'Août',
        9: 'Septembre',
        10: 'Octobre',
        11: 'Novembre',
        12: 'Décembre',
    }
124

125
    @method
126 127
    class iter_documents(DictElement):
        item_xpath = 'items'
128 129 130 131

        class item(ItemElement):
            klass = Bill

132 133
            obj_id = Format('%s_%s', Env('subid'), Dict('idFacture'))
            obj_url = Format('https://api.bouyguestelecom.fr%s', Dict('_links/facturePDF/href'))
134
            obj_date = Env('date')
135
            obj_duedate = Env('duedate')
136
            obj_format = u"pdf"
137
            obj_label = Env('label')
138
            obj_type = u"bill"
139
            obj_price = CleanDecimal(Dict('mntTotFacture'))
Edouard Lambert's avatar
Edouard Lambert committed
140
            obj_currency = u'EUR'
141 142

            def parse(self, el):
143 144 145 146 147 148 149 150 151 152 153 154 155
                bill_date = datetime.strptime(Dict('dateFacturation')(self), "%Y-%m-%dT%H:%M:%SZ").date()

                # dateFacturation is like: 'YYYY-MM-DDTHH:00:00Z' where Z is UTC time and HH 23 in winter and 22 in summer
                # which always correspond to the day after at midnight in French time zone
                # so we remove hour and consider the day after as date (which is also the date inside pdf)
                self.env['date'] = bill_date + timedelta(days=1)

                duedate = Dict('dateLimitePaieFacture', default=NotLoaded)(self)
                if duedate:
                    self.env['duedate'] = datetime.strptime(duedate, "%Y-%m-%dT%H:%M:%SZ").date() + timedelta(days=1)
                else:
                    # for some connections we don't have duedate (why ?)
                    self.env['duedate'] = NotLoaded
156

157 158 159 160
                self.env['label'] = "%s %d" % (self.page.FRENCH_MONTHS[self.env['date'].month], self.env['date'].year)

    def get_one_shot_download_url(self):
        return self.doc['_actions']['telecharger']['action']
161 162


cadrien's avatar
cadrien committed
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
class ProfilePage(LoggedPage, JsonPage):
    def get_profile(self, subscriber):
        data = self.doc

        last_address = data['adressesPostales'][0]
        for address in data['adressesPostales']:
            if address['dateMiseAJour'] > last_address['dateMiseAJour']:
                last_address = address

        p = Profile()
        p.name = subscriber
        p.address = '%s %s %s %s' % (last_address['numero'], last_address['rue'],
                                     last_address['codePostal'], last_address['ville'])
        p.country = last_address['pays']

        for email in data['emails']:
            if email['emailPrincipal']:
                p.email = email['email']
                break

        if 'telephones' in data:
            for phone in data['telephones']:
                if phone['telephonePrincipal']:
                    p.phone = phone['numero']
                    break

        return p


192 193
class UselessPage(HTMLPage):
    pass
194 195 196 197


class DocumentFilePage(PDFPage):
    pass