Beispiel #1
0
 def on_loaded(self):
     self.accounts = OrderedDict()
     self.parse_table('comptes',         Account.TYPE_CHECKING)
     self.parse_table('comptesEpargne',  Account.TYPE_SAVINGS)
     self.parse_table('comptesTitres',   Account.TYPE_MARKET)
     self.parse_table('comptesVie',      Account.TYPE_DEPOSIT)
     self.parse_table('comptesRetraireEuros')
Beispiel #2
0
 def get_loan_list(self):
     accounts = OrderedDict()
     # New website
     for table in self.document.xpath('//div[@class="panel"]'):
         title = table.getprevious()
         if title is None:
             continue
         account_type = self.ACCOUNT_TYPES.get(self.parser.tocleanstring(title), Account.TYPE_UNKNOWN)
         for tr in table.xpath('./table/tbody/tr[contains(@id,"MM_SYNTHESE_CREDITS") and contains(@id,"IdTrGlobal")]'):
             tds = tr.findall('td')
             if len(tds) == 0 :
                 continue
             for i in tds[0].xpath('.//a/strong'):
                 label = i.text.strip()
                 break
             balance = Decimal(FrenchTransaction.clean_amount(self.parser.tocleanstring(tds[-1])))
             account = Account()
             account.id = label.split(' ')[-1]
             account.label = unicode(label)
             account.type = account_type
             account.balance = -abs(balance)
             account.currency = account.get_currency(self.parser.tocleanstring(tds[-1]))
             account._card_links = []
             accounts[account.id] = account
     return accounts.itervalues()
Beispiel #3
0
    def format(self, obj, selected_fields=None):
        """
        Format an object to be human-readable.
        An object has fields which can be selected.
        If the object provides an iter_fields() method, the formatter will
        call it. It can be used to specify the fields order.

        @param obj  [object] object to format
        @param selected_fields  [tuple] fields to display. If None, all fields are selected
        @return  a string of the formatted object
        """
        assert isinstance(obj, (dict, CapBaseObject, tuple))

        if isinstance(obj, dict):
            item = obj
        elif isinstance(obj, tuple):
            item = OrderedDict([(k, v) for k, v in obj])
        else:
            item = self.to_dict(obj, selected_fields)

        if item is None:
            return None

        if self.MANDATORY_FIELDS:
            missing_fields = set(self.MANDATORY_FIELDS) - set(item.keys())
            if missing_fields:
                raise MandatoryFieldsNotFound(missing_fields)

        formatted = self.format_dict(item=item)
        if formatted:
            self.after_format(formatted)
        return formatted
Beispiel #4
0
 def on_loaded(self):
     self.accounts = OrderedDict()
     self.parse_table('comptes')
     self.parse_table('comptesEpargne')
     self.parse_table('comptesTitres')
     self.parse_table('comptesVie')
     self.parse_table('comptesRetraireEuros')
Beispiel #5
0
 def get_loan_list(self):
     accounts = OrderedDict()
     # New website
     for table in self.document.xpath('//div[@class="panel"]'):
         title = table.getprevious()
         if title is None:
             continue
         account_type = self.ACCOUNT_TYPES.get(
             self.parser.tocleanstring(title), Account.TYPE_UNKNOWN)
         for tr in table.xpath(
                 './table/tbody/tr[contains(@id,"MM_SYNTHESE_CREDITS") and contains(@id,"IdTrGlobal")]'
         ):
             tds = tr.findall('td')
             if len(tds) == 0:
                 continue
             for i in tds[0].xpath('.//a/strong'):
                 label = i.text.strip()
                 break
             balance = Decimal(
                 FrenchTransaction.clean_amount(
                     self.parser.tocleanstring(tds[-1])))
             account = Account()
             account.id = label.split(' ')[-1]
             account.label = unicode(label)
             account.type = account_type
             account.balance = -abs(balance)
             account.currency = account.get_currency(
                 self.parser.tocleanstring(tds[-1]))
             account._card_links = []
             accounts[account.id] = account
     return accounts.itervalues()
Beispiel #6
0
    def get_list(self):
        accounts = OrderedDict()

        for tr in self.document.getiterator('tr'):
            first_td = tr.getchildren()[0]
            if (first_td.attrib.get('class', '') == 'i g' or first_td.attrib.get('class', '') == 'p g') \
               and first_td.find('a') is not None:

                a = first_td.find('a')
                link = a.get('href', '')
                if link.startswith('POR_SyntheseLst'):
                    continue

                url = urlparse(link)
                p = parse_qs(url.query)
                if not 'rib' in p:
                    continue

                for i in (2,1):
                    balance = FrenchTransaction.clean_amount(tr.getchildren()[i].text)
                    currency = Account.get_currency(tr.getchildren()[i].text)
                    if len(balance) > 0:
                        break
                balance = Decimal(balance)

                id = p['rib'][0]
                if id in accounts:
                    account = accounts[id]
                    if not account.coming:
                        account.coming = Decimal('0.0')
                    account.coming += balance
                    account._card_links.append(link)
                    continue

                account = Account()
                account.id = id
                account.label = unicode(a.text).strip().lstrip(' 0123456789').title()
                account._link_id = link
                account._card_links = []

                # Find accounting amount
                page = self.browser.get_document(self.browser.openurl(link))
                coming = self.find_amount(page, u"Opérations à venir")
                accounting = self.find_amount(page, u"Solde comptable")

                if accounting is not None and accounting + (coming or Decimal('0')) != balance:
                    self.logger.warning('%s + %s != %s' % (accounting, coming, balance))

                if accounting is not None:
                    balance = accounting

                if coming is not None:
                    account.coming = coming
                account.balance = balance
                account.currency = currency

                accounts[account.id] = account

        return accounts.itervalues()
Beispiel #7
0
 def on_loaded(self):
     if self.document.xpath(u'//h2[text()="%s"]' % u'ERREUR'):
         raise BrowserUnavailable()
     self.accounts = OrderedDict()
     self.parse_table('comptes', Account.TYPE_CHECKING)
     self.parse_table('comptesEpargne', Account.TYPE_SAVINGS)
     self.parse_table('comptesTitres', Account.TYPE_MARKET)
     self.parse_table('comptesVie', Account.TYPE_DEPOSIT)
     self.parse_table('comptesRetraireEuros')
Beispiel #8
0
    def get_list(self):
        accounts = OrderedDict()

        # Old website
        for table in self.document.xpath('//table[@cellpadding="1"]'):
            account_type = Account.TYPE_UNKNOWN
            for tr in table.xpath('./tr'):
                tds = tr.findall('td')
                if tr.attrib.get('class', '') == 'DataGridHeader':
                    account_type = self.ACCOUNT_TYPES.get(tds[1].text.strip()) or\
                                   self.ACCOUNT_TYPES.get(self.parser.tocleanstring(tds[2])) or\
                                   self.ACCOUNT_TYPES.get(self.parser.tocleanstring(tds[3]), Account.TYPE_UNKNOWN)
                else:
                    # On the same row, there are many accounts (for example a
                    # check accound and a card one).
                    if len(tds) > 4:
                        for i, a in enumerate(tds[2].xpath('./a')):
                            label = self.parser.tocleanstring(a)
                            balance = self.parser.tocleanstring(
                                tds[-2].xpath('./a')[i])
                            self._add_account(accounts, a, label, account_type,
                                              balance)
                    # Only 4 tds on banque de la reunion website.
                    elif len(tds) == 4:
                        for i, a in enumerate(tds[1].xpath('./a')):
                            label = self.parser.tocleanstring(a)
                            balance = self.parser.tocleanstring(
                                tds[-1].xpath('./a')[i])
                            self._add_account(accounts, a, label, account_type,
                                              balance)

        if len(accounts) == 0:
            # New website
            for table in self.document.xpath('//div[@class="panel"]'):
                title = table.getprevious()
                if title is None:
                    continue
                account_type = self.ACCOUNT_TYPES.get(
                    self.parser.tocleanstring(title), Account.TYPE_UNKNOWN)
                for tr in table.xpath('.//tr'):
                    tds = tr.findall('td')
                    for i in xrange(len(tds)):
                        a = tds[i].find('a')
                        if a is not None:
                            break

                    if a is None:
                        continue

                    label = self.parser.tocleanstring(tds[0])
                    balance = self.parser.tocleanstring(tds[-1])

                    self._add_account(accounts, a, label, account_type,
                                      balance)

        return accounts.itervalues()
Beispiel #9
0
    def get_list(self):
        accounts = OrderedDict()

        # Old website
        for table in self.document.xpath('//table[@cellpadding="1"]'):
            account_type = Account.TYPE_UNKNOWN
            for tr in table.xpath('./tr'):
                tds = tr.findall('td')
                if tr.attrib.get('class', '') == 'DataGridHeader':
                    account_type = self.ACCOUNT_TYPES.get(tds[1].text.strip(), Account.TYPE_UNKNOWN)
                else:
                    label = ''
                    i = 1
                    a = None
                    while label == '' and i < len(tds):
                        a = tds[i].find('a')
                        if a is None:
                            continue

                        label = self.parser.tocleanstring(a)
                        i += 1

                    balance = ''
                    i = -1
                    while balance == '' and i > -len(tds):
                        try:
                            balance = self.parser.tocleanstring(tds[i].xpath('./a')[0])
                        except KeyError:
                            balance = u''.join([txt.strip() for txt in tds[i].itertext()])
                        i -= 1
                    self._add_account(accounts, a, label, account_type, balance)

        if len(accounts) == 0:
            # New website
            for table in self.document.xpath('//div[@class="panel"]'):
                title = table.getprevious()
                if title is None:
                    continue
                account_type = self.ACCOUNT_TYPES.get(self.parser.tocleanstring(title), Account.TYPE_UNKNOWN)
                for tr in table.xpath('.//tr'):
                    tds = tr.findall('td')
                    for i in xrange(len(tds)):
                        a = tds[i].find('a')
                        if a is not None:
                            break

                    if a is None:
                        continue

                    label = self.parser.tocleanstring(tds[0])
                    balance = self.parser.tocleanstring(tds[-1])

                    self._add_account(accounts, a, label, account_type, balance)

        return accounts.itervalues()
Beispiel #10
0
 def __init__(self, name, backend):
     self.my_id = backend.browser.get_userid()
     self.name = 'wiki/weboob/%s' % name
     self.description = None
     self.date = None
     self.begin = None
     self.end = None
     self.location = None
     self.winner = None
     self.backend = backend
     self.members = OrderedDict()
     self.load()
Beispiel #11
0
    def on_loaded(self):
        for script in self.document.xpath('//script'):
            text = script.text
            if text is None:
                continue
            m = re.search("window.location.replace\('([^']+)'\);", text)
            if m:
                self.browser.location(m.group(1))

        try:
            self.browser.select_form(name='banque')
        except FormNotFoundError:
            pass
        else:
            self.browser.set_all_readonly(False)
            accounts = OrderedDict()
            for tr in self.document.getroot().cssselect(
                    'table.compteTable > tbody > tr'):
                if len(tr.findall('td')) == 0:
                    continue
                attr = tr.xpath('.//a')[0].attrib.get('onclick', '')
                m = re.search(
                    "value = '(\w+)';(checkAndSubmit\('\w+','(\w+)','(\w+)'\))?",
                    attr)
                if m:
                    typeCompte = m.group(1)
                    tagName = m.group(3)
                    if tagName is not None:
                        value = self.document.xpath(
                            '//input[@name="%s"]' % m.group(3))[int(
                                m.group(4))].attrib['value']
                    else:
                        value = typeCompte
                    accounts[value] = (typeCompte, tagName)

            try:
                typeCompte, tagName = accounts[self.browser.accnum]
                value = self.browser.accnum
            except KeyError:
                accnums = ', '.join(accounts.keys())
                if self.browser.accnum != '00000000000':
                    self.logger.warning(
                        u'Unable to find account "%s". Available ones: %s' %
                        (self.browser.accnum, accnums))
                elif len(accounts) > 1:
                    self.logger.warning(
                        'There are several accounts, please use "accnum" backend parameter to force the one to use (%s)'
                        % accnums)
                value, (typeCompte, tagName) = accounts.popitem(last=False)
            self.browser['typeCompte'] = typeCompte
            if tagName is not None:
                self.browser[tagName] = [value]
            self.browser.submit()
Beispiel #12
0
    def get_profile(self):
        title = self.parser.select(self.document.getroot(), 'title', 1)
        if title.text == 'OkCupid: Account Not Found':
            return None

        profile = {}
        profile['id'] = unicode(title.text[len('OkCupid: '):])
        profile['data'] = OrderedDict()

        profile_p = self.parser.select(self.document.getroot(), "//div[@id='page_content']//p", method='xpath')

        profile['data']['infos'] = ProfileNode('infos', u'Informations', OrderedDict(), flags=ProfileNode.SECTION)

        info = {
                        'age' : unicode(profile_p[1].text.split(' / ')[0]),
                        'sex' : unicode(profile_p[1].text.split(' / ')[1]),
                        'orientation' : unicode(profile_p[1].text.split(' / ')[2]),
                        'relationship' : unicode(profile_p[1].text.split(' / ')[3]),
            }

        for key, val in info.iteritems():
            profile['data']['infos'].value[key] = ProfileNode(key, key.capitalize(), val)

        div_essays = self.parser.select(self.document.getroot(), "//div[@class='essay']", method='xpath')
        h3_essays = self.parser.select(self.document.getroot(), "//div[@id='page_content']//h3", method='xpath')
        essays = OrderedDict(zip(h3_essays, div_essays))

        profile['data']['look_for'] = ProfileNode('look_for', u'Look for', OrderedDict(), flags=ProfileNode.SECTION)
        profile['data']['details'] = ProfileNode('details', u'Details', OrderedDict(), flags=ProfileNode.SECTION)
        profile['data']['essays'] = ProfileNode('essays', u'Essays', OrderedDict(), flags=ProfileNode.SECTION)

        for label, val in essays.iteritems():
            label = unicode(label.text).strip()
            txt = self.parser.tocleanstring(val)
            if 'looking for' in label:
                for i, li in enumerate(val.xpath('.//li')):
                    profile['data']['look_for'].value['look_for_%s' % i] = ProfileNode('look_for_%s' % i, '', li.text.strip())
            elif 'summary' in label and 'summary' not in profile:
                profile['summary'] = txt
            else:
                key = label.replace(' ', '_')
                profile['data']['essays'].value[key] = ProfileNode(key, label, txt)

        details_div = self.parser.select(self.document.getroot(), "//div[@id='details']//li", method='xpath')
        for elem in details_div:
            label = unicode(elem.getchildren()[0].text.strip())
            val = unicode(elem.getchildren()[1].text.strip())
            key = label.lower().replace(' ', '_')
            profile['data']['details'].value[key] = ProfileNode(key, label, val)

        return profile
Beispiel #13
0
    def parse_profile(self, profile, consts):
        if profile['online']:
            self.status = Contact.STATUS_ONLINE
            self.status_msg = u'online'
            self.status_msg = u'since %s' % profile['last_cnx']
        else:
            self.status = Contact.STATUS_OFFLINE
            self.status_msg = u'last connection %s' % profile['last_cnx']

        self.summary = unicode(unescape(profile.get('announce', '').strip()))
        if len(profile.get('shopping_list', '')) > 0:
            self.summary += u'\n\nLooking for:\n%s' % unescape(
                profile['shopping_list'].strip())

        for photo in profile['pics']:
            self.set_photo(photo.split('/')[-1],
                           url=photo + '/full',
                           thumbnail_url=photo + '/small',
                           hidden=False)
        self.profile = OrderedDict()

        if 'sex' in profile:
            for section, d in self.TABLE.iteritems():
                flags = ProfileNode.SECTION
                if section.startswith('_'):
                    flags |= ProfileNode.HEAD
                if (section.startswith('+') and int(profile['sex']) != 1) or \
                   (section.startswith('-') and int(profile['sex']) != 0):
                    continue

                section = section.lstrip('_+-')

                s = ProfileNode(section,
                                section.capitalize(),
                                OrderedDict(),
                                flags=flags)

                for key, builder in d.iteritems():
                    try:
                        value = builder.get_value(profile,
                                                  consts[int(profile['sex'])])
                    except KeyError:
                        pass
                    else:
                        s.value[key] = ProfileNode(
                            key,
                            key.capitalize().replace('_', ' '), value)

                self.profile[section] = s

        self._aum_profile = profile
Beispiel #14
0
    def get_list(self):
        accounts = OrderedDict()

        # Old website
        for table in self.document.xpath('//table[@cellpadding="1"]'):
            account_type = Account.TYPE_UNKNOWN
            for tr in table.xpath('./tr'):
                tds = tr.findall('td')
                if tr.attrib.get('class', '') == 'DataGridHeader':
                    account_type = self.ACCOUNT_TYPES.get(tds[1].text.strip()) or\
                                   self.ACCOUNT_TYPES.get(self.parser.tocleanstring(tds[2])) or\
                                   self.ACCOUNT_TYPES.get(self.parser.tocleanstring(tds[3]), Account.TYPE_UNKNOWN)
                else:
                    # On the same row, there are many accounts (for example a
                    # check accound and a card one).
                    if len(tds) > 4:
                        for i, a in enumerate(tds[2].xpath('./a')):
                            label = self.parser.tocleanstring(a)
                            balance = self.parser.tocleanstring(tds[-2].xpath('./a')[i])
                            self._add_account(accounts, a, label, account_type, balance)
                    # Only 4 tds on banque de la reunion website.
                    elif len(tds) == 4:
                        for i, a in enumerate(tds[1].xpath('./a')):
                            label = self.parser.tocleanstring(a)
                            balance = self.parser.tocleanstring(tds[-1].xpath('./a')[i])
                            self._add_account(accounts, a, label, account_type, balance)

        if len(accounts) == 0:
            # New website
            for table in self.document.xpath('//div[@class="panel"]'):
                title = table.getprevious()
                if title is None:
                    continue
                account_type = self.ACCOUNT_TYPES.get(self.parser.tocleanstring(title), Account.TYPE_UNKNOWN)
                for tr in table.xpath('.//tr'):
                    tds = tr.findall('td')
                    for i in xrange(len(tds)):
                        a = tds[i].find('a')
                        if a is not None:
                            break

                    if a is None:
                        continue

                    label = self.parser.tocleanstring(tds[0])
                    balance = self.parser.tocleanstring(tds[-1])

                    self._add_account(accounts, a, label, account_type, balance)

        return accounts.itervalues()
Beispiel #15
0
    def to_dict(self, obj):
        if not isinstance(obj, CapBaseObject):
            try:
                return OrderedDict(obj)
            except ValueError:
                raise TypeError('Please give a CapBaseObject or a dict')

        def iter_decorate(d):
            for key, value in d:
                if key == 'id' and obj.backend is not None:
                    value = obj.fullid
                yield key, value

        fields_iterator = obj.iter_fields()
        return OrderedDict(iter_decorate(fields_iterator))
Beispiel #16
0
    def load(self, default={}):
        self.values = OrderedDict(default)

        if os.path.exists(self.path):
            logging.debug(u'Loading application configuration file: %s.' %
                          self.path)
            self.config.read(self.path)
            for section in self.config.sections():
                args = section.split(':')
                if args[0] == self.ROOTSECT:
                    args.pop(0)
                for key, value in self.config.items(section):
                    self.set(*(args + [key, value]))
            # retro compatibility
            if len(self.config.sections()) == 0:
                first = True
                for key, value in self.config.items(DEFAULTSECT):
                    if first:
                        logging.warning(
                            'The configuration file "%s" uses an old-style' %
                            self.path)
                        logging.warning('Please rename the %s section to %s' %
                                        (DEFAULTSECT, self.ROOTSECT))
                        first = False
                    self.set(key, value)
            logging.debug(u'Application configuration file loaded: %s.' %
                          self.path)
        else:
            self.save()
            logging.debug(
                u'Application configuration file created with default values: %s. '
                'Please customize it.' % self.path)
        return self.values
Beispiel #17
0
class NewspaperPresseuropBrowser(BaseBrowser):
    "NewspaperPresseuropBrowser class"
    PAGES = OrderedDict((
        ("http://www.presseurop.eu/.*/news-brief/.*", DailySinglePage),
        ("http://www.presseurop.eu/.*/today/.*", DailyTitlesPage),
        ("http://www.presseurop.eu/.*/cartoon/.*", CartoonPage),
        ("http://www.presseurop.eu/.*", PresseuropPage),
    ))

    def is_logged(self):
        return False

    def login(self):
        pass

    def fillobj(self, obj, fields):
        pass

    def get_content(self, _id):
        "return page article content"
        self.location(_id)
        return self.page.get_article(_id)

    def get_daily_date(self, _id):
        self.location(_id)
        return self.page.get_daily_date()

    def get_daily_infos(self, _id):
        url = "http://www.presseurop.eu/fr/today/" + _id
        self.location(url)
        title = self.page.get_title()
        article_date = date(*[int(x) for x in _id.split('-')])
        article_time = time(0, 0, 0)
        article_datetime = datetime.combine(article_date, article_time)
        return url, title, article_datetime
Beispiel #18
0
class YahooModule(Module, CapWeather):
    NAME = 'yahoo'
    MAINTAINER = u'Romain Bignon'
    EMAIL = '*****@*****.**'
    VERSION = '1.2'
    DESCRIPTION = 'Yahoo! Weather.'
    LICENSE = 'AGPLv3+'
    BROWSER = YahooBrowser

    units_choice = OrderedDict([('c', 'International System of Units'),
                                ('f', 'U.S. System of Units')])

    CONFIG = BackendConfig(Value('units', label=u'System of Units', choices=units_choice))

    def create_default_browser(self):
        return self.create_browser(unit=self.config['units'].get())

    def iter_city_search(self, pattern):
        return self.browser.iter_city_search(pattern)

    def get_current(self, city_id):
        return self.browser.get_current(city_id)

    def iter_forecast(self, city_id):
        return self.browser.iter_forecast(city_id)
Beispiel #19
0
 def on_loaded(self):
     self.accounts = OrderedDict()
     self.parse_table("comptes")
     self.parse_table("comptesEpargne")
     self.parse_table("comptesTitres")
     self.parse_table("comptesVie")
     self.parse_table("comptesRetraireEuros")
Beispiel #20
0
class RazibusModule(Module, CapCalendarEvent):
    NAME = 'razibus'
    DESCRIPTION = u'site annonçant les évènements attendus par les punks a chiens'
    MAINTAINER = u'Bezleputh'
    EMAIL = '*****@*****.**'
    LICENSE = 'AGPLv3+'
    VERSION = '1.1'
    ASSOCIATED_CATEGORIES = [CATEGORIES.CONCERT]
    BROWSER = RazibusBrowser

    region_choices = OrderedDict([
        (k, u'%s' % (v)) for k, v in sorted({
            '': u'-- Indifférent --',
            'Alsace': u'Alsace',
            'Aquitaine': u'Aquitaine',
            'Auvergne': u'Auvergne',
            'Basse-Normandie': u'Basse-Normandie',
            'Bourgogne': u'Bourgogne',
            'Bretagne': u'Bretagne',
            'Centre': u'Centre',
            'Champagne-Ardenne': u'Champagne-Ardenne',
            'Franche-Comte': u'Franche-Comté',
            'Haute-Normandie': u'Haute-Normandie',
            'Ile-de-France': u'Île-de-France',
            'Languedoc-Roussillon': u'Languedoc-Roussillon',
            'Limousin': u'Limousin',
            'Lorraine': u'Lorraine',
            'Midi-Pyrenees': u'Midi-Pyrénées',
            'Nord-Pas-de-Calais': u'Nord-Pas-de-Calais',
            'Pays-de-la-Loire': u'Pays de la Loire',
            'Picardie': u'Picardie',
            'Poitou-Charentes': u'Poitou-Charentes',
            'PACA': u'PACA',
            'Rhone-Alpes': u'Rhône-Alpes',
            'Belgique': u'Belgique',
            'Suisse': u'Suisse',
        }.iteritems())
    ])

    CONFIG = BackendConfig(
        Value('region', label=u'Region', choices=region_choices, default=''))

    def create_default_browser(self):
        region = self.config['region'].get()
        return self.create_browser(region)

    def search_events(self, query):
        return self.browser.list_events(query.start_date, query.end_date,
                                        query.city, query.categories)

    def get_event(self, _id):
        return self.browser.get_event(_id)

    def list_events(self, date_from, date_to=None):
        return self.browser.list_events(date_from, date_to)

    def fill_obj(self, event, fields):
        return self.browser.get_event(event.id, event)

    OBJECTS = {RazibusCalendarEvent: fill_obj}
Beispiel #21
0
 def on_loaded(self):
     self.accounts = OrderedDict()
     self.parse_table('comptes',         Account.TYPE_CHECKING)
     self.parse_table('comptesEpargne',  Account.TYPE_SAVINGS)
     self.parse_table('comptesTitres',   Account.TYPE_MARKET)
     self.parse_table('comptesVie',      Account.TYPE_DEPOSIT)
     self.parse_table('comptesRetraireEuros')
Beispiel #22
0
class GanAssurancesModule(Module, CapBank):
    NAME = 'ganassurances'
    MAINTAINER = u'Romain Bignon'
    EMAIL = '*****@*****.**'
    VERSION = '1.1'
    DESCRIPTION = u'Groupama'
    LICENSE = 'AGPLv3+'
    website_choices = OrderedDict([(k, u'%s (%s)' % (v, k)) for k, v in sorted({
        'espaceclient.groupama.fr':    u'Groupama Banque',
        'espaceclient.ganassurances.fr':   u'Gan Assurances',
        }.iteritems(), key=lambda k_v: (k_v[1], k_v[0]))])
    CONFIG = BackendConfig(Value('website',  label='Banque', choices=website_choices, default='espaceclient.ganassurances.fr'),
                           ValueBackendPassword('login',    label=u'Numéro client', masked=False),
                           ValueBackendPassword('password', label=u"Code d'accès"))
    BROWSER = GanAssurances

    def create_default_browser(self):
        return self.create_browser(self.config['website'].get(),
                                   self.config['login'].get(),
                                   self.config['password'].get())

    def iter_accounts(self):
        return self.browser.get_accounts_list()

    def get_account(self, _id):
        return find_object(self.browser.get_accounts_list(), id=_id, error=AccountNotFound)

    def iter_history(self, account):
        return self.browser.get_history(account)

    def iter_coming(self, account):
        return self.browser.get_coming(account)
Beispiel #23
0
class CappedBrowser(Browser):
    DOMAIN = 'capped.tv'
    PROTOCOL = 'http'
    ENCODING = None
    PAGES = OrderedDict((
            (r'http://capped\.tv/?', IndexPage),
            (r'http://capped\.tv/newest', IndexPage),
            (r'http://capped\.tv/mostviews', IndexPage),
            (r'http://capped\.tv/leastviews', IndexPage),
            (r'http://capped\.tv/monthtop', IndexPage),
            (r'http://capped\.tv/monthbottom', IndexPage),
            (r'http://capped\.tv/alpha', IndexPage),
            (r'http://capped\.tv/ahpla', IndexPage),
            (r'http://capped\.tv/search\?s\=(?P<pattern>.+)', IndexPage),
            (r'http://capped\.tv/(?P<id>.+)', VideoPage),
            ))

    @id2url(CappedVideo.id2url)
    def get_video(self, url, video=None):
        self.location(url)
        assert self.is_on_page(VideoPage), 'Should be on video page.'
        return self.page.get_video(video)

    def search_videos(self, pattern):
        self.location('/search?s=%s' % (urllib.quote_plus(pattern.encode('utf-8'))))
        assert self.is_on_page(IndexPage)
        return self.page.iter_videos()

    def latest_videos(self):
        self.home()
        assert self.is_on_page(IndexPage)
        return self.page.iter_videos()
Beispiel #24
0
 def set(self, *args):
     v = self.values
     for k in args[:-2]:
         if k not in v:
             v[k] = OrderedDict()
         v = v[k]
     v[args[-2]] = args[-1]
Beispiel #25
0
    def build_request(self, url, referrer=None, data_encoding=None, **kwargs):
        """
        Does the same job as open(), but returns a Request without
        submitting it.
        This allows further customization to the Request.
        """
        if isinstance(url, requests.Request):
            req = url
            url = req.url
        else:
            req = requests.Request(url=url, **kwargs)

        # guess method
        if req.method is None:
            if req.data:
                req.method = 'POST'
            else:
                req.method = 'GET'

        # convert unicode strings to proper encoding
        if isinstance(req.data, unicode) and data_encoding:
            req.data = req.data.encode(data_encoding)
        if isinstance(req.data, dict) and data_encoding:
            req.data = OrderedDict([
                (k, v.encode(data_encoding) if isinstance(v, unicode) else v)
                for k, v in req.data.iteritems()
            ])

        if referrer is None:
            referrer = self.get_referrer(self.url, url)
        if referrer:
            # Yes, it is a misspelling.
            req.headers.setdefault('Referer', referrer)

        return req
Beispiel #26
0
    def __new__(cls, name, bases, attrs):
        fields = [(field_name, attrs.pop(field_name))
                  for field_name, obj in attrs.items()
                  if isinstance(obj, Field)]
        fields.sort(key=lambda x: x[1]._creation_counter)

        new_class = super(_BaseObjectMeta,
                          cls).__new__(cls, name, bases, attrs)
        if new_class._fields is None:
            new_class._fields = OrderedDict()
        else:
            new_class._fields = deepcopy(new_class._fields)
        new_class._fields.update(fields)

        if new_class.__doc__ is None:
            new_class.__doc__ = ''
        for name, field in fields:
            doc = '(%s) %s' % (', '.join([
                ':class:`%s`' % v.__name__ if isinstance(v, type) else v
                for v in field.types
            ]), field.doc)
            if field.value is not NotLoaded:
                doc += ' (default: %s)' % field.value
            new_class.__doc__ += '\n:var %s: %s' % (name, doc)
        return new_class
Beispiel #27
0
    def do_list(self, line):
        """
        list [CAPS ..]

        Show backends.
        """
        caps = line.split()
        for instance_name, name, params in sorted(
                self.weboob.backends_config.iter_backends()):
            try:
                module = self.weboob.modules_loader.get_or_load_module(name)
            except ModuleLoadError as e:
                self.logger.warning('Unable to load module %r: %s' % (name, e))
                continue

            if caps and not module.has_caps(*caps):
                continue
            row = OrderedDict([
                ('Name', instance_name),
                ('Module', name),
                ('Configuration', ', '.join(
                    '%s=%s' % (key, ('*****' if key in module.config
                                     and module.config[key].masked else value))
                    for key, value in params.iteritems())),
            ])
            self.format(row)
Beispiel #28
0
class CreditDuNordModule(Module, CapBank):
    NAME = 'creditdunord'
    MAINTAINER = u'Romain Bignon'
    EMAIL = '*****@*****.**'
    VERSION = '1.1'
    DESCRIPTION = u'Crédit du Nord, Banque Courtois, Kolb, Tarneaud'
    LICENSE = 'AGPLv3+'
    website_choices = OrderedDict([
        (k, u'%s (%s)' % (v, k))
        for k, v in sorted({
            'www.credit-du-nord.fr': u'Crédit du Nord',
            'www.banque-courtois.fr': u'Banque Courtois',
            'www.banque-kolb.fr': u'Banque Kolb',
            'www.banque-rhone-alpes.fr': u'Banque Rhône-Alpes',
            'www.tarneaud.fr': u'Tarneaud',
        }.iteritems(),
                           key=lambda k_v: (k_v[1], k_v[0]))
    ])
    CONFIG = BackendConfig(
        Value('website',
              label='Banque',
              choices=website_choices,
              default='www.credit-du-nord.fr'),
        ValueBackendPassword('login', label='Identifiant', masked=False),
        ValueBackendPassword('password', label='Code confidentiel'))
    BROWSER = CreditDuNordBrowser

    def create_default_browser(self):
        return self.create_browser(self.config['website'].get(),
                                   self.config['login'].get(),
                                   self.config['password'].get())

    def iter_accounts(self):
        with self.browser:
            for account in self.browser.get_accounts_list():
                yield account

    def get_account(self, _id):
        with self.browser:
            account = self.browser.get_account(_id)

        if account:
            return account
        else:
            raise AccountNotFound()

    def iter_history(self, account):
        with self.browser:
            account = self.browser.get_account(account.id)
            transactions = list(self.browser.get_history(account))
            transactions.sort(key=lambda tr: tr.rdate, reverse=True)
            return [tr for tr in transactions if not tr._is_coming]

    def iter_coming(self, account):
        with self.browser:
            account = self.browser.get_account(account.id)
            transactions = list(self.browser.get_card_operations(account))
            transactions.sort(key=lambda tr: tr.rdate, reverse=True)
            return [tr for tr in transactions if tr._is_coming]
Beispiel #29
0
class AccountList(Page):
    def on_loaded(self):
        if self.document.xpath(u'//h2[text()="%s"]' % u'ERREUR'):
            raise BrowserUnavailable()
        self.accounts = OrderedDict()
        self.parse_table('comptes',         Account.TYPE_CHECKING)
        self.parse_table('comptesEpargne',  Account.TYPE_SAVINGS)
        self.parse_table('comptesTitres',   Account.TYPE_MARKET)
        self.parse_table('comptesVie',      Account.TYPE_DEPOSIT)
        self.parse_table('comptesRetraireEuros')

    def get_accounts_list(self):
        return self.accounts.itervalues()

    def parse_table(self, what, actype=Account.TYPE_UNKNOWN):
        tables = self.document.xpath("//table[@id='%s']" % what, smart_strings=False)
        if len(tables) < 1:
            return

        lines = tables[0].xpath(".//tbody/tr")
        for line in lines:
            account = Account()
            tmp = line.xpath("./td//a")[0]
            account.label = to_unicode(tmp.text)
            account.type = actype
            account._link_id = tmp.get("href")
            if 'BourseEnLigne' in account._link_id:
                account.type = Account.TYPE_MARKET

            tmp = line.xpath("./td/span/strong")
            if len(tmp) >= 2:
                tmp_id = tmp[0].text
                tmp_balance = tmp[1].text
            else:
                tmp_id = line.xpath("./td//span")[1].text
                tmp_balance = tmp[0].text

            account.id = tmp_id
            account.currency = account.get_currency(tmp_balance)
            account.balance = Decimal(FrenchTransaction.clean_amount(tmp_balance))

            if account.id in self.accounts:
                a = self.accounts[account.id]
                a._card_links.append(account._link_id)
                if not a.coming:
                    a.coming = Decimal('0.0')
                a.coming += account.balance
            else:
                account._card_links = []
                self.accounts[account.id] = account

                page = self.browser.get_page(self.browser.openurl(self.browser.buildurl('/voscomptes/canalXHTML/comptesCommun/imprimerRIB/init-imprimer_rib.ea', ('compte.numero', account.id))))
                account.iban = page.get_iban()

    def get_account(self, id):
        try:
            return self.accounts[id]
        except KeyError:
            raise AccountNotFound('Unable to find account: %s' % id)
Beispiel #30
0
class BanquePopulaireModule(Module, CapBank):
    NAME = 'banquepopulaire'
    MAINTAINER = u'Romain Bignon'
    EMAIL = '*****@*****.**'
    VERSION = '1.1'
    DESCRIPTION = u'Banque Populaire'
    LICENSE = 'AGPLv3+'
    website_choices = OrderedDict([(k, u'%s (%s)' % (v, k)) for k, v in sorted({
        'www.ibps.alpes.banquepopulaire.fr': u'Alpes',
        'www.ibps.alsace.banquepopulaire.fr': u'Alsace',
        'www.ibps.bpaca.banquepopulaire.fr': u'Aquitaine Centre atlantique',
        'www.ibps.atlantique.banquepopulaire.fr': u'Atlantique',
        'www.ibps.bpbfc.banquepopulaire.fr': u'Bourgogne-Franche Comté',
        'www.ibps.bretagnenormandie.cmm.groupe.banquepopulaire.fr': u'Crédit Maritime Bretagne Normandie',
        'www.ibps.atlantique.creditmaritime.groupe.banquepopulaire.fr': u'Crédit Maritime Atlantique',
        'www.ibps.sudouest.creditmaritime.groupe.banquepopulaire.fr': u'Crédit Maritime du Littoral du Sud-Ouest',
        'www.ibps.cotedazur.banquepopulaire.fr': u'Côte d\'azur',
        'www.ibps.loirelyonnais.banquepopulaire.fr': u'Loire et Lyonnais',
        'www.ibps.lorrainechampagne.banquepopulaire.fr': u'Lorraine Champagne',
        'www.ibps.massifcentral.banquepopulaire.fr': u'Massif central',
        'www.ibps.nord.banquepopulaire.fr': u'Nord',
        'www.ibps.occitane.banquepopulaire.fr': u'Occitane',
        'www.ibps.ouest.banquepopulaire.fr': u'Ouest',
        'www.ibps.provencecorse.banquepopulaire.fr': u'Provence et Corse',
        'www.ibps.rivesparis.banquepopulaire.fr': u'Rives de Paris',
        'www.ibps.sud.banquepopulaire.fr': u'Sud',
        'www.ibps.valdefrance.banquepopulaire.fr': u'Val de France',
        }.iteritems(), key=lambda k_v: (k_v[1], k_v[0]))])
    CONFIG = BackendConfig(Value('website',  label=u'Région', choices=website_choices),
                           ValueBackendPassword('login',    label='Identifiant', masked=False),
                           ValueBackendPassword('password', label='Mot de passee'))
    BROWSER = BanquePopulaire

    def create_default_browser(self):
        return self.create_browser(self.config['website'].get(),
                                   self.config['login'].get(),
                                   self.config['password'].get())

    def iter_accounts(self):
        with self.browser:
            return self.browser.get_accounts_list()

    def get_account(self, _id):
        with self.browser:
            account = self.browser.get_account(_id)

        if account:
            return account
        else:
            raise AccountNotFound()

    def iter_history(self, account):
        with self.browser:
            return self.browser.get_history(account)

    def iter_coming(self, account):
        with self.browser:
            return self.browser.get_history(account, coming=True)
Beispiel #31
0
class AccountList(Page):
    def on_loaded(self):
        if self.document.xpath(u'//h2[text()="%s"]' % u'ERREUR'):
            raise BrowserUnavailable()
        self.accounts = OrderedDict()
        self.parse_table('comptes', Account.TYPE_CHECKING)
        self.parse_table('comptesEpargne', Account.TYPE_SAVINGS)
        self.parse_table('comptesTitres', Account.TYPE_MARKET)
        self.parse_table('comptesVie', Account.TYPE_DEPOSIT)
        self.parse_table('comptesRetraireEuros')

    def get_accounts_list(self):
        return self.accounts.itervalues()

    def parse_table(self, what, actype=Account.TYPE_UNKNOWN):
        tables = self.document.xpath("//table[@id='%s']" % what,
                                     smart_strings=False)
        if len(tables) < 1:
            return

        lines = tables[0].xpath(".//tbody/tr")
        for line in lines:
            account = Account()
            tmp = line.xpath("./td//a")[0]
            account.label = to_unicode(tmp.text)
            account.type = actype
            account._link_id = tmp.get("href")
            if 'BourseEnLigne' in account._link_id:
                account.type = Account.TYPE_MARKET

            tmp = line.xpath("./td/span/strong")
            if len(tmp) >= 2:
                tmp_id = tmp[0].text
                tmp_balance = tmp[1].text
            else:
                tmp_id = line.xpath("./td//span")[1].text
                tmp_balance = tmp[0].text

            account.id = tmp_id
            account.currency = account.get_currency(tmp_balance)
            account.balance = Decimal(
                FrenchTransaction.clean_amount(tmp_balance))

            if account.id in self.accounts:
                a = self.accounts[account.id]
                a._card_links.append(account._link_id)
                if not a.coming:
                    a.coming = Decimal('0.0')
                a.coming += account.balance
            else:
                account._card_links = []
                self.accounts[account.id] = account

    def get_account(self, id):
        try:
            return self.accounts[id]
        except KeyError:
            raise AccountNotFound('Unable to find account: %s' % id)
Beispiel #32
0
class CaisseEpargneModule(Module, CapBank):
    NAME = 'caissedepargne'
    MAINTAINER = u'Romain Bignon'
    EMAIL = '*****@*****.**'
    VERSION = '1.2'
    DESCRIPTION = u'Caisse d\'Épargne'
    LICENSE = 'AGPLv3+'
    website_choices = OrderedDict([
        (k, u'%s (%s)' % (v, k))
        for k, v in sorted({
            'www.caisse-epargne.fr': u'Caisse d\'Épargne',
            'www.banquebcp.fr': u'Banque BCP',
        }.iteritems(),
                           key=lambda k_v: (k_v[1], k_v[0]))
    ])
    CONFIG = BackendConfig(
        Value('website',
              label='Banque',
              choices=website_choices,
              default='www.caisse-epargne.fr'),
        ValueBackendPassword('login', label='Identifiant client',
                             masked=False),
        ValueBackendPassword('password', label='Code personnel', regexp='\d+'),
        Value('nuser', label='User ID (optional)', default=''))
    BROWSER = CaisseEpargne

    def create_default_browser(self):
        return self.create_browser(nuser=self.config['nuser'].get(),
                                   username=self.config['login'].get(),
                                   password=self.config['password'].get(),
                                   domain=self.config['website'].get())

    def iter_accounts(self):
        with self.browser:
            for account in self.browser.get_accounts_list():
                yield account
            for account in self.browser.get_loans_list():
                yield account

    def get_account(self, _id):
        with self.browser:
            account = self.browser.get_account(_id)

        if account:
            return account
        else:
            raise AccountNotFound()

    def iter_history(self, account):
        with self.browser:
            return self.browser.get_history(account)

    def iter_coming(self, account):
        with self.browser:
            return self.browser.get_coming(account)

    def iter_investment(self, account):
        return self.browser.get_investment(account)
Beispiel #33
0
class S2eModule(Module, CapBank):
    NAME = 's2e'
    MAINTAINER = u'Christophe Lampin'
    EMAIL = '*****@*****.**'
    VERSION = '1.2'
    LICENSE = 'AGPLv3+'
    DESCRIPTION = u'Esalia, Capeasi, BNP PERE, HSBC ERE'

    website_choices = OrderedDict([
        (k, u'%s (%s)' % (v, k)) for k, v in sorted(
            {
                'm.esalia.com': u'Esalia',  # Good Url. Tested
                'mobile.capeasi.com': u'Capeasi',  # Good Url. Not fully tested
                'mobi.ere.hsbc.fr': u'ERE HSBC',  # Good Url. Tested
                'smartphone.s2e-net.com': u'BNPP ERE',  # Good Url. Tested
                # 'smartphone.s2e-net.com':   u'Groupe Crédit du Nord',  # Mobile version not available yet.
            }.iteritems(),
            key=lambda k_v: (k_v[1], k_v[0]))
    ])

    BROWSERS = {
        'm.esalia.com': Esalia,
        'mobile.capeasi.com': Capeasi,
        'mobi.ere.hsbc.fr': EREHSBC,
        'smartphone.s2e-net.com': BNPPERE,
        # 'smartphone.s2e-net.com':  CreditNord,  # Mobile version not available yet.
    }

    CONFIG = BackendConfig(
        Value('website',
              label='Banque',
              choices=website_choices,
              default='smartphone.s2e-net.com'),
        ValueBackendPassword('login', label='Identifiant', masked=False),
        ValueBackendPassword('password',
                             label='Code secret',
                             regexp='^(\d{6}|)$'))

    def create_default_browser(self):
        self.BROWSER = self.BROWSERS[self.config['website'].get()]
        return self.create_browser(self.config['website'].get(),
                                   self.config['login'].get(),
                                   self.config['password'].get())

    def iter_accounts(self):
        return self.browser.get_accounts_list()

    def get_account(self, _id):
        return find_object(self.browser.get_accounts_list(),
                           id=_id,
                           error=AccountNotFound)

    def iter_investment(self, account):
        return account._investments

    def iter_history(self, account):
        return self.browser.iter_history(account)
Beispiel #34
0
 def on_loaded(self):
     if self.document.xpath(u'//h2[text()="%s"]' % u'ERREUR'):
         raise BrowserUnavailable()
     self.accounts = OrderedDict()
     self.parse_table('comptes',         Account.TYPE_CHECKING)
     self.parse_table('comptesEpargne',  Account.TYPE_SAVINGS)
     self.parse_table('comptesTitres',   Account.TYPE_MARKET)
     self.parse_table('comptesVie',      Account.TYPE_DEPOSIT)
     self.parse_table('comptesRetraireEuros')
Beispiel #35
0
    def to_dict(self):
        def iter_decorate(d):
            for key, value in d:
                if key == 'id' and self.backend is not None:
                    value = self.fullid
                yield key, value

        fields_iterator = self.iter_fields()
        return OrderedDict(iter_decorate(fields_iterator))
Beispiel #36
0
    def get_list(self):
        accounts = OrderedDict()

        for tr in self.document.getiterator('tr'):
            first_td = tr.getchildren()[0]
            if (first_td.attrib.get('class', '') == 'i g' or first_td.attrib.get('class', '') == 'p g') \
               and first_td.find('a') is not None:

                a = first_td.find('a')
                link = a.get('href', '')
                if link.startswith('POR_SyntheseLst'):
                    continue

                url = urlparse(link)
                p = parse_qs(url.query)
                if not 'rib' in p:
                    continue

                for i in (2,1):
                    balance = FrenchTransaction.clean_amount(tr.getchildren()[i].text.strip(' EUR'))
                    if len(balance) > 0:
                        break
                balance = Decimal(balance)

                id = p['rib'][0]
                if id in accounts:
                    account = accounts[id]
                    if not account.coming:
                        account.coming = Decimal('0.0')
                    account.coming += balance
                    account._card_links.append(link)
                    continue

                account = Account()
                account.id = id
                account.label = unicode(a.text).strip().lstrip(' 0123456789').title()
                account._link_id = link
                account._card_links = []

                account.balance = balance

                accounts[account.id] = account

        return accounts.itervalues()
Beispiel #37
0
    def on_loaded(self):
        for script in self.document.xpath('//script'):
            text = script.text
            if text is None:
                continue
            m = re.search("window.location.replace\('([^']+)'\);", text)
            if m:
                self.browser.location(m.group(1))

        try:
            self.browser.select_form(name='banque')
        except FormNotFoundError:
            pass
        else:
            self.browser.set_all_readonly(False)
            accounts = OrderedDict()
            for tr in self.document.getroot().cssselect('table.compteTable > tbody > tr'):
                if len(tr.findall('td')) == 0:
                    continue
                attr = tr.xpath('.//a')[0].attrib.get('onclick', '')
                m = re.search("value = '(\w+)';(checkAndSubmit\('\w+','(\w+)','(\w+)'\))?", attr)
                if m:
                    typeCompte = m.group(1)
                    tagName = m.group(3)
                    if tagName is not None:
                        value = self.document.xpath('//input[@name="%s"]' % m.group(3))[int(m.group(4))].attrib['value']
                    else:
                        value = typeCompte
                    accounts[value] = (typeCompte, tagName)

            try:
                typeCompte, tagName = accounts[self.browser.accnum]
                value = self.browser.accnum
            except KeyError:
                accnums = ', '.join(accounts.keys())
                if self.browser.accnum != '00000000000':
                    self.logger.warning(u'Unable to find account "%s". Available ones: %s' % (self.browser.accnum, accnums))
                elif len(accounts) > 1:
                    self.logger.warning('There are several accounts, please use "accnum" backend parameter to force the one to use (%s)' % accnums)
                value, (typeCompte, tagName) = accounts.popitem(last=False)
            self.browser['typeCompte'] = typeCompte
            if tagName is not None:
                self.browser[tagName] = [value]
            self.browser.submit()
Beispiel #38
0
class BanquePopulaireBackend(BaseBackend, ICapBank):
    NAME = 'banquepopulaire'
    MAINTAINER = u'Romain Bignon'
    EMAIL = '*****@*****.**'
    VERSION = '0.e'
    DESCRIPTION = u'Banque Populaire French bank website'
    LICENSE = 'AGPLv3+'
    website_choices = OrderedDict([(k, u'%s (%s)' % (v, k)) for k, v in sorted(
        {
            'www.ibps.alpes.banquepopulaire.fr': u'Alpes',
            'www.ibps.alsace.banquepopulaire.fr': u'Alsace',
            'www.ibps.bpaca.banquepopulaire.fr':
            u'Aquitaine Centre atlantique',
            'www.ibps.atlantique.banquepopulaire.fr': u'Atlantique',
            'www.ibps.bpbfc.banquepopulaire.fr': u'Bourgogne-Franche Comté',
            'www.ibps.cotedazur.banquepopulaire.fr': u'Côte d\'azur',
            'www.ibps.loirelyonnais.banquepopulaire.fr': u'Loire et Lyonnais',
            'www.ibps.lorrainechampagne.banquepopulaire.fr':
            u'Lorraine Champagne',
            'www.ibps.massifcentral.banquepopulaire.fr': u'Massif central',
            'www.ibps.nord.banquepopulaire.fr': u'Nord',
            'www.ibps.occitane.banquepopulaire.fr': u'Occitane',
            'www.ibps.ouest.banquepopulaire.fr': u'Ouest',
            'www.ibps.provencecorse.banquepopulaire.fr': u'Provence et Corse',
            'www.ibps.rivesparis.banquepopulaire.fr': u'Rives de Paris',
            'www.ibps.sud.banquepopulaire.fr': u'Sud',
            'www.ibps.valdefrance.banquepopulaire.fr': u'Val de France',
        }.iteritems())])
    CONFIG = BackendConfig(
        Value('website', label='Website to use', choices=website_choices),
        ValueBackendPassword('login', label='Account ID', masked=False),
        ValueBackendPassword('password', label='Password'))
    BROWSER = BanquePopulaire

    def create_default_browser(self):
        return self.create_browser(self.config['website'].get(),
                                   self.config['login'].get(),
                                   self.config['password'].get())

    def iter_accounts(self):
        with self.browser:
            return self.browser.get_accounts_list()

    def get_account(self, _id):
        with self.browser:
            account = self.browser.get_account(_id)

        if account:
            return account
        else:
            raise AccountNotFound()

    def iter_history(self, account):
        with self.browser:
            return self.browser.get_history(account)
Beispiel #39
0
    def __new__(mcs, name, bases, attrs):
        urls = [(url_name, attrs.pop(url_name)) for url_name, obj in attrs.items() if isinstance(obj, URL)]
        urls.sort(key=lambda x: x[1]._creation_counter)

        new_class = super(_PagesBrowserMeta, mcs).__new__(mcs, name, bases, attrs)
        if new_class._urls is None:
            new_class._urls = OrderedDict()
        else:
            new_class._urls = deepcopy(new_class._urls)
        new_class._urls.update(urls)
        return new_class
Beispiel #40
0
class AccountList(BasePage):
    def on_loaded(self):
        self.accounts = OrderedDict()
        self.parse_table('comptes',         Account.TYPE_CHECKING)
        self.parse_table('comptesEpargne',  Account.TYPE_SAVINGS)
        self.parse_table('comptesTitres',   Account.TYPE_MARKET)
        self.parse_table('comptesVie',      Account.TYPE_DEPOSIT)
        self.parse_table('comptesRetraireEuros')

    def get_accounts_list(self):
        return self.accounts.itervalues()

    def parse_table(self, what, actype=Account.TYPE_UNKNOWN):
        tables = self.document.xpath("//table[@id='%s']" % what, smart_strings=False)
        if len(tables) < 1:
            return

        lines = tables[0].xpath(".//tbody/tr")
        for line in lines:
            account = Account()
            tmp = line.xpath("./td//a")[0]
            account.label = to_unicode(tmp.text)
            account.type = actype
            account._link_id = tmp.get("href")
            if 'BourseEnLigne' in account._link_id:
                account.type = Account.TYPE_MARKET

            tmp = line.xpath("./td/span/strong")
            if len(tmp) >= 2:
                tmp_id = tmp[0].text
                tmp_balance = tmp[1].text
            else:
                tmp_id = line.xpath("./td//span")[1].text
                tmp_balance = tmp[0].text

            account.id = tmp_id
            account.currency = account.get_currency(tmp_balance)
            account.balance = Decimal(FrenchTransaction.clean_amount(tmp_balance))

            if account.id in self.accounts:
                a = self.accounts[account.id]
                a._card_links.append(account._link_id)
                if not a.coming:
                    a.coming = Decimal('0.0')
                a.coming += account.balance
            else:
                account._card_links = []
                self.accounts[account.id] = account

    def get_account(self, id):
        try:
            return self.accounts[id]
        except KeyError:
            raise AccountNotFound('Unable to find account: %s' % id)
Beispiel #41
0
 def __init__(self, *args, **kwargs):
     self.PAGES = OrderedDict((
         ('%s://%s/Pgn/.+PageID=SoldeV3&.+' % (self.PROTOCOL, self.DOMAIN), AccountsPage),
         ('%s://%s/Pgn/.+PageID=Cartes&.+' % (self.PROTOCOL, self.DOMAIN), CardsPage),
         ('%s://%s/Pgn/.+PageID=ReleveCompteV3&.+' % (self.PROTOCOL, self.DOMAIN), HistoryPage),
         ('%s://%s/Pgn/.+PageID=ReleveCarte&.+' % (self.PROTOCOL, self.DOMAIN), CardHistoryPage),
         ('%s://%s/ord-web/ord//ord-liste-compte-emetteur.json' % (self.PROTOCOL, self.DOMAIN), (OrderPage, JsonParser())),
         ('%s://%s/authent\.html' % (self.PROTOCOL, self.DOMAIN), ErrorPage),
         ('%s://%s/' % (self.PROTOCOL, self.DOMAIN), LoginPage),
     ))
     Browser.__init__(self, *args, **kwargs)
Beispiel #42
0
    def to_dict(self):
        def iter_decorate(d):
            for key, value in d:
                if key == 'id' and self.backend is not None:
                    value = u'%s@%s' % (self.basename, self.backend)
                yield key, value

                if key == 'split_path':
                    yield key, '/'.join(value)

        fields_iterator = self.iter_fields()
        return OrderedDict(iter_decorate(fields_iterator))
Beispiel #43
0
 def __init__(self, name, backend):
     self.my_id = backend.browser.get_userid()
     self.name = 'wiki/weboob/%s' % name
     self.description = None
     self.date = None
     self.begin = None
     self.end = None
     self.location = None
     self.winner = None
     self.backend = backend
     self.members = OrderedDict()
     self.load()
Beispiel #44
0
    def parse_profile(self, profile, consts):
        if profile['online']:
            self.status = Contact.STATUS_ONLINE
            self.status_msg = u'online'
            self.status_msg = u'since %s' % profile['last_cnx']
        else:
            self.status = Contact.STATUS_OFFLINE
            self.status_msg = u'last connection %s' % profile['last_cnx']

        self.summary = html2text(profile.get('announce', '')).strip().replace('\n\n', '\n')
        if len(profile.get('shopping_list', '')) > 0:
            self.summary += u'\n\nLooking for:\n%s' % html2text(profile['shopping_list']).strip().replace('\n\n', '\n')

        for photo in profile['pics']:
            self.set_photo(photo.split('/')[-1],
                              url=photo + '/full',
                              thumbnail_url=photo + '/small',
                              hidden=False)
        self.profile = OrderedDict()

        if 'sex' in profile:
            for section, d in self.TABLE.iteritems():
                flags = ProfileNode.SECTION
                if section.startswith('_'):
                    flags |= ProfileNode.HEAD
                if (section.startswith('+') and int(profile['sex']) != 1) or \
                   (section.startswith('-') and int(profile['sex']) != 0):
                    continue

                section = section.lstrip('_+-')

                s = ProfileNode(section, section.capitalize(), OrderedDict(), flags=flags)

                for key, builder in d.iteritems():
                    try:
                        value = builder.get_value(profile, consts[int(profile['sex'])])
                    except KeyError:
                        pass
                    else:
                        s.value[key] = ProfileNode(key, key.capitalize().replace('_', ' '), value)

                self.profile[section] = s

        self._aum_profile = profile
Beispiel #45
0
    def format(self, obj, selected_fields=None, alias=None):
        """
        Format an object to be human-readable.
        An object has fields which can be selected.

        :param obj: object to format
        :type obj: BaseObject or dict
        :param selected_fields: fields to display. If None, all fields are selected
        :type selected_fields: tuple
        :param alias: an alias to use instead of the object's ID
        :type alias: unicode
        """
        if isinstance(obj, BaseObject):
            if selected_fields:  # can be an empty list (nothing to do), or None (return all fields)
                obj = obj.copy()
                for name, value in obj.iter_fields():
                    if name not in selected_fields:
                        delattr(obj, name)

            if self.MANDATORY_FIELDS:
                missing_fields = set(self.MANDATORY_FIELDS) - set([name for name, value in obj.iter_fields()])
                if missing_fields:
                    raise MandatoryFieldsNotFound(missing_fields)

            formatted = self.format_obj(obj, alias)
        else:
            try:
                obj = OrderedDict(obj)
            except ValueError:
                raise TypeError('Please give a BaseObject or a dict')

            if selected_fields:
                obj = obj.copy()
                for name, value in obj.iteritems():
                    if name not in selected_fields:
                        obj.pop(name)

            if self.MANDATORY_FIELDS:
                missing_fields = set(self.MANDATORY_FIELDS) - set(obj.iterkeys())
                if missing_fields:
                    raise MandatoryFieldsNotFound(missing_fields)

            formatted = self.format_dict(obj)

        if formatted:
            self.output(formatted)
        return formatted
Beispiel #46
0
    def registerEvent(self):
        selection = self.ui.modulesList.selectedItems()
        if not selection:
            return

        try:
            module = self.weboob.modules_loader.get_or_load_module(unicode(selection[0].text()).lower())
        except ModuleLoadError:
            module = None

        if not module:
            return

        dialog = QDialog(self)
        vbox = QVBoxLayout(dialog)
        if module.website:
            website = 'on the website <b>%s</b>' % module.website
        else:
            website = 'with the module <b>%s</b>' % module.name
        vbox.addWidget(QLabel('To create an account %s, please provide this information:' % website))
        formlayout = QFormLayout()
        props_widgets = OrderedDict()
        for key, prop in module.klass.ACCOUNT_REGISTER_PROPERTIES.iteritems():
            widget = QtValue(prop)
            formlayout.addRow(QLabel(u'%s:' % prop.label), widget)
            props_widgets[prop.id] = widget

        vbox.addLayout(formlayout)
        buttonBox = QDialogButtonBox(dialog)
        buttonBox.setStandardButtons(QDialogButtonBox.Ok|QDialogButtonBox.Cancel)
        self.connect(buttonBox, SIGNAL("accepted()"), dialog.accept)
        self.connect(buttonBox, SIGNAL("rejected()"), dialog.reject)
        vbox.addWidget(buttonBox)

        end = False
        while not end:
            end = True
            if dialog.exec_():
                account = Account()
                account.properties = {}
                for key, widget in props_widgets.iteritems():
                    try:
                        v = widget.get_value()
                    except ValueError as e:
                        QMessageBox.critical(self, self.tr('Invalid value'),
                            unicode(self.tr('Invalid value for field "%s":<br /><br />%s')) % (key, e))
                        end = False
                        break
                    else:
                        account.properties[key] = v
                if end:
                    try:
                        module.klass.register_account(account)
                    except AccountRegisterError as e:
                        QMessageBox.critical(self, self.tr('Error during register'),
                            unicode(self.tr('Unable to register account %s:<br /><br />%s')) % (website, e))
                        end = False
                    else:
                        for key, value in account.properties.iteritems():
                            if key in self.config_widgets:
                                self.config_widgets[key][1].set_value(value)
Beispiel #47
0
class Contact(_Contact):
    TABLE = OrderedDict((
                 ('_info',        OrderedDict((
                                    ('title',               FieldStr('title')),
                                    # ipaddr is not available anymore.
                                    #('IPaddr',              FieldIP('last_ip', 'first_ip')),
                                    ('admin',               FieldBool('admin')),
                                    ('ban',                 FieldBool('isBan')),
                                    ('first',               FieldStr('first_cnx')),
                                    ('godfather',           FieldProfileURL('godfather')),
                                  ))),
                 ('_stats',       OrderedDict((
                                    ('mails',               FieldPopu('mails')),
                                    ('baskets',             FieldPopu('contacts')),
                                    ('charms',              FieldPopu('flashs')),
                                    ('visites',             FieldPopu('visites')),
                                    ('invits',              FieldPopu('invits')),
                                    ('bonus',               FieldPopu('bonus')),
                                    ('score',               FieldStr('points')),
                                    ('ratio',               FieldPopuRatio('mails', 'flashs')),
                                    ('mailable',            FieldBool('can_mail')),
                                  ))),
                 ('details',      OrderedDict((
                                    ('old',                 FieldStr('age')),
                                    #('old',                 FieldOld('birthday')),
                                    ('birthday',            FieldStr('birthday')),
                                    ('zipcode',             FieldStr('zip')),
                                    ('location',            FieldStr('city')),
                                    ('distance',            FieldDist('dist')),
                                    ('country',             FieldStr('country')),
                                    ('phone',               FieldStr('phone')),
                                    ('eyes',                FieldConst('eyes_color')),
                                    ('hair_color',          FieldConst('hair_color')),
                                    ('hair_size',           FieldConst('hair_size')),
                                    ('height',              FieldConst('size')),
                                    ('weight',              FieldConst('weight')),
                                    ('BMI',                 FieldBMI('size', 'weight')),
                                    ('fat',                 FieldBMI('size', 'weight', fat=True)),
                                    ('shape',               FieldConst('shape')),
                                    ('origins',             FieldConst('origins')),
                                    ('signs',               FieldConst('features')),
                                    ('job',                 FieldStr('job')),
                                    ('style',               FieldConst('style')),
                                    ('food',                FieldConst('diet')),
                                    ('drink',               FieldConst('alcohol')),
                                    ('smoke',               FieldConst('tobacco')),
                                  ))),
                ('tastes',        OrderedDict((
                                    ('hobbies',             FieldStr('hobbies')),
                                    ('music',               FieldList('music')),
                                    ('cinema',              FieldList('cinema')),
                                    ('books',               FieldList('books')),
                                    ('tv',                  FieldList('tvs')),
                                  ))),
                ('+sex',          OrderedDict((
                                    ('underwear',           FieldConst('underwear')),
                                    ('practices',           FieldConst('sexgames')),
                                    ('favorite',            FieldConst('arousing')),
                                    ('toys',                FieldConst('sextoys')),
                                  ))),
                ('+personality',  OrderedDict((
                                    ('snap',                FieldStr('fall_for')),
                                    ('exciting',            FieldStr('turned_on_by')),
                                    ('hate',                FieldStr('cant_stand')),
                                    ('vices',               FieldStr('vices')),
                                    ('assets',              FieldStr('assets')),
                                    ('fantasies',           FieldStr('fantasies')),
                                    ('is',                  FieldConst('character')),
                                  )))
        ))

    def parse_profile(self, profile, consts):
        if profile['online']:
            self.status = Contact.STATUS_ONLINE
            self.status_msg = u'online'
            self.status_msg = u'since %s' % profile['last_cnx']
        else:
            self.status = Contact.STATUS_OFFLINE
            self.status_msg = u'last connection %s' % profile['last_cnx']

        self.summary = html2text(profile.get('announce', '')).strip().replace('\n\n', '\n')
        if len(profile.get('shopping_list', '')) > 0:
            self.summary += u'\n\nLooking for:\n%s' % html2text(profile['shopping_list']).strip().replace('\n\n', '\n')

        for photo in profile['pics']:
            self.set_photo(photo.split('/')[-1],
                              url=photo + '/full',
                              thumbnail_url=photo + '/small',
                              hidden=False)
        self.profile = OrderedDict()

        if 'sex' in profile:
            for section, d in self.TABLE.iteritems():
                flags = ProfileNode.SECTION
                if section.startswith('_'):
                    flags |= ProfileNode.HEAD
                if (section.startswith('+') and int(profile['sex']) != 1) or \
                   (section.startswith('-') and int(profile['sex']) != 0):
                    continue

                section = section.lstrip('_+-')

                s = ProfileNode(section, section.capitalize(), OrderedDict(), flags=flags)

                for key, builder in d.iteritems():
                    try:
                        value = builder.get_value(profile, consts[int(profile['sex'])])
                    except KeyError:
                        pass
                    else:
                        s.value[key] = ProfileNode(key, key.capitalize().replace('_', ' '), value)

                self.profile[section] = s

        self._aum_profile = profile

    def get_text(self):
        def print_node(node, level=1):
            result = u''
            if node.flags & node.SECTION:
                result += u'\t' * level + node.label + '\n'
                for sub in node.value.itervalues():
                    result += print_node(sub, level + 1)
            else:
                if isinstance(node.value, (tuple, list)):
                    value = ', '.join(unicode(v) for v in node.value)
                elif isinstance(node.value, float):
                    value = '%.2f' % node.value
                else:
                    value = node.value
                result += u'\t' * level + u'%-20s %s\n' % (node.label + ':', value)
            return result

        result = u'Nickname: %s\n' % self.name
        if self.status & Contact.STATUS_ONLINE:
            s = 'online'
        elif self.status & Contact.STATUS_OFFLINE:
            s = 'offline'
        elif self.status & Contact.STATUS_AWAY:
            s = 'away'
        else:
            s = 'unknown'
        result += u'Status: %s (%s)\n' % (s, self.status_msg)
        result += u'URL: %s\n' % self.url
        result += u'Photos:\n'
        for name, photo in self.photos.iteritems():
            result += u'\t%s%s\n' % (photo, ' (hidden)' if photo.hidden else '')
        result += u'\nProfile:\n'
        for head in self.profile.itervalues():
            result += print_node(head)
        result += u'Description:\n'
        for s in self.summary.split('\n'):
            result += u'\t%s\n' % s
        return result
Beispiel #48
0
class Event(object):
    def __init__(self, name, backend):
        self.my_id = backend.browser.get_userid()
        self.name = 'wiki/weboob/%s' % name
        self.description = None
        self.date = None
        self.begin = None
        self.end = None
        self.location = None
        self.winner = None
        self.backend = backend
        self.members = OrderedDict()
        self.load()

    def get_me(self):
        return self.members.get(self.backend.browser.get_userid(), None)

    def currently_in_event(self):
        if not self.date or not self.begin or not self.end:
            return False

        return self.begin < datetime.now() < self.end

    def is_closed(self):
        return self.end < datetime.now()

    def format_duration(self):
        if not self.begin or not self.end:
            return None

        delta = self.end - self.begin
        return '%02d:%02d' % (delta.seconds/3600, delta.seconds%3600)

    def check_time_coherence(self):
        """
        Check if the end's day is before the begin's one, in
        case it stops at the next day (eg. 15h->1h).

        If it occures, add a day.
        """
        if self.begin > self.end:
            self.end = self.end + timedelta(1)

    def load(self):
        self.content = self.backend.get_content(self.name)
        self.members.clear()
        member = None
        for line in self.content.content.split('\n'):
            line = line.strip()
            if line.startswith('h1. '):
                self.title = line[4:]
            elif line.startswith('h3=. '):
                m = re.match('h3=. Event finished. Winner is "(.*)":/users/(\d+)\!', line)
                if not m:
                    print >>self.stderr, 'Unable to parse h3=: %s' % line
                    continue
                self.winner = Member(int(m.group(2)), m.group(1))
            elif line.startswith('h2. '):
                continue
            elif line.startswith('h3. '):
                m = re.match('h3. "(.*)":/users/(\d+)', line)
                if not m:
                    print >>self.stderr, 'Unable to parse user "%s"' % line
                    continue
                member = Member(int(m.group(2)), m.group(1))
                if member.id == self.my_id:
                    member.is_me = True
                if self.winner is not None and member.id == self.winner.id:
                    self.winner = member
                self.members[member.id] = member
            elif self.description is None and len(line) > 0 and line != '{{TOC}}':
                self.description = line
            elif line.startswith('* '):
                m = re.match('\* \*(\w+)\*: (.*)', line)
                if not m:
                    continue
                key, value = m.group(1), m.group(2)
                if member is None:
                    if key == 'Date':
                        self.date = self.parse_date(value)
                    elif key == 'Start' or key == 'Begin':
                        self.begin = self.parse_time(value)
                    elif key == 'End':
                        self.end = self.parse_time(value)
                        self.check_time_coherence()
                    elif key == 'Location':
                        self.location = value
                else:
                    if key == 'Repository':
                        m = re.match('"(.*.git)":.*', value)
                        if m:
                            member.repository = m.group(1)
                        else:
                            member.repository = value
                    elif key == 'Hardware':
                        member.hardware = value
                    elif key == 'Availabilities':
                        member.availabilities = value
            elif line.startswith('[['):
                m = re.match('\[\[(\w+)\]\]\|\[\[(\w+)\]\]\|(.*)\|', line)
                if not m:
                    print >>self.stderr, 'Unable to parse task: "%s"' % line
                    continue
                task = Task(m.group(1), m.group(2))
                member.tasks.append(task)
                if m.group(3) == '!/img/weboob/_progress.png!':
                    task.status = task.STATUS_PROGRESS
                    continue

                mm = re.match('!/img/weboob/_done.png! (\d+):(\d+) (\w+)', m.group(3))
                if mm and self.date:
                    task.status = task.STATUS_DONE
                    task.date = datetime(self.date.year,
                                         self.date.month,
                                         self.date.day,
                                         int(mm.group(1)),
                                         int(mm.group(2)))
                    task.branch = mm.group(3)

    def parse_date(self, value):
        try:
            return datetime.strptime(value, '%Y-%m-%d')
        except ValueError:
            return None

    def parse_time(self, value):
        m = re.match('(\d+):(\d+)', value)
        if not m:
            return

        try:
            return self.date.replace(hour=int(m.group(1)),
                                     minute=int(m.group(2)))
        except ValueError:
            return None

    def save(self, message):
        if self.winner:
            finished = u'\nh3=. Event finished. Winner is "%s":/users/%d!\n' % (self.winner.name,
                                                                                self.winner.id)
        else:
            finished = u''
        s = u"""h1. %s

{{TOC}}
%s
h2. Event

%s

* *Date*: %s
* *Begin*: %s
* *End*: %s
* *Duration*: %s
* *Location*: %s

h2. Attendees

""" % (self.title,
       finished,
       self.description,
       self.date.strftime('%Y-%m-%d') if self.date else '_Unknown_',
       self.begin.strftime('%H:%M') if self.begin else '_Unknown_',
       self.end.strftime('%H:%M') if self.end else '_Unknown_',
       self.format_duration() or '_Unknown_',
       self.location or '_Unknown_')

        for member in self.members.itervalues():
            if self.date:
                availabilities = ''
            else:
                availabilities = '* *Availabilities*: %s' % member.availabilities
            if member.repository is None:
                repository = '_Unknown_'
            elif member.repository.endswith('.git'):
                repository = '"%s":git://git.symlink.me/pub/%s ("http":http://git.symlink.me/?p=%s;a=summary)'
                repository = repository.replace('%s', member.repository)
            else:
                repository = member.repository

            s += u"""h3. "%s":/users/%d

* *Repository*: %s
* *Hardware*: %s
%s

|_.Backend|_.Capabilities|_.Status|""" % (member.name,
                                        member.id,
                                        repository,
                                        member.hardware,
                                        availabilities)

            for task in member.tasks:
                if task.status == task.STATUS_DONE:
                    status = '!/img/weboob/_done.png! %02d:%02d %s' % (task.date.hour,
                                                                       task.date.minute,
                                                                       task.branch)
                elif task.status == task.STATUS_PROGRESS:
                    status = '!/img/weboob/_progress.png!'
                else:
                    status = ' '
                s += u"""
|=.!/img/weboob/%s.png!:/projects/weboob/wiki/%s
[[%s]]|[[%s]]|%s|""" % (task.backend.lower(), task.backend, task.backend, task.capability, status)
            s += '\n\n'

        self.content.content = s
        self.backend.push_content(self.content, message)
Beispiel #49
0
 def __init__(self, *args, **kwargs):
     super(ListElement, self).__init__(*args, **kwargs)
     self.logger = getLogger(self.__class__.__name__.lower())
     self.objects = OrderedDict()
Beispiel #50
0
class ListElement(AbstractElement):
    item_xpath = None
    flush_at_end = False
    ignore_duplicate = False

    def __init__(self, *args, **kwargs):
        super(ListElement, self).__init__(*args, **kwargs)
        self.logger = getLogger(self.__class__.__name__.lower())
        self.objects = OrderedDict()

    def __call__(self, *args, **kwargs):
        for key, value in kwargs.iteritems():
            self.env[key] = value

        return self.__iter__()

    def find_elements(self):
        """
        Get the nodes that will have to be processed.
        This method can be overridden if xpath filters are not
        sufficient.
        """
        if self.item_xpath is not None:
            for el in self.el.xpath(self.item_xpath):
                yield el
        else:
            yield self.el

    def __iter__(self):
        self.parse(self.el)

        items = []
        for el in self.find_elements():
            for attrname in dir(self):
                attr = getattr(self, attrname)
                if isinstance(attr, type) and issubclass(attr, AbstractElement) and attr != type(self):
                    item = attr(self.page, self, el)
                    item.handle_loaders()
                    items.append(item)

        for item in items:
            for obj in item:
                obj = self.store(obj)
                if obj and not self.flush_at_end:
                    yield obj

        if self.flush_at_end:
            for obj in self.flush():
                yield obj

        self.check_next_page()

    def flush(self):
        for obj in self.objects.itervalues():
            yield obj

    def check_next_page(self):
        if not hasattr(self, 'next_page'):
            return

        next_page = getattr(self, 'next_page')
        try:
            value = self.use_selector(next_page)
        except (AttributeNotFound, XPathNotFound):
            return

        if value is None:
            return

        raise NextPage(value)


    def store(self, obj):
        if obj.id:
            if obj.id in self.objects:
                if self.ignore_duplicate:
                    self.logger.warning('There are two objects with the same ID! %s' % obj.id)
                    return
                else:
                    raise DataError('There are two objects with the same ID! %s' % obj.id)
            self.objects[obj.id] = obj
        return obj