1# -*- coding: utf-8 -*- 2 3# Copyright(C) 2014 Romain Bignon 4# 5# This file is part of weboob. 6# 7# weboob is free software: you can redistribute it and/or modify 8# it under the terms of the GNU Lesser General Public License as published by 9# the Free Software Foundation, either version 3 of the License, or 10# (at your option) any later version. 11# 12# weboob is distributed in the hope that it will be useful, 13# but WITHOUT ANY WARRANTY; without even the implied warranty of 14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15# GNU Lesser General Public License for more details. 16# 17# You should have received a copy of the GNU Lesser General Public License 18# along with weboob. If not, see <http://www.gnu.org/licenses/>. 19 20 21from weboob.tools.misc import to_unicode 22from weboob.tools.compat import StrConv 23 24 25class BrowserIncorrectPassword(Exception): 26 pass 27 28 29class BrowserForbidden(Exception): 30 pass 31 32 33class BrowserBanned(BrowserIncorrectPassword): 34 pass 35 36 37class BrowserUnavailable(Exception): 38 pass 39 40 41class BrowserInteraction(Exception): 42 pass 43 44 45class BrowserQuestion(BrowserInteraction, StrConv): 46 """ 47 When raised by a browser, 48 """ 49 def __init__(self, *fields): 50 self.fields = fields 51 52 def __str__(self): 53 return ", ".join("{}: {}".format( 54 field.id or field.label, field.description) for field in self.fields 55 ) 56 57 def __unicode__(self): 58 return ", ".join( 59 u"{}: {}".format( 60 to_unicode(field.id) or to_unicode(field.label), 61 to_unicode(field.description) 62 ) for field in self.fields 63 ) 64 65 66class DecoupledValidation(BrowserInteraction): 67 def __init__(self, message='', resource=None, *values): 68 super(DecoupledValidation, self).__init__(*values) 69 self.message = message 70 self.resource = resource 71 72 def __str__(self): 73 return self.message 74 75 76class AppValidation(DecoupledValidation): 77 pass 78 79 80class AppValidationError(Exception): 81 pass 82 83 84class AppValidationCancelled(AppValidationError): 85 pass 86 87 88class AppValidationExpired(AppValidationError): 89 pass 90 91 92class BrowserRedirect(BrowserInteraction): 93 def __init__(self, url, resource=None): 94 self.url = url 95 96 # Needed for transfer redirection 97 self.resource = resource 98 99 def __str__(self): 100 return 'Redirecting to %s' % self.url 101 102 103class CaptchaQuestion(Exception): 104 """Site requires solving a CAPTCHA (base class)""" 105 # could be improved to pass the name of the backendconfig key 106 107 def __init__(self, type=None, **kwargs): 108 super(CaptchaQuestion, self).__init__("The site requires solving a captcha") 109 self.type = type 110 for key, value in kwargs.items(): 111 setattr(self, key, value) 112 113 114class WrongCaptchaResponse(Exception): 115 """when website tell us captcha response is not good""" 116 def __init__(self, message=None): 117 super(WrongCaptchaResponse, self).__init__(message or "Captcha response is wrong") 118 119 120class ImageCaptchaQuestion(CaptchaQuestion): 121 type = 'image_captcha' 122 123 image_data = None 124 125 def __init__(self, image_data): 126 super(ImageCaptchaQuestion, self).__init__(self.type, image_data=image_data) 127 128 129class NocaptchaQuestion(CaptchaQuestion): 130 type = 'g_recaptcha' 131 132 website_key = None 133 website_url = None 134 135 def __init__(self, website_key, website_url): 136 super(NocaptchaQuestion, self).__init__(self.type, website_key=website_key, website_url=website_url) 137 138 139class RecaptchaQuestion(CaptchaQuestion): 140 type = 'g_recaptcha' 141 142 website_key = None 143 website_url = None 144 145 def __init__(self, website_key, website_url): 146 super(RecaptchaQuestion, self).__init__(self.type, website_key=website_key, website_url=website_url) 147 148 149class RecaptchaV3Question(CaptchaQuestion): 150 type = 'g_recaptcha' 151 152 website_key = None 153 website_url = None 154 action = None 155 156 def __init__(self, website_key, website_url, action=None): 157 super(RecaptchaV3Question, self).__init__(self.type, website_key=website_key, website_url=website_url) 158 self.action = action 159 160 161class FuncaptchaQuestion(CaptchaQuestion): 162 type = 'funcaptcha' 163 164 website_key = None 165 website_url = None 166 sub_domain = None 167 168 def __init__(self, website_key, website_url, sub_domain=None): 169 super(FuncaptchaQuestion, self).__init__( 170 self.type, website_key=website_key, website_url=website_url, sub_domain=sub_domain) 171 172 173class BrowserHTTPNotFound(Exception): 174 pass 175 176 177class BrowserHTTPError(BrowserUnavailable): 178 pass 179 180 181class BrowserHTTPSDowngrade(Exception): 182 pass 183 184 185class BrowserSSLError(BrowserUnavailable): 186 pass 187 188 189class ParseError(Exception): 190 pass 191 192 193class FormFieldConversionWarning(UserWarning): 194 """ 195 A value has been set to a form's field and has been implicitly converted. 196 """ 197 198 199class NoAccountsException(Exception): 200 pass 201 202 203class ModuleInstallError(Exception): 204 pass 205 206 207class ModuleLoadError(Exception): 208 def __init__(self, module_name, msg): 209 super(ModuleLoadError, self).__init__(msg) 210 self.module = module_name 211 212 213class ActionNeeded(Exception): 214 pass 215 216 217class AuthMethodNotImplemented(ActionNeeded): 218 pass 219 220 221class BrowserPasswordExpired(ActionNeeded): 222 pass 223 224 225class NeedInteractive(Exception): 226 pass 227 228 229class NeedInteractiveForRedirect(NeedInteractive): 230 """ 231 An authentication is required to connect and credentials are not supplied 232 """ 233 pass 234 235 236class NeedInteractiveFor2FA(NeedInteractive): 237 """ 238 A 2FA is required to connect, credentials are supplied but not the second factor 239 """ 240 pass 241