diff --git a/modules/cmso/module.py b/modules/cmso/module.py
index 546d171fdb9d61af37acee54e6920925923e0e28..7bdf9299f89e30ab8456e0b4db3926cffb040350 100644
--- a/modules/cmso/module.py
+++ b/modules/cmso/module.py
@@ -17,6 +17,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with this weboob module. If not, see .
+# flake8: compatible
+
from __future__ import unicode_literals
from weboob.capabilities.bank import CapBankTransfer, Account, AccountNotFound, RecipientNotFound
@@ -41,23 +43,40 @@ class CmsoModule(Module, CapBankTransfer, CapBankWealth, CapContact, CapProfile)
VERSION = '2.1'
DESCRIPTION = 'Crédit Mutuel Sud-Ouest'
LICENSE = 'LGPLv3+'
- CONFIG = BackendConfig(ValueBackendPassword('login', label='Identifiant', masked=False),
- ValueBackendPassword('password', label='Mot de passe'),
- ValueTransient('code'),
- ValueTransient('request_information'),
- Value('website', label='Type de compte', default='par',
- choices={'par': 'Particuliers', 'pro': 'Professionnels'}))
+ CONFIG = BackendConfig(
+ ValueBackendPassword('login', label='Identifiant', masked=False),
+ ValueBackendPassword('password', label='Mot de passe'),
+ ValueTransient('code'),
+ ValueTransient('request_information'),
+ Value(
+ 'website',
+ label='Type de compte',
+ default='par',
+ choices={
+ 'par': 'Particuliers',
+ 'pro': 'Professionnels',
+ }
+ )
+ )
BROWSER = CmsoParBrowser
AVAILABLE_BROWSERS = {'par': CmsoParBrowser, 'pro': CmsoProBrowser}
def create_default_browser(self):
self.BROWSER = self.AVAILABLE_BROWSERS[self.config['website'].get()]
- return self.create_browser("%s.%s" % (self.NAME, 'com' if self.NAME == 'cmso' else 'fr'),
- self.config,
- self.config['login'].get(),
- self.config['password'].get(),
- weboob=self.weboob)
+
+ if self.NAME == 'cmso':
+ tld = 'com'
+ else:
+ tld = 'fr'
+
+ return self.create_browser(
+ "%s.%s" % (self.NAME, tld),
+ self.config,
+ self.config['login'].get(),
+ self.config['password'].get(),
+ weboob=self.weboob
+ )
def get_account(self, _id):
return find_object(self.browser.iter_accounts(), id=_id, error=AccountNotFound)
diff --git a/modules/cmso/par/browser.py b/modules/cmso/par/browser.py
index cd4ab43a2fba91d1a7c286036b202ceef7272bc8..bf0ea2f4619bef8a0a48c5bb303ac759eb160082 100644
--- a/modules/cmso/par/browser.py
+++ b/modules/cmso/par/browser.py
@@ -17,6 +17,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with this weboob module. If not, see .
+# flake8: compatible
+
from __future__ import unicode_literals
import time
@@ -54,7 +56,8 @@ def retry(exc_check, tries=4):
def decorator(func):
@wraps(func)
def wrapper(browser, *args, **kwargs):
- cb = lambda: func(browser, *args, **kwargs)
+ def cb():
+ return func(browser, *args, **kwargs)
for i in range(tries, 0, -1):
try:
@@ -102,9 +105,12 @@ class CmsoParBrowser(TwoFactorBrowser):
RedirectInsurancePage
)
lifeinsurance = URL(r'https://domiweb.suravenir.fr', LifeinsurancePage)
- market = URL(r'/domiapi/oauth/json/ssoDomifronttitre',
- r'https://www.(?P.*)/domifronttitre/front/sso/domiweb/01/(?P.*)Portefeuille\?csrf=',
- r'https://www.*/domiweb/prive/particulier', MarketPage)
+ market = URL(
+ r'/domiapi/oauth/json/ssoDomifronttitre',
+ r'https://www.(?P.*)/domifronttitre/front/sso/domiweb/01/(?P.*)Portefeuille\?csrf=',
+ r'https://www.*/domiweb/prive/particulier',
+ MarketPage
+ )
advisor = URL(r'/edrapi/v(?P\w+)/oauth/(?P\w+)', AdvisorPage)
transfer_info = URL(r'/domiapi/oauth/json/transfer/transferinfos', TransferInfoPage)
@@ -112,7 +118,10 @@ class CmsoParBrowser(TwoFactorBrowser):
# recipients
ext_recipients_list = URL(r'/transfersfedesapi/api/beneficiaries', RecipientsListPage)
int_recipients_list = URL(r'/transfersfedesapi/api/accounts', RecipientsListPage)
- available_int_recipients = URL(r'/transfersfedesapi/api/credited-accounts/(?P.*)', AllowedRecipientsPage)
+ available_int_recipients = URL(
+ r'/transfersfedesapi/api/credited-accounts/(?P.*)',
+ AllowedRecipientsPage
+ )
# transfers
init_transfer_page = URL(r'/transfersfedesapi/api/transfers/control', TransferPage)
@@ -149,7 +158,7 @@ def init_login(self):
if self.headers:
self.session.headers = self.headers
else:
- self.set_profile(self.PROFILE) # reset headers but don't clear them
+ self.set_profile(self.PROFILE) # reset headers but don't clear them
self.session.cookies.clear()
self.accounts_list = []
@@ -166,7 +175,7 @@ def send_sms(self):
data = {
'template': '',
'typeMedia': 'SMS', # can be SVI for interactive voice server
- 'valueMedia': contact_information['portable']['numeroCrypte']
+ 'valueMedia': contact_information['portable']['numeroCrypte'],
}
self.location('/securityapi/otp/generate', json=data)
@@ -192,7 +201,7 @@ def get_sms_data(self):
'accessInfos': {
'efs': self.arkea,
'si': self.arkea_si,
- }
+ },
}
def get_login_data(self):
@@ -355,7 +364,7 @@ def iter_history(self, account):
self.history.go(
json={
'index': account._index,
- 'filtreOperationsComptabilisees': "MOIS_MOINS_UN"
+ 'filtreOperationsComptabilisees': "MOIS_MOINS_UN",
},
page="detailcompte"
)
@@ -394,9 +403,9 @@ def iter_coming(self, account):
if hasattr(c, '_deferred_date'):
c.bdate = c.rdate
c.date = c._deferred_date
- c.type = Transaction.TYPE_DEFERRED_CARD # force deferred card type for comings inside cards
+ c.type = Transaction.TYPE_DEFERRED_CARD # force deferred card type for comings inside cards
- c.vdate = None # vdate don't work for comings
+ c.vdate = None # vdate don't work for comings
comings.append(c)
return iter(comings)
@@ -612,8 +621,7 @@ def __next__(self):
# recreated iterator, consume previous items
try:
- nb = -1
- for nb, sent in enumerate(self.items):
+ for sent in self.items:
new = next(self.it)
if hasattr(new, 'iter_fields'):
equal = dict(sent.iter_fields()) == dict(new.iter_fields())
@@ -623,7 +631,7 @@ def __next__(self):
# safety is not guaranteed
raise BrowserUnavailable('Site replied inconsistently between retries, %r vs %r', sent, new)
except StopIteration:
- raise BrowserUnavailable('Site replied fewer elements (%d) than last iteration (%d)', nb + 1, len(self.items))
+ raise BrowserUnavailable('Site replied fewer elements than last iteration')
except self.exc_check as exc:
self.delogged = True
if self.logger:
diff --git a/modules/cmso/par/pages.py b/modules/cmso/par/pages.py
index 1ef4de643e025262fa3875952ac35acf7b4479f5..e15084b1a87387db908325f1697da8f3d995263c 100644
--- a/modules/cmso/par/pages.py
+++ b/modules/cmso/par/pages.py
@@ -17,6 +17,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with this weboob module. If not, see .
+# flake8: compatible
+
from __future__ import unicode_literals
import re
@@ -88,10 +90,11 @@ def get_keys(self):
def check_response(self):
if "exception" in self.doc:
- self.logger.warning("There are no checking accounts: exception '{}' with code {}".format(
- self.doc['exception']['message'],
- self.doc['exception']['code'])
- )
+ self.logger.warning(
+ "There are no checking accounts: exception %r with code %s",
+ self.doc['exception']['message'],
+ self.doc['exception']['code']
+ )
def get_numbers(self):
keys = self.get_keys()
@@ -114,7 +117,7 @@ def find_elements(self):
selector = self.item_xpath.split('/')
for sub_element in selector:
if isinstance(self.el, dict) and self.el and sub_element == '*':
- self.el = next(iter(self.el.values())) # replace self.el with its first value
+ self.el = next(iter(self.el.values())) # replace self.el with its first value
if sub_element == '*':
continue
self.el = self.el[sub_element]
@@ -124,11 +127,12 @@ def find_elements(self):
class item(ItemElement):
klass = Account
- condition = lambda self: "LIVRET" not in Dict('accountType')(self.el)
+ def condition(self):
+ return "LIVRET" not in Dict('accountType')(self.el)
obj_id = Dict('numeroContratSouscrit')
obj_label = Upper(Dict('lib'))
- obj_currency = Dict('deviseCompteCode')
+ obj_currency = Dict('deviseCompteCode')
obj_coming = CleanDecimal(Dict('AVenir', default=None), default=NotAvailable)
# Iban is available without last 5 numbers, or by sms
obj_iban = NotAvailable
@@ -170,7 +174,9 @@ def obj__recipient_id(self):
def obj_balance(self):
balance = CleanDecimal(Dict('soldeEuro', default="0"))(self)
- return -abs(balance) if Field('type')(self) == Account.TYPE_LOAN else balance
+ if Field('type')(self) == Account.TYPE_LOAN:
+ balance = -abs(balance)
+ return balance
# It can have revolving credit on this page
def obj__total_amount(self):
@@ -305,7 +311,7 @@ def obj__recipient_id(self):
# between the request in iter_accounts and the requests
# listing recipients. Sorting the owner name is a way to
# have the same md5 hash in both of those cases.
- to_hash = '%s %s' % (
+ to_hash = '%s %s' % (
Upper(Field('label'))(self),
''.join(sorted(Field('_owner_name')(self))),
)
@@ -343,14 +349,14 @@ def obj_maturity_date(self):
# Key not always available, when revolving credit not yet consummed
timestamp = Dict('dateFin', default=None)(self)
if timestamp:
- return dt.date.fromtimestamp(timestamp/1000)
+ return dt.date.fromtimestamp(timestamp / 1000)
return NotAvailable
def obj_next_payment_date(self):
# Key not always available, when revolving credit not yet consummed
timestamp = Dict('dateProchaineEcheance', default=None)(self)
if timestamp:
- return dt.date.fromtimestamp(timestamp/1000)
+ return dt.date.fromtimestamp(timestamp / 1000)
return NotAvailable
def obj_balance(self):
@@ -366,16 +372,17 @@ def obj_ownership(self):
class Transaction(FrenchTransaction):
- PATTERNS = [(re.compile(r'^CARTE (?P\d{2})/(?P\d{2}) (?P.*)'), FrenchTransaction.TYPE_CARD),
- (re.compile(r'^(?P(PRLV|PRELEVEMENTS).*)'), FrenchTransaction.TYPE_ORDER),
- (re.compile(r'^(?PRET DAB.*)'), FrenchTransaction.TYPE_WITHDRAWAL),
- (re.compile(r'^(?PECH.*)'), FrenchTransaction.TYPE_LOAN_PAYMENT),
- (re.compile(r'^(?PVIR.*)'), FrenchTransaction.TYPE_TRANSFER),
- (re.compile(r'^(?PANN.*)'), FrenchTransaction.TYPE_PAYBACK),
- (re.compile(r'^(?P(VRST|VERSEMENT).*)'), FrenchTransaction.TYPE_DEPOSIT),
- (re.compile(r'^(?PCHQ.*)'), FrenchTransaction.TYPE_CHECK),
- (re.compile(r'^(?P.*)'), FrenchTransaction.TYPE_BANK)
- ]
+ PATTERNS = [
+ (re.compile(r'^CARTE (?P\d{2})/(?P\d{2}) (?P.*)'), FrenchTransaction.TYPE_CARD),
+ (re.compile(r'^(?P(PRLV|PRELEVEMENTS).*)'), FrenchTransaction.TYPE_ORDER),
+ (re.compile(r'^(?PRET DAB.*)'), FrenchTransaction.TYPE_WITHDRAWAL),
+ (re.compile(r'^(?PECH.*)'), FrenchTransaction.TYPE_LOAN_PAYMENT),
+ (re.compile(r'^(?PVIR.*)'), FrenchTransaction.TYPE_TRANSFER),
+ (re.compile(r'^(?PANN.*)'), FrenchTransaction.TYPE_PAYBACK),
+ (re.compile(r'^(?P(VRST|VERSEMENT).*)'), FrenchTransaction.TYPE_DEPOSIT),
+ (re.compile(r'^(?PCHQ.*)'), FrenchTransaction.TYPE_CHECK),
+ (re.compile(r'^(?P.*)'), FrenchTransaction.TYPE_BANK),
+ ]
class HistoryPage(LoggedPage, JsonPage):
@@ -444,7 +451,7 @@ def parse(self, el):
deferred_date = Dict('dateDiffere', default=None)(x)
if deferred_date:
break
- setattr(self.obj, '_deferred_date', self.FromTimestamp().filter(deferred_date))
+ self.obj._deferred_date = self.FromTimestamp().filter(deferred_date)
class RedirectInsurancePage(LoggedPage, JsonPage):
@@ -485,7 +492,11 @@ def obj_url(self):
@method
class fill_account(ItemElement):
def obj_valuation_diff_ratio(self):
- valuation_diff_percent = CleanDecimal.French('//div[@class="perfContrat"]/span[@class="value"]', default=None)(self)
+ valuation_diff_percent = CleanDecimal.French(
+ '//div[@class="perfContrat"]/span[@class="value"]',
+ default=None
+ )(self)
+
if valuation_diff_percent:
return valuation_diff_percent / 100
return NotAvailable
@@ -543,7 +554,8 @@ def obj_diff_ratio(self):
class MarketPage(LoggedPage, HTMLPage):
def find_account(self, acclabel, accowner):
- accowner = sorted(accowner.lower().split()) # first name and last name may not be ordered the same way on market site...
+ # first name and last name may not be ordered the same way on market site...
+ accowner = sorted(accowner.lower().split())
def get_ids(ref, acclabel, accowner):
ids = None
@@ -564,8 +576,10 @@ def get_ids(ref, acclabel, accowner):
return False
ref = CleanText(self.doc.xpath('//a[contains(@href, "indiceCompte")]'))(self)
- return get_ids('onclick', acclabel, accowner) if not ref else get_ids('href', acclabel, accowner)
-
+ if not ref:
+ return get_ids('onclick', acclabel, accowner)
+ else:
+ return get_ids('href', acclabel, accowner)
def get_account_id(self, acclabel, owner):
account = self.find_account(acclabel, owner)
@@ -638,7 +652,8 @@ class iter_investment(TableElement):
class item(ItemElement):
klass = Investment
- condition = lambda self: not CleanText('//div[has-class("errorConteneur")]', default=None)(self.el)
+ def condition(self):
+ return not CleanText('//div[has-class("errorConteneur")]', default=None)(self.el)
obj_label = Upper(TableCell('label'))
obj_quantity = CleanDecimal.French(TableCell('quantity'), default=NotAvailable)
@@ -681,11 +696,13 @@ class get_profile(ItemElement):
klass = Profile
def obj_id(self):
- return (Dict('identifiantExterne',default=None)(self)
- or Dict('login')(self))
+ return (
+ Dict('identifiantExterne', default=None)(self)
+ or Dict('login')(self)
+ )
obj_name = Format('%s %s', Dict('firstName'), Dict('lastName'))
- obj_email = Dict('email', default=NotAvailable) # can be unavailable on pro website for example
+ obj_email = Dict('email', default=NotAvailable) # can be unavailable on pro website for example
def get_token(self):
return Dict('loginEncrypted')(self.doc)
diff --git a/modules/cmso/par/transfer_pages.py b/modules/cmso/par/transfer_pages.py
index c56be2300365c5ac8c1b1b19b77293fd0d6f27c2..fe3d5dd79a34ed0d402f2deeb3742aea2eb26d67 100644
--- a/modules/cmso/par/transfer_pages.py
+++ b/modules/cmso/par/transfer_pages.py
@@ -17,6 +17,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with this weboob module. If not, see .
+# flake8: compatible
+
from __future__ import unicode_literals
from hashlib import md5
@@ -156,7 +158,8 @@ def find_elements(self):
class item(ItemElement):
klass = Emitter
- condition = lambda self: Dict('eligibiliteDebit', default=None)(self.el)
+ def condition(self):
+ return Dict('eligibiliteDebit', default=None)(self.el)
obj_id = Dict('numeroContratSouscrit')
obj_label = Upper(Dict('lib'))
@@ -173,8 +176,10 @@ def on_load(self):
if self.doc.get('exception') and not self.doc.get('debitAccountOwner'):
if Dict('exception/type')(self.doc) == 1:
# technical error
- assert False, 'Error with code %s occured during init_transfer: %s' % \
- (Dict('exception/code')(self.doc), Dict('exception/message')(self.doc))
+ raise AssertionError(
+ 'Error with code %s occured during init_transfer: %s'
+ % (Dict('exception/code')(self.doc), Dict('exception/message')(self.doc))
+ )
elif Dict('exception/type')(self.doc) == 2:
# user error
raise TransferBankError(message=Dict('exception/message')(self.doc))
diff --git a/modules/cmso/pro/browser.py b/modules/cmso/pro/browser.py
index a1404844066924b77f5e21987e53a11de1e5c78b..9f975de7e548ae600336fe51a4a594c2cd330af7 100644
--- a/modules/cmso/pro/browser.py
+++ b/modules/cmso/pro/browser.py
@@ -17,6 +17,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with this weboob module. If not, see .
+# flake8: compatible
+
from __future__ import unicode_literals
import datetime
@@ -43,12 +45,24 @@
class CmsoProBrowser(LoginBrowser):
login = URL(r'https://api.(?P[\w.]+)/oauth-implicit/token', LoginPage)
subscription = URL(r'https://api.(?P[\w.]+)/domiapi/oauth/json/accesAbonnement', SubscriptionPage)
- accounts = URL(r'/domiweb/prive/professionnel/situationGlobaleProfessionnel/0-situationGlobaleProfessionnel.act', AccountsPage)
- history = URL(r'/domiweb/prive/professionnel/situationGlobaleProfessionnel/1-situationGlobaleProfessionnel.act', HistoryPage)
- password_creation = URL(r'/domiweb/prive/particulier/modificationMotDePasse/0-creationMotDePasse.act', PasswordCreationPage)
+ accounts = URL(
+ r'/domiweb/prive/professionnel/situationGlobaleProfessionnel/0-situationGlobaleProfessionnel.act',
+ AccountsPage
+ )
+ history = URL(
+ r'/domiweb/prive/professionnel/situationGlobaleProfessionnel/1-situationGlobaleProfessionnel.act',
+ HistoryPage
+ )
+ password_creation = URL(
+ r'/domiweb/prive/particulier/modificationMotDePasse/0-creationMotDePasse.act',
+ PasswordCreationPage
+ )
useless = URL(r'/domiweb/prive/particulier/modificationMotDePasse/0-expirationMotDePasse.act', UselessPage)
investment = URL(r'/domiweb/prive/particulier/portefeuilleSituation/0-situationPortefeuille.act', InvestmentPage)
- invest_account = URL(r'/domiweb/prive/particulier/portefeuilleSituation/2-situationPortefeuille.act\?(?:csrf=[^&]*&)?indiceCompte=(?P\d+)&idRacine=(?P\d+)', InvestmentAccountPage)
+ invest_account = URL(
+ r'/domiweb/prive/particulier/portefeuilleSituation/2-situationPortefeuille.act\?(?:csrf=[^&]*&)?indiceCompte=(?P\d+)&idRacine=(?P\d+)',
+ InvestmentAccountPage
+ )
error = URL(r'https://pro.(?P[\w.]+)/auth/errorauthn', ErrorPage)
profile = URL(r'https://api.(?P[\w.]+)/domiapi/oauth/json/edr/infosPerson', ProfilePage)
ssoDomiweb = URL(r'https://api.(?P[\w.]+)/domiapi/oauth/json/ssoDomiwebEmbedded', SSODomiPage)
@@ -201,10 +215,14 @@ def iter_accounts(self):
def _build_next_date_range(self, date_range):
date_format = '%d/%m/%Y'
+
last_day = datetime.datetime.strptime(date_range[10:], date_format)
first_day = last_day + datetime.timedelta(days=1)
last_day = first_day + relativedelta(months=1, days=-1)
- return ''.join((datetime.datetime.strftime(first_day, date_format), datetime.datetime.strftime(last_day, date_format)))
+
+ first_str = datetime.datetime.strftime(first_day, date_format)
+ last_str = datetime.datetime.strftime(last_day, date_format)
+ return first_str + last_str
@need_login
def iter_history(self, account):
diff --git a/modules/cmso/pro/pages.py b/modules/cmso/pro/pages.py
index 7a7df7d38ade8f50b79ecd85d16d0e32e0e778ad..32aed111505fb6e6cae930b86321d458d929d653 100644
--- a/modules/cmso/pro/pages.py
+++ b/modules/cmso/pro/pages.py
@@ -17,6 +17,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with this weboob module. If not, see .
+# flake8: compatible
+
from __future__ import unicode_literals
import re
@@ -24,7 +26,9 @@
from weboob.exceptions import BrowserIncorrectPassword
from weboob.browser.pages import HTMLPage, JsonPage, pagination, LoggedPage
from weboob.browser.elements import ListElement, ItemElement, TableElement, method
-from weboob.browser.filters.standard import CleanText, CleanDecimal, DateGuesser, Env, Field, Filter, Regexp, Currency, Date
+from weboob.browser.filters.standard import (
+ CleanText, CleanDecimal, DateGuesser, Env, Field, Filter, Regexp, Currency, Date,
+)
from weboob.browser.filters.html import Link, Attr, TableCell
from weboob.capabilities.bank import Account
from weboob.capabilities.wealth import Investment
@@ -68,11 +72,12 @@ def logged(self):
class AccountsPage(CMSOPage):
- TYPES = {'COMPTE CHEQUES': Account.TYPE_CHECKING,
- 'COMPTE TITRES': Account.TYPE_MARKET,
- "ACTIV'EPARGNE": Account.TYPE_SAVINGS,
- "TRESO'VIV": Account.TYPE_SAVINGS,
- }
+ TYPES = {
+ 'COMPTE CHEQUES': Account.TYPE_CHECKING,
+ 'COMPTE TITRES': Account.TYPE_MARKET,
+ "ACTIV'EPARGNE": Account.TYPE_SAVINGS,
+ "TRESO'VIV": Account.TYPE_SAVINGS,
+ }
@method
class iter_accounts(ListElement):
@@ -107,8 +112,7 @@ def validate(self, obj):
def on_load(self):
if self.doc.xpath('//p[contains(text(), "incident technique")]'):
- raise BrowserIncorrectPassword("Vous n'avez aucun compte sur cet espace. " \
- "Veuillez choisir un autre type de compte.")
+ raise BrowserIncorrectPassword("Vous n'avez aucun compte sur cet espace. Veuillez choisir un autre type de compte.")
class InvestmentPage(CMSOPage):
@@ -123,8 +127,12 @@ class item(ItemElement):
klass = Account
def obj_id(self):
- area_id = Regexp(CleanText('(./preceding-sibling::tr[@class="LnMnTiers"][1])//span[@class="CelMnTiersT1"]'),
- r'\((\d+)\)', default='')(self)
+ area_id = Regexp(
+ CleanText('(./preceding-sibling::tr[@class="LnMnTiers"][1])//span[@class="CelMnTiersT1"]'),
+ r'\((\d+)\)',
+ default=''
+ )(self)
+
acc_id = Regexp(CleanText('./td[1]'), r'(\d+)\s*(\d+)', r'\1\2')(self)
if area_id:
return '%s.%s' % (area_id, acc_id)
@@ -177,33 +185,38 @@ class item(ItemElement):
def obj_code(self):
if Field('label')(self) == "LIQUIDITES":
return 'XX-liquidity'
+
code = CleanText(TableCell('code'))(self)
- return code if is_isin_valid(code) else NotAvailable
+ if is_isin_valid(code):
+ return code
+ return NotAvailable
def obj_code_type(self):
- return Investment.CODE_TYPE_ISIN if is_isin_valid(Field('code')(self)) else NotAvailable
+ if is_isin_valid(Field('code')(self)):
+ return Investment.CODE_TYPE_ISIN
+ return NotAvailable
class Transaction(FrenchTransaction):
- PATTERNS = [(re.compile(r'^RET DAB (?P\d{2})/?(?P\d{2})(/?(?P\d{2}))? (?P.*)'),
- FrenchTransaction.TYPE_WITHDRAWAL),
- (re.compile(r'CARTE (?P\d{2})/(?P\d{2}) (?P.*)'),
- FrenchTransaction.TYPE_CARD),
- (re.compile(r'^(?PVIR(EMEN)?T? (SEPA)?(RECU|FAVEUR)?)( /FRM)?(?P.*)'),
- FrenchTransaction.TYPE_TRANSFER),
- (re.compile(r'^PRLV (?P.*)( \d+)?$'), FrenchTransaction.TYPE_ORDER),
- (re.compile(r'^(CHQ|CHEQUE) .*$'), FrenchTransaction.TYPE_CHECK),
- (re.compile(r'^(AGIOS /|FRAIS) (?P.*)'), FrenchTransaction.TYPE_BANK),
- (re.compile(r'^(CONVENTION \d+ |F )?COTIS(ATION)? (?P.*)'),
- FrenchTransaction.TYPE_BANK),
- (re.compile(r'^REMISE (?P.*)'), FrenchTransaction.TYPE_DEPOSIT),
- (re.compile(r'^(?P.*)( \d+)? QUITTANCE .*'),
- FrenchTransaction.TYPE_ORDER),
- (re.compile(r'^.* LE (?P\d{2})/(?P\d{2})/(?P\d{2})$'),
- FrenchTransaction.TYPE_UNKNOWN),
- (re.compile(r'^.* PAIEMENT (?P\d{2})/(?P\d{2}) (?P.*)'),
- FrenchTransaction.TYPE_UNKNOWN),
- ]
+ PATTERNS = [
+ (
+ re.compile(r'^RET DAB (?P\d{2})/?(?P\d{2})(/?(?P\d{2}))? (?P.*)'),
+ FrenchTransaction.TYPE_WITHDRAWAL,
+ ),
+ (re.compile(r'CARTE (?P\d{2})/(?P\d{2}) (?P.*)'), FrenchTransaction.TYPE_CARD),
+ (
+ re.compile(r'^(?PVIR(EMEN)?T? (SEPA)?(RECU|FAVEUR)?)( /FRM)?(?P.*)'),
+ FrenchTransaction.TYPE_TRANSFER,
+ ),
+ (re.compile(r'^PRLV (?P.*)( \d+)?$'), FrenchTransaction.TYPE_ORDER),
+ (re.compile(r'^(CHQ|CHEQUE) .*$'), FrenchTransaction.TYPE_CHECK),
+ (re.compile(r'^(AGIOS /|FRAIS) (?P.*)'), FrenchTransaction.TYPE_BANK),
+ (re.compile(r'^(CONVENTION \d+ |F )?COTIS(ATION)? (?P.*)'), FrenchTransaction.TYPE_BANK),
+ (re.compile(r'^REMISE (?P.*)'), FrenchTransaction.TYPE_DEPOSIT),
+ (re.compile(r'^(?P.*)( \d+)? QUITTANCE .*'), FrenchTransaction.TYPE_ORDER),
+ (re.compile(r'^.* LE (?P\d{2})/(?P\d{2})/(?P\d{2})$'), FrenchTransaction.TYPE_UNKNOWN),
+ (re.compile(r'^.* PAIEMENT (?P\d{2})/(?P\d{2}) (?P.*)'), FrenchTransaction.TYPE_UNKNOWN),
+ ]
class CmsoTransactionElement(ItemElement):
@@ -234,9 +247,11 @@ def next_page(self):
return self.page.browser.build_request(url_next_page)
class item(CmsoTransactionElement):
-
def date(selector):
- return DateGuesser(Regexp(CleanText(selector), r'\w+ (\d{2}/\d{2})'), Env('date_guesser')) | Transaction.Date(selector)
+ return (
+ DateGuesser(Regexp(CleanText(selector), r'\w+ (\d{2}/\d{2})'), Env('date_guesser'))
+ | Transaction.Date(selector)
+ )
# CAUTION: this website write a 'Date valeur' inside a div with a class == 'c-ope'
# and a 'Date opération' inside a div with a class == 'c-val'
@@ -260,4 +275,3 @@ def get_sso_url(self):
class AuthCheckUser(HTMLPage):
pass
-