diff --git a/contrib/munin/boobank-munin b/contrib/munin/boobank-munin index e6279c52e0571c327756991f172f872766139b1b..67c88adb58dc829ae38c28d50e9194831654d7fa 100755 --- a/contrib/munin/boobank-munin +++ b/contrib/munin/boobank-munin @@ -28,6 +28,7 @@ from weboob.core import Weboob, CallErrors from weboob.capabilities.bank import CapBank from weboob.exceptions import BrowserIncorrectPassword + class BoobankMuninPlugin(object): def __init__(self): if 'weboob_path' in os.environ: diff --git a/contrib/windows-install/convertPNG2ICO.py b/contrib/windows-install/convertPNG2ICO.py index 943fbff1051bee009e44a74c14310aec1c340121..13c221812e4102cd801bf04871c7f89f144078a1 100644 --- a/contrib/windows-install/convertPNG2ICO.py +++ b/contrib/windows-install/convertPNG2ICO.py @@ -33,6 +33,7 @@ # bpp: bits per pixel, could *only* be 24 or 32! # return: an "array" of BYTES which, if write to file, is a size*size ico file + def genico(data, size=16, bpp=24): from array import array a = array('B') @@ -80,7 +81,6 @@ def genico(data, size=16, bpp=24): return a - # x,y indicate the hotspot position # simply set the type/hotspot(x&y) after generates the icon def gencur(data, size=16, bpp=24, x=0, y=0): @@ -89,7 +89,6 @@ def gencur(data, size=16, bpp=24, x=0, y=0): return a - #C:\Python27\Lib\site-packages\weboob-0.g-py2.7.egg\share\icons\hicolor\64x64\apps if __name__ == "__main__": diff --git a/contrib/windows-install/ez_setup.py b/contrib/windows-install/ez_setup.py index e0c57d97312c41737930310694d9c1cda063f6e6..eb2d529086712bd69aa77bec6330d170ba4ef4ec 100644 --- a/contrib/windows-install/ez_setup.py +++ b/contrib/windows-install/ez_setup.py @@ -32,12 +32,15 @@ DEFAULT_VERSION = "1.1.6" DEFAULT_URL = "https://pypi.python.org/packages/source/s/setuptools/" + def _python_cmd(*args): args = (sys.executable,) + args return subprocess.call(args) == 0 + def _check_call_py24(cmd, *args, **kwargs): res = subprocess.call(cmd, *args, **kwargs) + class CalledProcessError(Exception): pass if not res == 0: @@ -45,6 +48,7 @@ class CalledProcessError(Exception): raise CalledProcessError(msg) vars(subprocess).setdefault('check_call', _check_call_py24) + def _install(tarball, install_args=()): # extracting the tarball tmpdir = tempfile.mkdtemp() @@ -151,6 +155,7 @@ def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, return _do_download(version, download_base, to_dir, download_delay) + def download_file_powershell(url, target): """ Download the file at url to target using Powershell (which will validate @@ -164,6 +169,7 @@ def download_file_powershell(url, target): ] subprocess.check_call(cmd) + def has_powershell(): if platform.system() != 'Windows': return False @@ -180,10 +186,12 @@ def has_powershell(): download_file_powershell.viable = has_powershell + def download_file_curl(url, target): cmd = ['curl', url, '--silent', '--output', target] subprocess.check_call(cmd) + def has_curl(): cmd = ['curl', '--version'] devnull = open(os.path.devnull, 'wb') @@ -198,10 +206,12 @@ def has_curl(): download_file_curl.viable = has_curl + def download_file_wget(url, target): cmd = ['wget', url, '--quiet', '--output-document', target] subprocess.check_call(cmd) + def has_wget(): cmd = ['wget', '--version'] devnull = open(os.path.devnull, 'wb') @@ -216,6 +226,7 @@ def has_wget(): download_file_wget.viable = has_wget + def download_file_insecure(url, target): """ Use Python to download the file, even though it cannot authenticate the @@ -241,6 +252,7 @@ def download_file_insecure(url, target): download_file_insecure.viable = lambda: True + def get_best_downloader(): downloaders = [ download_file_powershell, @@ -253,6 +265,7 @@ def get_best_downloader(): if dl.viable(): return dl + def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, delay=15, downloader_factory=get_best_downloader): @@ -338,6 +351,7 @@ def _build_install_args(options): install_args.append('--user') return install_args + def _parse_args(): """ Parse the command line for options @@ -359,6 +373,7 @@ def _parse_args(): # positional arguments are ignored return options + def main(version=DEFAULT_VERSION): """Install or upgrade setuptools and EasyInstall""" options = _parse_args() diff --git a/modules/750g/module.py b/modules/750g/module.py index 2e284fb6a632677ef0d6f24c5385c3937b782850..ba71c6c37417c663f8f9a5d49659451c8e79e3bd 100644 --- a/modules/750g/module.py +++ b/modules/750g/module.py @@ -24,6 +24,7 @@ import unicodedata + def strip_accents(s): return ''.join(c for c in unicodedata.normalize('NFD', s) if unicodedata.category(c) != 'Mn') diff --git a/modules/750g/pages.py b/modules/750g/pages.py index c29b0536fde717fb3608e51fcfec98e55b7a5ceb..ed4e2a9ac04c0b2e1226c995e9b2ca76c3d4df63 100644 --- a/modules/750g/pages.py +++ b/modules/750g/pages.py @@ -26,6 +26,7 @@ class ResultsPage(Page): """ Page which contains results as a list of recipies """ + def iter_recipes(self): for div in self.parser.select(self.document.getroot(), 'div.recette_description > div.data'): links = self.parser.select(div, 'div.info > p.title > a.fn') @@ -65,6 +66,7 @@ def iter_recipes(self): class RecipePage(Page): """ Page which contains a recipe """ + def get_recipe(self, id): title = NotAvailable preparation_time = NotAvailable diff --git a/modules/allocine/test.py b/modules/allocine/test.py index bde18710be56455803d78522e2c1567a37e27021..499231cc380325e237dce38250fba6f0d5c13158 100644 --- a/modules/allocine/test.py +++ b/modules/allocine/test.py @@ -20,6 +20,7 @@ from weboob.tools.test import BackendTest import re + class AllocineTest(BackendTest): MODULE = 'allocine' diff --git a/modules/alloresto/module.py b/modules/alloresto/module.py index 89aae4ab9b1b92e1683e0acafaa7798cdc1a5e28..70b7864c467fffaabfc57ffab809b5e0c2aefa4c 100644 --- a/modules/alloresto/module.py +++ b/modules/alloresto/module.py @@ -60,4 +60,3 @@ def iter_history(self, account): def iter_coming(self, account): return self.browser.get_coming(account) - diff --git a/modules/alloresto/pages.py b/modules/alloresto/pages.py index 5a5399949088740330aa8d90d4d147412820dfc5..4c33eb42d271e79efe813ed4033681a8f63cf433 100644 --- a/modules/alloresto/pages.py +++ b/modules/alloresto/pages.py @@ -52,6 +52,7 @@ def __call__(self): class MyDate(Filter): MONTHS = ['janv', u'févr', u'mars', u'avr', u'mai', u'juin', u'juil', u'août', u'sept', u'oct', u'nov', u'déc'] + def filter(self, txt): day, month, year = txt.split(' ') day = int(day) diff --git a/modules/allrecipes/pages.py b/modules/allrecipes/pages.py index 5060f431c9413aa01983a89aa7fc82b2b7fde58e..8fc91e35f4788bc2e269a47e86a26cfc8c419387 100644 --- a/modules/allrecipes/pages.py +++ b/modules/allrecipes/pages.py @@ -30,6 +30,7 @@ class FourOFourPage(Page): class ResultsPage(Page): """ Page which contains results as a list of recipies """ + def iter_recipes(self): for div in self.parser.select(self.document.getroot(), 'div.recipe-info'): thumbnail_url = NotAvailable @@ -59,6 +60,7 @@ def iter_recipes(self): class RecipePage(Page): """ Page which contains a recipe """ + def get_recipe(self, id): title = NotAvailable preparation_time = NotAvailable diff --git a/modules/ameli/pages.py b/modules/ameli/pages.py index 8abd1c4a5fcb147d55e35c0fc3a3abb01d8f09c8..156af1276423351c8117a8cf2180f2fe769ed89a 100644 --- a/modules/ameli/pages.py +++ b/modules/ameli/pages.py @@ -29,6 +29,7 @@ # Ugly array to avoid the use of french locale FRENCH_MONTHS = [u'janvier', u'février', u'mars', u'avril', u'mai', u'juin', u'juillet', u'août', u'septembre', u'octobre', u'novembre', u'décembre'] + class AmeliBasePage(Page): def is_logged(self): try: @@ -40,6 +41,7 @@ def is_logged(self): self.logger.debug('logged: %s' % (logged)) return logged + class LoginPage(AmeliBasePage): def login(self, login, password): self.browser.select_form('connexionCompteForm') @@ -47,9 +49,11 @@ def login(self, login, password): self.browser["connexioncompte_2codeConfidentiel"] = password.encode('utf8') self.browser.submit() + class HomePage(AmeliBasePage): pass + class AccountPage(AmeliBasePage): def iter_subscription_list(self): idents = self.document.xpath('//div[contains(@class, "blocfond")]') diff --git a/modules/americanexpress/module.py b/modules/americanexpress/module.py index 2bd42a7fe0caa56a0c2d74abab8dfa771930e76d..e5b00ad1c10812669b15c42d00e01dfd57ae8823 100644 --- a/modules/americanexpress/module.py +++ b/modules/americanexpress/module.py @@ -63,4 +63,3 @@ def iter_history(self, account): transactions = list(self.browser.get_history(account)) transactions.sort(key=lambda tr: tr.rdate, reverse=True) return transactions - diff --git a/modules/americanexpress/pages.py b/modules/americanexpress/pages.py index 35e939ec12f7e939b8cc02949eee648d7af1293a..a862313cf1fd9e6907372f2a5d6ac0fbebc0995f 100644 --- a/modules/americanexpress/pages.py +++ b/modules/americanexpress/pages.py @@ -56,6 +56,7 @@ def get_list(self): yield a + class TransactionsPage(Page): COL_ID = 0 COL_DATE = 1 @@ -81,6 +82,7 @@ def get_end_debit_date(self): return datetime.date(int(m.group(3)), self.MONTHS.index(m.group(2).rstrip('.')) + 1, int(m.group(1))) + def get_beginning_debit_date(self): for option in self.document.xpath('//select[@id="viewPeriod"]/option'): if 'selected' in option.attrib: diff --git a/modules/audioaddict/test.py b/modules/audioaddict/test.py index 6b8eee0ff5ad7270d4e5a5420cffcaf69b0c88ac..e65fbd7204ff89599899aac098b4f38f039749b0 100644 --- a/modules/audioaddict/test.py +++ b/modules/audioaddict/test.py @@ -39,4 +39,3 @@ def test_audioaddict(self): self.assertTrue(radio.current.what) self.assertTrue(radio.streams[0].url) self.assertTrue(radio.streams[0].title) - diff --git a/modules/aum/browser.py b/modules/aum/browser.py index 71c23ff6a1674796caa8090285a4fa045d81f0a6..fb367f96f63c2abe472c819caf6b21af912c5561 100644 --- a/modules/aum/browser.py +++ b/modules/aum/browser.py @@ -127,6 +127,7 @@ def get_profile(self, id): return profile + class AuMBrowser(Browser): DOMAIN = 'www.adopteunmec.com' APIKEY = 'fb0123456789abcd' diff --git a/modules/axabanque/pages.py b/modules/axabanque/pages.py index 33626c83f7c65d289a084cf8c977c56da30e1a60..5d7ef9f519d40bf561cc4f7c3b1f3d9573cc4b4a 100644 --- a/modules/axabanque/pages.py +++ b/modules/axabanque/pages.py @@ -256,6 +256,7 @@ def get_history(self): yield t + class CBTransactionsPage(TransactionsPage): COL_CB_CREDIT = 2 diff --git a/modules/banqueaccord/pages.py b/modules/banqueaccord/pages.py index 11720f05b4b922b1db68d897f8af0d8ff606139a..b91d848d4c534e86bd2fa61e60e5f83d94547e60 100644 --- a/modules/banqueaccord/pages.py +++ b/modules/banqueaccord/pages.py @@ -87,6 +87,7 @@ def get_string_code(self, string): code += self.get_symbol_code(self.symbols[c]) return code + class LoginPage(HTMLPage): def login(self, login, password): vk = VirtKeyboard(self) @@ -98,6 +99,7 @@ def login(self, login, password): form['code'] = code form.submit() + class IndexPage(LoggedPage, HTMLPage): @method class get_list(ListElement): @@ -152,6 +154,7 @@ def iter_loan_transactions(self): def get_card_name(self): return CleanText('//h1[1]')(self.doc) + class AccountsPage(LoggedPage, HTMLPage): def get_balance(self): balance = Decimal('0.0') diff --git a/modules/banquepopulaire/browser.py b/modules/banquepopulaire/browser.py index b1888db6cd96c10e685f14f49482cf27f0a710f6..1f500b25a19ee43cdf06c9f71f56b8b3a6e7a5e9 100644 --- a/modules/banquepopulaire/browser.py +++ b/modules/banquepopulaire/browser.py @@ -82,6 +82,7 @@ def login(self): self.token = self.page.get_token() ACCOUNT_URLS = ['mesComptes', 'mesComptesPRO', 'maSyntheseGratuite', 'accueilSynthese'] + def go_on_accounts_list(self): for taskInfoOID in self.ACCOUNT_URLS: self.location(self.buildurl('/cyber/internet/StartTask.do', taskInfoOID=taskInfoOID, token=self.token)) diff --git a/modules/bnporc/enterprise/pages.py b/modules/bnporc/enterprise/pages.py index 1657325c8ba53238f66ea8a9bb6476e65866bfb0..ea9d52fca3aa222422ef22d8b0c12e0d5985f35d 100644 --- a/modules/bnporc/enterprise/pages.py +++ b/modules/bnporc/enterprise/pages.py @@ -267,5 +267,6 @@ def get_next_numpage(self): # Last page return None + class UnknownPage(BEPage): pass diff --git a/modules/boursorama/pages/__init__.py b/modules/boursorama/pages/__init__.py index 3fc78d1454ee06e1c6a7570982a22a7a4adb36d1..44da434a72f36b120f487920d3340f52a15b0346 100644 --- a/modules/boursorama/pages/__init__.py +++ b/modules/boursorama/pages/__init__.py @@ -26,6 +26,7 @@ from .two_authentication import AuthenticationPage + class AccountPrelevement(AccountsList): pass diff --git a/modules/bp/pages/login.py b/modules/bp/pages/login.py index 5fda4a1e7f96111abc3cd2fc786e82d8834a9bf1..6224caf6222d830aacd29aa1f825473495395f32 100644 --- a/modules/bp/pages/login.py +++ b/modules/bp/pages/login.py @@ -37,6 +37,7 @@ class UnavailablePage(Page): def on_loaded(self): raise BrowserUnavailable() + class Keyboard(VirtKeyboard): symbols={'0':'daa52d75287bea58f505823ef6c8b96c', '1':'f5da96c2592803a8cdc5a928a2e4a3b0', @@ -86,6 +87,7 @@ def get_symbol_coords(self, coords): x1, y1, x2, y2 = coords return VirtKeyboard.get_symbol_coords(self, (x1+3, y1+3, x2-3, y2-3)) + class LoginPage(Page): def login(self, login, pwd): vk = Keyboard(self) diff --git a/modules/btdigg/module.py b/modules/btdigg/module.py index bc2cfe432a43fe66e7d74d7108220ddd097c8652..9f76b66ea144e53fcbfd89df596810c9649ff217 100644 --- a/modules/btdigg/module.py +++ b/modules/btdigg/module.py @@ -8,6 +8,7 @@ __all__ = ['BTDiggModule'] + class BTDiggModule(Module, CapTorrent): NAME = 'btdigg' MAINTAINER = u'Matthieu Rakotojaona' diff --git a/modules/btdigg/pages/torrents.py b/modules/btdigg/pages/torrents.py index aa97b3222247e6fc1431ddcc15f1414955d885c9..962db295701b7b52dd5a1b0c65d081fe880e5edb 100644 --- a/modules/btdigg/pages/torrents.py +++ b/modules/btdigg/pages/torrents.py @@ -50,6 +50,7 @@ def iter_torrents(self): torrent.date = date yield torrent + class TorrentPage(Page): def get_torrent(self, id): trs = self.document.getroot().cssselect('table.torrent_info_tbl tr') diff --git a/modules/caissedepargne/pages.py b/modules/caissedepargne/pages.py index 1d8c586f49c840db0f7ddff6e7dfb4595c9ea3ba..e307bd7ab84a1ca9915a80d7670fa623da5e9e5a 100644 --- a/modules/caissedepargne/pages.py +++ b/modules/caissedepargne/pages.py @@ -39,6 +39,7 @@ def on_loaded(self): except BrokenPageError: pass + class LoginPage(_LogoutPage): def login(self, login): self.browser.select_form(name='Main') @@ -83,6 +84,7 @@ def login3(self, passwd): class ErrorPage(_LogoutPage): pass + class UnavailablePage(Page): def on_loaded(self): try: diff --git a/modules/chronopost/pages.py b/modules/chronopost/pages.py index b7038228d394664ce8e7af70f4ea9138046ee2f6..5d80eb33b67fe9f99db7d069d471059096f74beb 100644 --- a/modules/chronopost/pages.py +++ b/modules/chronopost/pages.py @@ -32,6 +32,7 @@ def track_package(self, _id): self.browser['chronoNumbers'] = _id.encode('utf-8') self.browser.submit() + class TrackPage(Page): def get_info(self, id): if len(self.document.xpath('//libelle[@nom="MSG_AUCUN_EVT"]')) > 0: diff --git a/modules/cic/pages.py b/modules/cic/pages.py index 4c76f5da688cc34e2135eca52817e2e2ef32ed28..6d89d29c2532859d28b0468f1eff2dee1ea74ccf 100644 --- a/modules/cic/pages.py +++ b/modules/cic/pages.py @@ -47,10 +47,12 @@ class ChangePasswordPage(Page): def on_loaded(self): raise BrowserIncorrectPassword('Please change your password') + class VerifCodePage(Page): def on_loaded(self): raise BrowserIncorrectPassword('Unable to login: website asks a code from a card') + class InfoPage(Page): pass @@ -303,6 +305,7 @@ def get_history(self): tr.set_amount(tds[-1].text) yield tr + class NoOperationsPage(OperationsPage): def get_history(self): return iter([]) diff --git a/modules/colisprive/pages.py b/modules/colisprive/pages.py index 70ee6241d0821d8c248f73a54b40f0181c2b79c3..b38ac110d13b028a756e519f37d7c4c3e764b390 100644 --- a/modules/colisprive/pages.py +++ b/modules/colisprive/pages.py @@ -26,6 +26,7 @@ def update_status(p, status): if p.status < status: p.status = status + class TrackPage(Page): def get_info(self, _id): p = Parcel(_id) @@ -70,5 +71,6 @@ def get_info(self, _id): pass return p + class ErrorPage(Page): pass diff --git a/modules/cragr/mobile/pages/tokenextractor.py b/modules/cragr/mobile/pages/tokenextractor.py index f2f2adddd0500dd07ffddfff4f08fe60fd61f1ba..ecb950e69c152b95a1280564bf5a4fe1df3b1e5c 100644 --- a/modules/cragr/mobile/pages/tokenextractor.py +++ b/modules/cragr/mobile/pages/tokenextractor.py @@ -20,6 +20,7 @@ class TokenExtractor(object): """ Extracts texts token from an HTML document """ + def __init__(self): self.iterated_elements = [] diff --git a/modules/cragr/web/pages.py b/modules/cragr/web/pages.py index 680c2105cbd4cedabdb02fd937c3a783e4bcc7a2..9ba99ad8cbd988b49ccea4c307cb0eeb7f18964e 100644 --- a/modules/cragr/web/pages.py +++ b/modules/cragr/web/pages.py @@ -39,6 +39,7 @@ def get_post_url(self): return None + class LoginPage(Page): def login(self, password): assert password.isdigit() @@ -60,12 +61,15 @@ def login(self, password): def get_result_url(self): return self.parser.tocleanstring(self.document.getroot()) + class UselessPage(Page): pass + class LoginErrorPage(Page): pass + class _AccountsPage(Page): COL_LABEL = 0 COL_ID = 2 @@ -223,12 +227,15 @@ def get_history(self, date_guesser): yield t + class AccountsPage(_AccountsPage): pass + class SavingsPage(_AccountsPage): COL_ID = 1 + class TransactionsPage(Page): def get_next_url(self): links = self.document.xpath('//span[@class="pager"]/a[@class="liennavigationcorpspage"]') diff --git a/modules/creditcooperatif/pro/pages.py b/modules/creditcooperatif/pro/pages.py index d1ca85bde6737fcdf00b46b80968f8fcfcf36691..fd5f0744ec6c4f07534261b480375f756f0d7c92 100644 --- a/modules/creditcooperatif/pro/pages.py +++ b/modules/creditcooperatif/pro/pages.py @@ -95,6 +95,7 @@ class Transaction(FrenchTransaction): FrenchTransaction.TYPE_UNKNOWN), ] + class ITransactionsPage(Page): def get_next_url(self): # can be 'Suivant' or ' Suivant' @@ -108,6 +109,7 @@ def get_next_url(self): def get_history(self): raise NotImplementedError() + class TransactionsPage(ITransactionsPage): TR_DATE = 0 TR_TEXT = 2 @@ -135,6 +137,7 @@ def get_content(td): yield t + class ComingTransactionsPage(TransactionsPage): TR_DATE = 2 TR_TEXT = 1 @@ -142,6 +145,7 @@ class ComingTransactionsPage(TransactionsPage): TR_CREDIT = -1 TABLE_NAME = 'operationAVenir' + class CardTransactionsPage(ITransactionsPage): COM_TR_COMMENT = 0 COM_TR_DATE = 1 diff --git a/modules/creditmutuel/pages.py b/modules/creditmutuel/pages.py index 5b595ffb4b87217c504265ea6950ea89a911f6b8..a94731cfc2ab20f73494927ddb6c5e9044728f45 100644 --- a/modules/creditmutuel/pages.py +++ b/modules/creditmutuel/pages.py @@ -53,13 +53,16 @@ class LoginErrorPage(HTMLPage): class EmptyPage(LoggedPage, HTMLPage): pass + class UserSpacePage(LoggedPage, HTMLPage): pass + class ChangePasswordPage(LoggedPage, HTMLPage): def on_load(self): raise BrowserIncorrectPassword('Please change your password') + class VerifCodePage(LoggedPage, HTMLPage): def on_load(self): raise BrowserIncorrectPassword('Unable to login: website asks a code from a card') diff --git a/modules/cuisineaz/module.py b/modules/cuisineaz/module.py index ba09aaf4116faf8b25fb470f358ea789eec4632c..9ee734799dfce92f5deb29017ef8f0005cd9cb74 100644 --- a/modules/cuisineaz/module.py +++ b/modules/cuisineaz/module.py @@ -26,6 +26,7 @@ __all__ = ['CuisineazModule'] + def strip_accents(s): return ''.join(c for c in unicodedata.normalize('NFD', s) if unicodedata.category(c) != 'Mn') diff --git a/modules/cuisineaz/pages.py b/modules/cuisineaz/pages.py index 537dce6a4ec36095ef9d6b35162cb9d67de1928b..4e150a872edb0ad0390b0f8d5c02b85931f2156a 100644 --- a/modules/cuisineaz/pages.py +++ b/modules/cuisineaz/pages.py @@ -26,6 +26,7 @@ class ResultsPage(Page): """ Page which contains results as a list of recipies """ + def iter_recipes(self): for div in self.parser.select(self.document.getroot(), 'div.rechRecette'): thumbnail_url = NotAvailable @@ -74,6 +75,7 @@ def iter_recipes(self): class RecipePage(Page): """ Page which contains a recipe """ + def get_recipe(self, id): title = NotAvailable preparation_time = NotAvailable diff --git a/modules/dailymotion/pages.py b/modules/dailymotion/pages.py index 4b0315ac03ac8dd46922311d07768badb5f66222..af2943022cbdd007274b47d04b82232a57f2dee3 100644 --- a/modules/dailymotion/pages.py +++ b/modules/dailymotion/pages.py @@ -154,6 +154,7 @@ def set_video_url(self, video): video.url = unicode(info[max_quality]) + class KidsVideoPage(VideoPage): CONTROLLER_PAGE = 'http://kids.dailymotion.com/controller/Page_Kids_KidsUserHome?%s' diff --git a/modules/delubac/pages.py b/modules/delubac/pages.py index 71a682e8d8f2812b8a3564afde4b8da7de333d11..ce1c8b332bf03d567e91418ba93ebca7d27a1e61 100644 --- a/modules/delubac/pages.py +++ b/modules/delubac/pages.py @@ -94,6 +94,7 @@ def next_page(self): if next_button: return next_button[0] + class LCRPage(OperationsPage): def iter_history(self): date = None diff --git a/modules/edf/pages.py b/modules/edf/pages.py index 14361d93b72560979c393830fa40562e7197ef6c..17ae73b7d028fae0cde55a4e40591b3bbb34bbb5 100644 --- a/modules/edf/pages.py +++ b/modules/edf/pages.py @@ -27,6 +27,7 @@ base_url = "http://particuliers.edf.com/" + class EdfBasePage(Page): def is_logged(self): return (u'Me déconnecter' in self.document.xpath('//a/text()')) \ @@ -45,16 +46,19 @@ class HomePage(EdfBasePage): def on_loaded(self): pass + class FirstRedirectionPage(EdfBasePage): def on_loaded(self): self.browser.select_form("form1") self.browser.submit() + class SecondRedirectionPage(EdfBasePage): def on_loaded(self): self.browser.select_form("redirectForm") self.browser.submit() + class OtherPage(EdfBasePage): def on_loaded(self): self.browser.open(base_url) @@ -122,6 +126,7 @@ def iter_bills(self, sub): def get_bill(self, bill): self.location(bill._url) + class LastPaymentsPage(EdfBasePage): def on_loaded(self): @@ -146,6 +151,7 @@ def on_loaded(self): self.browser.location('/ASPFront/appmanager/ASPFront/front/portlet_echeancier_2?%s' % urllib.urlencode(params)) + class LastPaymentsPage2(EdfBasePage): def iter_payments(self, sub): diff --git a/modules/gdcvault/pages.py b/modules/gdcvault/pages.py index d8ddac25ac8f369ea2f48770b8a8d6716d8be577..348d7d8f932c27a93e8feaa10120dc6c781cb408 100644 --- a/modules/gdcvault/pages.py +++ b/modules/gdcvault/pages.py @@ -79,6 +79,8 @@ def iter_videos(self): # the search page class uses a JSON parser, # since it's what search.php returns when POSTed (from Ajax) + + class SearchPage(Page): def iter_videos(self): if self.document is None or self.document['data'] is None: @@ -90,6 +92,7 @@ def iter_videos(self): continue yield video + class VideoPage(Page): def get_video(self, video=None): # check for slides id variant diff --git a/modules/github/browser.py b/modules/github/browser.py index cb8055d4a778781774ffd77c5a29960e8394b991..70445df772df3552fb0c7c29502862ff7d85c095 100644 --- a/modules/github/browser.py +++ b/modules/github/browser.py @@ -199,6 +199,7 @@ def auth_headers(self): # TODO use a cache for objects and/or pages? # TODO use an api-key? + def parse_date(s): if s.endswith('Z'): s = s[:-1] diff --git a/modules/github/module.py b/modules/github/module.py index 984de02d6f63d0a7c496ed3a7849ddf490ed2cbc..8946c67b4b01a5c5dd1f3f2612a84830ba6c7cb3 100644 --- a/modules/github/module.py +++ b/modules/github/module.py @@ -32,6 +32,7 @@ 'closed': Status('closed', u'closed', Status.VALUE_RESOLVED)} # TODO tentatively parse github "labels"? + class GithubModule(Module, CapBugTracker): NAME = 'github' DESCRIPTION = u'GitHub issues tracking' diff --git a/modules/hellobank/perso/transactions.py b/modules/hellobank/perso/transactions.py index 32e01b063770862b9f2e1b7ccf85cf7aca5821f5..7af575fcd1435adb1f7f5ba6707f2cb41e814b69 100644 --- a/modules/hellobank/perso/transactions.py +++ b/modules/hellobank/perso/transactions.py @@ -89,5 +89,6 @@ def iter_coming_operations(self): def get_IBAN(self): return self.document.xpath('//a[@class="lien_perso_libelle"]')[0].attrib['id'][10:26] + class AccountComing(AccountHistory): pass diff --git a/modules/hsbc/pages.py b/modules/hsbc/pages.py index 2a82fb6716a4b670194c94f2297cb64cfb760c5e..c826167af9ee4bdd39e378028c5f0b1b33abe4ca 100644 --- a/modules/hsbc/pages.py +++ b/modules/hsbc/pages.py @@ -43,6 +43,7 @@ class Transaction(FrenchTransaction): (re.compile(r'^REMISE (?P.*)'), FrenchTransaction.TYPE_DEPOSIT), ] + class AccountsPage(LoggedPage, HTMLPage): def get_frame(self): try: @@ -129,6 +130,7 @@ class item(Transaction.TransactionElement): obj_date = DateGuesser(CleanText(TableCell("date")), Env("date_guesser")) obj_vdate = DateGuesser(CleanText(TableCell("date")), Env("date_guesser")) + class CPTOperationPage(LoggedPage, HTMLPage): def get_history(self): for script in self.doc.xpath('//script'): @@ -142,6 +144,7 @@ def get_history(self): op._coming = (re.match(r'\d+/\d+/\d+', m.group(2)) is None) yield op + class LoginPage(HTMLPage): def on_load(self): for message in self.doc.getroot().cssselect('div.csPanelErrors'): diff --git a/modules/imdb/pages.py b/modules/imdb/pages.py index 6a60f03df4fed93edb25191aa6fb32a98c9d94e3..e5ac59aa0b4d94030c9e173d2bb999fa6a78ae13 100644 --- a/modules/imdb/pages.py +++ b/modules/imdb/pages.py @@ -29,6 +29,7 @@ class ReleasePage(Page): ''' Page containing releases of a movie ''' + def get_movie_releases(self, country_filter): result = unicode() links = self.parser.select(self.document.getroot(), 'table#release_dates a') @@ -57,6 +58,7 @@ def get_movie_releases(self, country_filter): class BiographyPage(Page): ''' Page containing biography of a person ''' + def get_biography(self): bio = unicode() start = False @@ -74,6 +76,7 @@ def get_biography(self): class MovieCrewPage(Page): ''' Page listing all the persons related to a movie ''' + def iter_persons(self, role_filter=None): if (role_filter is None or (role_filter is not None and role_filter == 'actor')): tables = self.parser.select(self.document.getroot(), 'table.cast_list') @@ -130,6 +133,7 @@ class PersonPage(Page): ''' Page informing about a person It is used to build a Person instance and to get the movie list related to a person ''' + def get_person(self, id): name = NotAvailable short_biography = NotAvailable diff --git a/modules/inrocks/pages/article.py b/modules/inrocks/pages/article.py index 83491a94ed8f5c45e38b46e4911bb9cf32bf6946..4cda37068b966eeecb82567843d1e2bc4ad13b01 100644 --- a/modules/inrocks/pages/article.py +++ b/modules/inrocks/pages/article.py @@ -26,6 +26,7 @@ class ArticlePage(GenericNewsPage): "ArticlePage object for inrocks" + def on_loaded(self): self.main_div = self.document.getroot() self.element_title_selector = "h1" diff --git a/modules/inrocks/pages/inrockstv.py b/modules/inrocks/pages/inrockstv.py index 75caa1fe9355f0591e29d7af26260eb1be61f80c..f22cead7e15d8699e266885b72ab0bb8263ba534 100644 --- a/modules/inrocks/pages/inrockstv.py +++ b/modules/inrocks/pages/inrockstv.py @@ -23,6 +23,7 @@ class InrocksTvPage(GenericNewsPage): "ArticlePage object for inrocks" + def on_loaded(self): self.main_div = self.document.getroot() self.element_title_selector = "h2" diff --git a/modules/jvmalin/pages.py b/modules/jvmalin/pages.py index 910be40908917fc4d225af8a149701576dad446d..fc2d3ac13fdcb1dab7db41d15824dd8d70b6b754 100644 --- a/modules/jvmalin/pages.py +++ b/modules/jvmalin/pages.py @@ -13,6 +13,7 @@ class RoadmapAmbiguity(RoadmapError): def __init__(self, error): RoadmapError.__init__(self, error) + class RoadmapSearchPage(Page): def search(self, departure, arrival, departure_time, arrival_time): match = -1 @@ -46,6 +47,7 @@ def search(self, departure, arrival, departure_time, arrival_time): raise RoadmapError('Unable to establish a roadmap with %s time at "%s"' % ('departure' if departure_time else 'arrival', time)) self.browser.submit() + class RoadmapResultsPage(Page): def html_br_strip(self, text): return "".join([l.strip() for l in text.split("\n")]).strip().replace(' ', '%20') @@ -96,6 +98,7 @@ def resubmit_best_form(self): self.browser[propname] = [ propvalue ] self.browser.submit() + class RoadmapPage(Page): def get_steps(self): errors = [] diff --git a/modules/lcl/browser.py b/modules/lcl/browser.py index 9fb2d79d70295c658e0de0b7319ed3b882489754..9d9139d55d7f5f0021525993482092bcd299489d 100644 --- a/modules/lcl/browser.py +++ b/modules/lcl/browser.py @@ -122,6 +122,7 @@ def get_cb_operations(self, account, month=0): for tr in self.page.get_operations(): yield tr + class LCLProBrowser(LCLBrowser): PROTOCOL = 'https' DOMAIN = 'professionnels.secure.lcl.fr' @@ -165,4 +166,3 @@ def add_cookie(self, name, value): def __init__(self, *args, **kwargs): Browser.__init__(self, *args, **kwargs) self.add_cookie("lclgen","professionnels") - diff --git a/modules/lcl/pages.py b/modules/lcl/pages.py index 037b7102df94c87eaad031871ba76c08335dd258..c4dae7c3b3d9a707e3b59bf6ebdb7386fc20366a 100644 --- a/modules/lcl/pages.py +++ b/modules/lcl/pages.py @@ -132,6 +132,7 @@ def is_error(self): errors = self.document.xpath(u'//div[@class="erreur" or @class="messError"]') return len(errors) > 0 + class ContractsPage(Page): def on_loaded(self): self.select_contract() diff --git a/modules/lefigaro/pages/article.py b/modules/lefigaro/pages/article.py index 6f2f9aa63d9ed3d4059aab6963ee16ad30ce0261..2ac98dee59e7d3baf3e430d7e6e25f1a2aa4a77a 100644 --- a/modules/lefigaro/pages/article.py +++ b/modules/lefigaro/pages/article.py @@ -23,6 +23,7 @@ class ArticlePage(GenericNewsPage): "ArticlePage object for lefigaro" + def on_loaded(self): self.main_div = self.document.getroot() self.element_title_selector = "h1" diff --git a/modules/lefigaro/pages/flashactu.py b/modules/lefigaro/pages/flashactu.py index 1b4a50c4a56d04be9f2598db261851a4e3e7c23b..a741f00bca288d5288082074b37f7cf73473d5ab 100644 --- a/modules/lefigaro/pages/flashactu.py +++ b/modules/lefigaro/pages/flashactu.py @@ -23,6 +23,7 @@ class FlashActuPage(GenericNewsPage): "ArticlePage object for lefigaro" + def on_loaded(self): self.main_div = self.document.getroot() self.element_title_selector = "h1" diff --git a/modules/lefigaro/tools.py b/modules/lefigaro/tools.py index 3857b6bed1c4f8621a60b65700567de36e96fac7..fcd537da4adf3b72b463577e91e9bab956470956 100644 --- a/modules/lefigaro/tools.py +++ b/modules/lefigaro/tools.py @@ -18,6 +18,7 @@ # You should have received a copy of the GNU Affero General Public License # along with weboob. If not, see . + def url2id(url): "return an id from an url" return url diff --git a/modules/mailinator/browser.py b/modules/mailinator/browser.py index e24985d5f4733aa63fd25d5ab52b4ebd6c1d3dc2..514d2c0d31c525155ad4e3f5ec1179cd6e78bf89 100644 --- a/modules/mailinator/browser.py +++ b/modules/mailinator/browser.py @@ -65,8 +65,10 @@ def get_mail_content(self, mailid): divs = doc.cssselect('.mailview') return divs[0].text_content().strip() + def millis(): return int(time.time() * 1000) + def frommillis(millis): return datetime.fromtimestamp(millis / 1000) diff --git a/modules/mailinator/test.py b/modules/mailinator/test.py index 51d38209d7a0ec5591357d3e70d257491216eb23..f0c79b14a8437b693020e49d8047708dfbef84bf 100644 --- a/modules/mailinator/test.py +++ b/modules/mailinator/test.py @@ -32,4 +32,3 @@ def test_mailinator(self): assert t.root.date assert t.root.sender assert t.root.receivers - diff --git a/modules/marmiton/pages.py b/modules/marmiton/pages.py index 212770f6950a43eed47dbe7e195e9bdca74aa16a..db8f1f16913e5c9afa561e762035f43138cc0299 100644 --- a/modules/marmiton/pages.py +++ b/modules/marmiton/pages.py @@ -26,6 +26,7 @@ class ResultsPage(Page): """ Page which contains results as a list of recipies """ + def iter_recipes(self): for div in self.parser.select(self.document.getroot(), 'div.m_search_result'): tds = self.parser.select(div, 'td') @@ -57,6 +58,7 @@ def iter_recipes(self): class RecipePage(Page): """ Page which contains a recipe """ + def get_recipe(self, id): title = NotAvailable preparation_time = NotAvailable diff --git a/modules/minutes20/pages/article.py b/modules/minutes20/pages/article.py index 5bf1347af8b37adab80b48e87673cec831eb4c02..072658d48385d80a4ea91410c59786731479fff2 100644 --- a/modules/minutes20/pages/article.py +++ b/modules/minutes20/pages/article.py @@ -24,6 +24,7 @@ class ArticlePage(SimplePage): "ArticlePage object for minutes20" + def on_loaded(self): self.main_div = self.document.getroot() self.element_title_selector = "h1" diff --git a/modules/minutes20/pages/simple.py b/modules/minutes20/pages/simple.py index b61ef7e5446b0f122b49f57510d03b11f032b444..c05883a104527a04d098c363277c70bb6d140064 100644 --- a/modules/minutes20/pages/simple.py +++ b/modules/minutes20/pages/simple.py @@ -23,6 +23,7 @@ class SimplePage(GenericNewsPage): "ArticlePage object for minutes20" + def on_loaded(self): self.main_div = self.document.getroot() self.element_title_selector = "h1" diff --git a/modules/nectarine/browser.py b/modules/nectarine/browser.py index a188c8197cb57101de7dfc5ef276353b175dcb2f..fd701396b21b6255dd56bcb4fcae6d86cc140898 100644 --- a/modules/nectarine/browser.py +++ b/modules/nectarine/browser.py @@ -22,6 +22,7 @@ __all__ = ['NectarineBrowser'] + class NectarineBrowser(Browser): DOMAIN = 'www.scenemusic.net' PROTOCOL = 'https' diff --git a/modules/nectarine/module.py b/modules/nectarine/module.py index d5110bdef9559e6bb9bb95e18371ddc966053171..ff3086c8bc1532015a490200d2a564c6fc48fe77 100644 --- a/modules/nectarine/module.py +++ b/modules/nectarine/module.py @@ -23,6 +23,7 @@ __all__ = ['NectarineModule'] + class NectarineModule(Module, CapRadio, CapCollection): NAME = 'nectarine' MAINTAINER = u'Thomas Lecavelier' diff --git a/modules/nihonnooto/browser.py b/modules/nihonnooto/browser.py index d4346c446e7e5bf47a9c335df86444bc0fb06093..9baa089aec68a8f9d57a43985616ad3afd0842b2 100644 --- a/modules/nihonnooto/browser.py +++ b/modules/nihonnooto/browser.py @@ -22,6 +22,7 @@ __all__ = ['NihonNoOtoBrowser'] + class NihonNoOtoBrowser(Browser): DOMAIN = 'www.nihon-no-oto.com' PROTOCOL = 'http' diff --git a/modules/nihonnooto/module.py b/modules/nihonnooto/module.py index bb94704fa6b58e8a23c291551bc3a3657c2c87f2..76bf4209459f75d836905ffac0e438a2465d5363 100644 --- a/modules/nihonnooto/module.py +++ b/modules/nihonnooto/module.py @@ -23,6 +23,7 @@ __all__ = ['NihonNoOtoModule'] + class NihonNoOtoModule(Module, CapRadio, CapCollection): NAME = 'nihonnooto' MAINTAINER = u'Thomas Lecavelier' diff --git a/modules/nolifetv/browser.py b/modules/nolifetv/browser.py index 86022343f4c8a4d2986736bb4f6ce9e9a0d866a0..9cace718d1400933167a6cccd19b590dc969d62c 100644 --- a/modules/nolifetv/browser.py +++ b/modules/nolifetv/browser.py @@ -28,6 +28,7 @@ __all__ = ['NolifeTVBrowser'] + class NolifeTVBrowser(Browser): USER_AGENT = Browser.USER_AGENTS['desktop_firefox'] DOMAIN = 'mobile.nolife-tv.com' diff --git a/modules/nolifetv/module.py b/modules/nolifetv/module.py index eb2558ec9a3f0a339d6b7f2ea8b1f1b05b58d00d..c02798ff2bb673105ad2982643127bb082c50590 100644 --- a/modules/nolifetv/module.py +++ b/modules/nolifetv/module.py @@ -32,6 +32,7 @@ __all__ = ['NolifeTVModule'] + class NolifeTVModule(Module, CapVideo, CapCollection): NAME = 'nolifetv' MAINTAINER = u'Romain Bignon' diff --git a/modules/nolifetv/pages.py b/modules/nolifetv/pages.py index 5cabb75d874cc2a4656f423e53f2119c2148fc86..e722a1e73633e780bdccb8c9603a035e0cfdf9e3 100644 --- a/modules/nolifetv/pages.py +++ b/modules/nolifetv/pages.py @@ -67,6 +67,7 @@ def get_video(self, video): seconds=int(m.group(3))) return video + class VideoListPage(Page): def is_list_empty(self): return self.document.getroot() is None @@ -85,6 +86,7 @@ def iter_video(self, available_videos): video.title = video.title + ' - ' + strongs[3].text yield video + class FamilyPage(Page): def iter_category(self): subs = list() @@ -109,6 +111,7 @@ def iter_family(self, sub): if m and m.group(1): yield Collection([m.group(1)], unicode(h1.text)) + class AboPage(Page): def get_available_videos(self): available = ['[Gratuit]'] @@ -130,6 +133,7 @@ def login(self, username, password): self.browser['password'] = str(password) self.browser.submit() + class HomePage(Page): def is_logged(self): return len(self.document.xpath('//a[@href="deconnexion/"]')) == 1 diff --git a/modules/nolifetv/test.py b/modules/nolifetv/test.py index 73b58f0d0f582b78558a033e59bf47733ab44caa..c8a7ee41756e9ed14fa7925f7fc401fc947bbc3c 100644 --- a/modules/nolifetv/test.py +++ b/modules/nolifetv/test.py @@ -21,6 +21,7 @@ from weboob.tools.test import BackendTest from weboob.capabilities.video import BaseVideo + class NolifeTVTest(BackendTest): MODULE = 'nolifetv' diff --git a/modules/okc/browser.py b/modules/okc/browser.py index 5deb768f0d56d02084e4847db27cd745dbfcdc5a..ad43044a29faba8e7e33ad09731f1f9681309d9c 100644 --- a/modules/okc/browser.py +++ b/modules/okc/browser.py @@ -266,5 +266,3 @@ def do_rate(self, id): self.addheaders = [('Referer', self.page.url), ('Content-Type', 'application/x-www-form-urlencoded;charset=UTF-8')] self.open('http://m.okcupid.com%s' %abs_url, data=data) return True - - diff --git a/modules/okc/pages.py b/modules/okc/pages.py index d38a43b2fcfb2b93ff4b24061718c2f10602f19a..946a8f9977873f0947ff68e2b8e5909846b8e917 100644 --- a/modules/okc/pages.py +++ b/modules/okc/pages.py @@ -26,6 +26,7 @@ from weboob.tools.html import html2text from weboob.tools.date import local2utc + class LoginPage(Page): def login(self, username, password): self.browser.select_form(name='loginf') @@ -191,6 +192,7 @@ def post_mail(self, id, content): self.browser['body'] = content.encode('utf-8') self.browser.submit() + class VisitsPage(Page): def get_visits(self): ul_item = self.parser.select(self.document.getroot(), '//*[@id="page_content"]/ul[3]', method='xpath')[0] @@ -206,6 +208,7 @@ def get_visits(self): }) return visitors + class QuickMatchPage(Page): def get_id(self): element = self.parser.select(self.document.getroot(), '//*[@id="sn"]', method='xpath')[0] diff --git a/modules/oney/pages.py b/modules/oney/pages.py index 0df4ec7474dd94b86e590291bb369fdf4b1094df..0b7489e3a10ef353aa6760876dd7c0ddc02e9ead 100644 --- a/modules/oney/pages.py +++ b/modules/oney/pages.py @@ -97,6 +97,7 @@ def get_string_code(self, string): code += self.get_symbol_code(self.symbols[c]) return code + class LoginPage(HTMLPage): is_here ="//form[@id='formulaire-login']" @@ -115,12 +116,14 @@ def login(self, login, password): form['personneIdentifiee'] = 'N' form.submit() + class IndexPage(LoggedPage, HTMLPage): is_here = "//div[@id='situation']" def get_balance(self): return -CleanDecimal('.', replace_dots=True)(self.doc.xpath('//div[@id = "total-sommes-dues"]/p[contains(text(), "sommes dues")]/span[@class = "montant"]')[0]) + class OperationsPage(LoggedPage, HTMLPage): is_here = "//div[@id='releve-reserve-credit'] | //div[@id='operations-recentes'] | //select[@id='periode']" diff --git a/modules/opensubtitles/pages.py b/modules/opensubtitles/pages.py index 10da1b759aaae09365efa5a04057a206f7a954b8..cbd2a5f382c3de53b847eb28cde447c34d11bcda 100644 --- a/modules/opensubtitles/pages.py +++ b/modules/opensubtitles/pages.py @@ -28,6 +28,7 @@ class SearchPage(Page): """ Page which contains results as a list of movies """ + def iter_subtitles(self): tabresults = self.parser.select(self.document.getroot(), 'table#search_results') if len(tabresults) > 0: @@ -49,6 +50,7 @@ def iter_subtitles(self): class SubtitlesPage(Page): """ Page which contains several subtitles for a single movie """ + def iter_subtitles(self): tabresults = self.parser.select(self.document.getroot(), 'table#search_results') if len(tabresults) > 0: @@ -102,6 +104,7 @@ def get_subtitle_from_line(self, line): class SubtitlePage(Page): """ Page which contains a single subtitle for a movie """ + def get_subtitle(self): desc = NotAvailable a = self.parser.select(self.document.getroot(), 'a#bt-dwl', 1) diff --git a/modules/pariskiwi/pages.py b/modules/pariskiwi/pages.py index 7f962b9b146390c38d8873f18e4235ec118ed032..e9bf8dba08b1dfbc2bc0ad665039d02d8ca147ff 100644 --- a/modules/pariskiwi/pages.py +++ b/modules/pariskiwi/pages.py @@ -29,12 +29,15 @@ def date_from_id(_id): textdate = _id.split('_')[0] return datetime.strptime(textdate, '%m-%d-%Y') + def id_from_path(title): return title.replace(' ', '_').split('/')[-1] + def combine(dt, t): return datetime(dt.year, dt.month, dt.day, t.hour, t.minute) + class PageList(Page): def get_events(self): raise NotImplementedError() diff --git a/modules/paypal/pages.py b/modules/paypal/pages.py index 6d06e5ff0b48303eb893bffc2db0d40afc045aa4..037f19ffb53c56c47ccec1b8a17161030df922b5 100644 --- a/modules/paypal/pages.py +++ b/modules/paypal/pages.py @@ -34,6 +34,7 @@ class CSVAlreadyAsked(Exception): pass + def clean_amount(text): amnt = AmericanTransaction.clean_amount(text) return Decimal(amnt) if amnt else Decimal("0") @@ -135,6 +136,7 @@ def download(self, start, end): self.browser.submit() + class LastDownloadHistoryPage(Page): def download(self): self.browser.select_form(nr=1) @@ -142,10 +144,12 @@ def download(self): self.browser['log_select'] = [log_select] self.browser.submit() + class SubmitPage(Page): """ Any result of form submission """ + def iter_transactions(self, account): csv = self.document diff --git a/modules/podnapisi/pages.py b/modules/podnapisi/pages.py index 9715d05c1f778be977ea40fca0401433ec9da4bd..aef0d5e06ec3258d1c48ae4a12d86e06c2404687 100644 --- a/modules/podnapisi/pages.py +++ b/modules/podnapisi/pages.py @@ -74,6 +74,7 @@ class SearchPage(Page): """ Page which contains results as a list of movies """ + def iter_subtitles(self, language): linksresults = self.parser.select(self.document.getroot(), 'a.subtitle_page_link') for link in linksresults: @@ -93,6 +94,7 @@ def iter_subtitles(self, language): class SubtitlePage(Page): """ Page which contains a single subtitle for a movie """ + def get_subtitle(self, id): language = NotAvailable url = NotAvailable diff --git a/modules/presseurop/pages/article.py b/modules/presseurop/pages/article.py index bc23389d2b0d1de6f93f4c801302a04c6d2df9f5..4694946a50b50f8f6a1af7e2272f243800271004 100644 --- a/modules/presseurop/pages/article.py +++ b/modules/presseurop/pages/article.py @@ -55,6 +55,7 @@ def get_author(self): except: return author + class DailyTitlesPage(PresseuropPage): def on_loaded(self): self.main_div = self.document.getroot() diff --git a/modules/quvi/module.py b/modules/quvi/module.py index 24d968738a439c4fbcca5723dfa8f62303072497..41d5dc0f2fa9b61d371825ba6bc313db4bf4d58c 100644 --- a/modules/quvi/module.py +++ b/modules/quvi/module.py @@ -74,6 +74,7 @@ def get_video(self, _id): video.thumbnail.url = video.thumbnail.id return video + class QuviVideo(BaseVideo): BACKENDS = { 'youtube': 'https://www.youtube.com/watch?v=%s', diff --git a/modules/quvi/test.py b/modules/quvi/test.py index 4482e0b63caa79a36f4c5e291434277cacb83b63..c0d76cfdbb5978ca896005456ffe75dc36621af8 100644 --- a/modules/quvi/test.py +++ b/modules/quvi/test.py @@ -45,4 +45,3 @@ def test_get_shortened(self): assert len(v.url) assert len(v.title) assert v.page_url.startswith('http://www.youtube.com/watch?v=BaW_jenozKc') - diff --git a/modules/redmine/pages/issues.py b/modules/redmine/pages/issues.py index d2d9c5979ef954ddd6154e92d9b0c6d2ef549392..30cd0f873dbe8b8cceabc8d6f9429ec8291d0ccc 100644 --- a/modules/redmine/pages/issues.py +++ b/modules/redmine/pages/issues.py @@ -157,6 +157,7 @@ def get_project(self, project_name): return project args = json.loads(args) + def get_values(key): values = [] if not key in args: diff --git a/modules/sfr/test.py b/modules/sfr/test.py index f13898e16312ed70c7e9dade9500fba3fc3aac64..1cd64613648d3bafc1ff218f0aafc4f7e93c5ec3 100644 --- a/modules/sfr/test.py +++ b/modules/sfr/test.py @@ -19,6 +19,7 @@ from weboob.tools.test import BackendTest + class SFRTest(BackendTest): MODULE = 'sfr' diff --git a/modules/somafm/module.py b/modules/somafm/module.py index 6779c4d08e08bfec04050f1d16e4885b3d6fa56a..c2ebf6842836720cb6c1af694be4eb7be94d34fb 100644 --- a/modules/somafm/module.py +++ b/modules/somafm/module.py @@ -125,4 +125,3 @@ def fill_radio(self, radio, fields): return radio OBJECTS = {Radio: fill_radio} - diff --git a/modules/somafm/test.py b/modules/somafm/test.py index 0b251e8560eff43f83943ba3ec4d0774c3504f53..1c092b29bfc369b36b3e10046f4e6a9002efa20d 100644 --- a/modules/somafm/test.py +++ b/modules/somafm/test.py @@ -40,4 +40,3 @@ def test_difm(self): self.assertTrue(radio.current.what) self.assertTrue(radio.streams[0].url) self.assertTrue(radio.streams[0].title) - diff --git a/modules/sueurdemetal/test.py b/modules/sueurdemetal/test.py index 66b3d01b28d5611007894b831f1cc5e6250f5dd0..1071e764f08d0dd903af51941efbbeed1029d605 100644 --- a/modules/sueurdemetal/test.py +++ b/modules/sueurdemetal/test.py @@ -22,6 +22,7 @@ from weboob.capabilities.calendar import Query, CATEGORIES from datetime import datetime, timedelta + class SueurDeMetalTest(BackendTest): MODULE = 'sueurdemetal' diff --git a/modules/supertoinette/pages.py b/modules/supertoinette/pages.py index 0ab7dea1e250a23bef755ed992b6a2d4afaaca11..e3944e7d346004c29780457365d32ddff9c1b3bb 100644 --- a/modules/supertoinette/pages.py +++ b/modules/supertoinette/pages.py @@ -28,6 +28,7 @@ class ResultsPage(Page): """ Page which contains results as a list of recipies """ + def iter_recipes(self): for div in self.parser.select(self.document.getroot(), 'div.result-recipe'): thumbnail_url = NotAvailable @@ -60,6 +61,7 @@ def iter_recipes(self): class RecipePage(Page): """ Page which contains a recipe """ + def get_recipe(self, id): title = NotAvailable preparation_time = NotAvailable diff --git a/modules/tvsubtitles/pages.py b/modules/tvsubtitles/pages.py index 9d2ef3058e5d534676543216b2935a6557d8cf25..0016f8a36b8df22f33cfe68c220e15c4bbb6b50a 100644 --- a/modules/tvsubtitles/pages.py +++ b/modules/tvsubtitles/pages.py @@ -36,6 +36,7 @@ def iter_subtitles(self, language, pattern): class SearchPage(Page): """ Page which contains results as a list of series """ + def iter_subtitles(self, language): list_result = self.parser.select(self.document.getroot(), 'div.left_articles ul') if len(list_result) > 0: @@ -53,6 +54,7 @@ def iter_subtitles(self, language): class SeriePage(Page): """ Page of all seasons """ + def iter_subtitles(self, language, only_one_season=False): # handle the current season last_table_line = self.parser.select(self.document.getroot(), 'table#table5 tr')[-1] @@ -80,6 +82,7 @@ def iter_subtitles(self, language, only_one_season=False): class SeasonPage(Page): """ Page of a season with the right language """ + def get_subtitle(self): filename_line = self.parser.select(self.document.getroot(), 'img[alt=filename]', 1).getparent().getparent() name = unicode(self.parser.select(filename_line, 'td')[2].text) diff --git a/modules/unsee/browser.py b/modules/unsee/browser.py index 59287145469a40270994b551c0db1788e0e0c721..729e1ff792742c5df4b40373759bc188f3f6b3a4 100644 --- a/modules/unsee/browser.py +++ b/modules/unsee/browser.py @@ -36,6 +36,7 @@ def to_bytes(s): else: return s + class FileField(object): def __init__(self, filename, contents=None, headers=None): self.filename = to_bytes(os.path.basename(filename)) diff --git a/modules/unsee/module.py b/modules/unsee/module.py index 69b47570057e09a39c8884db61f9c19f90aeb609..7812357b36a655a44c645f2fdbdd56aa914830a8 100644 --- a/modules/unsee/module.py +++ b/modules/unsee/module.py @@ -74,4 +74,3 @@ def post_paste(self, paste, max_age=None): d = self.browser.post_image(paste.title, paste.contents.decode('base64'), max_code) paste.id = d['id'] return paste - diff --git a/modules/voyagessncf/pages.py b/modules/voyagessncf/pages.py index 4566df5acf59826f74c19eb6b176b6e9059574b4..df57d572c747c06249b9ec71eb69f94465a9c513 100644 --- a/modules/voyagessncf/pages.py +++ b/modules/voyagessncf/pages.py @@ -32,11 +32,13 @@ class ForeignPage(Page): def on_loaded(self): raise UserError('Your IP address is localized in a country not supported by this module (%s). Currently only the French website is supported.' % self.group_dict['country']) + class CitiesPage(Page): def get_stations(self): result = json.loads(self.document[self.document.find('{'):-2]) return result['CITIES'] + class SearchPage(Page): def search(self, departure, arrival, date, age, card, comfort_class): self.browser.select_form(name='saisie') @@ -57,6 +59,7 @@ def search(self, departure, arrival, date, age, card, comfort_class): self.browser['nbAnimalsForTravel'] = '0' self.browser.submit() + class SearchErrorPage(Page): def on_loaded(self): p = self.document.getroot().cssselect('div.messagesError p') @@ -64,11 +67,13 @@ def on_loaded(self): message = p[0].text.strip() raise UserError(message) + class SearchInProgressPage(Page): def on_loaded(self): link = self.document.xpath('//a[@id="url_redirect_proposals"]')[0] self.browser.location(link.attrib['href']) + class ResultsPage(Page): def get_value(self, div, name, last=False): i = -1 if last else 0 diff --git a/modules/wellsfargo/__init__.py b/modules/wellsfargo/__init__.py index 8c59ebde6cac37987c6c294bf26678ac2d9ca0fd..5e82523887cf8d2493174a27f4b5d540144faa74 100644 --- a/modules/wellsfargo/__init__.py +++ b/modules/wellsfargo/__init__.py @@ -21,4 +21,3 @@ from .module import WellsFargoModule __all__ = ['WellsFargoModule'] - diff --git a/modules/wellsfargo/pages.py b/modules/wellsfargo/pages.py index 2c75bdae70cfb2a500e18baf8f65ead79495c014..dcd869b2016b79a4899c5d7939246f1ee4b7e10b 100644 --- a/modules/wellsfargo/pages.py +++ b/modules/wellsfargo/pages.py @@ -353,4 +353,3 @@ def iter_transactions(self): cmp=lambda t1, t2: cmp(t2.date, t1.date) or cmp(t1.label, t2.label) or cmp(t1.amount, t2.amount)) - diff --git a/modules/wellsfargo/parsers.py b/modules/wellsfargo/parsers.py index 2f84b65f0a80375876a32da9ab363b360be7c886..596f0b6aea356024e79214386c41c23edeb59b7b 100644 --- a/modules/wellsfargo/parsers.py +++ b/modules/wellsfargo/parsers.py @@ -396,4 +396,3 @@ def value(self): for type_, _ in StatementToken.LEX: setattr(StatementToken, 'is_%s' % type_, eval('lambda self: self._type == "%s"' % type_)) - diff --git a/modules/youtube/pages.py b/modules/youtube/pages.py index 27d7416dfdd91d9693146f39c5e52d802de165d5..9ab06aa83002880b38f3848c076d6aca48a80242 100644 --- a/modules/youtube/pages.py +++ b/modules/youtube/pages.py @@ -864,6 +864,7 @@ def _static_decrypt_signature(self, s, video_id, player_url, age_gate): def _extract_from_m3u8(self, manifest_url, video_id): url_map = {} + def _get_urls(_manifest): lines = _manifest.split('\n') urls = filter(lambda l: l and not l.startswith('#'), lines) diff --git a/weboob/applications/boobank/boobank.py b/weboob/applications/boobank/boobank.py index e67f65a6e20d648eb3ebbf2f06a1a5adf1e45c6a..10a20a142a986e2d4546076061ff5ebe3a79978a 100644 --- a/weboob/applications/boobank/boobank.py +++ b/weboob/applications/boobank/boobank.py @@ -105,6 +105,7 @@ def flush(self): self.output(u'%s' % datetime.date.today().strftime('%Y%m%d')) self.output(u'') + class QifFormatter(IFormatter): MANDATORY_FIELDS = ('id', 'date', 'raw', 'amount') diff --git a/weboob/applications/parceloob/parceloob.py b/weboob/applications/parceloob/parceloob.py index bb9cd529bc8a723f32fbeb3204dac283547c5b9c..87fe9c90ccc7b76aef8a7b869f64f5ddae77bd1c 100644 --- a/weboob/applications/parceloob/parceloob.py +++ b/weboob/applications/parceloob/parceloob.py @@ -58,6 +58,7 @@ def format_obj(self, obj, alias): self.colored('%-17s' % (obj.location or ''), 'magenta'), self.colored(obj.activity or '', 'yellow')) + class StatusFormatter(IFormatter): MANDATORY_FIELDS = ('id',) diff --git a/weboob/applications/qhavedate/contacts.py b/weboob/applications/qhavedate/contacts.py index 1c0a590f7fa9e2046553bcfab65fc43ce5e352b8..8e489d31d2f4d66639f9fb68e0ee3b7d8d4dfb3d 100644 --- a/weboob/applications/qhavedate/contacts.py +++ b/weboob/applications/qhavedate/contacts.py @@ -101,6 +101,7 @@ def refreshMessages(self, fillobj=False): return self.ui.refreshButton.setEnabled(False) + def finished(): #v = self.ui.scrollArea.verticalScrollBar() #print v.minimum(), v.value(), v.maximum(), v.sliderPosition() @@ -572,6 +573,7 @@ def urlClicked(self): def retrieveContact(self, url): backend_name = unicode(self.ui.backendsList.currentText()) self.ui.urlButton.setEnabled(False) + def finished(): self.url_process = None self.ui.urlButton.setEnabled(True) diff --git a/weboob/applications/qhavedate/events.py b/weboob/applications/qhavedate/events.py index 279238789e535c5f9edabec58b6a36dc650c1040..ef21accbd49cb0c80c6fc7f9965800e642c1c252 100644 --- a/weboob/applications/qhavedate/events.py +++ b/weboob/applications/qhavedate/events.py @@ -66,6 +66,7 @@ def refreshEventsList(self): self.ui.typeBox.setEnabled(False) self.ui.typeBox.clear() self.ui.typeBox.addItem('All', None) + def finished(): self.ui.refreshButton.setEnabled(True) self.ui.typeBox.setEnabled(True) diff --git a/weboob/applications/traveloob/traveloob.py b/weboob/applications/traveloob/traveloob.py index 936d36c154137eab5a71d280b6d2b30daa45405f..f5ad1ad0f279ca96757a37753373f7225e93e438 100644 --- a/weboob/applications/traveloob/traveloob.py +++ b/weboob/applications/traveloob/traveloob.py @@ -56,12 +56,14 @@ def get_description(self, obj): return s + class StationsFormatter(PrettyFormatter): MANDATORY_FIELDS = ('id', 'name') def get_title(self, obj): return obj.name + class Traveloob(ReplApplication): APPNAME = 'traveloob' VERSION = '1.0' diff --git a/weboob/browser/browsers.py b/weboob/browser/browsers.py index eb09a946da77f369b22ad01970af04b5070159ec..f49f0a92ba13704918baad6bbf8b39aa66d033d8 100644 --- a/weboob/browser/browsers.py +++ b/weboob/browser/browsers.py @@ -527,6 +527,7 @@ def __new__(mcs, name, bases, attrs): new_class._urls.update(urls) return new_class + class PagesBrowser(DomainBrowser): r""" A browser which works pages and keep state of navigation. @@ -680,6 +681,7 @@ class LoginBrowser(PagesBrowser): """ A browser which supports login. """ + def __init__(self, username, password, *args, **kwargs): super(LoginBrowser, self).__init__(*args, **kwargs) self.username = username diff --git a/weboob/browser/elements.py b/weboob/browser/elements.py index ad5a79481847d7b055f37b1adfbd6d31b5deac88..674c03dcfc4365fe531b9fa197cd5d36a376605a 100644 --- a/weboob/browser/elements.py +++ b/weboob/browser/elements.py @@ -42,6 +42,7 @@ def method(klass): """ Class-decorator to call it as a method. """ + def inner(self, *args, **kwargs): return klass(self)(*args, **kwargs) return inner @@ -300,5 +301,3 @@ def __init__(self, *args, **kwargs): def get_colnum(self, name): return self._cols.get(name, None) - - diff --git a/weboob/browser/filters/javascript.py b/weboob/browser/filters/javascript.py index 3610aacc6624eb2499e8d083c00e8f433c862649..d8763fbb76812b015d65f916a78d5eed6a1b0a27 100644 --- a/weboob/browser/filters/javascript.py +++ b/weboob/browser/filters/javascript.py @@ -131,4 +131,3 @@ def filter(self, txt): return super(JSVar, self).filter(txt) except RegexpError: raise ParseError('Variable %r not found' % self.var) - diff --git a/weboob/browser/filters/standard.py b/weboob/browser/filters/standard.py index 0f4ad031a8eabff983e6877300212a0debe39f6e..73474d97f1621a734bc712ed9f059b8aabc62e05 100644 --- a/weboob/browser/filters/standard.py +++ b/weboob/browser/filters/standard.py @@ -32,6 +32,7 @@ from weboob.browser.url import URL from weboob.tools.log import getLogger, DEBUG_FILTERS + class NoDefault(object): def __repr__(self): return 'NO_DEFAULT' @@ -217,6 +218,7 @@ class Base(Filter): >>> Base(Env('header'), CleanText('./h1')) # doctest: +SKIP """ + def __call__(self, item): base = self.select(self.base, item, obj=self._obj, key=self._key) return self.selector(base) @@ -425,6 +427,7 @@ class Type(Filter): >>> Type(type=str, minlen=0, default='a').filter('') 'a' """ + def __init__(self, selector=None, type=None, minlen=0, default=_NO_DEFAULT): super(Type, self).__init__(selector, default=default) self.type_func = type diff --git a/weboob/browser/pages.py b/weboob/browser/pages.py index b0db8b1691ca7d2a5204c8b7d508c980cf2d3cfc..9cfedcc60dd27cce6654beb4ec4c6565ea8027ed 100644 --- a/weboob/browser/pages.py +++ b/weboob/browser/pages.py @@ -82,6 +82,7 @@ class NextPage(Exception): See :meth:`PagesBrowser.pagination` or decorator :func:`pagination`. """ + def __init__(self, request): super(NextPage, self).__init__() self.request = request @@ -122,17 +123,20 @@ def on_leave(self): Event called when browser leaves this page. """ + class FormNotFound(Exception): """ Raised when :meth:`HTMLPage.get_form` can't find a form. """ + class FormSubmitWarning(UserWarning): """ A form has more than one submit element selected, and will likely generate an invalid request. """ + class Form(OrderedDict): """ Represents a form of an HTML page. diff --git a/weboob/browser/profiles.py b/weboob/browser/profiles.py index 23cbcfa9d77770986f918f767cf571421012d00b..3110a1bd0cd734a8147b96f0b2bce89a8f97c8c5 100644 --- a/weboob/browser/profiles.py +++ b/weboob/browser/profiles.py @@ -82,6 +82,7 @@ class Wget(Profile): Some websites will give you a version with less JavaScript. Some others could ban you (after all, wget is not a real browser). """ + def __init__(self, version='1.11.4'): self.version = version diff --git a/weboob/browser/sessions.py b/weboob/browser/sessions.py index f24ba267f310e531d4fc8d3bc545ef8e5dafb266..3736792dd411176aff5322b419bbf55f22fc58cd 100644 --- a/weboob/browser/sessions.py +++ b/weboob/browser/sessions.py @@ -34,6 +34,7 @@ from requests.structures import CaseInsensitiveDict from requests.utils import get_netrc_auth + def merge_hooks(request_hooks, session_hooks, dict_class=OrderedDict): """ Properly merges both requests and session hooks. diff --git a/weboob/browser/url.py b/weboob/browser/url.py index 6f8ff1a047b2e838caba225596f8bf5636df23de..81b9a7b996661e844e6056d6e7ad87aa5bb7e871 100644 --- a/weboob/browser/url.py +++ b/weboob/browser/url.py @@ -201,5 +201,3 @@ def inner(browser, id_or_url, *args, **kwargs): return func(browser, id_or_url, *args, **kwargs) return inner - - diff --git a/weboob/capabilities/audiostream.py b/weboob/capabilities/audiostream.py index 3a353e1a1761e5d40704bd8ca2ea5f6727b36437..08fd2b8e59aa20595ab5cdb5e6f9add1a1928517 100644 --- a/weboob/capabilities/audiostream.py +++ b/weboob/capabilities/audiostream.py @@ -44,6 +44,7 @@ class CapAudioStream(CapAudio): """ Audio streams provider """ + def search_audiostreams(self, pattern, sortby=CapFile.SEARCH_RELEVANCE): """ Search an audio stream diff --git a/weboob/capabilities/bank.py b/weboob/capabilities/bank.py index c5481681c3a94acdbf6e373ee94f57310d315459..6b40dc0cfab9a884c955e2b31ea0b1e75f080000 100644 --- a/weboob/capabilities/bank.py +++ b/weboob/capabilities/bank.py @@ -184,6 +184,7 @@ class CapBank(CapCollection): """ Capability of bank websites to see accounts and transactions. """ + def iter_resources(self, objs, split_path): """ Iter resources. diff --git a/weboob/capabilities/base.py b/weboob/capabilities/base.py index 92b04500c10c64855da5fc2e98cb60cbe99f2071..0c9d333cb2c0a711626c7f214f2835aee3f66720 100644 --- a/weboob/capabilities/base.py +++ b/weboob/capabilities/base.py @@ -45,6 +45,7 @@ def empty(value): return True return False + def find_object(mylist, error=None, **kwargs): """ Very simple tools to return an object with the matching parameters in @@ -63,6 +64,7 @@ def find_object(mylist, error=None, **kwargs): raise error() return None + class UserError(Exception): """ Exception containing an error message for user. @@ -78,6 +80,7 @@ class FieldNotFound(Exception): :param field: field not found :type field: :class:`Field` """ + def __init__(self, obj, field): Exception.__init__(self, u'Field "%s" not found for object %s' % (field, obj)) @@ -102,6 +105,7 @@ class NotAvailableType(object): """ NotAvailable is a constant to use on non available fields. """ + def __str__(self): return unicode(self).decode('utf-8') @@ -199,6 +203,7 @@ class IntField(Field): """ A field which accepts only :class:`int` and :class:`long` types. """ + def __init__(self, doc, **kwargs): Field.__init__(self, doc, int, long, **kwargs) @@ -210,6 +215,7 @@ class DecimalField(Field): """ A field which accepts only :class:`decimal` type. """ + def __init__(self, doc, **kwargs): Field.__init__(self, doc, Decimal, **kwargs) @@ -223,6 +229,7 @@ class FloatField(Field): """ A field which accepts only :class:`float` type. """ + def __init__(self, doc, **kwargs): Field.__init__(self, doc, float, **kwargs) @@ -234,6 +241,7 @@ class StringField(Field): """ A field which accepts only :class:`unicode` strings. """ + def __init__(self, doc, **kwargs): Field.__init__(self, doc, unicode, **kwargs) @@ -245,6 +253,7 @@ class BytesField(Field): """ A field which accepts only :class:`str` strings. """ + def __init__(self, doc, **kwargs): Field.__init__(self, doc, str, **kwargs) diff --git a/weboob/capabilities/bill.py b/weboob/capabilities/bill.py index e167788530afd181062a9e2570d9e5c4bb29c19c..f405cef339be04c418d3e8665fb34a2eff735515 100644 --- a/weboob/capabilities/bill.py +++ b/weboob/capabilities/bill.py @@ -30,6 +30,7 @@ class SubscriptionNotFound(UserError): """ Raised when a subscription is not found. """ + def __init__(self, msg='Subscription not found'): UserError.__init__(self, msg) @@ -38,6 +39,7 @@ class BillNotFound(UserError): """ Raised when a bill is not found. """ + def __init__(self, msg='Bill not found'): UserError.__init__(self, msg) diff --git a/weboob/capabilities/bugtracker.py b/weboob/capabilities/bugtracker.py index 99d78b68b68395ce8c3f6c82f53de1de14cbb877..df9639cf033687873c008f1340e9f4195874619f 100644 --- a/weboob/capabilities/bugtracker.py +++ b/weboob/capabilities/bugtracker.py @@ -236,6 +236,7 @@ class CapBugTracker(Capability): """ Bug trackers websites. """ + def iter_issues(self, query): """ Iter issues with optionnal patterns. diff --git a/weboob/capabilities/chat.py b/weboob/capabilities/chat.py index c2ee9d3391c49dcb5a9855ad2effb6ece26bb56b..2527ae2a2fbe7c97922a916da5736326dc0cfd99 100644 --- a/weboob/capabilities/chat.py +++ b/weboob/capabilities/chat.py @@ -57,6 +57,7 @@ class CapChat(Capability): """ Websites with a chat system. """ + def iter_chat_messages(self, _id=None): """ Iter messages. diff --git a/weboob/capabilities/cinema.py b/weboob/capabilities/cinema.py index 4158097d650df3c7318a81b1426ccecec0df2051..59885acb818b307044c8cb3c3b29b6adacfb0986 100644 --- a/weboob/capabilities/cinema.py +++ b/weboob/capabilities/cinema.py @@ -73,6 +73,7 @@ class CapCinema(Capability): """ Cinema databases. """ + def iter_movies(self, pattern): """ Search movies and iterate on results. diff --git a/weboob/capabilities/collection.py b/weboob/capabilities/collection.py index 4971c06fc64d5d5b7f789636d21e5bc98c48df11..a7f3e8be55a8d7191e97d29773dc93ec3f0cf2e7 100644 --- a/weboob/capabilities/collection.py +++ b/weboob/capabilities/collection.py @@ -39,6 +39,7 @@ class BaseCollection(BaseObject): Inherit from this if you want to create an object that is *also* a Collection. However, this probably will not work properly for now. """ + def __init__(self, split_path): BaseObject.__init__(self, None) self.split_path = split_path diff --git a/weboob/capabilities/date.py b/weboob/capabilities/date.py index ff7a745b64b55fac887f198e2affd70e286e2c18..b56a7caf8fc0275b95e094e71c5cd8185073c948 100644 --- a/weboob/capabilities/date.py +++ b/weboob/capabilities/date.py @@ -24,10 +24,12 @@ __all__ = ['DateField', 'TimeField', 'DeltaField'] + class DateField(Field): """ A field which accepts only :class:`datetime.date` and :class:`datetime.datetime` types. """ + def __init__(self, doc, **kwargs): Field.__init__(self, doc, datetime.date, datetime.datetime, **kwargs) @@ -46,6 +48,7 @@ class TimeField(Field): """ A field which accepts only :class:`datetime.time` and :class:`datetime.time` types. """ + def __init__(self, doc, **kwargs): Field.__init__(self, doc, datetime.time, datetime.datetime, **kwargs) @@ -54,5 +57,6 @@ class DeltaField(Field): """ A field which accepts only :class:`datetime.timedelta` type. """ + def __init__(self, doc, **kwargs): Field.__init__(self, doc, datetime.timedelta, **kwargs) diff --git a/weboob/capabilities/dating.py b/weboob/capabilities/dating.py index 688e26e477e35d2c9753f60db658c99a2555eac2..0117ac7de33e8697509051a8c1574b393f6128f3 100644 --- a/weboob/capabilities/dating.py +++ b/weboob/capabilities/dating.py @@ -94,6 +94,7 @@ class CapDating(Capability): """ Capability for dating websites. """ + def init_optimizations(self): """ Initialization of optimizations. @@ -155,4 +156,3 @@ def iter_new_contacts(self): :rtype: iter[:class:`Contact`] """ raise NotImplementedError() - diff --git a/weboob/capabilities/geolocip.py b/weboob/capabilities/geolocip.py index 7fa4d3925f0d29bc9e612eac88b9c809c6551f2f..ac7b9f52bf8c779945b91862deec9cbd81a7590f 100644 --- a/weboob/capabilities/geolocip.py +++ b/weboob/capabilities/geolocip.py @@ -46,6 +46,7 @@ class CapGeolocIp(Capability): """ Access information about IP addresses database. """ + def get_location(self, ipaddr): """ Get location of an IP address. diff --git a/weboob/capabilities/housing.py b/weboob/capabilities/housing.py index ad9c7fbc7253ceeb96433824048215f79652b017..6f9368fe91ec3d6b6598f94652af38ed044fc8a5 100644 --- a/weboob/capabilities/housing.py +++ b/weboob/capabilities/housing.py @@ -110,6 +110,7 @@ class CapHousing(Capability): """ Capability of websites to search housings. """ + def search_housings(self, query): """ Search housings. diff --git a/weboob/capabilities/image.py b/weboob/capabilities/image.py index cc19dfe14ce3b49693e20be219db782fa733aa98..9c49a0f0185c476a206fdf719d576f3cca5b1008 100644 --- a/weboob/capabilities/image.py +++ b/weboob/capabilities/image.py @@ -24,6 +24,7 @@ __all__ = ['BaseImage', 'CapImage'] + class _BaseImage(BaseFile): """ Fake class to allow the inclusion of a BaseImage property within @@ -31,6 +32,7 @@ class _BaseImage(BaseFile): """ pass + class BaseImage(_BaseImage): """ Represents an image file. @@ -61,6 +63,7 @@ class CapImage(CapFile): """ Image file provider """ + def search_image(self, pattern, sortby=CapFile.SEARCH_RELEVANCE, nsfw=False): """ search for an image file @@ -83,4 +86,3 @@ def get_image(self, _id): :rtype: :class:`BaseImage`] """ return self.get_file(_id) - diff --git a/weboob/capabilities/job.py b/weboob/capabilities/job.py index f9be67d6a1df26944d2f12a86c0dea8a609d4068..c5731d5384de209343d33d2187c48ecb405e9f75 100644 --- a/weboob/capabilities/job.py +++ b/weboob/capabilities/job.py @@ -72,6 +72,7 @@ class CapJob(Capability): """ Capability of job annouce websites. """ + def search_job(self, pattern=None): """ Iter results of a search on a pattern. diff --git a/weboob/capabilities/library.py b/weboob/capabilities/library.py index 8741a197e5c108d7e126df6754ab2a39f5c90265..bc05772017a02c259ecbe080b09e7def7b68e7dd 100644 --- a/weboob/capabilities/library.py +++ b/weboob/capabilities/library.py @@ -47,6 +47,7 @@ class CapBook(CapCollection): """ Library websites. """ + def iter_resources(self, objs, split_path): """ Iter resources. It retuns :func:`iter_books`. diff --git a/weboob/capabilities/lyrics.py b/weboob/capabilities/lyrics.py index 3b775231df9bc40bbe0b07c877743b5abe639c34..bceb783fb2b304025464fe7f365b082748212f09 100644 --- a/weboob/capabilities/lyrics.py +++ b/weboob/capabilities/lyrics.py @@ -41,6 +41,7 @@ class CapLyrics(Capability): """ Lyrics websites. """ + def iter_lyrics(self, criteria, pattern): """ Search lyrics by artist or by song diff --git a/weboob/capabilities/messages.py b/weboob/capabilities/messages.py index 6a181d2f28825bec563209e229e07791e9b62212..a7081e485cd1ea2e74e2312465f30e17933db239 100644 --- a/weboob/capabilities/messages.py +++ b/weboob/capabilities/messages.py @@ -173,6 +173,7 @@ class CapMessages(Capability): """ Capability to read messages. """ + def iter_threads(self): """ Iterates on threads, from newers to olders. @@ -217,6 +218,7 @@ class CapMessagesPost(Capability): """ This capability allow user to send a message. """ + def post_message(self, message): """ Post a message. diff --git a/weboob/capabilities/parcel.py b/weboob/capabilities/parcel.py index 054b8cede9f3eec8656a2b0e1416e52b6ecd40d1..a9d4e00ca62d1ff6c7946af2b07899f7301113c1 100644 --- a/weboob/capabilities/parcel.py +++ b/weboob/capabilities/parcel.py @@ -62,5 +62,6 @@ class ParcelNotFound(UserError): Raised when a parcell is not found. It can be an user error, or an expired parcel """ + def __init__(self, msg='Account not found'): UserError.__init__(self, msg) diff --git a/weboob/capabilities/paste.py b/weboob/capabilities/paste.py index c5bb0f93e5fa903ae4403cc547772e79501f8988..358cb5e3303b4f274eb376551f8d89dc5942aa3b 100644 --- a/weboob/capabilities/paste.py +++ b/weboob/capabilities/paste.py @@ -28,6 +28,7 @@ class PasteNotFound(UserError): """ Raised when a paste is not found. """ + def __init__(self): return super(PasteNotFound, self).__init__("Paste not found") diff --git a/weboob/capabilities/radio.py b/weboob/capabilities/radio.py index 27970a4c941fb716e233647e3add102864f8fa66..b1d2fa06c8720b0bf9721c44f5e1fe56695aca12 100644 --- a/weboob/capabilities/radio.py +++ b/weboob/capabilities/radio.py @@ -35,10 +35,12 @@ class Radio(BaseObject): current = Field('Current emission', StreamInfo) streams = Field('List of streams', list) + class CapRadio(Capability): """ Capability of radio websites. """ + def iter_radios_search(self, pattern): """ Search a radio. diff --git a/weboob/capabilities/recipe.py b/weboob/capabilities/recipe.py index eb0390e5a9fa6edac30dd370c8a15895224df06d..e55f5fda3a505228312d4cde88dbca08c3f6fd9e 100644 --- a/weboob/capabilities/recipe.py +++ b/weboob/capabilities/recipe.py @@ -165,6 +165,7 @@ class CapRecipe(Capability): """ Recipe providers. """ + def iter_recipes(self, pattern): """ Search recipes and iterate on results. diff --git a/weboob/capabilities/subtitle.py b/weboob/capabilities/subtitle.py index ff53faf06d75dbb16a18ddb4bd962a51ef589843..d4d80d8546613e617582852ac850316dcc9ad7d6 100644 --- a/weboob/capabilities/subtitle.py +++ b/weboob/capabilities/subtitle.py @@ -48,10 +48,12 @@ def __init__(self, id, name): BaseObject.__init__(self, id) self.name = name + class CapSubtitle(Capability): """ Subtitle providers. """ + def iter_subtitles(self, pattern): """ Search subtitles and iterate on results. diff --git a/weboob/capabilities/torrent.py b/weboob/capabilities/torrent.py index 4399d54908d61318e1322c73f122f52096650078..af5cbd4320ef848533e767bfc1cbdf2c7b896ef8 100644 --- a/weboob/capabilities/torrent.py +++ b/weboob/capabilities/torrent.py @@ -29,6 +29,7 @@ class MagnetOnly(UserError): """ Raised when trying to get URL to torrent but only magnet is available. """ + def __init__(self, magnet): self.magnet = magnet UserError.__init__(self, 'Only magnet URL is available') @@ -58,6 +59,7 @@ class CapTorrent(Capability): """ Torrent trackers. """ + def iter_torrents(self, pattern): """ Search torrents and iterate on results. diff --git a/weboob/capabilities/travel.py b/weboob/capabilities/travel.py index a72c073b37f96d5cc8aca3dce140a2fb654f67ff..fdecd5d0a7d1085a44352d689d13847a7d35b004 100644 --- a/weboob/capabilities/travel.py +++ b/weboob/capabilities/travel.py @@ -99,6 +99,7 @@ class CapTravel(Capability): """ Travel websites. """ + def iter_station_search(self, pattern): """ Iterates on search results of stations. diff --git a/weboob/capabilities/weather.py b/weboob/capabilities/weather.py index e132832409829da4931517f2866e9a82cdd7c8e3..a6c4185972456de0fec9c88b8ed6460a56223f5e 100644 --- a/weboob/capabilities/weather.py +++ b/weboob/capabilities/weather.py @@ -113,6 +113,7 @@ class CapWeather(Capability): """ Capability for weather websites. """ + def iter_city_search(self, pattern): """ Look for a city. diff --git a/weboob/core/modules.py b/weboob/core/modules.py index 1ad0a7e20f47544e68a9987ef1b3a310e87def98..82fa43b71af11ed37a9fef95adf5fbd6ce7628ff 100644 --- a/weboob/core/modules.py +++ b/weboob/core/modules.py @@ -103,6 +103,7 @@ class ModulesLoader(object): """ Load modules. """ + def __init__(self, path, version=None): self.version = version self.path = path @@ -162,10 +163,12 @@ def load_module(self, module_name): def get_module_path(self, module_name): return self.path + class RepositoryModulesLoader(ModulesLoader): """ Load modules from repositories. """ + def __init__(self, repositories): super(RepositoryModulesLoader, self).__init__(repositories.modules_dir, repositories.version) self.repositories = repositories diff --git a/weboob/core/ouiboube.py b/weboob/core/ouiboube.py index bf0de538f12f17f8dd7543cd3431e0ec89f780b2..317fd511f2b81528dcd30f71775123d99e64e1b9 100644 --- a/weboob/core/ouiboube.py +++ b/weboob/core/ouiboube.py @@ -111,6 +111,7 @@ class LoadError(Exception): :param backend_name: name of backend we can't load :param exception: exception object """ + def __init__(self, backend_name, exception): Exception.__init__(self, unicode(exception)) self.backend_name = backend_name diff --git a/weboob/core/repositories.py b/weboob/core/repositories.py index a9c3e42db18fe4cb00b38b136c2c375c29915c4e..d7afe42abb9aae02e3f6e5044804b12204045fe4 100644 --- a/weboob/core/repositories.py +++ b/weboob/core/repositories.py @@ -45,6 +45,7 @@ class ModuleInfo(object): """ Information about a module available on a repository. """ + def __init__(self, name): self.name = name @@ -380,6 +381,7 @@ def error(self, message): def __repr__(self): return '<%s>' % self.__class__.__name__ + class PrintProgress(IProgress): def progress(self, percent, message): print('=== [%3.0f%%] %s' % (percent*100, message)) @@ -450,6 +452,7 @@ def __init__(self, workdir, datadir, version): def load_browser(self): from weboob.browser.browsers import Browser from weboob.browser.profiles import Weboob as WeboobProfile + class WeboobBrowser(Browser): PROFILE = WeboobProfile(self.version) if self.browser is None: diff --git a/weboob/deprecated/browser/browser.py b/weboob/deprecated/browser/browser.py index d3a55d79d734178267630cddb5f6588cec4549b0..718ddc7450434d6d44f0d9d1baa88ac3c6af711f 100644 --- a/weboob/deprecated/browser/browser.py +++ b/weboob/deprecated/browser/browser.py @@ -69,6 +69,7 @@ class NoHistory(object): """ We don't want to fill memory with history """ + def __init__(self): pass @@ -703,6 +704,7 @@ class DNSTimeoutException(Exception): cacheDNS = {} + def my_getaddrinfo(*args): try: res, timeout = cacheDNS[args] diff --git a/weboob/deprecated/browser/parsers/csvparser.py b/weboob/deprecated/browser/parsers/csvparser.py index 639149cc97a430317a62916ecc002b706c0218e6..4407d5a967671b36b7f41a0eefa0284d30bf7fab 100644 --- a/weboob/deprecated/browser/parsers/csvparser.py +++ b/weboob/deprecated/browser/parsers/csvparser.py @@ -29,6 +29,7 @@ class Csv(object): rows contains the raw rows drows contains the rows with cells indexed by header title """ + def __init__(self): self.header = None self.rows = [] diff --git a/weboob/deprecated/browser/parsers/lxmlparser.py b/weboob/deprecated/browser/parsers/lxmlparser.py index b5e13fa24538ec43f6bd8470fbffc4af9e2229c9..6b59d07d9e19f6be4ce350c26ec95fec0910914b 100644 --- a/weboob/deprecated/browser/parsers/lxmlparser.py +++ b/weboob/deprecated/browser/parsers/lxmlparser.py @@ -109,6 +109,7 @@ class LxmlHtmlParser(LxmlParser): Note that it is not available on every systems. """ + def __init__(self, *args, **kwargs): self.module = html @@ -122,6 +123,7 @@ class LxmlXmlParser(LxmlParser): Note that it is not available on every systems. """ + def __init__(self, *args, **kwargs): self.module = etree diff --git a/weboob/tools/application/formatters/json.py b/weboob/tools/application/formatters/json.py index 94b23e2be367c56c9a5f246351717d2076a40193..5908685a5af223975c1409df424ffcc10967e902 100644 --- a/weboob/tools/application/formatters/json.py +++ b/weboob/tools/application/formatters/json.py @@ -47,6 +47,7 @@ class JsonFormatter(IFormatter): """ Formats the whole list as a single JSON list object. """ + def __init__(self): IFormatter.__init__(self) self.queue = [] @@ -66,9 +67,11 @@ class JsonLineFormatter(IFormatter): Formats the list as received, with a JSON object per line. The advantage is that it can be streamed. """ + def format_dict(self, item): self.output(json.dumps(item, cls=Encoder)) + def test(): from .iformatter import formatter_test_output as fmt assert fmt(JsonFormatter, {'foo': 'bar'}) == '[{"foo": "bar"}]\n' diff --git a/weboob/tools/application/formatters/table.py b/weboob/tools/application/formatters/table.py index 81322d87808bae947ce4c919ccf6b1dd7649c6ea..73c4a89d65992a80fdc1cba84c4357170515dd95 100644 --- a/weboob/tools/application/formatters/table.py +++ b/weboob/tools/application/formatters/table.py @@ -100,6 +100,7 @@ def set_header(self, string): class HTMLTableFormatter(TableFormatter): HTML = True + def test(): from .iformatter import formatter_test_output as fmt assert fmt(TableFormatter, {'foo': 'bar'}) == \ diff --git a/weboob/tools/application/media_player.py b/weboob/tools/application/media_player.py index f2847bed0cb1108fab569e33508cd22394897832..6f319ad076d1447231c89b206c88c1cceac846e5 100644 --- a/weboob/tools/application/media_player.py +++ b/weboob/tools/application/media_player.py @@ -61,6 +61,7 @@ class MediaPlayer(object): world, the media player used is chosen from a static list of programs. See PLAYERS for more information. """ + def __init__(self, logger=None): self.logger = getLogger('mediaplayer', logger) diff --git a/weboob/tools/application/qt/qt.py b/weboob/tools/application/qt/qt.py index 29de87968f8cf292ce1779d3d8944d31e1cb3f33..a73afb6b78ff42a67bd831a1362022402a629d4a 100644 --- a/weboob/tools/application/qt/qt.py +++ b/weboob/tools/application/qt/qt.py @@ -178,6 +178,7 @@ def load_backends(self, *args, **kwargs): QMessageBox.information(None, self.tr('Update of repositories'), self.tr('Repositories updated!'), QMessageBox.Ok) + class QtMainWindow(QMainWindow): def __init__(self, parent=None): QMainWindow.__init__(self, parent) diff --git a/weboob/tools/backend.py b/weboob/tools/backend.py index 75eae470e3c0e3ae7fa0756fce8d492233cb3aff..f78eecf588763c1c3a55b964c118af60e382e139 100644 --- a/weboob/tools/backend.py +++ b/weboob/tools/backend.py @@ -44,6 +44,7 @@ class BackendStorage(object): :param storage: storage object :type storage: :class:`weboob.tools.storage.IStorage` """ + def __init__(self, name, storage): self.name = name self.storage = storage diff --git a/weboob/tools/capabilities/bank/transactions.py b/weboob/tools/capabilities/bank/transactions.py index d73c9d619384d4ded04401278f1984d68d1c112b..502c06e4f647ad41b56d41ad73ff77811d96d413 100644 --- a/weboob/tools/capabilities/bank/transactions.py +++ b/weboob/tools/capabilities/bank/transactions.py @@ -38,6 +38,7 @@ class classproperty(object): def __init__(self, f): self.f = f + def __get__(self, obj, owner): return self.f(owner) @@ -225,6 +226,7 @@ def filter(self, date): @classmethod def Raw(klass, *args, **kwargs): patterns = klass.PATTERNS + class Filter(CleanText): def __call__(self, item): raw = super(Filter, self).__call__(item) @@ -286,6 +288,7 @@ def inargs(key): break return raw + def filter(self, text): text = super(Filter, self).filter(text) return to_unicode(text.replace(u'\n', u' ').strip()) @@ -332,6 +335,7 @@ def clean_amount(klass, text): text = text.replace(',', ' ').replace('.', ',') return FrenchTransaction.clean_amount(text) + def test(): clean_amount = AmericanTransaction.clean_amount assert clean_amount('42') == '42' diff --git a/weboob/tools/capabilities/paste.py b/weboob/tools/capabilities/paste.py index fe3c5ddc37f1cb938ca342f037d086117a25dbea..90c07329b3552101fdfdd56f586a69526bd8bc3d 100644 --- a/weboob/tools/capabilities/paste.py +++ b/weboob/tools/capabilities/paste.py @@ -70,6 +70,7 @@ def image_mime(data_base64, supported_formats=('gif', 'jpeg', 'png')): 'MM\x2a\x00' in beginning): return 'image/tiff' + def test(): class MockPasteModule(BasePasteModule): def __init__(self, expirations): diff --git a/weboob/tools/capabilities/streaminfo.py b/weboob/tools/capabilities/streaminfo.py index 15272e543110495bb35d27a9bc0bb6545c0b2624..9c093892fce7fb74c10e5b1dd3c69569d058a83d 100644 --- a/weboob/tools/capabilities/streaminfo.py +++ b/weboob/tools/capabilities/streaminfo.py @@ -39,4 +39,3 @@ def __unicode__(self): return u'%s - %s' % (self.who, self.what) else: return self.what - diff --git a/weboob/tools/date.py b/weboob/tools/date.py index 2407926fec6edd4643e5eab5900d7e3a69fa6e73..ab29571cfaa3c9ce5393db8821b6c861489eace7 100644 --- a/weboob/tools/date.py +++ b/weboob/tools/date.py @@ -214,6 +214,7 @@ class ChaoticDateGuesser(LinearDateGuesser): This class aim to find the guess the date when you know the day and month and the minimum year """ + def __init__(self, min_date, current_date=None, date_max_bump=timedelta(7)): if min_date is None: raise ValueError("min_date is not set") diff --git a/weboob/tools/log.py b/weboob/tools/log.py index fdb197f05efc4cf4f8b91e78ad7932e48c23f069..bc8fce9b1b55ad091ef6de7ba244b356b8b21dc1 100644 --- a/weboob/tools/log.py +++ b/weboob/tools/log.py @@ -59,6 +59,7 @@ class ColoredFormatter(Formatter): Class written by airmind: http://stackoverflow.com/questions/384076/how-can-i-make-the-python-logging-output-to-be-colored """ + def format(self, record): levelname = record.levelname msg = Formatter.format(self, record) diff --git a/weboob/tools/regex_helper.py b/weboob/tools/regex_helper.py index 9e7639b82077ebf77e9f183a630a4c5cc3320218..42252c94a8069bb07c909b126608f61ce33ee214 100644 --- a/weboob/tools/regex_helper.py +++ b/weboob/tools/regex_helper.py @@ -50,6 +50,7 @@ "Z": None, } + class Choice(list): """ Used to represent multiple possibilities at this point in a pattern string. @@ -57,16 +58,19 @@ class Choice(list): code is clear. """ + class Group(list): """ Used to represent a capturing group in the pattern string. """ + class NonCapture(list): """ Used to represent a non-capturing group in the pattern string. """ + def normalize(pattern): """ Given a reg-exp pattern, normalizes it to a list of forms that suffice for @@ -222,6 +226,7 @@ def normalize(pattern): return zip(*flatten_result(result)) + def next_char(input_iter): """ An iterator that yields the next character from "pattern_iter", respecting @@ -242,6 +247,7 @@ def next_char(input_iter): continue yield representative, True + def walk_to_end(ch, input_iter): """ The iterator is currently inside a capturing group. We want to walk to the @@ -262,6 +268,7 @@ def walk_to_end(ch, input_iter): return nesting -= 1 + def get_quantifier(ch, input_iter): """ Parse a quantifier from the input, where "ch" is the first character in the @@ -298,6 +305,7 @@ def get_quantifier(ch, input_iter): ch = None return int(values[0]), ch + def contains(source, inst): """ Returns True if the "source" contains an instance of "inst". False, @@ -311,6 +319,7 @@ def contains(source, inst): return True return False + def flatten_result(source): """ Turns the given source sequence into a list of reg-exp possibilities and @@ -363,4 +372,3 @@ def flatten_result(source): for i in range(len(result)): result[i] += piece return result, result_args - diff --git a/weboob/tools/value.py b/weboob/tools/value.py index 92bfaec26767ca804ecbe36d9f052d5a2be9ec56..6fe19e02806f38ba1894a301bf0cacc254f6fe11 100644 --- a/weboob/tools/value.py +++ b/weboob/tools/value.py @@ -33,6 +33,7 @@ class ValuesDict(OrderedDict): >>> ValuesDict(Value('a', label='Test'), ValueInt('b', label='Test2')) """ + def __init__(self, *values): OrderedDict.__init__(self) for v in values: