diff --git a/modules/amazon/compat/weboob_exceptions.py b/modules/amazon/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/amazon/compat/weboob_exceptions.py
+++ b/modules/amazon/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/amazonstorecard/compat/weboob_exceptions.py b/modules/amazonstorecard/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/amazonstorecard/compat/weboob_exceptions.py
+++ b/modules/amazonstorecard/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/ameli/compat/weboob_exceptions.py b/modules/ameli/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/ameli/compat/weboob_exceptions.py
+++ b/modules/ameli/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/amelipro/compat/weboob_exceptions.py b/modules/amelipro/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/amelipro/compat/weboob_exceptions.py
+++ b/modules/amelipro/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/americanexpress/compat/weboob_exceptions.py b/modules/americanexpress/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/americanexpress/compat/weboob_exceptions.py
+++ b/modules/americanexpress/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/amundi/compat/weboob_exceptions.py b/modules/amundi/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/amundi/compat/weboob_exceptions.py
+++ b/modules/amundi/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/anticaptcha/compat/weboob_exceptions.py b/modules/anticaptcha/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/anticaptcha/compat/weboob_exceptions.py
+++ b/modules/anticaptcha/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/apivie/compat/weboob_exceptions.py b/modules/apivie/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/apivie/compat/weboob_exceptions.py
+++ b/modules/apivie/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/asana/compat/weboob_exceptions.py b/modules/asana/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/asana/compat/weboob_exceptions.py
+++ b/modules/asana/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/aum/compat/weboob_exceptions.py b/modules/aum/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/aum/compat/weboob_exceptions.py
+++ b/modules/aum/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/aum/optim/compat/weboob_exceptions.py b/modules/aum/optim/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/aum/optim/compat/weboob_exceptions.py
+++ b/modules/aum/optim/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/aviva/compat/weboob_exceptions.py b/modules/aviva/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/aviva/compat/weboob_exceptions.py
+++ b/modules/aviva/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/aviva/pages/compat/weboob_exceptions.py b/modules/aviva/pages/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/aviva/pages/compat/weboob_exceptions.py
+++ b/modules/aviva/pages/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/axabanque/compat/weboob_exceptions.py b/modules/axabanque/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/axabanque/compat/weboob_exceptions.py
+++ b/modules/axabanque/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/axabanque/pages/compat/weboob_exceptions.py b/modules/axabanque/pages/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/axabanque/pages/compat/weboob_exceptions.py
+++ b/modules/axabanque/pages/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/banquepopulaire/compat/weboob_exceptions.py b/modules/banquepopulaire/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/banquepopulaire/compat/weboob_exceptions.py
+++ b/modules/banquepopulaire/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/barclays/compat/weboob_exceptions.py b/modules/barclays/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/barclays/compat/weboob_exceptions.py
+++ b/modules/barclays/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/becm/compat/weboob_exceptions.py b/modules/becm/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/becm/compat/weboob_exceptions.py
+++ b/modules/becm/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/bforbank/compat/weboob_exceptions.py b/modules/bforbank/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/bforbank/compat/weboob_exceptions.py
+++ b/modules/bforbank/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/binck/compat/weboob_exceptions.py b/modules/binck/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/binck/compat/weboob_exceptions.py
+++ b/modules/binck/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/bnpcards/compat/weboob_exceptions.py b/modules/bnpcards/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/bnpcards/compat/weboob_exceptions.py
+++ b/modules/bnpcards/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/bnpcards/corporate/compat/weboob_exceptions.py b/modules/bnpcards/corporate/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/bnpcards/corporate/compat/weboob_exceptions.py
+++ b/modules/bnpcards/corporate/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/bnpcards/phenix/compat/weboob_exceptions.py b/modules/bnpcards/phenix/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/bnpcards/phenix/compat/weboob_exceptions.py
+++ b/modules/bnpcards/phenix/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/bnporc/company/compat/weboob_exceptions.py b/modules/bnporc/company/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/bnporc/company/compat/weboob_exceptions.py
+++ b/modules/bnporc/company/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/bnporc/enterprise/compat/weboob_exceptions.py b/modules/bnporc/enterprise/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/bnporc/enterprise/compat/weboob_exceptions.py
+++ b/modules/bnporc/enterprise/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/bnporc/pp/compat/weboob_exceptions.py b/modules/bnporc/pp/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/bnporc/pp/compat/weboob_exceptions.py
+++ b/modules/bnporc/pp/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/bnppere/compat/weboob_exceptions.py b/modules/bnppere/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/bnppere/compat/weboob_exceptions.py
+++ b/modules/bnppere/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/bolden/compat/weboob_exceptions.py b/modules/bolden/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/bolden/compat/weboob_exceptions.py
+++ b/modules/bolden/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/boursorama/compat/weboob_exceptions.py b/modules/boursorama/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/boursorama/compat/weboob_exceptions.py
+++ b/modules/boursorama/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/bouygues/compat/weboob_exceptions.py b/modules/bouygues/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/bouygues/compat/weboob_exceptions.py
+++ b/modules/bouygues/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/bp/compat/weboob_exceptions.py b/modules/bp/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/bp/compat/weboob_exceptions.py
+++ b/modules/bp/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/bp/pages/compat/weboob_exceptions.py b/modules/bp/pages/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/bp/pages/compat/weboob_exceptions.py
+++ b/modules/bp/pages/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/bred/bred/compat/weboob_exceptions.py b/modules/bred/bred/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/bred/bred/compat/weboob_exceptions.py
+++ b/modules/bred/bred/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/bred/dispobank/compat/weboob_exceptions.py b/modules/bred/dispobank/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/bred/dispobank/compat/weboob_exceptions.py
+++ b/modules/bred/dispobank/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/caissedepargne/cenet/compat/weboob_exceptions.py b/modules/caissedepargne/cenet/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/caissedepargne/cenet/compat/weboob_exceptions.py
+++ b/modules/caissedepargne/cenet/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/caissedepargne/compat/weboob_exceptions.py b/modules/caissedepargne/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/caissedepargne/compat/weboob_exceptions.py
+++ b/modules/caissedepargne/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/carrefourbanque/compat/weboob_exceptions.py b/modules/carrefourbanque/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/carrefourbanque/compat/weboob_exceptions.py
+++ b/modules/carrefourbanque/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/centquatre/compat/weboob_exceptions.py b/modules/centquatre/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/centquatre/compat/weboob_exceptions.py
+++ b/modules/centquatre/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/cesu/compat/weboob_exceptions.py b/modules/cesu/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/cesu/compat/weboob_exceptions.py
+++ b/modules/cesu/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/citibank/compat/weboob_exceptions.py b/modules/citibank/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/citibank/compat/weboob_exceptions.py
+++ b/modules/citibank/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/cityscoot/compat/weboob_exceptions.py b/modules/cityscoot/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/cityscoot/compat/weboob_exceptions.py
+++ b/modules/cityscoot/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/cmes/compat/weboob_exceptions.py b/modules/cmes/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/cmes/compat/weboob_exceptions.py
+++ b/modules/cmes/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/cmso/par/compat/weboob_exceptions.py b/modules/cmso/par/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/cmso/par/compat/weboob_exceptions.py
+++ b/modules/cmso/par/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/cmso/pro/compat/weboob_exceptions.py b/modules/cmso/pro/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/cmso/pro/compat/weboob_exceptions.py
+++ b/modules/cmso/pro/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/cragr/api/compat/weboob_exceptions.py b/modules/cragr/api/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/cragr/api/compat/weboob_exceptions.py
+++ b/modules/cragr/api/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/cragr/regions/compat/weboob_exceptions.py b/modules/cragr/regions/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/cragr/regions/compat/weboob_exceptions.py
+++ b/modules/cragr/regions/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/creditdunord/compat/weboob_exceptions.py b/modules/creditdunord/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/creditdunord/compat/weboob_exceptions.py
+++ b/modules/creditdunord/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/creditmutuel/compat/weboob_exceptions.py b/modules/creditmutuel/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/creditmutuel/compat/weboob_exceptions.py
+++ b/modules/creditmutuel/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/dailymotion/compat/weboob_exceptions.py b/modules/dailymotion/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/dailymotion/compat/weboob_exceptions.py
+++ b/modules/dailymotion/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/degiro/compat/weboob_exceptions.py b/modules/degiro/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/degiro/compat/weboob_exceptions.py
+++ b/modules/degiro/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/delubac/compat/weboob_exceptions.py b/modules/delubac/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/delubac/compat/weboob_exceptions.py
+++ b/modules/delubac/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/dlfp/compat/weboob_exceptions.py b/modules/dlfp/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/dlfp/compat/weboob_exceptions.py
+++ b/modules/dlfp/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/edf/par/compat/weboob_exceptions.py b/modules/edf/par/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/edf/par/compat/weboob_exceptions.py
+++ b/modules/edf/par/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/edf/pro/compat/weboob_exceptions.py b/modules/edf/pro/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/edf/pro/compat/weboob_exceptions.py
+++ b/modules/edf/pro/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/ekwateur/compat/weboob_exceptions.py b/modules/ekwateur/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/ekwateur/compat/weboob_exceptions.py
+++ b/modules/ekwateur/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/ensap/compat/weboob_exceptions.py b/modules/ensap/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/ensap/compat/weboob_exceptions.py
+++ b/modules/ensap/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/feedly/compat/weboob_exceptions.py b/modules/feedly/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/feedly/compat/weboob_exceptions.py
+++ b/modules/feedly/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/fortuneo/compat/weboob_exceptions.py b/modules/fortuneo/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/fortuneo/compat/weboob_exceptions.py
+++ b/modules/fortuneo/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/fortuneo/pages/compat/weboob_exceptions.py b/modules/fortuneo/pages/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/fortuneo/pages/compat/weboob_exceptions.py
+++ b/modules/fortuneo/pages/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/freemobile/compat/weboob_exceptions.py b/modules/freemobile/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/freemobile/compat/weboob_exceptions.py
+++ b/modules/freemobile/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/freemobile/pages/compat/weboob_exceptions.py b/modules/freemobile/pages/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/freemobile/pages/compat/weboob_exceptions.py
+++ b/modules/freemobile/pages/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/funmooc/compat/weboob_exceptions.py b/modules/funmooc/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/funmooc/compat/weboob_exceptions.py
+++ b/modules/funmooc/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/gmf/compat/weboob_exceptions.py b/modules/gmf/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/gmf/compat/weboob_exceptions.py
+++ b/modules/gmf/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/happn/compat/weboob_exceptions.py b/modules/happn/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/happn/compat/weboob_exceptions.py
+++ b/modules/happn/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/hsbc/compat/weboob_exceptions.py b/modules/hsbc/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/hsbc/compat/weboob_exceptions.py
+++ b/modules/hsbc/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/hsbc/pages/compat/weboob_exceptions.py b/modules/hsbc/pages/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/hsbc/pages/compat/weboob_exceptions.py
+++ b/modules/hsbc/pages/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/hsbchk/compat/weboob_exceptions.py b/modules/hsbchk/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/hsbchk/compat/weboob_exceptions.py
+++ b/modules/hsbchk/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/hsbchk/pages/compat/weboob_exceptions.py b/modules/hsbchk/pages/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/hsbchk/pages/compat/weboob_exceptions.py
+++ b/modules/hsbchk/pages/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/ideel/compat/weboob_exceptions.py b/modules/ideel/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/ideel/compat/weboob_exceptions.py
+++ b/modules/ideel/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/imdb/compat/weboob_exceptions.py b/modules/imdb/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/imdb/compat/weboob_exceptions.py
+++ b/modules/imdb/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/infomaniak/compat/weboob_exceptions.py b/modules/infomaniak/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/infomaniak/compat/weboob_exceptions.py
+++ b/modules/infomaniak/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/ing/compat/weboob_exceptions.py b/modules/ing/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/ing/compat/weboob_exceptions.py
+++ b/modules/ing/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/ing/web/compat/weboob_exceptions.py b/modules/ing/web/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/ing/web/compat/weboob_exceptions.py
+++ b/modules/ing/web/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/kiwibank/compat/weboob_exceptions.py b/modules/kiwibank/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/kiwibank/compat/weboob_exceptions.py
+++ b/modules/kiwibank/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/lampiris/compat/weboob_exceptions.py b/modules/lampiris/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/lampiris/compat/weboob_exceptions.py
+++ b/modules/lampiris/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/lcl/compat/weboob_exceptions.py b/modules/lcl/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/lcl/compat/weboob_exceptions.py
+++ b/modules/lcl/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/lcl/enterprise/compat/weboob_exceptions.py b/modules/lcl/enterprise/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/lcl/enterprise/compat/weboob_exceptions.py
+++ b/modules/lcl/enterprise/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/ldlc/compat/weboob_exceptions.py b/modules/ldlc/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/ldlc/compat/weboob_exceptions.py
+++ b/modules/ldlc/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/lendosphere/compat/weboob_exceptions.py b/modules/lendosphere/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/lendosphere/compat/weboob_exceptions.py
+++ b/modules/lendosphere/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/linebourse/compat/weboob_exceptions.py b/modules/linebourse/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/linebourse/compat/weboob_exceptions.py
+++ b/modules/linebourse/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/lucca/compat/weboob_exceptions.py b/modules/lucca/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/lucca/compat/weboob_exceptions.py
+++ b/modules/lucca/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/lunchr/compat/weboob_exceptions.py b/modules/lunchr/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/lunchr/compat/weboob_exceptions.py
+++ b/modules/lunchr/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/materielnet/compat/weboob_exceptions.py b/modules/materielnet/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/materielnet/compat/weboob_exceptions.py
+++ b/modules/materielnet/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/mediawiki/compat/weboob_exceptions.py b/modules/mediawiki/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/mediawiki/compat/weboob_exceptions.py
+++ b/modules/mediawiki/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/myedenred/compat/weboob_exceptions.py b/modules/myedenred/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/myedenred/compat/weboob_exceptions.py
+++ b/modules/myedenred/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/myfoncia/compat/weboob_exceptions.py b/modules/myfoncia/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/myfoncia/compat/weboob_exceptions.py
+++ b/modules/myfoncia/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/myhabit/compat/weboob_exceptions.py b/modules/myhabit/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/myhabit/compat/weboob_exceptions.py
+++ b/modules/myhabit/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/n26/compat/weboob_exceptions.py b/modules/n26/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/n26/compat/weboob_exceptions.py
+++ b/modules/n26/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/nef/compat/weboob_exceptions.py b/modules/nef/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/nef/compat/weboob_exceptions.py
+++ b/modules/nef/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/netfinca/compat/weboob_exceptions.py b/modules/netfinca/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/netfinca/compat/weboob_exceptions.py
+++ b/modules/netfinca/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/okc/compat/weboob_exceptions.py b/modules/okc/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/okc/compat/weboob_exceptions.py
+++ b/modules/okc/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/oney/compat/weboob_exceptions.py b/modules/oney/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/oney/compat/weboob_exceptions.py
+++ b/modules/oney/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/onlinenet/compat/weboob_exceptions.py b/modules/onlinenet/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/onlinenet/compat/weboob_exceptions.py
+++ b/modules/onlinenet/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/openedx/compat/weboob_exceptions.py b/modules/openedx/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/openedx/compat/weboob_exceptions.py
+++ b/modules/openedx/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/orange/compat/weboob_exceptions.py b/modules/orange/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/orange/compat/weboob_exceptions.py
+++ b/modules/orange/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/ovh/compat/weboob_exceptions.py b/modules/ovh/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/ovh/compat/weboob_exceptions.py
+++ b/modules/ovh/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/pajemploi/compat/weboob_exceptions.py b/modules/pajemploi/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/pajemploi/compat/weboob_exceptions.py
+++ b/modules/pajemploi/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/pastealacon/compat/weboob_exceptions.py b/modules/pastealacon/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/pastealacon/compat/weboob_exceptions.py
+++ b/modules/pastealacon/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/pastebin/compat/weboob_exceptions.py b/modules/pastebin/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/pastebin/compat/weboob_exceptions.py
+++ b/modules/pastebin/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/paypal/compat/weboob_exceptions.py b/modules/paypal/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/paypal/compat/weboob_exceptions.py
+++ b/modules/paypal/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/phpbb/compat/weboob_exceptions.py b/modules/phpbb/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/phpbb/compat/weboob_exceptions.py
+++ b/modules/phpbb/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/pixabay/compat/weboob_exceptions.py b/modules/pixabay/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/pixabay/compat/weboob_exceptions.py
+++ b/modules/pixabay/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/playme/compat/weboob_exceptions.py b/modules/playme/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/playme/compat/weboob_exceptions.py
+++ b/modules/playme/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/poivy/compat/weboob_exceptions.py b/modules/poivy/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/poivy/compat/weboob_exceptions.py
+++ b/modules/poivy/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/redmine/compat/weboob_exceptions.py b/modules/redmine/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/redmine/compat/weboob_exceptions.py
+++ b/modules/redmine/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/regionsjob/compat/weboob_exceptions.py b/modules/regionsjob/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/regionsjob/compat/weboob_exceptions.py
+++ b/modules/regionsjob/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/relaiscolis/compat/weboob_exceptions.py b/modules/relaiscolis/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/relaiscolis/compat/weboob_exceptions.py
+++ b/modules/relaiscolis/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/residentadvisor/compat/weboob_exceptions.py b/modules/residentadvisor/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/residentadvisor/compat/weboob_exceptions.py
+++ b/modules/residentadvisor/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/s2e/compat/weboob_exceptions.py b/modules/s2e/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/s2e/compat/weboob_exceptions.py
+++ b/modules/s2e/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/sachsen/compat/weboob_exceptions.py b/modules/sachsen/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/sachsen/compat/weboob_exceptions.py
+++ b/modules/sachsen/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/seloger/browser.py b/modules/seloger/browser.py
index ce07cfd8698589a414e79c6a471c3f5ed3861373..b75b02eaa69c048553afe7a354756c138ab39b12 100644
--- a/modules/seloger/browser.py
+++ b/modules/seloger/browser.py
@@ -18,10 +18,9 @@
# along with this weboob module. If not, see .
from weboob.capabilities.housing import TypeNotSupported, POSTS_TYPES
-from weboob.tools.compat import urlencode
from weboob.browser import PagesBrowser, URL
-from .pages import SearchResultsPage, HousingPage, CitiesPage
+from .pages import SearchResultsPage, HousingPage, CitiesPage, ErrorPage, HousingJsonPage
from weboob.browser.profiles import Android
from .constants import TYPES, RET
@@ -30,50 +29,57 @@
class SeLogerBrowser(PagesBrowser):
- BASEURL = 'http://www.seloger.com'
+ BASEURL = 'https://www.seloger.com'
PROFILE = Android()
- cities = URL('https://autocomplete.svc.groupe-seloger.com/auto/complete/0/Ville/6\?text=(?P.*)', CitiesPage)
- search = URL('https://ws-seloger.svc.groupe-seloger.com/search.xml\?(?P.*)', SearchResultsPage)
- housing = URL('https://ws-seloger.svc.groupe-seloger.com/annonceDetail.xml\?idAnnonce=(?P<_id>\d+)&noAudiotel=(?P\d)',
+ cities = URL(r'https://autocomplete.svc.groupe-seloger.com/auto/complete/0/Ville/6\?text=(?P.*)',
+ CitiesPage)
+ search = URL(r'/list.html\?(?P.*)&LISTING-LISTpg=(?P\d+)', SearchResultsPage)
+ housing = URL(r'/(?P<_id>.+)/detail.htm',
+ r'/annonces/.+',
HousingPage)
+ housing_detail = URL(r'detail,json,caracteristique_bien.json\?idannonce=(?P<_id>\d+)', HousingJsonPage)
+ captcha = URL(r'http://validate.perfdrive.com', ErrorPage)
def search_geo(self, pattern):
return self.cities.open(pattern=pattern).iter_cities()
- def search_housings(self, type, cities, nb_rooms, area_min, area_max,
+ def search_housings(self, _type, cities, nb_rooms, area_min, area_max,
cost_min, cost_max, house_types, advert_types):
- if type not in TYPES:
- raise TypeNotSupported()
- data = {'ci': ','.join(cities),
- 'idtt': TYPES.get(type, 1),
- 'org': 'advanced_search',
- 'surfacemax': area_max or '',
- 'surfacemin': area_min or '',
- 'tri': 'd_dt_crea',
- }
-
- if type == POSTS_TYPES.SALE:
- data['pxmax'] = cost_max or ''
- data['pxmin'] = cost_min or ''
- else:
- data['px_loyermax'] = cost_max or ''
- data['px_loyermin'] = cost_min or ''
+ price = '{}/{}'.format(cost_min or 'NaN', cost_max or 'Nan')
+ surface = '{}/{}'.format(area_min or 'Nan', area_max or 'Nan')
+ rooms = ''
if nb_rooms:
- data['nb_pieces'] = nb_rooms
+ rooms = '&rooms={}'.format(nb_rooms if nb_rooms <= 5 else 5)
- ret = []
- for house_type in house_types:
- if house_type in RET:
- ret.append(RET.get(house_type))
+ viager = ""
+ if _type not in TYPES:
+ raise TypeNotSupported()
+ elif _type != POSTS_TYPES.VIAGER:
+ _type = '{}'.format(TYPES.get(_type))
+ viager = "&natures=1,2,4"
+ else:
+ _type = TYPES.get(_type)
- if ret:
- data['idtypebien'] = ','.join(ret)
+ places = '|'.join(['{{ci:{}}}'.format(c) for c in cities])
+ places = '[{}]'.format(places)
- return self.search.go(request=urlencode(data)).iter_housings(
- query_type=type, advert_types=advert_types
- )
+ ret = ','.join([RET.get(t) for t in house_types if t in RET])
+
+ query = "projects={}{}&places={}&types={}&price={}&surface={}{}&enterprise=0&qsVersion=1.0"\
+ .format(_type,
+ viager,
+ places,
+ ret,
+ price,
+ surface,
+ rooms)
+
+ return self.search.go(query=query, page_number=1).iter_housings(query_type=_type, advert_types=advert_types, ret=ret)
def get_housing(self, _id, obj=None):
- return self.housing.go(_id=_id, noAudiotel=1).get_housing(obj=obj)
+ return self.housing.go(_id=_id).get_housing(obj=obj)
+
+ def get_housing_detail(self, obj):
+ return self.housing_detail.go(_id=obj.id).get_housing(obj=obj)
diff --git a/modules/seloger/compat/weboob_capabilities_address.py b/modules/seloger/compat/weboob_capabilities_address.py
new file mode 100644
index 0000000000000000000000000000000000000000..932d713e8e48cf6e8cc963e42b1eb0dc1464485d
--- /dev/null
+++ b/modules/seloger/compat/weboob_capabilities_address.py
@@ -0,0 +1,62 @@
+# -*- coding: utf-8 -*-
+
+# Copyright(C) 2010-2019 weboob project
+#
+# This file is part of weboob.
+#
+# weboob is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# weboob is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with weboob. If not, see .
+
+from weboob.capabilities.base import (
+ BaseObject, StringField, DecimalField,
+)
+
+
+class GeoCoordinates(BaseObject):
+ latitude = DecimalField('Latitude')
+ longitude = DecimalField('Longitude')
+ altitude = DecimalField('Altitude')
+
+ def __repr__(self):
+ return '<%s %s;%s>' % (type(self).__name__, self.latitude, self.longitude)
+
+
+class PostalAddress(BaseObject):
+ street = StringField('Street address')
+ postal_code = StringField('Postal code')
+ city = StringField('City')
+ region = StringField('Region')
+ country = StringField('Country')
+
+ full_address = StringField('Full address if detailed address is not available')
+
+ def __repr__(self):
+ if self.full_address:
+ return '<%s full_address=%r>' % (type(self).__name__, self.full_address)
+ return '<%s street=%r postal_code=%r region=%r city=%r country=%r>' % (type(self).__name__, self.street, self.postal_code, self.region, self.city, self.country)
+
+
+def compat_field(field, sub):
+ @property
+ def f(self):
+ return getattr(self, field) and getattr(getattr(self, field), sub)
+
+ @f.setter
+ def f(self, value):
+ if not getattr(self, field):
+ type_ = self._fields[field].types[0]
+ setattr(self, field, type_())
+ setattr(getattr(self, field), sub, value)
+
+ return f
+
diff --git a/modules/seloger/compat/weboob_exceptions.py b/modules/seloger/compat/weboob_exceptions.py
new file mode 100644
index 0000000000000000000000000000000000000000..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4
--- /dev/null
+++ b/modules/seloger/compat/weboob_exceptions.py
@@ -0,0 +1,86 @@
+
+import weboob.exceptions as OLD
+
+# can't import *, __all__ is incomplete...
+for attr in dir(OLD):
+ globals()[attr] = getattr(OLD, attr)
+
+
+try:
+ __all__ = OLD.__all__
+except AttributeError:
+ pass
+
+
+class BrowserInteraction(Exception):
+ pass
+
+
+class BrowserQuestion(BrowserInteraction):
+ """
+ When raised by a browser,
+ """
+ def __init__(self, *fields):
+ self.fields = fields
+
+
+class DecoupledValidation(BrowserInteraction):
+ def __init__(self, message='', resource=None, *values):
+ super(DecoupledValidation, self).__init__(*values)
+ self.message = message
+ self.resource = resource
+
+ def __str__(self):
+ return self.message
+
+
+class AppValidation(DecoupledValidation):
+ pass
+
+
+class AppValidationError(Exception):
+ pass
+
+
+class AppValidationCancelled(AppValidationError):
+ pass
+
+
+class AppValidationExpired(AppValidationError):
+ pass
+
+
+class NeedInteractive(Exception):
+ pass
+
+
+class NeedInteractiveForRedirect(NeedInteractive):
+ """
+ An authentication is required to connect and credentials are not supplied
+ """
+ pass
+
+
+class NeedInteractiveFor2FA(NeedInteractive):
+ """
+ A 2FA is required to connect, credentials are supplied but not the second factor
+ """
+ pass
+
+
+class WrongCaptchaResponse(Exception):
+ """when website tell us captcha response is not good"""
+ def __init__(self, message=None):
+ super(WrongCaptchaResponse, self).__init__(message or "Captcha response is wrong")
+
+
+class RecaptchaV3Question(CaptchaQuestion):
+ type = 'g_recaptcha'
+
+ website_key = None
+ website_url = None
+ action = None
+
+ def __init__(self, website_key, website_url, action=None):
+ super(RecaptchaV3Question, self).__init__(self.type, website_key=website_key, website_url=website_url)
+ self.action = action
diff --git a/modules/seloger/module.py b/modules/seloger/module.py
index 1e34665fa220f0d1e3ebaf6d81efdac892f8a40e..5fc2f4afa18d518401edf384f397f5d94f854e8a 100644
--- a/modules/seloger/module.py
+++ b/modules/seloger/module.py
@@ -66,6 +66,15 @@ def fill_photo(self, photo, fields):
return photo
def fill_housing(self, housing, fields):
- return self.browser.get_housing(housing.id, housing)
+
+ if 'DPE' in fields or 'GES' in fields:
+ housing = self.browser.get_housing_detail(housing)
+ fields.remove('DPE')
+ fields.remove('GES')
+
+ if len(fields) > 0:
+ housing = self.browser.get_housing(housing.id, housing)
+
+ return housing
OBJECTS = {HousingPhoto: fill_photo, Housing: fill_housing}
diff --git a/modules/seloger/pages.py b/modules/seloger/pages.py
index 4069cdc3e470c20ce5be80470c6832034571fde7..9b57ab8e996b378a979621c88954777d08c9a4be 100644
--- a/modules/seloger/pages.py
+++ b/modules/seloger/pages.py
@@ -18,19 +18,27 @@
# along with this weboob module. If not, see .
-from weboob.browser.pages import XMLPage, JsonPage, pagination
-from weboob.browser.elements import ItemElement, ListElement, DictElement, method
+from weboob.browser.pages import JsonPage, pagination, HTMLPage
+from weboob.browser.elements import ItemElement, DictElement, method
from weboob.browser.filters.json import Dict
from weboob.browser.filters.html import XPath
from .compat.weboob_browser_filters_standard import (CleanText, CleanDecimal, Currency,
- DateTime, Env, Format, Regexp)
+ Env, Regexp, Field, BrowserURL)
from weboob.capabilities.base import NotAvailable, NotLoaded
from weboob.capabilities.housing import (Housing, HousingPhoto, City,
UTILITIES, ENERGY_CLASS, POSTS_TYPES,
ADVERT_TYPES)
+from .compat.weboob_capabilities_address import PostalAddress
from weboob.tools.capabilities.housing.housing import PricePerMeterFilter
-
+from weboob.tools.json import json
+from .compat.weboob_exceptions import ActionNeeded
from .constants import TYPES, RET
+import codecs
+
+
+class ErrorPage(HTMLPage):
+ def on_load(self):
+ raise ActionNeeded("Please resolve the captcha")
class CitiesPage(JsonPage):
@@ -45,156 +53,210 @@ class item(ItemElement):
obj_name = Dict('Display')
-class SeLogerItem(ItemElement):
- klass = Housing
-
- obj_id = CleanText('idAnnonce')
-
- def obj_type(self):
- idType = int(CleanText('idTypeTransaction')(self))
- type = next(k for k, v in TYPES.items() if v == idType)
- if type == POSTS_TYPES.FURNISHED_RENT:
- # SeLoger does not let us discriminate between furnished and not
- # furnished.
- return POSTS_TYPES.RENT
- return type
-
- def obj_house_type(self):
- idType = CleanText('idTypeBien')(self)
- try:
- return next(k for k, v in RET.items() if v == idType)
- except StopIteration:
- return NotLoaded
-
- obj_title = Format(
- "%s %s%s - %s",
- CleanText('titre'),
- CleanText('surface'),
- CleanText('surfaceUnite'),
- CleanText('ville'),
- )
- obj_date = DateTime(CleanText('dtFraicheur'))
- obj_cost = CleanDecimal('prix', default=NotLoaded)
-
- obj_currency = Currency(Regexp(CleanText('prixUnite'), r'(\W).*', r'\1'))
-
- obj_area = CleanDecimal('surface', default=NotLoaded)
- obj_price_per_meter = PricePerMeterFilter()
- obj_text = CleanText('descriptif')
- obj_rooms = CleanDecimal('nbPiece|nbPieces', default=NotLoaded)
- obj_bedrooms = CleanDecimal('nbChambre|nbChambres', default=NotLoaded)
-
- def obj_location(self):
- location = CleanText('adresse', default="")(self)
- quartier = CleanText('quartier', default=None)(self)
- if not location and quartier is not None:
- location = quartier
- ville = CleanText('ville')(self)
- cp = CleanText('cp')(self)
- return u'%s %s (%s)' % (location, ville, cp)
-
- obj_station = CleanText('proximite', default=NotLoaded)
- obj_url = CleanText('permaLien')
-
-
-class SearchResultsPage(XMLPage):
+class SearchResultsPage(HTMLPage):
+ def __init__(self, *args, **kwargs):
+ HTMLPage.__init__(self, *args, **kwargs)
+ json_content = Regexp(CleanText('//script'),
+ r"window\[\"initialData\"\] = JSON.parse\(\"({.*})\"\);window\[\"tags\"\]")(self.doc)
+ json_content = codecs.unicode_escape_decode(json_content)[0]
+ json_content = json_content.encode('utf-8', 'surrogatepass').decode('utf-8')
+ self.doc = json.loads(json_content)
+
@pagination
@method
- class iter_housings(ListElement):
- item_xpath = "//annonce"
+ class iter_housings(DictElement):
+ item_xpath = 'cards/list'
def next_page(self):
- page = CleanText('//pageSuivante', default=None, replace=[('http://ws.seloger.com/', '')])(self)
- if page:
- return page
+ page_nb = Dict('navigation/pagination/page')(self)
+ max_results = Dict('navigation/pagination/maxResults')(self)
+ results_per_page = Dict('navigation/pagination/resultsPerPage')(self)
+
+ if int(max_results) / int(results_per_page) > int(page_nb):
+ return BrowserURL('search', query=Env('query'), page_number=int(page_nb) + 1)(self)
+
+ # TODO handle bellesdemeures
+
+ class item(ItemElement):
+ klass = Housing
- class item(SeLogerItem):
def condition(self):
- if self.env['query_type'] == POSTS_TYPES.SALE:
- # Ignore VIAGER
- return CleanText('idTypeTransaction')(self) == '2'
- return True
+ return Dict('cardType')(self) not in ['advertising', 'localExpert'] and Dict('id', default=False)(self)
+
+ obj_id = Dict('id')
- def validate(self, obj):
- return (len(self.env['advert_types']) == 1 and
- self.env['advert_types'][0] == obj.advert_type) or \
- self.env['advert_types'] > 1
+ def obj_type(self):
+ idType = int(Env('query_type')(self))
+ type = next(k for k, v in TYPES.items() if v == idType)
+ if type == POSTS_TYPES.FURNISHED_RENT:
+ # SeLoger does not let us discriminate between furnished and not furnished.
+ return POSTS_TYPES.RENT
+ return type
- obj_type = Env('query_type')
+ def obj_title(self):
+ return "{} - {} - {}".format(Dict('estateType')(self),
+ " / ".join(Dict('tags')(self)),
+ Field('location')(self))
def obj_advert_type(self):
- is_agency = (
- ';' not in CleanText('contact/nom')(self)
- )
+ is_agency = Dict('contact/agencyId', default=False)(self)
if is_agency:
return ADVERT_TYPES.PROFESSIONAL
else:
return ADVERT_TYPES.PERSONAL
+ obj_utilities = UTILITIES.EXCLUDED
+
def obj_photos(self):
photos = []
-
- for photo in XPath('./photos/photo/stdUrl')(self):
- photos.append(HousingPhoto(CleanText('.')(photo)))
-
+ for photo in Dict('photos')(self):
+ photos.append(HousingPhoto(photo))
return photos
- def obj_utilities(self):
- currency = CleanText('prixUnite')(self)
- if "+ch" in currency:
- return UTILITIES.EXCLUDED
- elif "cc*" in currency:
- return UTILITIES.INCLUDED
- else:
- return UTILITIES.UNKNOWN
+ def obj_location(self):
+ quartier = Dict('districtLabel')(self)
+ quartier = quartier if quartier else ''
+ ville = Dict('cityLabel')(self)
+ ville = ville if ville else ''
+ cp = Dict('zipCode')(self)
+ cp = cp if cp else ''
+ return u'%s %s (%s)' % (quartier, ville, cp)
+ obj_url = Dict('classifiedURL')
-class HousingPage(XMLPage):
- @method
- class get_housing(SeLogerItem):
+ obj_text = Dict('description')
- def obj_photos(self):
- photos = []
+ obj_cost = CleanDecimal(Dict('pricing/price', default=NotLoaded), default=NotLoaded)
+ obj_currency = Currency(Dict('pricing/price', default=NotLoaded), default=NotLoaded)
+ obj_price_per_meter = CleanDecimal(Dict('pricing/squareMeterPrice'), default=PricePerMeterFilter)
- for photo in XPath('./photos/photo')(self):
- url = CleanText('bigUrl', default=None)(photo)
- if not url:
- url = CleanText('stdUrl', default=None)(photo)
- photos.append(HousingPhoto(url))
- return photos
+
+class HousingPage(HTMLPage):
+ @method
+ class get_housing(ItemElement):
+ klass = Housing
+
+ def parse(self, el):
+ json_content = Regexp(CleanText('//script'), "var ava_data = ({.+?});")(self)
+ json_content = json_content.replace("logged", "\"logged\"")
+ json_content = json_content.replace("lengthcarrousel", "\"lengthcarrousel\"")
+ json_content = json_content.replace("products", "\"products\"")
+ json_content = json_content.replace("// // ANNONCES_SIMILAIRE / RECO", "")
+ self.house_json_datas = json.loads(json_content)['products'][0]
+
+ obj_id = CleanText('//form[@name="central"]/input[@name="idannonce"]/@value')
+
+ def obj_house_type(self):
+ naturebien = CleanText('//form[@name="central"]/input[@name="naturebien"]/@value')(self)
+ try:
+ return next(k for k, v in RET.items() if v == naturebien)
+ except StopIteration:
+ return NotLoaded
+
+ def obj_type(self):
+ idType = int(CleanText('//form[@name="central"]/input[@name="idtt"]/@value')(self))
+ type = next(k for k, v in TYPES.items() if v == idType)
+ if type == POSTS_TYPES.FURNISHED_RENT:
+ # SeLoger does not let us discriminate between furnished and not furnished.
+ return POSTS_TYPES.RENT
+ return type
def obj_advert_type(self):
is_agency = (
- CleanText('contact/rcsSiren')(self) or
- CleanText('contact/rcsNic')(self) or
- CleanText('contact/idAnnuaire')(self)
+ CleanText('//form[@name="central"]/input[@name="nomagance"]/@value')(self) or
+ CleanText('//form[@name="central"]/input[@name="urlagence"]/@value')(self) or
+ CleanText('//form[@name="central"]/input[@name="adresseagence"]/@value')(self)
)
if is_agency:
return ADVERT_TYPES.PROFESSIONAL
else:
return ADVERT_TYPES.PERSONAL
- def obj_DPE(self):
- DPE = CleanText('//bilanConsoEnergie', default="")(self)
- return getattr(ENERGY_CLASS, DPE, NotAvailable)
+ def obj_photos(self):
+ photos = []
- def obj_GES(self):
- GES = CleanText('//bilanEmissionGES', default="")(self)
- return getattr(ENERGY_CLASS, GES, NotAvailable)
+ for photo in XPath('//div[@class="carrousel_slide"]/img/@src')(self):
+ photos.append(HousingPhoto("https:{}".format(photo)))
- def obj_details(self):
- details = {}
- for detail in XPath('//detailAnnonce/details/detail')(self):
- details[CleanText('libelle')(detail)] = CleanText('valeur', default='N/A')(detail)
+ for photo in XPath('//div[@class="carrousel_slide"]/@data-lazy')(self):
+ p = json.loads(photo)
+ photos.append(HousingPhoto("https:{}".format(p['url'])))
- details['Reference'] = CleanText('//detailAnnonce/reference')(self)
- return details
+ return photos
+
+ obj_title = CleanText('//title[1]')
+
+ def obj_location(self):
+ quartier = Regexp(CleanText('//script'),
+ r"'nomQuartier', { value: \"([\w -]+)\", ")(self)
+ ville = CleanText('//form[@name="central"]/input[@name="ville"]/@value')(self)
+ ville = ville if ville else ''
+ cp = CleanText('//form[@name="central"]/input[@name="codepostal"]/@value')(self)
+ cp = cp if cp else ''
+ return u'%s %s (%s)' % (quartier, ville, cp)
+
+ def obj_address(self):
+ p = PostalAddress()
+
+ p.street = Regexp(CleanText('//script'),
+ r"'nomQuartier', { value: \"([\w -]+)\", ")(self)
+ p.postal_code = CleanText('//form[@name="central"]/input[@name="codepostal"]/@value')(self)
+ p.city = CleanText('//form[@name="central"]/input[@name="ville"]/@value')(self)
+ p.full_address = Field('location')(self)
+ return p
+
+ obj_text = CleanText('//form[@name="central"]/input[@name="description"]/@value')
+
+ obj_cost = CleanDecimal(CleanText('//a[@id="price"]'), default=NotLoaded)
+ obj_currency = Currency(CleanText('//a[@id="price"]'), default=NotLoaded)
+ obj_price_per_meter = PricePerMeterFilter()
- obj_phone = CleanText('//contact/telephone')
+ obj_area = CleanDecimal('//form[@name="central"]/input[@name="surface"]/@value', replace_dots=True)
+ obj_url = CleanText('//form[@name="central"]/input[@name="urlannonce"]/@value')
+ obj_phone = CleanText('//div[@class="data-action"]/a[@data-phone]/@data-phone')
def obj_utilities(self):
- mention = CleanText('prixMention')(self)
- if "charges comprises" in mention:
+ mention = CleanText('//span[@class="detail_indice_prix"]', default="")(self)
+ if "(CC) Loyer mensuel charges comprises" in mention:
return UTILITIES.INCLUDED
else:
return UTILITIES.UNKNOWN
+
+ def obj_bedrooms(self):
+ return CleanDecimal(Dict('nb_chambres', default=NotLoaded))(self.house_json_datas)
+
+ def obj_rooms(self):
+ return CleanDecimal(Dict('nb_pieces', default=NotLoaded))(self.house_json_datas)
+
+
+class HousingJsonPage(JsonPage):
+ @method
+ class get_housing(ItemElement):
+ klass = Housing
+
+ def obj_DPE(self):
+ DPE = Dict("energie", default="")(self)
+ if DPE['status'] > 0:
+ return NotAvailable
+ else:
+ return getattr(ENERGY_CLASS, DPE['lettre'], NotAvailable)
+
+ def obj_GES(self):
+ GES = Dict("ges", default="")(self)
+ if GES['status'] > 0:
+ return NotAvailable
+ else:
+ return getattr(ENERGY_CLASS, GES['lettre'], NotAvailable)
+
+ def obj_details(self):
+ details = {}
+
+ for c in Dict('categories')(self):
+ if c['criteria']:
+ details[c['name']] = ' / '.join([_['value'] for _ in c['criteria']])
+
+ for _, c in Dict('infos_acquereur')(self).items():
+ for key, value in c.items():
+ details[key] = value
+
+ return details
diff --git a/modules/seloger/test.py b/modules/seloger/test.py
index fae7e086c1652d2a80c1f4f14277de4e8df8acbc..3bc358b737e22a54d69cdfd53ed7cf70dfbc746a 100644
--- a/modules/seloger/test.py
+++ b/modules/seloger/test.py
@@ -33,9 +33,6 @@ class SeLogerTest(BackendTest, HousingTest):
"cost", # Some posts don't have cost in seloger
"currency", # Same
"photos",
- "station",
- "rooms",
- "bedrooms"
]
FIELDS_ALL_SINGLE_HOUSING = [
"id", "url", "type", "advert_type", "house_type", "title", "area",
diff --git a/modules/societegenerale/compat/weboob_exceptions.py b/modules/societegenerale/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/societegenerale/compat/weboob_exceptions.py
+++ b/modules/societegenerale/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/societegenerale/pages/compat/weboob_exceptions.py b/modules/societegenerale/pages/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/societegenerale/pages/compat/weboob_exceptions.py
+++ b/modules/societegenerale/pages/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/societegenerale/sgpe/compat/weboob_exceptions.py b/modules/societegenerale/sgpe/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/societegenerale/sgpe/compat/weboob_exceptions.py
+++ b/modules/societegenerale/sgpe/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/sogecartenet/compat/weboob_exceptions.py b/modules/sogecartenet/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/sogecartenet/compat/weboob_exceptions.py
+++ b/modules/sogecartenet/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/spirica/compat/weboob_exceptions.py b/modules/spirica/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/spirica/compat/weboob_exceptions.py
+++ b/modules/spirica/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/suravenir/compat/weboob_exceptions.py b/modules/suravenir/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/suravenir/compat/weboob_exceptions.py
+++ b/modules/suravenir/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/t411/compat/weboob_exceptions.py b/modules/t411/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/t411/compat/weboob_exceptions.py
+++ b/modules/t411/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/tapatalk/compat/weboob_exceptions.py b/modules/tapatalk/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/tapatalk/compat/weboob_exceptions.py
+++ b/modules/tapatalk/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/themisbanque/compat/weboob_exceptions.py b/modules/themisbanque/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/themisbanque/compat/weboob_exceptions.py
+++ b/modules/themisbanque/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/ticketscesu/compat/weboob_exceptions.py b/modules/ticketscesu/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/ticketscesu/compat/weboob_exceptions.py
+++ b/modules/ticketscesu/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/tinder/compat/weboob_exceptions.py b/modules/tinder/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/tinder/compat/weboob_exceptions.py
+++ b/modules/tinder/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/trainline/compat/weboob_exceptions.py b/modules/trainline/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/trainline/compat/weboob_exceptions.py
+++ b/modules/trainline/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/twitter/compat/weboob_exceptions.py b/modules/twitter/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/twitter/compat/weboob_exceptions.py
+++ b/modules/twitter/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/vicsec/compat/weboob_exceptions.py b/modules/vicsec/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/vicsec/compat/weboob_exceptions.py
+++ b/modules/vicsec/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/vicseccard/compat/weboob_exceptions.py b/modules/vicseccard/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/vicseccard/compat/weboob_exceptions.py
+++ b/modules/vicseccard/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/wiseed/compat/weboob_exceptions.py b/modules/wiseed/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/wiseed/compat/weboob_exceptions.py
+++ b/modules/wiseed/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/yggtorrent/compat/weboob_exceptions.py b/modules/yggtorrent/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/yggtorrent/compat/weboob_exceptions.py
+++ b/modules/yggtorrent/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/modules/yomoni/compat/weboob_exceptions.py b/modules/yomoni/compat/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/modules/yomoni/compat/weboob_exceptions.py
+++ b/modules/yomoni/compat/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor
diff --git a/tools/stable_backport_data/weboob_exceptions.py b/tools/stable_backport_data/weboob_exceptions.py
index 05261f6961beeeb6653b34af377b3656c621b585..ef2b5d45f5b38e8ce359d482530bed59f3fdefc4 100644
--- a/tools/stable_backport_data/weboob_exceptions.py
+++ b/tools/stable_backport_data/weboob_exceptions.py
@@ -59,8 +59,8 @@ class NeedInteractiveForRedirect(NeedInteractive):
An authentication is required to connect and credentials are not supplied
"""
pass
-
-
+
+
class NeedInteractiveFor2FA(NeedInteractive):
"""
A 2FA is required to connect, credentials are supplied but not the second factor