pep8 blank lines fixes

flake8 --select W391,E302,E301,E304

autopep8 can't fix W391 even though it claims it can.
Fixed using a simple custom script.
This commit is contained in:
Laurent Bachelier 2014-10-10 23:04:08 +02:00
commit 448c06d125
142 changed files with 249 additions and 25 deletions

View file

@ -28,6 +28,7 @@ from weboob.core import Weboob, CallErrors
from weboob.capabilities.bank import CapBank from weboob.capabilities.bank import CapBank
from weboob.exceptions import BrowserIncorrectPassword from weboob.exceptions import BrowserIncorrectPassword
class BoobankMuninPlugin(object): class BoobankMuninPlugin(object):
def __init__(self): def __init__(self):
if 'weboob_path' in os.environ: if 'weboob_path' in os.environ:

View file

@ -33,6 +33,7 @@ import os
# bpp: bits per pixel, could *only* be 24 or 32! # 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 # return: an "array" of BYTES which, if write to file, is a size*size ico file
def genico(data, size=16, bpp=24): def genico(data, size=16, bpp=24):
from array import array from array import array
a = array('B') a = array('B')
@ -80,7 +81,6 @@ def genico(data, size=16, bpp=24):
return a return a
# x,y indicate the hotspot position # x,y indicate the hotspot position
# simply set the type/hotspot(x&y) after generates the icon # simply set the type/hotspot(x&y) after generates the icon
def gencur(data, size=16, bpp=24, x=0, y=0): 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 return a
#C:\Python27\Lib\site-packages\weboob-0.g-py2.7.egg\share\icons\hicolor\64x64\apps #C:\Python27\Lib\site-packages\weboob-0.g-py2.7.egg\share\icons\hicolor\64x64\apps
if __name__ == "__main__": if __name__ == "__main__":

View file

@ -32,12 +32,15 @@ except ImportError:
DEFAULT_VERSION = "1.1.6" DEFAULT_VERSION = "1.1.6"
DEFAULT_URL = "https://pypi.python.org/packages/source/s/setuptools/" DEFAULT_URL = "https://pypi.python.org/packages/source/s/setuptools/"
def _python_cmd(*args): def _python_cmd(*args):
args = (sys.executable,) + args args = (sys.executable,) + args
return subprocess.call(args) == 0 return subprocess.call(args) == 0
def _check_call_py24(cmd, *args, **kwargs): def _check_call_py24(cmd, *args, **kwargs):
res = subprocess.call(cmd, *args, **kwargs) res = subprocess.call(cmd, *args, **kwargs)
class CalledProcessError(Exception): class CalledProcessError(Exception):
pass pass
if not res == 0: if not res == 0:
@ -45,6 +48,7 @@ def _check_call_py24(cmd, *args, **kwargs):
raise CalledProcessError(msg) raise CalledProcessError(msg)
vars(subprocess).setdefault('check_call', _check_call_py24) vars(subprocess).setdefault('check_call', _check_call_py24)
def _install(tarball, install_args=()): def _install(tarball, install_args=()):
# extracting the tarball # extracting the tarball
tmpdir = tempfile.mkdtemp() 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, return _do_download(version, download_base, to_dir,
download_delay) download_delay)
def download_file_powershell(url, target): def download_file_powershell(url, target):
""" """
Download the file at url to target using Powershell (which will validate 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) subprocess.check_call(cmd)
def has_powershell(): def has_powershell():
if platform.system() != 'Windows': if platform.system() != 'Windows':
return False return False
@ -180,10 +186,12 @@ def has_powershell():
download_file_powershell.viable = has_powershell download_file_powershell.viable = has_powershell
def download_file_curl(url, target): def download_file_curl(url, target):
cmd = ['curl', url, '--silent', '--output', target] cmd = ['curl', url, '--silent', '--output', target]
subprocess.check_call(cmd) subprocess.check_call(cmd)
def has_curl(): def has_curl():
cmd = ['curl', '--version'] cmd = ['curl', '--version']
devnull = open(os.path.devnull, 'wb') devnull = open(os.path.devnull, 'wb')
@ -198,10 +206,12 @@ def has_curl():
download_file_curl.viable = has_curl download_file_curl.viable = has_curl
def download_file_wget(url, target): def download_file_wget(url, target):
cmd = ['wget', url, '--quiet', '--output-document', target] cmd = ['wget', url, '--quiet', '--output-document', target]
subprocess.check_call(cmd) subprocess.check_call(cmd)
def has_wget(): def has_wget():
cmd = ['wget', '--version'] cmd = ['wget', '--version']
devnull = open(os.path.devnull, 'wb') devnull = open(os.path.devnull, 'wb')
@ -216,6 +226,7 @@ def has_wget():
download_file_wget.viable = has_wget download_file_wget.viable = has_wget
def download_file_insecure(url, target): def download_file_insecure(url, target):
""" """
Use Python to download the file, even though it cannot authenticate the 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 download_file_insecure.viable = lambda: True
def get_best_downloader(): def get_best_downloader():
downloaders = [ downloaders = [
download_file_powershell, download_file_powershell,
@ -253,6 +265,7 @@ def get_best_downloader():
if dl.viable(): if dl.viable():
return dl return dl
def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
to_dir=os.curdir, delay=15, to_dir=os.curdir, delay=15,
downloader_factory=get_best_downloader): downloader_factory=get_best_downloader):
@ -338,6 +351,7 @@ def _build_install_args(options):
install_args.append('--user') install_args.append('--user')
return install_args return install_args
def _parse_args(): def _parse_args():
""" """
Parse the command line for options Parse the command line for options
@ -359,6 +373,7 @@ def _parse_args():
# positional arguments are ignored # positional arguments are ignored
return options return options
def main(version=DEFAULT_VERSION): def main(version=DEFAULT_VERSION):
"""Install or upgrade setuptools and EasyInstall""" """Install or upgrade setuptools and EasyInstall"""
options = _parse_args() options = _parse_args()

View file

@ -24,6 +24,7 @@ from .browser import SevenFiftyGramsBrowser
import unicodedata import unicodedata
def strip_accents(s): def strip_accents(s):
return ''.join(c for c in unicodedata.normalize('NFD', s) if unicodedata.category(c) != 'Mn') return ''.join(c for c in unicodedata.normalize('NFD', s) if unicodedata.category(c) != 'Mn')

View file

@ -26,6 +26,7 @@ from weboob.deprecated.browser import Page
class ResultsPage(Page): class ResultsPage(Page):
""" Page which contains results as a list of recipies """ Page which contains results as a list of recipies
""" """
def iter_recipes(self): def iter_recipes(self):
for div in self.parser.select(self.document.getroot(), 'div.recette_description > div.data'): 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') links = self.parser.select(div, 'div.info > p.title > a.fn')
@ -65,6 +66,7 @@ class ResultsPage(Page):
class RecipePage(Page): class RecipePage(Page):
""" Page which contains a recipe """ Page which contains a recipe
""" """
def get_recipe(self, id): def get_recipe(self, id):
title = NotAvailable title = NotAvailable
preparation_time = NotAvailable preparation_time = NotAvailable

View file

@ -20,6 +20,7 @@
from weboob.tools.test import BackendTest from weboob.tools.test import BackendTest
import re import re
class AllocineTest(BackendTest): class AllocineTest(BackendTest):
MODULE = 'allocine' MODULE = 'allocine'

View file

@ -60,4 +60,3 @@ class AlloRestoModule(Module, CapBank):
def iter_coming(self, account): def iter_coming(self, account):
return self.browser.get_coming(account) return self.browser.get_coming(account)

View file

@ -52,6 +52,7 @@ class AccountsPage(LoggedPage, HTMLPage):
class MyDate(Filter): 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'] 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): def filter(self, txt):
day, month, year = txt.split(' ') day, month, year = txt.split(' ')
day = int(day) day = int(day)

View file

@ -30,6 +30,7 @@ class FourOFourPage(Page):
class ResultsPage(Page): class ResultsPage(Page):
""" Page which contains results as a list of recipies """ Page which contains results as a list of recipies
""" """
def iter_recipes(self): def iter_recipes(self):
for div in self.parser.select(self.document.getroot(), 'div.recipe-info'): for div in self.parser.select(self.document.getroot(), 'div.recipe-info'):
thumbnail_url = NotAvailable thumbnail_url = NotAvailable
@ -59,6 +60,7 @@ class ResultsPage(Page):
class RecipePage(Page): class RecipePage(Page):
""" Page which contains a recipe """ Page which contains a recipe
""" """
def get_recipe(self, id): def get_recipe(self, id):
title = NotAvailable title = NotAvailable
preparation_time = NotAvailable preparation_time = NotAvailable

View file

@ -29,6 +29,7 @@ from weboob.capabilities.bill import Subscription, Detail, Bill
# Ugly array to avoid the use of french locale # 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'] 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): class AmeliBasePage(Page):
def is_logged(self): def is_logged(self):
try: try:
@ -40,6 +41,7 @@ class AmeliBasePage(Page):
self.logger.debug('logged: %s' % (logged)) self.logger.debug('logged: %s' % (logged))
return logged return logged
class LoginPage(AmeliBasePage): class LoginPage(AmeliBasePage):
def login(self, login, password): def login(self, login, password):
self.browser.select_form('connexionCompteForm') self.browser.select_form('connexionCompteForm')
@ -47,9 +49,11 @@ class LoginPage(AmeliBasePage):
self.browser["connexioncompte_2codeConfidentiel"] = password.encode('utf8') self.browser["connexioncompte_2codeConfidentiel"] = password.encode('utf8')
self.browser.submit() self.browser.submit()
class HomePage(AmeliBasePage): class HomePage(AmeliBasePage):
pass pass
class AccountPage(AmeliBasePage): class AccountPage(AmeliBasePage):
def iter_subscription_list(self): def iter_subscription_list(self):
idents = self.document.xpath('//div[contains(@class, "blocfond")]') idents = self.document.xpath('//div[contains(@class, "blocfond")]')

View file

@ -63,4 +63,3 @@ class AmericanExpressModule(Module, CapBank):
transactions = list(self.browser.get_history(account)) transactions = list(self.browser.get_history(account))
transactions.sort(key=lambda tr: tr.rdate, reverse=True) transactions.sort(key=lambda tr: tr.rdate, reverse=True)
return transactions return transactions

View file

@ -56,6 +56,7 @@ class AccountsPage(Page):
yield a yield a
class TransactionsPage(Page): class TransactionsPage(Page):
COL_ID = 0 COL_ID = 0
COL_DATE = 1 COL_DATE = 1
@ -81,6 +82,7 @@ class TransactionsPage(Page):
return datetime.date(int(m.group(3)), return datetime.date(int(m.group(3)),
self.MONTHS.index(m.group(2).rstrip('.')) + 1, self.MONTHS.index(m.group(2).rstrip('.')) + 1,
int(m.group(1))) int(m.group(1)))
def get_beginning_debit_date(self): def get_beginning_debit_date(self):
for option in self.document.xpath('//select[@id="viewPeriod"]/option'): for option in self.document.xpath('//select[@id="viewPeriod"]/option'):
if 'selected' in option.attrib: if 'selected' in option.attrib:

View file

@ -39,4 +39,3 @@ class AudioAddictTest(BackendTest):
self.assertTrue(radio.current.what) self.assertTrue(radio.current.what)
self.assertTrue(radio.streams[0].url) self.assertTrue(radio.streams[0].url)
self.assertTrue(radio.streams[0].title) self.assertTrue(radio.streams[0].title)

View file

@ -127,6 +127,7 @@ class WebsiteBrowser(LoginBrowser):
return profile return profile
class AuMBrowser(Browser): class AuMBrowser(Browser):
DOMAIN = 'www.adopteunmec.com' DOMAIN = 'www.adopteunmec.com'
APIKEY = 'fb0123456789abcd' APIKEY = 'fb0123456789abcd'

View file

@ -256,6 +256,7 @@ class TransactionsPage(BasePage):
yield t yield t
class CBTransactionsPage(TransactionsPage): class CBTransactionsPage(TransactionsPage):
COL_CB_CREDIT = 2 COL_CB_CREDIT = 2

View file

@ -87,6 +87,7 @@ class VirtKeyboard(MappedVirtKeyboard):
code += self.get_symbol_code(self.symbols[c]) code += self.get_symbol_code(self.symbols[c])
return code return code
class LoginPage(HTMLPage): class LoginPage(HTMLPage):
def login(self, login, password): def login(self, login, password):
vk = VirtKeyboard(self) vk = VirtKeyboard(self)
@ -98,6 +99,7 @@ class LoginPage(HTMLPage):
form['code'] = code form['code'] = code
form.submit() form.submit()
class IndexPage(LoggedPage, HTMLPage): class IndexPage(LoggedPage, HTMLPage):
@method @method
class get_list(ListElement): class get_list(ListElement):
@ -152,6 +154,7 @@ class IndexPage(LoggedPage, HTMLPage):
def get_card_name(self): def get_card_name(self):
return CleanText('//h1[1]')(self.doc) return CleanText('//h1[1]')(self.doc)
class AccountsPage(LoggedPage, HTMLPage): class AccountsPage(LoggedPage, HTMLPage):
def get_balance(self): def get_balance(self):
balance = Decimal('0.0') balance = Decimal('0.0')

View file

@ -82,6 +82,7 @@ class BanquePopulaire(Browser):
self.token = self.page.get_token() self.token = self.page.get_token()
ACCOUNT_URLS = ['mesComptes', 'mesComptesPRO', 'maSyntheseGratuite', 'accueilSynthese'] ACCOUNT_URLS = ['mesComptes', 'mesComptesPRO', 'maSyntheseGratuite', 'accueilSynthese']
def go_on_accounts_list(self): def go_on_accounts_list(self):
for taskInfoOID in self.ACCOUNT_URLS: for taskInfoOID in self.ACCOUNT_URLS:
self.location(self.buildurl('/cyber/internet/StartTask.do', taskInfoOID=taskInfoOID, token=self.token)) self.location(self.buildurl('/cyber/internet/StartTask.do', taskInfoOID=taskInfoOID, token=self.token))

View file

@ -267,5 +267,6 @@ class HistoryPage(BEPage):
# Last page # Last page
return None return None
class UnknownPage(BEPage): class UnknownPage(BEPage):
pass pass

View file

@ -26,6 +26,7 @@ from .login import LoginPage, UpdateInfoPage
from .two_authentication import AuthenticationPage from .two_authentication import AuthenticationPage
class AccountPrelevement(AccountsList): class AccountPrelevement(AccountsList):
pass pass

View file

@ -37,6 +37,7 @@ class UnavailablePage(Page):
def on_loaded(self): def on_loaded(self):
raise BrowserUnavailable() raise BrowserUnavailable()
class Keyboard(VirtKeyboard): class Keyboard(VirtKeyboard):
symbols={'0':'daa52d75287bea58f505823ef6c8b96c', symbols={'0':'daa52d75287bea58f505823ef6c8b96c',
'1':'f5da96c2592803a8cdc5a928a2e4a3b0', '1':'f5da96c2592803a8cdc5a928a2e4a3b0',
@ -86,6 +87,7 @@ class Keyboard(VirtKeyboard):
x1, y1, x2, y2 = coords x1, y1, x2, y2 = coords
return VirtKeyboard.get_symbol_coords(self, (x1+3, y1+3, x2-3, y2-3)) return VirtKeyboard.get_symbol_coords(self, (x1+3, y1+3, x2-3, y2-3))
class LoginPage(Page): class LoginPage(Page):
def login(self, login, pwd): def login(self, login, pwd):
vk = Keyboard(self) vk = Keyboard(self)

View file

@ -8,6 +8,7 @@ from .browser import BTDiggBrowser
__all__ = ['BTDiggModule'] __all__ = ['BTDiggModule']
class BTDiggModule(Module, CapTorrent): class BTDiggModule(Module, CapTorrent):
NAME = 'btdigg' NAME = 'btdigg'
MAINTAINER = u'Matthieu Rakotojaona' MAINTAINER = u'Matthieu Rakotojaona'

View file

@ -50,6 +50,7 @@ class TorrentsPage(Page):
torrent.date = date torrent.date = date
yield torrent yield torrent
class TorrentPage(Page): class TorrentPage(Page):
def get_torrent(self, id): def get_torrent(self, id):
trs = self.document.getroot().cssselect('table.torrent_info_tbl tr') trs = self.document.getroot().cssselect('table.torrent_info_tbl tr')

View file

@ -39,6 +39,7 @@ class _LogoutPage(Page):
except BrokenPageError: except BrokenPageError:
pass pass
class LoginPage(_LogoutPage): class LoginPage(_LogoutPage):
def login(self, login): def login(self, login):
self.browser.select_form(name='Main') self.browser.select_form(name='Main')
@ -83,6 +84,7 @@ class LoginPage(_LogoutPage):
class ErrorPage(_LogoutPage): class ErrorPage(_LogoutPage):
pass pass
class UnavailablePage(Page): class UnavailablePage(Page):
def on_loaded(self): def on_loaded(self):
try: try:

View file

@ -32,6 +32,7 @@ class IndexPage(Page):
self.browser['chronoNumbers'] = _id.encode('utf-8') self.browser['chronoNumbers'] = _id.encode('utf-8')
self.browser.submit() self.browser.submit()
class TrackPage(Page): class TrackPage(Page):
def get_info(self, id): def get_info(self, id):
if len(self.document.xpath('//libelle[@nom="MSG_AUCUN_EVT"]')) > 0: if len(self.document.xpath('//libelle[@nom="MSG_AUCUN_EVT"]')) > 0:

View file

@ -47,10 +47,12 @@ class ChangePasswordPage(Page):
def on_loaded(self): def on_loaded(self):
raise BrowserIncorrectPassword('Please change your password') raise BrowserIncorrectPassword('Please change your password')
class VerifCodePage(Page): class VerifCodePage(Page):
def on_loaded(self): def on_loaded(self):
raise BrowserIncorrectPassword('Unable to login: website asks a code from a card') raise BrowserIncorrectPassword('Unable to login: website asks a code from a card')
class InfoPage(Page): class InfoPage(Page):
pass pass
@ -303,6 +305,7 @@ class CardPage(OperationsPage):
tr.set_amount(tds[-1].text) tr.set_amount(tds[-1].text)
yield tr yield tr
class NoOperationsPage(OperationsPage): class NoOperationsPage(OperationsPage):
def get_history(self): def get_history(self):
return iter([]) return iter([])

View file

@ -26,6 +26,7 @@ def update_status(p, status):
if p.status < status: if p.status < status:
p.status = status p.status = status
class TrackPage(Page): class TrackPage(Page):
def get_info(self, _id): def get_info(self, _id):
p = Parcel(_id) p = Parcel(_id)
@ -70,5 +71,6 @@ class TrackPage(Page):
pass pass
return p return p
class ErrorPage(Page): class ErrorPage(Page):
pass pass

View file

@ -20,6 +20,7 @@
class TokenExtractor(object): class TokenExtractor(object):
""" Extracts texts token from an HTML document """ """ Extracts texts token from an HTML document """
def __init__(self): def __init__(self):
self.iterated_elements = [] self.iterated_elements = []

View file

@ -39,6 +39,7 @@ class HomePage(Page):
return None return None
class LoginPage(Page): class LoginPage(Page):
def login(self, password): def login(self, password):
assert password.isdigit() assert password.isdigit()
@ -60,12 +61,15 @@ class LoginPage(Page):
def get_result_url(self): def get_result_url(self):
return self.parser.tocleanstring(self.document.getroot()) return self.parser.tocleanstring(self.document.getroot())
class UselessPage(Page): class UselessPage(Page):
pass pass
class LoginErrorPage(Page): class LoginErrorPage(Page):
pass pass
class _AccountsPage(Page): class _AccountsPage(Page):
COL_LABEL = 0 COL_LABEL = 0
COL_ID = 2 COL_ID = 2
@ -223,12 +227,15 @@ class CardsPage(Page):
yield t yield t
class AccountsPage(_AccountsPage): class AccountsPage(_AccountsPage):
pass pass
class SavingsPage(_AccountsPage): class SavingsPage(_AccountsPage):
COL_ID = 1 COL_ID = 1
class TransactionsPage(Page): class TransactionsPage(Page):
def get_next_url(self): def get_next_url(self):
links = self.document.xpath('//span[@class="pager"]/a[@class="liennavigationcorpspage"]') links = self.document.xpath('//span[@class="pager"]/a[@class="liennavigationcorpspage"]')

View file

@ -95,6 +95,7 @@ class Transaction(FrenchTransaction):
FrenchTransaction.TYPE_UNKNOWN), FrenchTransaction.TYPE_UNKNOWN),
] ]
class ITransactionsPage(Page): class ITransactionsPage(Page):
def get_next_url(self): def get_next_url(self):
# can be 'Suivant' or ' Suivant' # can be 'Suivant' or ' Suivant'
@ -108,6 +109,7 @@ class ITransactionsPage(Page):
def get_history(self): def get_history(self):
raise NotImplementedError() raise NotImplementedError()
class TransactionsPage(ITransactionsPage): class TransactionsPage(ITransactionsPage):
TR_DATE = 0 TR_DATE = 0
TR_TEXT = 2 TR_TEXT = 2
@ -135,6 +137,7 @@ class TransactionsPage(ITransactionsPage):
yield t yield t
class ComingTransactionsPage(TransactionsPage): class ComingTransactionsPage(TransactionsPage):
TR_DATE = 2 TR_DATE = 2
TR_TEXT = 1 TR_TEXT = 1
@ -142,6 +145,7 @@ class ComingTransactionsPage(TransactionsPage):
TR_CREDIT = -1 TR_CREDIT = -1
TABLE_NAME = 'operationAVenir' TABLE_NAME = 'operationAVenir'
class CardTransactionsPage(ITransactionsPage): class CardTransactionsPage(ITransactionsPage):
COM_TR_COMMENT = 0 COM_TR_COMMENT = 0
COM_TR_DATE = 1 COM_TR_DATE = 1

View file

@ -53,13 +53,16 @@ class LoginErrorPage(HTMLPage):
class EmptyPage(LoggedPage, HTMLPage): class EmptyPage(LoggedPage, HTMLPage):
pass pass
class UserSpacePage(LoggedPage, HTMLPage): class UserSpacePage(LoggedPage, HTMLPage):
pass pass
class ChangePasswordPage(LoggedPage, HTMLPage): class ChangePasswordPage(LoggedPage, HTMLPage):
def on_load(self): def on_load(self):
raise BrowserIncorrectPassword('Please change your password') raise BrowserIncorrectPassword('Please change your password')
class VerifCodePage(LoggedPage, HTMLPage): class VerifCodePage(LoggedPage, HTMLPage):
def on_load(self): def on_load(self):
raise BrowserIncorrectPassword('Unable to login: website asks a code from a card') raise BrowserIncorrectPassword('Unable to login: website asks a code from a card')

View file

@ -26,6 +26,7 @@ import unicodedata
__all__ = ['CuisineazModule'] __all__ = ['CuisineazModule']
def strip_accents(s): def strip_accents(s):
return ''.join(c for c in unicodedata.normalize('NFD', s) if unicodedata.category(c) != 'Mn') return ''.join(c for c in unicodedata.normalize('NFD', s) if unicodedata.category(c) != 'Mn')

View file

@ -26,6 +26,7 @@ from weboob.deprecated.browser import Page
class ResultsPage(Page): class ResultsPage(Page):
""" Page which contains results as a list of recipies """ Page which contains results as a list of recipies
""" """
def iter_recipes(self): def iter_recipes(self):
for div in self.parser.select(self.document.getroot(), 'div.rechRecette'): for div in self.parser.select(self.document.getroot(), 'div.rechRecette'):
thumbnail_url = NotAvailable thumbnail_url = NotAvailable
@ -74,6 +75,7 @@ class ResultsPage(Page):
class RecipePage(Page): class RecipePage(Page):
""" Page which contains a recipe """ Page which contains a recipe
""" """
def get_recipe(self, id): def get_recipe(self, id):
title = NotAvailable title = NotAvailable
preparation_time = NotAvailable preparation_time = NotAvailable

View file

@ -154,6 +154,7 @@ class VideoPage(Page):
video.url = unicode(info[max_quality]) video.url = unicode(info[max_quality])
class KidsVideoPage(VideoPage): class KidsVideoPage(VideoPage):
CONTROLLER_PAGE = 'http://kids.dailymotion.com/controller/Page_Kids_KidsUserHome?%s' CONTROLLER_PAGE = 'http://kids.dailymotion.com/controller/Page_Kids_KidsUserHome?%s'

View file

@ -94,6 +94,7 @@ class OperationsPage(Page):
if next_button: if next_button:
return next_button[0] return next_button[0]
class LCRPage(OperationsPage): class LCRPage(OperationsPage):
def iter_history(self): def iter_history(self):
date = None date = None

View file

@ -27,6 +27,7 @@ from weboob.capabilities.bill import Subscription, Detail, Bill
base_url = "http://particuliers.edf.com/" base_url = "http://particuliers.edf.com/"
class EdfBasePage(Page): class EdfBasePage(Page):
def is_logged(self): def is_logged(self):
return (u'Me déconnecter' in self.document.xpath('//a/text()')) \ return (u'Me déconnecter' in self.document.xpath('//a/text()')) \
@ -45,16 +46,19 @@ class HomePage(EdfBasePage):
def on_loaded(self): def on_loaded(self):
pass pass
class FirstRedirectionPage(EdfBasePage): class FirstRedirectionPage(EdfBasePage):
def on_loaded(self): def on_loaded(self):
self.browser.select_form("form1") self.browser.select_form("form1")
self.browser.submit() self.browser.submit()
class SecondRedirectionPage(EdfBasePage): class SecondRedirectionPage(EdfBasePage):
def on_loaded(self): def on_loaded(self):
self.browser.select_form("redirectForm") self.browser.select_form("redirectForm")
self.browser.submit() self.browser.submit()
class OtherPage(EdfBasePage): class OtherPage(EdfBasePage):
def on_loaded(self): def on_loaded(self):
self.browser.open(base_url) self.browser.open(base_url)
@ -122,6 +126,7 @@ class BillsPage(EdfBasePage):
def get_bill(self, bill): def get_bill(self, bill):
self.location(bill._url) self.location(bill._url)
class LastPaymentsPage(EdfBasePage): class LastPaymentsPage(EdfBasePage):
def on_loaded(self): 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)) self.browser.location('/ASPFront/appmanager/ASPFront/front/portlet_echeancier_2?%s' % urllib.urlencode(params))
class LastPaymentsPage2(EdfBasePage): class LastPaymentsPage2(EdfBasePage):
def iter_payments(self, sub): def iter_payments(self, sub):

View file

@ -79,6 +79,8 @@ class IndexPage(Page):
# the search page class uses a JSON parser, # the search page class uses a JSON parser,
# since it's what search.php returns when POSTed (from Ajax) # since it's what search.php returns when POSTed (from Ajax)
class SearchPage(Page): class SearchPage(Page):
def iter_videos(self): def iter_videos(self):
if self.document is None or self.document['data'] is None: if self.document is None or self.document['data'] is None:
@ -90,6 +92,7 @@ class SearchPage(Page):
continue continue
yield video yield video
class VideoPage(Page): class VideoPage(Page):
def get_video(self, video=None): def get_video(self, video=None):
# check for slides id variant # check for slides id variant

View file

@ -199,6 +199,7 @@ class GithubBrowser(Browser):
# TODO use a cache for objects and/or pages? # TODO use a cache for objects and/or pages?
# TODO use an api-key? # TODO use an api-key?
def parse_date(s): def parse_date(s):
if s.endswith('Z'): if s.endswith('Z'):
s = s[:-1] s = s[:-1]

View file

@ -32,6 +32,7 @@ STATUSES = {'open': Status('open', u'Open', Status.VALUE_NEW),
'closed': Status('closed', u'closed', Status.VALUE_RESOLVED)} 'closed': Status('closed', u'closed', Status.VALUE_RESOLVED)}
# TODO tentatively parse github "labels"? # TODO tentatively parse github "labels"?
class GithubModule(Module, CapBugTracker): class GithubModule(Module, CapBugTracker):
NAME = 'github' NAME = 'github'
DESCRIPTION = u'GitHub issues tracking' DESCRIPTION = u'GitHub issues tracking'

View file

@ -89,5 +89,6 @@ class AccountHistory(Page):
def get_IBAN(self): def get_IBAN(self):
return self.document.xpath('//a[@class="lien_perso_libelle"]')[0].attrib['id'][10:26] return self.document.xpath('//a[@class="lien_perso_libelle"]')[0].attrib['id'][10:26]
class AccountComing(AccountHistory): class AccountComing(AccountHistory):
pass pass

View file

@ -43,6 +43,7 @@ class Transaction(FrenchTransaction):
(re.compile(r'^REMISE (?P<text>.*)'), FrenchTransaction.TYPE_DEPOSIT), (re.compile(r'^REMISE (?P<text>.*)'), FrenchTransaction.TYPE_DEPOSIT),
] ]
class AccountsPage(LoggedPage, HTMLPage): class AccountsPage(LoggedPage, HTMLPage):
def get_frame(self): def get_frame(self):
try: try:
@ -129,6 +130,7 @@ class CBOperationPage(LoggedPage, HTMLPage):
obj_date = DateGuesser(CleanText(TableCell("date")), Env("date_guesser")) obj_date = DateGuesser(CleanText(TableCell("date")), Env("date_guesser"))
obj_vdate = DateGuesser(CleanText(TableCell("date")), Env("date_guesser")) obj_vdate = DateGuesser(CleanText(TableCell("date")), Env("date_guesser"))
class CPTOperationPage(LoggedPage, HTMLPage): class CPTOperationPage(LoggedPage, HTMLPage):
def get_history(self): def get_history(self):
for script in self.doc.xpath('//script'): 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) op._coming = (re.match(r'\d+/\d+/\d+', m.group(2)) is None)
yield op yield op
class LoginPage(HTMLPage): class LoginPage(HTMLPage):
def on_load(self): def on_load(self):
for message in self.doc.getroot().cssselect('div.csPanelErrors'): for message in self.doc.getroot().cssselect('div.csPanelErrors'):

View file

@ -29,6 +29,7 @@ import re
class ReleasePage(Page): class ReleasePage(Page):
''' Page containing releases of a movie ''' Page containing releases of a movie
''' '''
def get_movie_releases(self, country_filter): def get_movie_releases(self, country_filter):
result = unicode() result = unicode()
links = self.parser.select(self.document.getroot(), 'table#release_dates a') links = self.parser.select(self.document.getroot(), 'table#release_dates a')
@ -57,6 +58,7 @@ class ReleasePage(Page):
class BiographyPage(Page): class BiographyPage(Page):
''' Page containing biography of a person ''' Page containing biography of a person
''' '''
def get_biography(self): def get_biography(self):
bio = unicode() bio = unicode()
start = False start = False
@ -74,6 +76,7 @@ class BiographyPage(Page):
class MovieCrewPage(Page): class MovieCrewPage(Page):
''' Page listing all the persons related to a movie ''' Page listing all the persons related to a movie
''' '''
def iter_persons(self, role_filter=None): def iter_persons(self, role_filter=None):
if (role_filter is None or (role_filter is not None and role_filter == 'actor')): 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') tables = self.parser.select(self.document.getroot(), 'table.cast_list')
@ -130,6 +133,7 @@ class PersonPage(Page):
''' Page informing about a person ''' Page informing about a person
It is used to build a Person instance and to get the movie list related to 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): def get_person(self, id):
name = NotAvailable name = NotAvailable
short_biography = NotAvailable short_biography = NotAvailable

View file

@ -26,6 +26,7 @@ from weboob.tools.capabilities.messages.genericArticle import GenericNewsPage, t
class ArticlePage(GenericNewsPage): class ArticlePage(GenericNewsPage):
"ArticlePage object for inrocks" "ArticlePage object for inrocks"
def on_loaded(self): def on_loaded(self):
self.main_div = self.document.getroot() self.main_div = self.document.getroot()
self.element_title_selector = "h1" self.element_title_selector = "h1"

View file

@ -23,6 +23,7 @@ from weboob.tools.capabilities.messages.genericArticle import GenericNewsPage
class InrocksTvPage(GenericNewsPage): class InrocksTvPage(GenericNewsPage):
"ArticlePage object for inrocks" "ArticlePage object for inrocks"
def on_loaded(self): def on_loaded(self):
self.main_div = self.document.getroot() self.main_div = self.document.getroot()
self.element_title_selector = "h2" self.element_title_selector = "h2"

View file

@ -13,6 +13,7 @@ class RoadmapAmbiguity(RoadmapError):
def __init__(self, error): def __init__(self, error):
RoadmapError.__init__(self, error) RoadmapError.__init__(self, error)
class RoadmapSearchPage(Page): class RoadmapSearchPage(Page):
def search(self, departure, arrival, departure_time, arrival_time): def search(self, departure, arrival, departure_time, arrival_time):
match = -1 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)) raise RoadmapError('Unable to establish a roadmap with %s time at "%s"' % ('departure' if departure_time else 'arrival', time))
self.browser.submit() self.browser.submit()
class RoadmapResultsPage(Page): class RoadmapResultsPage(Page):
def html_br_strip(self, text): def html_br_strip(self, text):
return "".join([l.strip() for l in text.split("\n")]).strip().replace(' ', '%20') 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[propname] = [ propvalue ]
self.browser.submit() self.browser.submit()
class RoadmapPage(Page): class RoadmapPage(Page):
def get_steps(self): def get_steps(self):
errors = [] errors = []

View file

@ -122,6 +122,7 @@ class LCLBrowser(Browser):
for tr in self.page.get_operations(): for tr in self.page.get_operations():
yield tr yield tr
class LCLProBrowser(LCLBrowser): class LCLProBrowser(LCLBrowser):
PROTOCOL = 'https' PROTOCOL = 'https'
DOMAIN = 'professionnels.secure.lcl.fr' DOMAIN = 'professionnels.secure.lcl.fr'
@ -165,4 +166,3 @@ class LCLProBrowser(LCLBrowser):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
Browser.__init__(self, *args, **kwargs) Browser.__init__(self, *args, **kwargs)
self.add_cookie("lclgen","professionnels") self.add_cookie("lclgen","professionnels")

View file

@ -132,6 +132,7 @@ class LoginPage(Page):
errors = self.document.xpath(u'//div[@class="erreur" or @class="messError"]') errors = self.document.xpath(u'//div[@class="erreur" or @class="messError"]')
return len(errors) > 0 return len(errors) > 0
class ContractsPage(Page): class ContractsPage(Page):
def on_loaded(self): def on_loaded(self):
self.select_contract() self.select_contract()

View file

@ -23,6 +23,7 @@ from weboob.tools.capabilities.messages.genericArticle import GenericNewsPage, d
class ArticlePage(GenericNewsPage): class ArticlePage(GenericNewsPage):
"ArticlePage object for lefigaro" "ArticlePage object for lefigaro"
def on_loaded(self): def on_loaded(self):
self.main_div = self.document.getroot() self.main_div = self.document.getroot()
self.element_title_selector = "h1" self.element_title_selector = "h1"

View file

@ -23,6 +23,7 @@ from weboob.tools.capabilities.messages.genericArticle import GenericNewsPage
class FlashActuPage(GenericNewsPage): class FlashActuPage(GenericNewsPage):
"ArticlePage object for lefigaro" "ArticlePage object for lefigaro"
def on_loaded(self): def on_loaded(self):
self.main_div = self.document.getroot() self.main_div = self.document.getroot()
self.element_title_selector = "h1" self.element_title_selector = "h1"

View file

@ -18,6 +18,7 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with weboob. If not, see <http://www.gnu.org/licenses/>. # along with weboob. If not, see <http://www.gnu.org/licenses/>.
def url2id(url): def url2id(url):
"return an id from an url" "return an id from an url"
return url return url

View file

@ -65,8 +65,10 @@ class MailinatorBrowser(Browser):
divs = doc.cssselect('.mailview') divs = doc.cssselect('.mailview')
return divs[0].text_content().strip() return divs[0].text_content().strip()
def millis(): def millis():
return int(time.time() * 1000) return int(time.time() * 1000)
def frommillis(millis): def frommillis(millis):
return datetime.fromtimestamp(millis / 1000) return datetime.fromtimestamp(millis / 1000)

View file

@ -32,4 +32,3 @@ class MailinatorTest(BackendTest):
assert t.root.date assert t.root.date
assert t.root.sender assert t.root.sender
assert t.root.receivers assert t.root.receivers

View file

@ -26,6 +26,7 @@ from weboob.deprecated.browser import Page
class ResultsPage(Page): class ResultsPage(Page):
""" Page which contains results as a list of recipies """ Page which contains results as a list of recipies
""" """
def iter_recipes(self): def iter_recipes(self):
for div in self.parser.select(self.document.getroot(), 'div.m_search_result'): for div in self.parser.select(self.document.getroot(), 'div.m_search_result'):
tds = self.parser.select(div, 'td') tds = self.parser.select(div, 'td')
@ -57,6 +58,7 @@ class ResultsPage(Page):
class RecipePage(Page): class RecipePage(Page):
""" Page which contains a recipe """ Page which contains a recipe
""" """
def get_recipe(self, id): def get_recipe(self, id):
title = NotAvailable title = NotAvailable
preparation_time = NotAvailable preparation_time = NotAvailable

View file

@ -24,6 +24,7 @@ from .simple import SimplePage
class ArticlePage(SimplePage): class ArticlePage(SimplePage):
"ArticlePage object for minutes20" "ArticlePage object for minutes20"
def on_loaded(self): def on_loaded(self):
self.main_div = self.document.getroot() self.main_div = self.document.getroot()
self.element_title_selector = "h1" self.element_title_selector = "h1"

View file

@ -23,6 +23,7 @@ from weboob.tools.capabilities.messages.genericArticle import GenericNewsPage
class SimplePage(GenericNewsPage): class SimplePage(GenericNewsPage):
"ArticlePage object for minutes20" "ArticlePage object for minutes20"
def on_loaded(self): def on_loaded(self):
self.main_div = self.document.getroot() self.main_div = self.document.getroot()
self.element_title_selector = "h1" self.element_title_selector = "h1"

View file

@ -22,6 +22,7 @@ from .pages import LivePage, StreamsPage
__all__ = ['NectarineBrowser'] __all__ = ['NectarineBrowser']
class NectarineBrowser(Browser): class NectarineBrowser(Browser):
DOMAIN = 'www.scenemusic.net' DOMAIN = 'www.scenemusic.net'
PROTOCOL = 'https' PROTOCOL = 'https'

View file

@ -23,6 +23,7 @@ from .browser import NectarineBrowser
__all__ = ['NectarineModule'] __all__ = ['NectarineModule']
class NectarineModule(Module, CapRadio, CapCollection): class NectarineModule(Module, CapRadio, CapCollection):
NAME = 'nectarine' NAME = 'nectarine'
MAINTAINER = u'Thomas Lecavelier' MAINTAINER = u'Thomas Lecavelier'

View file

@ -22,6 +22,7 @@ from .pages import LivePage, ProgramPage
__all__ = ['NihonNoOtoBrowser'] __all__ = ['NihonNoOtoBrowser']
class NihonNoOtoBrowser(Browser): class NihonNoOtoBrowser(Browser):
DOMAIN = 'www.nihon-no-oto.com' DOMAIN = 'www.nihon-no-oto.com'
PROTOCOL = 'http' PROTOCOL = 'http'

View file

@ -23,6 +23,7 @@ from .browser import NihonNoOtoBrowser
__all__ = ['NihonNoOtoModule'] __all__ = ['NihonNoOtoModule']
class NihonNoOtoModule(Module, CapRadio, CapCollection): class NihonNoOtoModule(Module, CapRadio, CapCollection):
NAME = 'nihonnooto' NAME = 'nihonnooto'
MAINTAINER = u'Thomas Lecavelier' MAINTAINER = u'Thomas Lecavelier'

View file

@ -28,6 +28,7 @@ from .pages import VideoPage, VideoListPage, FamilyPage, AboPage, LoginPage, Hom
__all__ = ['NolifeTVBrowser'] __all__ = ['NolifeTVBrowser']
class NolifeTVBrowser(Browser): class NolifeTVBrowser(Browser):
USER_AGENT = Browser.USER_AGENTS['desktop_firefox'] USER_AGENT = Browser.USER_AGENTS['desktop_firefox']
DOMAIN = 'mobile.nolife-tv.com' DOMAIN = 'mobile.nolife-tv.com'

View file

@ -32,6 +32,7 @@ from hashlib import md5
__all__ = ['NolifeTVModule'] __all__ = ['NolifeTVModule']
class NolifeTVModule(Module, CapVideo, CapCollection): class NolifeTVModule(Module, CapVideo, CapCollection):
NAME = 'nolifetv' NAME = 'nolifetv'
MAINTAINER = u'Romain Bignon' MAINTAINER = u'Romain Bignon'

View file

@ -67,6 +67,7 @@ class VideoPage(Page):
seconds=int(m.group(3))) seconds=int(m.group(3)))
return video return video
class VideoListPage(Page): class VideoListPage(Page):
def is_list_empty(self): def is_list_empty(self):
return self.document.getroot() is None return self.document.getroot() is None
@ -85,6 +86,7 @@ class VideoListPage(Page):
video.title = video.title + ' - ' + strongs[3].text video.title = video.title + ' - ' + strongs[3].text
yield video yield video
class FamilyPage(Page): class FamilyPage(Page):
def iter_category(self): def iter_category(self):
subs = list() subs = list()
@ -109,6 +111,7 @@ class FamilyPage(Page):
if m and m.group(1): if m and m.group(1):
yield Collection([m.group(1)], unicode(h1.text)) yield Collection([m.group(1)], unicode(h1.text))
class AboPage(Page): class AboPage(Page):
def get_available_videos(self): def get_available_videos(self):
available = ['[Gratuit]'] available = ['[Gratuit]']
@ -130,6 +133,7 @@ class LoginPage(Page):
self.browser['password'] = str(password) self.browser['password'] = str(password)
self.browser.submit() self.browser.submit()
class HomePage(Page): class HomePage(Page):
def is_logged(self): def is_logged(self):
return len(self.document.xpath('//a[@href="deconnexion/"]')) == 1 return len(self.document.xpath('//a[@href="deconnexion/"]')) == 1

View file

@ -21,6 +21,7 @@
from weboob.tools.test import BackendTest from weboob.tools.test import BackendTest
from weboob.capabilities.video import BaseVideo from weboob.capabilities.video import BaseVideo
class NolifeTVTest(BackendTest): class NolifeTVTest(BackendTest):
MODULE = 'nolifetv' MODULE = 'nolifetv'

View file

@ -266,5 +266,3 @@ class OkCBrowser(Browser):
self.addheaders = [('Referer', self.page.url), ('Content-Type', 'application/x-www-form-urlencoded;charset=UTF-8')] 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) self.open('http://m.okcupid.com%s' %abs_url, data=data)
return True return True

View file

@ -26,6 +26,7 @@ from weboob.capabilities.contact import ProfileNode
from weboob.tools.html import html2text from weboob.tools.html import html2text
from weboob.tools.date import local2utc from weboob.tools.date import local2utc
class LoginPage(Page): class LoginPage(Page):
def login(self, username, password): def login(self, username, password):
self.browser.select_form(name='loginf') self.browser.select_form(name='loginf')
@ -191,6 +192,7 @@ class PostMessagePage(Page):
self.browser['body'] = content.encode('utf-8') self.browser['body'] = content.encode('utf-8')
self.browser.submit() self.browser.submit()
class VisitsPage(Page): class VisitsPage(Page):
def get_visits(self): def get_visits(self):
ul_item = self.parser.select(self.document.getroot(), '//*[@id="page_content"]/ul[3]', method='xpath')[0] 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 return visitors
class QuickMatchPage(Page): class QuickMatchPage(Page):
def get_id(self): def get_id(self):
element = self.parser.select(self.document.getroot(), '//*[@id="sn"]', method='xpath')[0] element = self.parser.select(self.document.getroot(), '//*[@id="sn"]', method='xpath')[0]

View file

@ -97,6 +97,7 @@ class VirtKeyboard(MappedVirtKeyboard):
code += self.get_symbol_code(self.symbols[c]) code += self.get_symbol_code(self.symbols[c])
return code return code
class LoginPage(HTMLPage): class LoginPage(HTMLPage):
is_here ="//form[@id='formulaire-login']" is_here ="//form[@id='formulaire-login']"
@ -115,12 +116,14 @@ class LoginPage(HTMLPage):
form['personneIdentifiee'] = 'N' form['personneIdentifiee'] = 'N'
form.submit() form.submit()
class IndexPage(LoggedPage, HTMLPage): class IndexPage(LoggedPage, HTMLPage):
is_here = "//div[@id='situation']" is_here = "//div[@id='situation']"
def get_balance(self): 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]) 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): class OperationsPage(LoggedPage, HTMLPage):
is_here = "//div[@id='releve-reserve-credit'] | //div[@id='operations-recentes'] | //select[@id='periode']" is_here = "//div[@id='releve-reserve-credit'] | //div[@id='operations-recentes'] | //select[@id='periode']"

View file

@ -28,6 +28,7 @@ from weboob.applications.suboob.suboob import LANGUAGE_CONV
class SearchPage(Page): class SearchPage(Page):
""" Page which contains results as a list of movies """ Page which contains results as a list of movies
""" """
def iter_subtitles(self): def iter_subtitles(self):
tabresults = self.parser.select(self.document.getroot(), 'table#search_results') tabresults = self.parser.select(self.document.getroot(), 'table#search_results')
if len(tabresults) > 0: if len(tabresults) > 0:
@ -49,6 +50,7 @@ class SearchPage(Page):
class SubtitlesPage(Page): class SubtitlesPage(Page):
""" Page which contains several subtitles for a single movie """ Page which contains several subtitles for a single movie
""" """
def iter_subtitles(self): def iter_subtitles(self):
tabresults = self.parser.select(self.document.getroot(), 'table#search_results') tabresults = self.parser.select(self.document.getroot(), 'table#search_results')
if len(tabresults) > 0: if len(tabresults) > 0:
@ -102,6 +104,7 @@ class SubtitlesPage(Page):
class SubtitlePage(Page): class SubtitlePage(Page):
""" Page which contains a single subtitle for a movie """ Page which contains a single subtitle for a movie
""" """
def get_subtitle(self): def get_subtitle(self):
desc = NotAvailable desc = NotAvailable
a = self.parser.select(self.document.getroot(), 'a#bt-dwl', 1) a = self.parser.select(self.document.getroot(), 'a#bt-dwl', 1)

View file

@ -29,12 +29,15 @@ def date_from_id(_id):
textdate = _id.split('_')[0] textdate = _id.split('_')[0]
return datetime.strptime(textdate, '%m-%d-%Y') return datetime.strptime(textdate, '%m-%d-%Y')
def id_from_path(title): def id_from_path(title):
return title.replace(' ', '_').split('/')[-1] return title.replace(' ', '_').split('/')[-1]
def combine(dt, t): def combine(dt, t):
return datetime(dt.year, dt.month, dt.day, t.hour, t.minute) return datetime(dt.year, dt.month, dt.day, t.hour, t.minute)
class PageList(Page): class PageList(Page):
def get_events(self): def get_events(self):
raise NotImplementedError() raise NotImplementedError()

View file

@ -34,6 +34,7 @@ from weboob.tools.capabilities.bank.transactions import AmericanTransaction
class CSVAlreadyAsked(Exception): class CSVAlreadyAsked(Exception):
pass pass
def clean_amount(text): def clean_amount(text):
amnt = AmericanTransaction.clean_amount(text) amnt = AmericanTransaction.clean_amount(text)
return Decimal(amnt) if amnt else Decimal("0") return Decimal(amnt) if amnt else Decimal("0")
@ -135,6 +136,7 @@ class DownloadHistoryPage(Page):
self.browser.submit() self.browser.submit()
class LastDownloadHistoryPage(Page): class LastDownloadHistoryPage(Page):
def download(self): def download(self):
self.browser.select_form(nr=1) self.browser.select_form(nr=1)
@ -142,10 +144,12 @@ class LastDownloadHistoryPage(Page):
self.browser['log_select'] = [log_select] self.browser['log_select'] = [log_select]
self.browser.submit() self.browser.submit()
class SubmitPage(Page): class SubmitPage(Page):
""" """
Any result of form submission Any result of form submission
""" """
def iter_transactions(self, account): def iter_transactions(self, account):
csv = self.document csv = self.document

View file

@ -74,6 +74,7 @@ LANGUAGE_NUMBERS = {
class SearchPage(Page): class SearchPage(Page):
""" Page which contains results as a list of movies """ Page which contains results as a list of movies
""" """
def iter_subtitles(self, language): def iter_subtitles(self, language):
linksresults = self.parser.select(self.document.getroot(), 'a.subtitle_page_link') linksresults = self.parser.select(self.document.getroot(), 'a.subtitle_page_link')
for link in linksresults: for link in linksresults:
@ -93,6 +94,7 @@ class SearchPage(Page):
class SubtitlePage(Page): class SubtitlePage(Page):
""" Page which contains a single subtitle for a movie """ Page which contains a single subtitle for a movie
""" """
def get_subtitle(self, id): def get_subtitle(self, id):
language = NotAvailable language = NotAvailable
url = NotAvailable url = NotAvailable

View file

@ -55,6 +55,7 @@ class PresseuropPage(GenericNewsPage):
except: except:
return author return author
class DailyTitlesPage(PresseuropPage): class DailyTitlesPage(PresseuropPage):
def on_loaded(self): def on_loaded(self):
self.main_div = self.document.getroot() self.main_div = self.document.getroot()

View file

@ -74,6 +74,7 @@ class QuviModule(Module, CapVideo):
video.thumbnail.url = video.thumbnail.id video.thumbnail.url = video.thumbnail.id
return video return video
class QuviVideo(BaseVideo): class QuviVideo(BaseVideo):
BACKENDS = { BACKENDS = {
'youtube': 'https://www.youtube.com/watch?v=%s', 'youtube': 'https://www.youtube.com/watch?v=%s',

View file

@ -45,4 +45,3 @@ class QuviTest(BackendTest):
assert len(v.url) assert len(v.url)
assert len(v.title) assert len(v.title)
assert v.page_url.startswith('http://www.youtube.com/watch?v=BaW_jenozKc') assert v.page_url.startswith('http://www.youtube.com/watch?v=BaW_jenozKc')

View file

@ -157,6 +157,7 @@ class IssuesPage(BaseIssuePage):
return project return project
args = json.loads(args) args = json.loads(args)
def get_values(key): def get_values(key):
values = [] values = []
if not key in args: if not key in args:

View file

@ -19,6 +19,7 @@
from weboob.tools.test import BackendTest from weboob.tools.test import BackendTest
class SFRTest(BackendTest): class SFRTest(BackendTest):
MODULE = 'sfr' MODULE = 'sfr'

View file

@ -125,4 +125,3 @@ class SomaFMModule(Module, CapRadio, CapCollection):
return radio return radio
OBJECTS = {Radio: fill_radio} OBJECTS = {Radio: fill_radio}

View file

@ -40,4 +40,3 @@ class SomaFMTest(BackendTest):
self.assertTrue(radio.current.what) self.assertTrue(radio.current.what)
self.assertTrue(radio.streams[0].url) self.assertTrue(radio.streams[0].url)
self.assertTrue(radio.streams[0].title) self.assertTrue(radio.streams[0].title)

View file

@ -22,6 +22,7 @@ from weboob.tools.test import BackendTest
from weboob.capabilities.calendar import Query, CATEGORIES from weboob.capabilities.calendar import Query, CATEGORIES
from datetime import datetime, timedelta from datetime import datetime, timedelta
class SueurDeMetalTest(BackendTest): class SueurDeMetalTest(BackendTest):
MODULE = 'sueurdemetal' MODULE = 'sueurdemetal'

View file

@ -28,6 +28,7 @@ import string
class ResultsPage(Page): class ResultsPage(Page):
""" Page which contains results as a list of recipies """ Page which contains results as a list of recipies
""" """
def iter_recipes(self): def iter_recipes(self):
for div in self.parser.select(self.document.getroot(), 'div.result-recipe'): for div in self.parser.select(self.document.getroot(), 'div.result-recipe'):
thumbnail_url = NotAvailable thumbnail_url = NotAvailable
@ -60,6 +61,7 @@ class ResultsPage(Page):
class RecipePage(Page): class RecipePage(Page):
""" Page which contains a recipe """ Page which contains a recipe
""" """
def get_recipe(self, id): def get_recipe(self, id):
title = NotAvailable title = NotAvailable
preparation_time = NotAvailable preparation_time = NotAvailable

View file

@ -36,6 +36,7 @@ class HomePage(Page):
class SearchPage(Page): class SearchPage(Page):
""" Page which contains results as a list of series """ Page which contains results as a list of series
""" """
def iter_subtitles(self, language): def iter_subtitles(self, language):
list_result = self.parser.select(self.document.getroot(), 'div.left_articles ul') list_result = self.parser.select(self.document.getroot(), 'div.left_articles ul')
if len(list_result) > 0: if len(list_result) > 0:
@ -53,6 +54,7 @@ class SearchPage(Page):
class SeriePage(Page): class SeriePage(Page):
""" Page of all seasons """ Page of all seasons
""" """
def iter_subtitles(self, language, only_one_season=False): def iter_subtitles(self, language, only_one_season=False):
# handle the current season # handle the current season
last_table_line = self.parser.select(self.document.getroot(), 'table#table5 tr')[-1] last_table_line = self.parser.select(self.document.getroot(), 'table#table5 tr')[-1]
@ -80,6 +82,7 @@ class SeriePage(Page):
class SeasonPage(Page): class SeasonPage(Page):
""" Page of a season with the right language """ Page of a season with the right language
""" """
def get_subtitle(self): def get_subtitle(self):
filename_line = self.parser.select(self.document.getroot(), 'img[alt=filename]', 1).getparent().getparent() filename_line = self.parser.select(self.document.getroot(), 'img[alt=filename]', 1).getparent().getparent()
name = unicode(self.parser.select(filename_line, 'td')[2].text) name = unicode(self.parser.select(filename_line, 'td')[2].text)

View file

@ -36,6 +36,7 @@ def to_bytes(s):
else: else:
return s return s
class FileField(object): class FileField(object):
def __init__(self, filename, contents=None, headers=None): def __init__(self, filename, contents=None, headers=None):
self.filename = to_bytes(os.path.basename(filename)) self.filename = to_bytes(os.path.basename(filename))

View file

@ -74,4 +74,3 @@ class UnseeModule(Module, BasePasteModule):
d = self.browser.post_image(paste.title, paste.contents.decode('base64'), max_code) d = self.browser.post_image(paste.title, paste.contents.decode('base64'), max_code)
paste.id = d['id'] paste.id = d['id']
return paste return paste

View file

@ -32,11 +32,13 @@ class ForeignPage(Page):
def on_loaded(self): 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']) 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): class CitiesPage(Page):
def get_stations(self): def get_stations(self):
result = json.loads(self.document[self.document.find('{'):-2]) result = json.loads(self.document[self.document.find('{'):-2])
return result['CITIES'] return result['CITIES']
class SearchPage(Page): class SearchPage(Page):
def search(self, departure, arrival, date, age, card, comfort_class): def search(self, departure, arrival, date, age, card, comfort_class):
self.browser.select_form(name='saisie') self.browser.select_form(name='saisie')
@ -57,6 +59,7 @@ class SearchPage(Page):
self.browser['nbAnimalsForTravel'] = '0' self.browser['nbAnimalsForTravel'] = '0'
self.browser.submit() self.browser.submit()
class SearchErrorPage(Page): class SearchErrorPage(Page):
def on_loaded(self): def on_loaded(self):
p = self.document.getroot().cssselect('div.messagesError p') p = self.document.getroot().cssselect('div.messagesError p')
@ -64,11 +67,13 @@ class SearchErrorPage(Page):
message = p[0].text.strip() message = p[0].text.strip()
raise UserError(message) raise UserError(message)
class SearchInProgressPage(Page): class SearchInProgressPage(Page):
def on_loaded(self): def on_loaded(self):
link = self.document.xpath('//a[@id="url_redirect_proposals"]')[0] link = self.document.xpath('//a[@id="url_redirect_proposals"]')[0]
self.browser.location(link.attrib['href']) self.browser.location(link.attrib['href'])
class ResultsPage(Page): class ResultsPage(Page):
def get_value(self, div, name, last=False): def get_value(self, div, name, last=False):
i = -1 if last else 0 i = -1 if last else 0

View file

@ -21,4 +21,3 @@
from .module import WellsFargoModule from .module import WellsFargoModule
__all__ = ['WellsFargoModule'] __all__ = ['WellsFargoModule']

View file

@ -353,4 +353,3 @@ class StatementPage(LoggedPage, RawPage):
cmp=lambda t1, t2: cmp(t2.date, t1.date) or cmp=lambda t1, t2: cmp(t2.date, t1.date) or
cmp(t1.label, t2.label) or cmp(t1.label, t2.label) or
cmp(t1.amount, t2.amount)) cmp(t1.amount, t2.amount))

View file

@ -396,4 +396,3 @@ class StatementToken(object):
for type_, _ in StatementToken.LEX: for type_, _ in StatementToken.LEX:
setattr(StatementToken, 'is_%s' % type_, setattr(StatementToken, 'is_%s' % type_,
eval('lambda self: self._type == "%s"' % type_)) eval('lambda self: self._type == "%s"' % type_))

View file

@ -864,6 +864,7 @@ class VideoPage(BaseYoutubePage):
def _extract_from_m3u8(self, manifest_url, video_id): def _extract_from_m3u8(self, manifest_url, video_id):
url_map = {} url_map = {}
def _get_urls(_manifest): def _get_urls(_manifest):
lines = _manifest.split('\n') lines = _manifest.split('\n')
urls = filter(lambda l: l and not l.startswith('#'), lines) urls = filter(lambda l: l and not l.startswith('#'), lines)

View file

@ -105,6 +105,7 @@ class OfxFormatter(IFormatter):
self.output(u'<DTASOF>%s</AVAILBAL>' % datetime.date.today().strftime('%Y%m%d')) self.output(u'<DTASOF>%s</AVAILBAL>' % datetime.date.today().strftime('%Y%m%d'))
self.output(u'</STMTRS></STMTTRNRS></BANKMSGSRSV1></OFX>') self.output(u'</STMTRS></STMTTRNRS></BANKMSGSRSV1></OFX>')
class QifFormatter(IFormatter): class QifFormatter(IFormatter):
MANDATORY_FIELDS = ('id', 'date', 'raw', 'amount') MANDATORY_FIELDS = ('id', 'date', 'raw', 'amount')

View file

@ -58,6 +58,7 @@ class HistoryFormatter(IFormatter):
self.colored('%-17s' % (obj.location or ''), 'magenta'), self.colored('%-17s' % (obj.location or ''), 'magenta'),
self.colored(obj.activity or '', 'yellow')) self.colored(obj.activity or '', 'yellow'))
class StatusFormatter(IFormatter): class StatusFormatter(IFormatter):
MANDATORY_FIELDS = ('id',) MANDATORY_FIELDS = ('id',)

View file

@ -101,6 +101,7 @@ class ContactThread(QWidget):
return return
self.ui.refreshButton.setEnabled(False) self.ui.refreshButton.setEnabled(False)
def finished(): def finished():
#v = self.ui.scrollArea.verticalScrollBar() #v = self.ui.scrollArea.verticalScrollBar()
#print v.minimum(), v.value(), v.maximum(), v.sliderPosition() #print v.minimum(), v.value(), v.maximum(), v.sliderPosition()
@ -572,6 +573,7 @@ class ContactsWidget(QWidget):
def retrieveContact(self, url): def retrieveContact(self, url):
backend_name = unicode(self.ui.backendsList.currentText()) backend_name = unicode(self.ui.backendsList.currentText())
self.ui.urlButton.setEnabled(False) self.ui.urlButton.setEnabled(False)
def finished(): def finished():
self.url_process = None self.url_process = None
self.ui.urlButton.setEnabled(True) self.ui.urlButton.setEnabled(True)

View file

@ -66,6 +66,7 @@ class EventsWidget(QWidget):
self.ui.typeBox.setEnabled(False) self.ui.typeBox.setEnabled(False)
self.ui.typeBox.clear() self.ui.typeBox.clear()
self.ui.typeBox.addItem('All', None) self.ui.typeBox.addItem('All', None)
def finished(): def finished():
self.ui.refreshButton.setEnabled(True) self.ui.refreshButton.setEnabled(True)
self.ui.typeBox.setEnabled(True) self.ui.typeBox.setEnabled(True)

View file

@ -56,12 +56,14 @@ class DeparturesFormatter(PrettyFormatter):
return s return s
class StationsFormatter(PrettyFormatter): class StationsFormatter(PrettyFormatter):
MANDATORY_FIELDS = ('id', 'name') MANDATORY_FIELDS = ('id', 'name')
def get_title(self, obj): def get_title(self, obj):
return obj.name return obj.name
class Traveloob(ReplApplication): class Traveloob(ReplApplication):
APPNAME = 'traveloob' APPNAME = 'traveloob'
VERSION = '1.0' VERSION = '1.0'

View file

@ -527,6 +527,7 @@ class _PagesBrowserMeta(type):
new_class._urls.update(urls) new_class._urls.update(urls)
return new_class return new_class
class PagesBrowser(DomainBrowser): class PagesBrowser(DomainBrowser):
r""" r"""
A browser which works pages and keep state of navigation. A browser which works pages and keep state of navigation.
@ -680,6 +681,7 @@ class LoginBrowser(PagesBrowser):
""" """
A browser which supports login. A browser which supports login.
""" """
def __init__(self, username, password, *args, **kwargs): def __init__(self, username, password, *args, **kwargs):
super(LoginBrowser, self).__init__(*args, **kwargs) super(LoginBrowser, self).__init__(*args, **kwargs)
self.username = username self.username = username

View file

@ -42,6 +42,7 @@ def method(klass):
""" """
Class-decorator to call it as a method. Class-decorator to call it as a method.
""" """
def inner(self, *args, **kwargs): def inner(self, *args, **kwargs):
return klass(self)(*args, **kwargs) return klass(self)(*args, **kwargs)
return inner return inner
@ -300,5 +301,3 @@ class TableElement(ListElement):
def get_colnum(self, name): def get_colnum(self, name):
return self._cols.get(name, None) return self._cols.get(name, None)

View file

@ -131,4 +131,3 @@ class JSVar(Regexp):
return super(JSVar, self).filter(txt) return super(JSVar, self).filter(txt)
except RegexpError: except RegexpError:
raise ParseError('Variable %r not found' % self.var) raise ParseError('Variable %r not found' % self.var)

View file

@ -32,6 +32,7 @@ from weboob.exceptions import ParseError
from weboob.browser.url import URL from weboob.browser.url import URL
from weboob.tools.log import getLogger, DEBUG_FILTERS from weboob.tools.log import getLogger, DEBUG_FILTERS
class NoDefault(object): class NoDefault(object):
def __repr__(self): def __repr__(self):
return 'NO_DEFAULT' return 'NO_DEFAULT'
@ -217,6 +218,7 @@ class Base(Filter):
>>> Base(Env('header'), CleanText('./h1')) # doctest: +SKIP >>> Base(Env('header'), CleanText('./h1')) # doctest: +SKIP
""" """
def __call__(self, item): def __call__(self, item):
base = self.select(self.base, item, obj=self._obj, key=self._key) base = self.select(self.base, item, obj=self._obj, key=self._key)
return self.selector(base) return self.selector(base)
@ -425,6 +427,7 @@ class Type(Filter):
>>> Type(type=str, minlen=0, default='a').filter('') >>> Type(type=str, minlen=0, default='a').filter('')
'a' 'a'
""" """
def __init__(self, selector=None, type=None, minlen=0, default=_NO_DEFAULT): def __init__(self, selector=None, type=None, minlen=0, default=_NO_DEFAULT):
super(Type, self).__init__(selector, default=default) super(Type, self).__init__(selector, default=default)
self.type_func = type self.type_func = type

View file

@ -82,6 +82,7 @@ class NextPage(Exception):
See :meth:`PagesBrowser.pagination` or decorator :func:`pagination`. See :meth:`PagesBrowser.pagination` or decorator :func:`pagination`.
""" """
def __init__(self, request): def __init__(self, request):
super(NextPage, self).__init__() super(NextPage, self).__init__()
self.request = request self.request = request
@ -122,17 +123,20 @@ class Page(object):
Event called when browser leaves this page. Event called when browser leaves this page.
""" """
class FormNotFound(Exception): class FormNotFound(Exception):
""" """
Raised when :meth:`HTMLPage.get_form` can't find a form. Raised when :meth:`HTMLPage.get_form` can't find a form.
""" """
class FormSubmitWarning(UserWarning): class FormSubmitWarning(UserWarning):
""" """
A form has more than one submit element selected, and will likely A form has more than one submit element selected, and will likely
generate an invalid request. generate an invalid request.
""" """
class Form(OrderedDict): class Form(OrderedDict):
""" """
Represents a form of an HTML page. Represents a form of an HTML page.

View file

@ -82,6 +82,7 @@ class Wget(Profile):
Some websites will give you a version with less JavaScript. Some websites will give you a version with less JavaScript.
Some others could ban you (after all, wget is not a real browser). Some others could ban you (after all, wget is not a real browser).
""" """
def __init__(self, version='1.11.4'): def __init__(self, version='1.11.4'):
self.version = version self.version = version

View file

@ -34,6 +34,7 @@ from requests.sessions import merge_setting
from requests.structures import CaseInsensitiveDict from requests.structures import CaseInsensitiveDict
from requests.utils import get_netrc_auth from requests.utils import get_netrc_auth
def merge_hooks(request_hooks, session_hooks, dict_class=OrderedDict): def merge_hooks(request_hooks, session_hooks, dict_class=OrderedDict):
""" """
Properly merges both requests and session hooks. Properly merges both requests and session hooks.

View file

@ -201,5 +201,3 @@ class URL(object):
return func(browser, id_or_url, *args, **kwargs) return func(browser, id_or_url, *args, **kwargs)
return inner return inner

View file

@ -44,6 +44,7 @@ class CapAudioStream(CapAudio):
""" """
Audio streams provider Audio streams provider
""" """
def search_audiostreams(self, pattern, sortby=CapFile.SEARCH_RELEVANCE): def search_audiostreams(self, pattern, sortby=CapFile.SEARCH_RELEVANCE):
""" """
Search an audio stream Search an audio stream

Some files were not shown because too many files have changed in this diff Show more