diff --git a/contrib/munin/boobank-munin b/contrib/munin/boobank-munin index e6279c52..67c88adb 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 943fbff1..13c22181 100644 --- a/contrib/windows-install/convertPNG2ICO.py +++ b/contrib/windows-install/convertPNG2ICO.py @@ -33,6 +33,7 @@ import os # 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 e0c57d97..eb2d5290 100644 --- a/contrib/windows-install/ez_setup.py +++ b/contrib/windows-install/ez_setup.py @@ -32,12 +32,15 @@ except ImportError: 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 @@ def _check_call_py24(cmd, *args, **kwargs): 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 2e284fb6..ba71c6c3 100644 --- a/modules/750g/module.py +++ b/modules/750g/module.py @@ -24,6 +24,7 @@ from .browser import SevenFiftyGramsBrowser 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 c29b0536..ed4e2a9a 100644 --- a/modules/750g/pages.py +++ b/modules/750g/pages.py @@ -26,6 +26,7 @@ from weboob.deprecated.browser import 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.recette_description > div.data'): links = self.parser.select(div, 'div.info > p.title > a.fn') @@ -65,6 +66,7 @@ class ResultsPage(Page): 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 bde18710..499231cc 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 89aae4ab..70b7864c 100644 --- a/modules/alloresto/module.py +++ b/modules/alloresto/module.py @@ -60,4 +60,3 @@ class AlloRestoModule(Module, CapBank): def iter_coming(self, account): return self.browser.get_coming(account) - diff --git a/modules/alloresto/pages.py b/modules/alloresto/pages.py index 5a539994..4c33eb42 100644 --- a/modules/alloresto/pages.py +++ b/modules/alloresto/pages.py @@ -52,6 +52,7 @@ class AccountsPage(LoggedPage, HTMLPage): 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 5060f431..8fc91e35 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 @@ class ResultsPage(Page): 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 8abd1c4a..156af127 100644 --- a/modules/ameli/pages.py +++ b/modules/ameli/pages.py @@ -29,6 +29,7 @@ from weboob.capabilities.bill import Subscription, Detail, Bill # 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 @@ class AmeliBasePage(Page): 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 @@ class LoginPage(AmeliBasePage): 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 2bd42a7f..e5b00ad1 100644 --- a/modules/americanexpress/module.py +++ b/modules/americanexpress/module.py @@ -63,4 +63,3 @@ class AmericanExpressModule(Module, CapBank): 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 35e939ec..a862313c 100644 --- a/modules/americanexpress/pages.py +++ b/modules/americanexpress/pages.py @@ -56,6 +56,7 @@ class AccountsPage(Page): yield a + class TransactionsPage(Page): COL_ID = 0 COL_DATE = 1 @@ -81,6 +82,7 @@ class TransactionsPage(Page): 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 6b8eee0f..e65fbd72 100644 --- a/modules/audioaddict/test.py +++ b/modules/audioaddict/test.py @@ -39,4 +39,3 @@ class AudioAddictTest(BackendTest): 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 71c23ff6..fb367f96 100644 --- a/modules/aum/browser.py +++ b/modules/aum/browser.py @@ -127,6 +127,7 @@ class WebsiteBrowser(LoginBrowser): return profile + class AuMBrowser(Browser): DOMAIN = 'www.adopteunmec.com' APIKEY = 'fb0123456789abcd' diff --git a/modules/axabanque/pages.py b/modules/axabanque/pages.py index 33626c83..5d7ef9f5 100644 --- a/modules/axabanque/pages.py +++ b/modules/axabanque/pages.py @@ -256,6 +256,7 @@ class TransactionsPage(BasePage): yield t + class CBTransactionsPage(TransactionsPage): COL_CB_CREDIT = 2 diff --git a/modules/banqueaccord/pages.py b/modules/banqueaccord/pages.py index 11720f05..b91d848d 100644 --- a/modules/banqueaccord/pages.py +++ b/modules/banqueaccord/pages.py @@ -87,6 +87,7 @@ class VirtKeyboard(MappedVirtKeyboard): 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 @@ class LoginPage(HTMLPage): form['code'] = code form.submit() + class IndexPage(LoggedPage, HTMLPage): @method class get_list(ListElement): @@ -152,6 +154,7 @@ class IndexPage(LoggedPage, HTMLPage): 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 b1888db6..1f500b25 100644 --- a/modules/banquepopulaire/browser.py +++ b/modules/banquepopulaire/browser.py @@ -82,6 +82,7 @@ class BanquePopulaire(Browser): 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 1657325c..ea9d52fc 100644 --- a/modules/bnporc/enterprise/pages.py +++ b/modules/bnporc/enterprise/pages.py @@ -267,5 +267,6 @@ class HistoryPage(BEPage): # Last page return None + class UnknownPage(BEPage): pass diff --git a/modules/boursorama/pages/__init__.py b/modules/boursorama/pages/__init__.py index 3fc78d14..44da434a 100644 --- a/modules/boursorama/pages/__init__.py +++ b/modules/boursorama/pages/__init__.py @@ -26,6 +26,7 @@ from .login import LoginPage, UpdateInfoPage from .two_authentication import AuthenticationPage + class AccountPrelevement(AccountsList): pass diff --git a/modules/bp/pages/login.py b/modules/bp/pages/login.py index 5fda4a1e..6224caf6 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 @@ class Keyboard(VirtKeyboard): 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 bc2cfe43..9f76b66e 100644 --- a/modules/btdigg/module.py +++ b/modules/btdigg/module.py @@ -8,6 +8,7 @@ from .browser import BTDiggBrowser __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 aa97b322..962db295 100644 --- a/modules/btdigg/pages/torrents.py +++ b/modules/btdigg/pages/torrents.py @@ -50,6 +50,7 @@ class TorrentsPage(Page): 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 1d8c586f..e307bd7a 100644 --- a/modules/caissedepargne/pages.py +++ b/modules/caissedepargne/pages.py @@ -39,6 +39,7 @@ class _LogoutPage(Page): except BrokenPageError: pass + class LoginPage(_LogoutPage): def login(self, login): self.browser.select_form(name='Main') @@ -83,6 +84,7 @@ class LoginPage(_LogoutPage): 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 b7038228..5d80eb33 100644 --- a/modules/chronopost/pages.py +++ b/modules/chronopost/pages.py @@ -32,6 +32,7 @@ class IndexPage(Page): 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 4c76f5da..6d89d29c 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 @@ class CardPage(OperationsPage): 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 70ee6241..b38ac110 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 @@ class TrackPage(Page): pass return p + class ErrorPage(Page): pass diff --git a/modules/cragr/mobile/pages/tokenextractor.py b/modules/cragr/mobile/pages/tokenextractor.py index f2f2addd..ecb950e6 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 680c2105..9ba99ad8 100644 --- a/modules/cragr/web/pages.py +++ b/modules/cragr/web/pages.py @@ -39,6 +39,7 @@ class HomePage(Page): return None + class LoginPage(Page): def login(self, password): assert password.isdigit() @@ -60,12 +61,15 @@ class LoginPage(Page): 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 @@ class CardsPage(Page): 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 d1ca85bd..fd5f0744 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 @@ class ITransactionsPage(Page): def get_history(self): raise NotImplementedError() + class TransactionsPage(ITransactionsPage): TR_DATE = 0 TR_TEXT = 2 @@ -135,6 +137,7 @@ class TransactionsPage(ITransactionsPage): 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 5b595ffb..a94731cf 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 ba09aaf4..9ee73479 100644 --- a/modules/cuisineaz/module.py +++ b/modules/cuisineaz/module.py @@ -26,6 +26,7 @@ import unicodedata __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 537dce6a..4e150a87 100644 --- a/modules/cuisineaz/pages.py +++ b/modules/cuisineaz/pages.py @@ -26,6 +26,7 @@ from weboob.deprecated.browser import 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.rechRecette'): thumbnail_url = NotAvailable @@ -74,6 +75,7 @@ class ResultsPage(Page): 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 4b0315ac..af294302 100644 --- a/modules/dailymotion/pages.py +++ b/modules/dailymotion/pages.py @@ -154,6 +154,7 @@ class VideoPage(Page): 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 71a682e8..ce1c8b33 100644 --- a/modules/delubac/pages.py +++ b/modules/delubac/pages.py @@ -94,6 +94,7 @@ class OperationsPage(Page): 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 14361d93..17ae73b7 100644 --- a/modules/edf/pages.py +++ b/modules/edf/pages.py @@ -27,6 +27,7 @@ from weboob.capabilities.bill import Subscription, Detail, Bill 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 @@ class BillsPage(EdfBasePage): def get_bill(self, bill): self.location(bill._url) + class LastPaymentsPage(EdfBasePage): def on_loaded(self): @@ -146,6 +151,7 @@ class LastPaymentsPage(EdfBasePage): 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 d8ddac25..348d7d8f 100644 --- a/modules/gdcvault/pages.py +++ b/modules/gdcvault/pages.py @@ -79,6 +79,8 @@ class IndexPage(Page): # 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 @@ class SearchPage(Page): 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 cb8055d4..70445df7 100644 --- a/modules/github/browser.py +++ b/modules/github/browser.py @@ -199,6 +199,7 @@ class GithubBrowser(Browser): # 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 984de02d..8946c67b 100644 --- a/modules/github/module.py +++ b/modules/github/module.py @@ -32,6 +32,7 @@ STATUSES = {'open': Status('open', u'Open', Status.VALUE_NEW), '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 32e01b06..7af575fc 100644 --- a/modules/hellobank/perso/transactions.py +++ b/modules/hellobank/perso/transactions.py @@ -89,5 +89,6 @@ class AccountHistory(Page): 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 2a82fb67..c826167a 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 CBOperationPage(LoggedPage, HTMLPage): 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 @@ class CPTOperationPage(LoggedPage, HTMLPage): 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 6a60f03d..e5ac59aa 100644 --- a/modules/imdb/pages.py +++ b/modules/imdb/pages.py @@ -29,6 +29,7 @@ import re 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 @@ class ReleasePage(Page): class BiographyPage(Page): ''' Page containing biography of a person ''' + def get_biography(self): bio = unicode() start = False @@ -74,6 +76,7 @@ class BiographyPage(Page): 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 83491a94..4cda3706 100644 --- a/modules/inrocks/pages/article.py +++ b/modules/inrocks/pages/article.py @@ -26,6 +26,7 @@ from weboob.tools.capabilities.messages.genericArticle import GenericNewsPage, t 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 75caa1fe..f22cead7 100644 --- a/modules/inrocks/pages/inrockstv.py +++ b/modules/inrocks/pages/inrockstv.py @@ -23,6 +23,7 @@ from weboob.tools.capabilities.messages.genericArticle import GenericNewsPage 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 910be409..fc2d3ac1 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 @@ class RoadmapSearchPage(Page): 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 @@ class RoadmapResultsPage(Page): 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 9fb2d79d..9d9139d5 100644 --- a/modules/lcl/browser.py +++ b/modules/lcl/browser.py @@ -122,6 +122,7 @@ class LCLBrowser(Browser): for tr in self.page.get_operations(): yield tr + class LCLProBrowser(LCLBrowser): PROTOCOL = 'https' DOMAIN = 'professionnels.secure.lcl.fr' @@ -165,4 +166,3 @@ class LCLProBrowser(LCLBrowser): 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 037b7102..c4dae7c3 100644 --- a/modules/lcl/pages.py +++ b/modules/lcl/pages.py @@ -132,6 +132,7 @@ class LoginPage(Page): 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 6f2f9aa6..2ac98dee 100644 --- a/modules/lefigaro/pages/article.py +++ b/modules/lefigaro/pages/article.py @@ -23,6 +23,7 @@ from weboob.tools.capabilities.messages.genericArticle import GenericNewsPage, d 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 1b4a50c4..a741f00b 100644 --- a/modules/lefigaro/pages/flashactu.py +++ b/modules/lefigaro/pages/flashactu.py @@ -23,6 +23,7 @@ from weboob.tools.capabilities.messages.genericArticle import GenericNewsPage 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 3857b6be..fcd537da 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 e24985d5..514d2c0d 100644 --- a/modules/mailinator/browser.py +++ b/modules/mailinator/browser.py @@ -65,8 +65,10 @@ class MailinatorBrowser(Browser): 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 51d38209..f0c79b14 100644 --- a/modules/mailinator/test.py +++ b/modules/mailinator/test.py @@ -32,4 +32,3 @@ class MailinatorTest(BackendTest): 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 212770f6..db8f1f16 100644 --- a/modules/marmiton/pages.py +++ b/modules/marmiton/pages.py @@ -26,6 +26,7 @@ from weboob.deprecated.browser import 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.m_search_result'): tds = self.parser.select(div, 'td') @@ -57,6 +58,7 @@ class ResultsPage(Page): 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 5bf1347a..072658d4 100644 --- a/modules/minutes20/pages/article.py +++ b/modules/minutes20/pages/article.py @@ -24,6 +24,7 @@ from .simple import SimplePage 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 b61ef7e5..c05883a1 100644 --- a/modules/minutes20/pages/simple.py +++ b/modules/minutes20/pages/simple.py @@ -23,6 +23,7 @@ from weboob.tools.capabilities.messages.genericArticle import GenericNewsPage 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 a188c819..fd701396 100644 --- a/modules/nectarine/browser.py +++ b/modules/nectarine/browser.py @@ -22,6 +22,7 @@ from .pages import LivePage, StreamsPage __all__ = ['NectarineBrowser'] + class NectarineBrowser(Browser): DOMAIN = 'www.scenemusic.net' PROTOCOL = 'https' diff --git a/modules/nectarine/module.py b/modules/nectarine/module.py index d5110bde..ff3086c8 100644 --- a/modules/nectarine/module.py +++ b/modules/nectarine/module.py @@ -23,6 +23,7 @@ from .browser import NectarineBrowser __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 d4346c44..9baa089a 100644 --- a/modules/nihonnooto/browser.py +++ b/modules/nihonnooto/browser.py @@ -22,6 +22,7 @@ from .pages import LivePage, ProgramPage __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 bb94704f..76bf4209 100644 --- a/modules/nihonnooto/module.py +++ b/modules/nihonnooto/module.py @@ -23,6 +23,7 @@ from .browser import NihonNoOtoBrowser __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 86022343..9cace718 100644 --- a/modules/nolifetv/browser.py +++ b/modules/nolifetv/browser.py @@ -28,6 +28,7 @@ from .pages import VideoPage, VideoListPage, FamilyPage, AboPage, LoginPage, Hom __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 eb2558ec..c02798ff 100644 --- a/modules/nolifetv/module.py +++ b/modules/nolifetv/module.py @@ -32,6 +32,7 @@ from hashlib import md5 __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 5cabb75d..e722a1e7 100644 --- a/modules/nolifetv/pages.py +++ b/modules/nolifetv/pages.py @@ -67,6 +67,7 @@ class VideoPage(Page): 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 @@ class VideoListPage(Page): video.title = video.title + ' - ' + strongs[3].text yield video + class FamilyPage(Page): def iter_category(self): subs = list() @@ -109,6 +111,7 @@ class FamilyPage(Page): 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 @@ class LoginPage(Page): 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 73b58f0d..c8a7ee41 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 5deb768f..ad43044a 100644 --- a/modules/okc/browser.py +++ b/modules/okc/browser.py @@ -266,5 +266,3 @@ class OkCBrowser(Browser): 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 d38a43b2..946a8f99 100644 --- a/modules/okc/pages.py +++ b/modules/okc/pages.py @@ -26,6 +26,7 @@ from weboob.capabilities.contact import ProfileNode 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 @@ class PostMessagePage(Page): 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 @@ class VisitsPage(Page): }) 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 0df4ec74..0b7489e3 100644 --- a/modules/oney/pages.py +++ b/modules/oney/pages.py @@ -97,6 +97,7 @@ class VirtKeyboard(MappedVirtKeyboard): code += self.get_symbol_code(self.symbols[c]) return code + class LoginPage(HTMLPage): is_here ="//form[@id='formulaire-login']" @@ -115,12 +116,14 @@ class LoginPage(HTMLPage): 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 10da1b75..cbd2a5f3 100644 --- a/modules/opensubtitles/pages.py +++ b/modules/opensubtitles/pages.py @@ -28,6 +28,7 @@ from weboob.applications.suboob.suboob import LANGUAGE_CONV 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 @@ class SearchPage(Page): 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 @@ class SubtitlesPage(Page): 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 7f962b9b..e9bf8dba 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 6d06e5ff..037f19ff 100644 --- a/modules/paypal/pages.py +++ b/modules/paypal/pages.py @@ -34,6 +34,7 @@ from weboob.tools.capabilities.bank.transactions import AmericanTransaction 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 @@ class DownloadHistoryPage(Page): self.browser.submit() + class LastDownloadHistoryPage(Page): def download(self): self.browser.select_form(nr=1) @@ -142,10 +144,12 @@ class LastDownloadHistoryPage(Page): 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 9715d05c..aef0d5e0 100644 --- a/modules/podnapisi/pages.py +++ b/modules/podnapisi/pages.py @@ -74,6 +74,7 @@ LANGUAGE_NUMBERS = { 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 @@ class SearchPage(Page): 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 bc23389d..4694946a 100644 --- a/modules/presseurop/pages/article.py +++ b/modules/presseurop/pages/article.py @@ -55,6 +55,7 @@ class PresseuropPage(GenericNewsPage): 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 24d96873..41d5dc0f 100644 --- a/modules/quvi/module.py +++ b/modules/quvi/module.py @@ -74,6 +74,7 @@ class QuviModule(Module, CapVideo): 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 4482e0b6..c0d76cfd 100644 --- a/modules/quvi/test.py +++ b/modules/quvi/test.py @@ -45,4 +45,3 @@ class QuviTest(BackendTest): 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 d2d9c597..30cd0f87 100644 --- a/modules/redmine/pages/issues.py +++ b/modules/redmine/pages/issues.py @@ -157,6 +157,7 @@ class IssuesPage(BaseIssuePage): 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 f13898e1..1cd64613 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 6779c4d0..c2ebf684 100644 --- a/modules/somafm/module.py +++ b/modules/somafm/module.py @@ -125,4 +125,3 @@ class SomaFMModule(Module, CapRadio, CapCollection): return radio OBJECTS = {Radio: fill_radio} - diff --git a/modules/somafm/test.py b/modules/somafm/test.py index 0b251e85..1c092b29 100644 --- a/modules/somafm/test.py +++ b/modules/somafm/test.py @@ -40,4 +40,3 @@ class SomaFMTest(BackendTest): 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 66b3d01b..1071e764 100644 --- a/modules/sueurdemetal/test.py +++ b/modules/sueurdemetal/test.py @@ -22,6 +22,7 @@ from weboob.tools.test import BackendTest 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 0ab7dea1..e3944e7d 100644 --- a/modules/supertoinette/pages.py +++ b/modules/supertoinette/pages.py @@ -28,6 +28,7 @@ import string 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 @@ class ResultsPage(Page): 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 9d2ef305..0016f8a3 100644 --- a/modules/tvsubtitles/pages.py +++ b/modules/tvsubtitles/pages.py @@ -36,6 +36,7 @@ class HomePage(Page): 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 @@ class SearchPage(Page): 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 @@ class SeriePage(Page): 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 59287145..729e1ff7 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 69b47570..7812357b 100644 --- a/modules/unsee/module.py +++ b/modules/unsee/module.py @@ -74,4 +74,3 @@ class UnseeModule(Module, BasePasteModule): 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 4566df5a..df57d572 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 @@ class SearchPage(Page): 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 @@ class SearchErrorPage(Page): 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 8c59ebde..5e825238 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 2c75bdae..dcd869b2 100644 --- a/modules/wellsfargo/pages.py +++ b/modules/wellsfargo/pages.py @@ -353,4 +353,3 @@ class StatementPage(LoggedPage, RawPage): 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 2f84b65f..596f0b6a 100644 --- a/modules/wellsfargo/parsers.py +++ b/modules/wellsfargo/parsers.py @@ -396,4 +396,3 @@ class StatementToken(object): 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 27d7416d..9ab06aa8 100644 --- a/modules/youtube/pages.py +++ b/modules/youtube/pages.py @@ -864,6 +864,7 @@ class VideoPage(BaseYoutubePage): 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 e67f65a6..10a20a14 100644 --- a/weboob/applications/boobank/boobank.py +++ b/weboob/applications/boobank/boobank.py @@ -105,6 +105,7 @@ class OfxFormatter(IFormatter): 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 bb9cd529..87fe9c90 100644 --- a/weboob/applications/parceloob/parceloob.py +++ b/weboob/applications/parceloob/parceloob.py @@ -58,6 +58,7 @@ class HistoryFormatter(IFormatter): 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 1c0a590f..8e489d31 100644 --- a/weboob/applications/qhavedate/contacts.py +++ b/weboob/applications/qhavedate/contacts.py @@ -101,6 +101,7 @@ class ContactThread(QWidget): 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 @@ class ContactsWidget(QWidget): 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 27923878..ef21accb 100644 --- a/weboob/applications/qhavedate/events.py +++ b/weboob/applications/qhavedate/events.py @@ -66,6 +66,7 @@ class EventsWidget(QWidget): 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 936d36c1..f5ad1ad0 100644 --- a/weboob/applications/traveloob/traveloob.py +++ b/weboob/applications/traveloob/traveloob.py @@ -56,12 +56,14 @@ class DeparturesFormatter(PrettyFormatter): 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 eb09a946..f49f0a92 100644 --- a/weboob/browser/browsers.py +++ b/weboob/browser/browsers.py @@ -527,6 +527,7 @@ class _PagesBrowserMeta(type): 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 ad5a7948..674c03dc 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 @@ class TableElement(ListElement): 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 3610aacc..d8763fbb 100644 --- a/weboob/browser/filters/javascript.py +++ b/weboob/browser/filters/javascript.py @@ -131,4 +131,3 @@ class JSVar(Regexp): 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 0f4ad031..73474d97 100644 --- a/weboob/browser/filters/standard.py +++ b/weboob/browser/filters/standard.py @@ -32,6 +32,7 @@ from weboob.exceptions import ParseError 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 b0db8b16..9cfedcc6 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 @@ class Page(object): 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 23cbcfa9..3110a1bd 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 f24ba267..3736792d 100644 --- a/weboob/browser/sessions.py +++ b/weboob/browser/sessions.py @@ -34,6 +34,7 @@ from requests.sessions import merge_setting 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 6f8ff1a0..81b9a7b9 100644 --- a/weboob/browser/url.py +++ b/weboob/browser/url.py @@ -201,5 +201,3 @@ class URL(object): return func(browser, id_or_url, *args, **kwargs) return inner - - diff --git a/weboob/capabilities/audiostream.py b/weboob/capabilities/audiostream.py index 3a353e1a..08fd2b8e 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 c5481681..6b40dc0c 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 92b04500..0c9d333c 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 e1677885..f405cef3 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 99d78b68..df9639cf 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 c2ee9d33..2527ae2a 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 4158097d..59885acb 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 4971c06f..a7f3e8be 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 ff7a745b..b56a7caf 100644 --- a/weboob/capabilities/date.py +++ b/weboob/capabilities/date.py @@ -24,10 +24,12 @@ from weboob.capabilities.base import Field __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 688e26e4..0117ac7d 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 @@ class CapDating(Capability): :rtype: iter[:class:`Contact`] """ raise NotImplementedError() - diff --git a/weboob/capabilities/geolocip.py b/weboob/capabilities/geolocip.py index 7fa4d392..ac7b9f52 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 ad9c7fbc..6f9368fe 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 cc19dfe1..9c49a0f0 100644 --- a/weboob/capabilities/image.py +++ b/weboob/capabilities/image.py @@ -24,6 +24,7 @@ from .file import CapFile, BaseFile __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 @@ class CapImage(CapFile): :rtype: :class:`BaseImage`] """ return self.get_file(_id) - diff --git a/weboob/capabilities/job.py b/weboob/capabilities/job.py index f9be67d6..c5731d53 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 8741a197..bc057720 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 3b775231..bceb783f 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 6a181d2f..a7081e48 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 054b8ced..a9d4e00c 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 c5bb0f93..358cb5e3 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 27970a4c..b1d2fa06 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 eb0390e5..e55f5fda 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 ff53faf0..d4d80d85 100644 --- a/weboob/capabilities/subtitle.py +++ b/weboob/capabilities/subtitle.py @@ -48,10 +48,12 @@ class Subtitle(BaseObject): 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 4399d549..af5cbd43 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 a72c073b..fdecd5d0 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 e1328324..a6c41859 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 1ad0a7e2..82fa43b7 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 @@ class ModulesLoader(object): 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 bf0de538..317fd511 100644 --- a/weboob/core/ouiboube.py +++ b/weboob/core/ouiboube.py @@ -111,6 +111,7 @@ class WebNip(object): :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 a9c3e42d..d7afe42a 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 @@ class IProgress(object): 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 @@ class Repositories(object): 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 d3a55d79..718ddc74 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 639149cc..4407d5a9 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 b5e13fa2..6b59d07d 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 94b23e2b..5908685a 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 81322d87..73c4a89d 100644 --- a/weboob/tools/application/formatters/table.py +++ b/weboob/tools/application/formatters/table.py @@ -100,6 +100,7 @@ class TableFormatter(IFormatter): 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 f2847bed..6f319ad0 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 29de8796..a73afb6b 100644 --- a/weboob/tools/application/qt/qt.py +++ b/weboob/tools/application/qt/qt.py @@ -178,6 +178,7 @@ class QtApplication(QApplication, Application): 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 75eae470..f78eecf5 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 d73c9d61..502c06e4 100644 --- a/weboob/tools/capabilities/bank/transactions.py +++ b/weboob/tools/capabilities/bank/transactions.py @@ -38,6 +38,7 @@ __all__ = ['FrenchTransaction', 'AmericanTransaction'] class classproperty(object): def __init__(self, f): self.f = f + def __get__(self, obj, owner): return self.f(owner) @@ -225,6 +226,7 @@ class FrenchTransaction(Transaction): @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 @@ class FrenchTransaction(Transaction): 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 @@ class AmericanTransaction(Transaction): 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 fe3c5ddc..90c07329 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 15272e54..9c093892 100644 --- a/weboob/tools/capabilities/streaminfo.py +++ b/weboob/tools/capabilities/streaminfo.py @@ -39,4 +39,3 @@ class StreamInfo(BaseObject): 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 2407926f..ab29571c 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 fdb197f0..bc8fce9b 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 9e7639b8..42252c94 100644 --- a/weboob/tools/regex_helper.py +++ b/weboob/tools/regex_helper.py @@ -50,6 +50,7 @@ ESCAPE_MAPPINGS = { "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 92bfaec2..6fe19e02 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: