browser.py 5.72 KB
Newer Older
1 2
# -*- coding: utf-8 -*-

3
# Copyright(C) 2010-2015 Bezleputh
4
#
5
# This file is part of weboob.
6
#
7 8 9 10 11 12
# 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,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14 15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
16
#
17 18
# 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

20 21
from jose import jwt

22
from weboob.browser import LoginBrowser, URL, need_login
23
from weboob.exceptions import BrowserIncorrectPassword, BrowserUnavailable
24
from weboob.browser.exceptions import ClientError
25 26 27
from weboob.tools.compat import urlparse, parse_qs
from .pages import (
    DocumentsPage, HomePage, LoginPage, SubscriberPage, SubscriptionPage, SubscriptionDetailPage,
cadrien's avatar
cadrien committed
28
    SendSMSPage, SendSMSErrorPage, UselessPage, DocumentFilePage, ProfilePage,
29
)
30

31
from weboob.capabilities.messages import CantSendMessage
32

33
__all__ = ['BouyguesBrowser']
34 35


36
class BouyguesBrowser(LoginBrowser):
37
    BASEURL = 'https://api.bouyguestelecom.fr'
38
    TIMEOUT = 20
39

40
    login = URL('https://www.mon-compte.bouyguestelecom.fr/cas/login', LoginPage)
41
    home = URL('https://www.bouyguestelecom.fr/mon-compte', HomePage)
42 43 44 45 46
    subscriber = URL('/personnes/(?P<idUser>\d+)$', SubscriberPage)
    subscriptions = URL('/personnes/(?P<idUser>\d+)/comptes-facturation', SubscriptionPage)
    subscriptions_details = URL('/comptes-facturation/(?P<idSub>\d+)/contrats-payes', SubscriptionDetailPage)
    document_file = URL('/comptes-facturation/(?P<idSub>\d+)/factures/\d+/documents', DocumentFilePage)
    documents = URL('/comptes-facturation/(?P<idSub>\d+)/factures', DocumentsPage)
47

48 49 50
    sms_page = URL('http://www.mobile.service.bbox.bouyguestelecom.fr/services/SMSIHD/sendSMS.phtml',
                   'http://www.mobile.service.bbox.bouyguestelecom.fr/services/SMSIHD/confirmSendSMS.phtml',
                   SendSMSPage)
51
    confirm = URL('http://www.mobile.service.bbox.bouyguestelecom.fr/services/SMSIHD/resultSendSMS.phtml', UselessPage)
52 53
    sms_error_page = URL('http://www.mobile.service.bbox.bouyguestelecom.fr/services/SMSIHD/SMS_erreur.phtml',
                         SendSMSErrorPage)
cadrien's avatar
cadrien committed
54
    profile = URL('/personnes/(?P<idUser>\d+)/coordonnees', ProfilePage)
55

56 57 58
    def __init__(self, username, password, lastname, *args, **kwargs):
        super(BouyguesBrowser, self).__init__(username, password, *args, **kwargs)
        self.lastname = lastname
59 60
        self.headers = None
        self.id_user = None
61

62
    def do_login(self):
63
        self.login.go()
64

65 66
        if self.home.is_here():
            return
67

68
        self.page.login(self.username, self.password, self.lastname)
69

70
        if not self.home.is_here():
71
            raise BrowserIncorrectPassword()
72

73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
        # after login we need to get some tokens to use bouygues api
        data = {
            'response_type': 'id_token token',
            'client_id': 'a360.bouyguestelecom.fr',
            'redirect_uri': 'https://www.bouyguestelecom.fr/mon-compte/'
        }
        self.location('https://oauth2.bouyguestelecom.fr/authorize', params=data)

        parsed_url = urlparse(self.response.url)
        fragment = parse_qs(parsed_url.fragment)

        if not fragment:
            query = parse_qs(parsed_url.query)
            if 'server_error' in query.get('error', []):
                raise BrowserUnavailable(query['error_description'][0])

        claims = jwt.get_unverified_claims(fragment['id_token'][0])
        self.headers = {'Authorization': 'Bearer %s' % fragment['access_token'][0]}
        self.id_user = claims['id_personne']

93
    @need_login
94
    def post_message(self, message):
95 96 97 98 99 100 101 102 103 104 105 106
        self.sms_page.go()

        if self.sms_error_page.is_here():
            raise CantSendMessage(self.page.get_error_message())

        receivers = ";".join(list(message.receivers)) if message.receivers else self.username
        self.page.send_sms(message, receivers)

        if self.sms_error_page.is_here():
            raise CantSendMessage(self.page.get_error_message())

        self.confirm.open()
107 108

    @need_login
109 110 111
    def iter_subscriptions(self):
        self.subscriber.go(idUser=self.id_user, headers=self.headers)
        subscriber = self.page.get_subscriber()
112
        phone_list = self.page.get_phone_list()
113 114 115

        self.subscriptions.go(idUser=self.id_user, headers=self.headers)
        for sub in self.page.iter_subscriptions(subscriber=subscriber):
116 117 118 119 120 121
            try:
                self.subscriptions_details.go(idSub=sub.id, headers=self.headers)
                sub.label = self.page.get_label()
            except ClientError:
                # if another person pay for your subscription you may not have access to this page with your credentials
                sub.label = phone_list
122 123
            if not sub.label:
                sub.label = subscriber
124
            yield sub
125 126

    @need_login
127
    def iter_documents(self, subscription):
128 129
        self.location(subscription.url, headers=self.headers)
        return self.page.iter_documents(subid=subscription.id)
130

131 132 133 134
    @need_login
    def download_document(self, document):
        self.location(document.url, headers=self.headers)
        return self.open(self.page.get_one_shot_download_url()).content
cadrien's avatar
cadrien committed
135 136 137 138 139 140 141 142 143

    @need_login
    def get_profile(self):
        self.subscriber.go(idUser=self.id_user, headers=self.headers)
        subscriber = self.page.get_subscriber()

        self.profile.go(idUser=self.id_user, headers=self.headers)

        return self.page.get_profile(subscriber=subscriber)