PEP8 style fixes and other small style fixes

I used autopep8 on some files and did carefully check the changes.
I ignored E501,E302,E231,E225,E222,E221,E241,E203 in my search, and at
least E501 on any autopep8 run.

Other style fixes not related to PEP8:
* Only use new-style classes. I don't think the usage of old-style
  classes was voluntary. Old-style classes are removed in Python 3.
* Convert an if/else to a one-liner in mediawiki, change docstring style
  change to a comment something that wasn't really appropriate for a
  docstring.
* Unneeded first if condition in meteofrance
This commit is contained in:
Laurent Bachelier 2012-03-14 03:24:02 +01:00
commit 006e97a8be
99 changed files with 441 additions and 350 deletions

View file

@ -24,7 +24,7 @@ import Image
class CaptchaError(Exception): pass class CaptchaError(Exception): pass
class Tile: class Tile(object):
hash = { hash = {
'bc8d52d96058478a6def26226145d53b': 'A', 'bc8d52d96058478a6def26226145d53b': 'A',
'c62ecdfddb72b2feaed96cd9fe7c2802': 'A', 'c62ecdfddb72b2feaed96cd9fe7c2802': 'A',
@ -111,7 +111,7 @@ class Tile:
print 'hash: %s' % checksum print 'hash: %s' % checksum
raise CaptchaError() raise CaptchaError()
class Captcha: class Captcha(object):
def __init__(self, f): def __init__(self, f):
self.img = Image.open(f) self.img = Image.open(f)
self.w, self.h = self.img.size self.w, self.h = self.img.size
@ -152,7 +152,7 @@ class Captcha:
s += tile.letter s += tile.letter
return s return s
class Decoder: class Decoder(object):
def __init__(self): def __init__(self):
self.hash = {} self.hash = {}

View file

@ -26,7 +26,8 @@ from weboob.tools.ordereddict import OrderedDict
from weboob.capabilities.contact import Contact as _Contact, ProfileNode from weboob.capabilities.contact import Contact as _Contact, ProfileNode
from weboob.tools.misc import html2text from weboob.tools.misc import html2text
class FieldBase:
class FieldBase(object):
def __init__(self, key, key2=None): def __init__(self, key, key2=None):
self.key = key self.key = key
self.key2 = key2 self.key2 = key2
@ -34,18 +35,22 @@ class FieldBase:
def get_value(self, value, consts): def get_value(self, value, consts):
raise NotImplementedError() raise NotImplementedError()
class FieldStr(FieldBase): class FieldStr(FieldBase):
def get_value(self, profile, consts): def get_value(self, profile, consts):
return html2text(unicode(profile[self.key])).strip() return html2text(unicode(profile[self.key])).strip()
class FieldBool(FieldBase): class FieldBool(FieldBase):
def get_value(self, profile, consts): def get_value(self, profile, consts):
return bool(int(profile[self.key])) return bool(int(profile[self.key]))
class FieldDist(FieldBase): class FieldDist(FieldBase):
def get_value(self, profile, consts): def get_value(self, profile, consts):
return '%.2f km' % float(profile[self.key]) return '%.2f km' % float(profile[self.key])
class FieldIP(FieldBase): class FieldIP(FieldBase):
def get_hostname(self, s): def get_hostname(self, s):
try: try:
@ -59,6 +64,7 @@ class FieldIP(FieldBase):
s += ' (first %s)' % self.get_hostname(profile[self.key2]) s += ' (first %s)' % self.get_hostname(profile[self.key2])
return s return s
class FieldProfileURL(FieldBase): class FieldProfileURL(FieldBase):
def get_value(self, profile, consts): def get_value(self, profile, consts):
id = int(profile[self.key]) id = int(profile[self.key])
@ -67,10 +73,12 @@ class FieldProfileURL(FieldBase):
else: else:
return '' return ''
class FieldPopu(FieldBase): class FieldPopu(FieldBase):
def get_value(self, profile, consts): def get_value(self, profile, consts):
return unicode(profile['popu'][self.key]) return unicode(profile['popu'][self.key])
class FieldPopuRatio(FieldBase): class FieldPopuRatio(FieldBase):
def get_value(self, profile, consts): def get_value(self, profile, consts):
v1 = float(profile['popu'][self.key]) v1 = float(profile['popu'][self.key])
@ -80,15 +88,18 @@ class FieldPopuRatio(FieldBase):
else: else:
return '%.2f' % (v1 / v2) return '%.2f' % (v1 / v2)
class FieldOld(FieldBase): class FieldOld(FieldBase):
def get_value(self, profile, consts): def get_value(self, profile, consts):
birthday = parse_dt(profile[self.key]) birthday = parse_dt(profile[self.key])
return int((datetime.now() - birthday).days / 365.25) return int((datetime.now() - birthday).days / 365.25)
class FieldSplit(FieldBase): class FieldSplit(FieldBase):
def get_value(self, profile, consts): def get_value(self, profile, consts):
return [html2text(s).strip() for s in profile[self.key].split(self.key2) if len(s.strip()) > 0] return [html2text(s).strip() for s in profile[self.key].split(self.key2) if len(s.strip()) > 0]
class FieldBMI(FieldBase): class FieldBMI(FieldBase):
def __init__(self, key, key2, fat=False): def __init__(self, key, key2, fat=False):
FieldBase.__init__(self, key, key2) FieldBase.__init__(self, key, key2)
@ -114,6 +125,7 @@ class FieldBMI(FieldBase):
else: else:
return 'obese' return 'obese'
class FieldFlags(FieldBase): class FieldFlags(FieldBase):
def get_value(self, profile, consts): def get_value(self, profile, consts):
i = int(profile[self.key]) i = int(profile[self.key])
@ -123,6 +135,7 @@ class FieldFlags(FieldBase):
labels.append(html2text(d['label']).strip()) labels.append(html2text(d['label']).strip())
return labels return labels
class FieldList(FieldBase): class FieldList(FieldBase):
def get_value(self, profile, consts): def get_value(self, profile, consts):
i = int(profile[self.key]) i = int(profile[self.key])
@ -131,6 +144,7 @@ class FieldList(FieldBase):
return html2text(d['label']).strip() return html2text(d['label']).strip()
return '' return ''
class Contact(_Contact): class Contact(_Contact):
TABLE = OrderedDict(( TABLE = OrderedDict((
('_info', OrderedDict(( ('_info', OrderedDict((

View file

@ -22,7 +22,6 @@ from weboob.tools.test import BackendTest
from weboob.tools.browser import BrowserUnavailable from weboob.tools.browser import BrowserUnavailable
__all__ = ['AuMTest'] __all__ = ['AuMTest']

View file

@ -21,6 +21,7 @@ from weboob.tools.capabilities.gallery.genericcomicreader import GenericComicRea
__all__ = ['BatotoBackend'] __all__ = ['BatotoBackend']
class BatotoBackend(GenericComicReaderBackend): class BatotoBackend(GenericComicReaderBackend):
NAME = 'batoto' NAME = 'batoto'
DESCRIPTION = 'Batoto manga reading website' DESCRIPTION = 'Batoto manga reading website'

View file

@ -19,8 +19,9 @@
from weboob.tools.capabilities.gallery.genericcomicreader import GenericComicReaderTest from weboob.tools.capabilities.gallery.genericcomicreader import GenericComicReaderTest
class BatotoTest(GenericComicReaderTest): class BatotoTest(GenericComicReaderTest):
BACKEND = 'batoto' BACKEND = 'batoto'
def test_download(self): def test_download(self):
return self._test_download('26287/yurumates_ch4_by_primitive-scans') return self._test_download('26287/yurumates_ch4_by_primitive-scans')

View file

@ -70,4 +70,3 @@ class BoursoramaBackend(BaseBackend, ICapBank):
with self.browser: with self.browser:
for coming in self.browser.get_coming_operations(account): for coming in self.browser.get_coming_operations(account):
yield coming yield coming

View file

@ -23,7 +23,8 @@ from .account_history import AccountHistory
from .accounts_list import AccountsList from .accounts_list import AccountsList
from .login import LoginPage from .login import LoginPage
class AccountPrelevement(AccountsList): pass class AccountPrelevement(AccountsList):
pass
__all__ = ['LoginPage', __all__ = ['LoginPage',
'AccountsList', 'AccountsList',

View file

@ -22,8 +22,8 @@
from weboob.capabilities.bank import Account from weboob.capabilities.bank import Account
from weboob.tools.browser import BasePage from weboob.tools.browser import BasePage
class AccountsList(BasePage):
class AccountsList(BasePage):
def on_loaded(self): def on_loaded(self):
pass pass

View file

@ -26,6 +26,7 @@ __all__ = ['CanalplusVideo']
class CanalplusVideo(BaseVideo): class CanalplusVideo(BaseVideo):
swf_player = False swf_player = False
@classmethod @classmethod
def id2url(cls, _id): def id2url(cls, _id):
return 'http://service.canal-plus.com/video/rest/getVideosLiees/cplus/%s' % _id return 'http://service.canal-plus.com/video/rest/getVideosLiees/cplus/%s' % _id

View file

@ -33,8 +33,10 @@ from lxml import etree
from datetime import date from datetime import date
from StringIO import StringIO from StringIO import StringIO
__all__ = ['CmbBackend'] __all__ = ['CmbBackend']
class CmbBackend(BaseBackend, ICapBank): class CmbBackend(BaseBackend, ICapBank):
NAME = 'cmb' NAME = 'cmb'
MAINTAINER = 'Johann Broudin' MAINTAINER = 'Johann Broudin'
@ -83,7 +85,6 @@ class CmbBackend(BaseBackend, ICapBank):
) )
] ]
cookie = None cookie = None
headers = { headers = {
'User-Agent': 'User-Agent':
@ -268,4 +269,3 @@ class CmbBackend(BaseBackend, ICapBank):
i += 1 i += 1
yield operation yield operation

View file

@ -24,6 +24,7 @@ from weboob.capabilities.bank import Account
from .base import CragrBasePage from .base import CragrBasePage
from weboob.capabilities.bank import Transaction from weboob.capabilities.bank import Transaction
def clean_amount(amount): def clean_amount(amount):
""" """
Removes weird characters and converts to a float Removes weird characters and converts to a float
@ -34,6 +35,7 @@ def clean_amount(amount):
matches = re.findall('^(-?[0-9]+\.[0-9]{2}).*$', data) matches = re.findall('^(-?[0-9]+\.[0-9]{2}).*$', data)
return float(matches[0]) if (matches) else 0.0 return float(matches[0]) if (matches) else 0.0
class AccountsList(CragrBasePage): class AccountsList(CragrBasePage):
def get_list(self): def get_list(self):

View file

@ -26,6 +26,7 @@ from .pages import LoginPage, LoginErrorPage, AccountsPage, UserSpacePage, Opera
__all__ = ['CreditMutuelBrowser'] __all__ = ['CreditMutuelBrowser']
# Browser # Browser
class CreditMutuelBrowser(BaseBrowser): class CreditMutuelBrowser(BaseBrowser):
PROTOCOL = 'https' PROTOCOL = 'https'

View file

@ -21,6 +21,7 @@ from weboob.tools.capabilities.gallery.genericcomicreader import GenericComicRea
__all__ = ['EatmangaBackend'] __all__ = ['EatmangaBackend']
class EatmangaBackend(GenericComicReaderBackend): class EatmangaBackend(GenericComicReaderBackend):
NAME = 'eatmanga' NAME = 'eatmanga'
DESCRIPTION = 'EatManga manga reading website' DESCRIPTION = 'EatManga manga reading website'

View file

@ -19,8 +19,9 @@
from weboob.tools.capabilities.gallery.genericcomicreader import GenericComicReaderTest from weboob.tools.capabilities.gallery.genericcomicreader import GenericComicReaderTest
class EatmangaTest(GenericComicReaderTest): class EatmangaTest(GenericComicReaderTest):
BACKEND = 'eatmanga' BACKEND = 'eatmanga'
def test_download(self): def test_download(self):
return self._test_download('Glass-Mask/Glass-Mask-Vol-031') return self._test_download('Glass-Mask/Glass-Mask-Vol-031')

View file

@ -61,7 +61,7 @@ class EHentaiBrowser(BaseBrowser):
assert self.is_on_page(GalleryPage) assert self.is_on_page(GalleryPage)
i = 0 i = 0
while True: while True:
n = self.page._next_page_link(); n = self.page._next_page_link()
for img in self.page.image_pages(): for img in self.page.image_pages():
yield EHentaiImage(img) yield EHentaiImage(img)
@ -104,4 +104,3 @@ class EHentaiBrowser(BaseBrowser):
# necessary in order to reach the fjords # necessary in order to reach the fjords
self.home() self.home()

View file

@ -27,6 +27,7 @@ from .gallery import EHentaiGallery
__all__ = ['GalleryPage', 'ImagePage', 'IndexPage', 'HomePage', 'LoginPage'] __all__ = ['GalleryPage', 'ImagePage', 'IndexPage', 'HomePage', 'LoginPage']
class LoginPage(BasePage): class LoginPage(BasePage):
def is_logged(self): def is_logged(self):
success_p = self.document.xpath( success_p = self.document.xpath(
@ -38,9 +39,11 @@ class LoginPage(BasePage):
print 'not logged on' print 'not logged on'
return False return False
class HomePage(BasePage): class HomePage(BasePage):
pass pass
class IndexPage(BasePage): class IndexPage(BasePage):
def iter_galleries(self): def iter_galleries(self):
lines = self.document.xpath('//table[@class="itg"]//tr[@class="gtr0" or @class="gtr1"]') lines = self.document.xpath('//table[@class="itg"]//tr[@class="gtr0" or @class="gtr1"]')
@ -50,6 +53,7 @@ class IndexPage(BasePage):
title = a.text.strip() title = a.text.strip()
yield EHentaiGallery(re.search('(?<=/g/)\d+/[\dabcdef]+', url).group(0), title=title) yield EHentaiGallery(re.search('(?<=/g/)\d+/[\dabcdef]+', url).group(0), title=title)
class GalleryPage(BasePage): class GalleryPage(BasePage):
def image_pages(self): def image_pages(self):
return self.document.xpath('//div[@class="gdtm"]//a/attribute::href') return self.document.xpath('//div[@class="gdtm"]//a/attribute::href')
@ -102,7 +106,7 @@ class GalleryPage(BasePage):
except IndexError: except IndexError:
return None return None
class ImagePage(BasePage): class ImagePage(BasePage):
def get_url(self): def get_url(self):
return self.document.xpath('//div[@class="sni"]/a/img/attribute::src')[0] return self.document.xpath('//div[@class="sni"]/a/img/attribute::src')[0]

View file

@ -20,6 +20,7 @@
from weboob.tools.test import BackendTest from weboob.tools.test import BackendTest
class EHentaiTest(BackendTest): class EHentaiTest(BackendTest):
BACKEND = 'ehentai' BACKEND = 'ehentai'
@ -35,4 +36,3 @@ class EHentaiTest(BackendTest):
self.backend.fillobj(img, ('url',)) self.backend.fillobj(img, ('url',))
self.assertTrue(v.url and v.url.startswith('http://'), 'URL for first image in gallery "%s" not found: %s' % (v.id, img.url)) self.assertTrue(v.url and v.url.startswith('http://'), 'URL for first image in gallery "%s" not found: %s' % (v.id, img.url))
self.backend.browser.openurl(img.url) self.backend.browser.openurl(img.url)

View file

@ -30,9 +30,11 @@ __all__ = ['ValidationPage', 'HomePage', 'HistoryPage', 'StoryPage']
class ValidationPage(BasePage): class ValidationPage(BasePage):
pass pass
class HomePage(BasePage): class HomePage(BasePage):
pass pass
class Author(object): class Author(object):
(UNKNOWN, (UNKNOWN,
MALE, MALE,
@ -45,6 +47,7 @@ class Author(object):
self.email = None self.email = None
self.description = None self.description = None
class Story(object): class Story(object):
def __init__(self, id): def __init__(self, id):
self.id = id self.id = id
@ -54,6 +57,7 @@ class Story(object):
self.author = None self.author = None
self.body = None self.body = None
class HistoryPage(BasePage): class HistoryPage(BasePage):
def get_numerous(self): def get_numerous(self):
td = self.parser.select(self.document.getroot(), 'td.t0', 1) td = self.parser.select(self.document.getroot(), 'td.t0', 1)
@ -89,6 +93,7 @@ class HistoryPage(BasePage):
yield story yield story
story = None story = None
class StoryPage(BasePage): class StoryPage(BasePage):
def get_story(self): def get_story(self):
p_tags = self.document.getroot().xpath('//body/p') p_tags = self.document.getroot().xpath('//body/p')
@ -179,4 +184,3 @@ class AuthorPage(BasePage):
if author.description.startswith(u'0 récit '): if author.description.startswith(u'0 récit '):
self.logger.warning('This author does not have published any story.') self.logger.warning('This author does not have published any story.')
return author return author

View file

@ -18,8 +18,8 @@
# 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/>.
import re import re
def id2url(_id): def id2url(_id):
"return an url from an id" "return an url from an id"
regexp2 = re.compile("(\w+).([0-9]+).(.*$)") regexp2 = re.compile("(\w+).([0-9]+).(.*$)")
@ -31,9 +31,11 @@ def id2url(_id):
else: else:
raise ValueError("id doesn't match") raise ValueError("id doesn't match")
def url2id(url): def url2id(url):
"return an id from an url" "return an id from an url"
return url return url
def rssid(entry): def rssid(entry):
return url2id(entry.id) return url2id(entry.id)

View file

@ -32,6 +32,7 @@ from weboob.tools.browser import BaseBrowser, BasePage
__all__ = ['IzneoBackend'] __all__ = ['IzneoBackend']
class ReaderV2(BasePage): class ReaderV2(BasePage):
def get_ean(self): def get_ean(self):
return self.document.xpath("//div[@id='viewer']/attribute::rel")[0] return self.document.xpath("//div[@id='viewer']/attribute::rel")[0]
@ -49,6 +50,7 @@ class ReaderV2(BasePage):
url=("http://www.izneo.com/playerv2/%s/%s/%s/%d/%s" % url=("http://www.izneo.com/playerv2/%s/%s/%s/%d/%s" %
(page['expires'], page['token'], ean, width, page['page']))) (page['expires'], page['token'], ean, width, page['page'])))
class IzneoBrowser(BaseBrowser): class IzneoBrowser(BaseBrowser):
PAGES = {r'http://.+\.izneo.\w+/readv2-.+': ReaderV2} PAGES = {r'http://.+\.izneo.\w+/readv2-.+': ReaderV2}

View file

@ -67,4 +67,3 @@ class LCLBackend(BaseBackend, ICapBank):
with self.browser: with self.browser:
for history in self.browser.get_history(account): for history in self.browser.get_history(account):
yield history yield history

View file

@ -28,6 +28,7 @@ import tempfile
import math import math
import random import random
class LCLVirtKeyboard(MappedVirtKeyboard): class LCLVirtKeyboard(MappedVirtKeyboard):
symbols={'0': '9da2724133f2221482013151735f033c', symbols={'0': '9da2724133f2221482013151735f033c',
'1': '873ab0087447610841ae1332221be37b', '1': '873ab0087447610841ae1332221be37b',
@ -66,9 +67,11 @@ class LCLVirtKeyboard(MappedVirtKeyboard):
code+=self.get_symbol_code(self.symbols[c]) code+=self.get_symbol_code(self.symbols[c])
return code return code
class SkipPage(BasePage): class SkipPage(BasePage):
pass pass
class LoginPage(BasePage): class LoginPage(BasePage):
def myXOR(self,value,seed): def myXOR(self,value,seed):
s='' s=''
@ -120,6 +123,7 @@ class LoginPage(BasePage):
return True return True
return False return False
class AccountsPage(BasePage): class AccountsPage(BasePage):
def get_list(self): def get_list(self):
l = [] l = []
@ -145,6 +149,7 @@ class AccountsPage(BasePage):
l.append(account) l.append(account)
return l return l
class AccountHistoryPage(BasePage): class AccountHistoryPage(BasePage):
def get_operations(self,account): def get_operations(self,account):
operations = [] operations = []
@ -194,5 +199,3 @@ class AccountHistoryPage(BasePage):
operation.amount=amount operation.amount=amount
operations.append(operation) operations.append(operation)
return operations return operations

View file

@ -20,6 +20,7 @@
from weboob.tools.capabilities.messages.genericArticle import GenericNewsPage, remove_from_selector_list, drop_comments, try_drop_tree, try_remove_from_selector_list from weboob.tools.capabilities.messages.genericArticle import GenericNewsPage, remove_from_selector_list, drop_comments, try_drop_tree, try_remove_from_selector_list
class ArticlePage(GenericNewsPage): class ArticlePage(GenericNewsPage):
"ArticlePage object for inrocks" "ArticlePage object for inrocks"
def on_loaded(self): def on_loaded(self):
@ -51,7 +52,6 @@ class ArticlePage(GenericNewsPage):
a.drop_tree() a.drop_tree()
div.drop_tree() div.drop_tree()
# This part of the article seems manually generated. # This part of the article seems manually generated.
for crappy_title in self.parser.select(element_body, 'p strong'): for crappy_title in self.parser.select(element_body, 'p strong'):
if crappy_title.text == 'LIRE AUSSI :' or crappy_title.text == 'LIRE AUSSI:': if crappy_title.text == 'LIRE AUSSI :' or crappy_title.text == 'LIRE AUSSI:':

View file

@ -20,6 +20,7 @@
from weboob.tools.capabilities.messages.genericArticle import GenericNewsPage from weboob.tools.capabilities.messages.genericArticle import GenericNewsPage
class FlashActuPage(GenericNewsPage): class FlashActuPage(GenericNewsPage):
"ArticlePage object for inrocks" "ArticlePage object for inrocks"
def on_loaded(self): def on_loaded(self):
@ -32,4 +33,3 @@ class FlashActuPage(GenericNewsPage):
element_body = self.get_element_body() element_body = self.get_element_body()
element_body.tag = "div" element_body.tag = "div"
return self.parser.tostring(element_body) return self.parser.tostring(element_body)

View file

@ -20,10 +20,11 @@
from weboob.tools.capabilities.messages.genericArticle import GenericNewsPage 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_author_selector = "div.mna-signature" self.element_author_selector = "div.mna-signature"
self.element_body_selector = "#article" self.element_body_selector = "#article"

View file

@ -19,6 +19,7 @@
from weboob.tools.capabilities.messages.genericArticle import GenericNewsPage, try_remove_from_selector_list from weboob.tools.capabilities.messages.genericArticle import GenericNewsPage, try_remove_from_selector_list
class SpecialPage(GenericNewsPage): class SpecialPage(GenericNewsPage):
"ArticlePage object for inrocks" "ArticlePage object for inrocks"
def on_loaded(self): def on_loaded(self):
@ -32,4 +33,3 @@ class SpecialPage(GenericNewsPage):
try_remove_from_selector_list(self.parser, element_body, ['div']) try_remove_from_selector_list(self.parser, element_body, ['div'])
element_body.tag = "div" element_body.tag = "div"
return self.parser.tostring(element_body) return self.parser.tostring(element_body)

View file

@ -18,8 +18,8 @@
# 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/>.
import re import re
def id2url(_id): def id2url(_id):
"return an url from an id" "return an url from an id"
regexp2 = re.compile("(\w+).([0-9]+).(.*$)") regexp2 = re.compile("(\w+).([0-9]+).(.*$)")
@ -31,9 +31,11 @@ def id2url(_id):
else: else:
raise ValueError("id doesn't match") raise ValueError("id doesn't match")
def url2id(url): def url2id(url):
"return an id from an url" "return an id from an url"
return url return url
def rssid(entry): def rssid(entry):
return url2id(entry.id) return url2id(entry.id)

View file

@ -21,6 +21,7 @@ from weboob.tools.capabilities.gallery.genericcomicreader import GenericComicRea
__all__ = ['MangafoxBackend'] __all__ = ['MangafoxBackend']
class MangafoxBackend(GenericComicReaderBackend): class MangafoxBackend(GenericComicReaderBackend):
NAME = 'mangafox' NAME = 'mangafox'
DESCRIPTION = 'Manga Fox manga reading website' DESCRIPTION = 'Manga Fox manga reading website'

View file

@ -20,7 +20,9 @@
from weboob.tools.capabilities.gallery.genericcomicreader import GenericComicReaderTest from weboob.tools.capabilities.gallery.genericcomicreader import GenericComicReaderTest
class MangafoxTest(GenericComicReaderTest): class MangafoxTest(GenericComicReaderTest):
BACKEND = 'mangafox' BACKEND = 'mangafox'
def test_download(self): def test_download(self):
return self._test_download('glass_no_kamen/v02/c000') return self._test_download('glass_no_kamen/v02/c000')

View file

@ -21,6 +21,7 @@ from weboob.tools.capabilities.gallery.genericcomicreader import GenericComicRea
__all__ = ['MangahereBackend'] __all__ = ['MangahereBackend']
class MangahereBackend(GenericComicReaderBackend): class MangahereBackend(GenericComicReaderBackend):
NAME = 'mangahere' NAME = 'mangahere'
DESCRIPTION = 'Manga Here manga reading website' DESCRIPTION = 'Manga Here manga reading website'

View file

@ -19,8 +19,9 @@
from weboob.tools.capabilities.gallery.genericcomicreader import GenericComicReaderTest from weboob.tools.capabilities.gallery.genericcomicreader import GenericComicReaderTest
class MangahereTest(GenericComicReaderTest): class MangahereTest(GenericComicReaderTest):
BACKEND = 'mangahere' BACKEND = 'mangahere'
def test_download(self): def test_download(self):
return self._test_download('glass_no_kamen/v02/c000') return self._test_download('glass_no_kamen/v02/c000')

View file

@ -19,8 +19,10 @@
from weboob.tools.capabilities.gallery.genericcomicreader import GenericComicReaderBackend, DisplayPage from weboob.tools.capabilities.gallery.genericcomicreader import GenericComicReaderBackend, DisplayPage
__all__ = ['MangareaderBackend'] __all__ = ['MangareaderBackend']
class MangareaderBackend(GenericComicReaderBackend): class MangareaderBackend(GenericComicReaderBackend):
NAME = 'mangareader' NAME = 'mangareader'
DESCRIPTION = 'MangaReader manga reading website' DESCRIPTION = 'MangaReader manga reading website'

View file

@ -19,8 +19,9 @@
from weboob.tools.capabilities.gallery.genericcomicreader import GenericComicReaderTest from weboob.tools.capabilities.gallery.genericcomicreader import GenericComicReaderTest
class MangareaderTest(GenericComicReaderTest): class MangareaderTest(GenericComicReaderTest):
BACKEND = 'mangareader' BACKEND = 'mangareader'
def test_download(self): def test_download(self):
return self._test_download('glass-mask/3') return self._test_download('glass-mask/3')

View file

@ -29,6 +29,7 @@ from .browser import MediawikiBrowser
__all__ = ['MediawikiBackend'] __all__ = ['MediawikiBackend']
class MediawikiBackend(BaseBackend, ICapContent): class MediawikiBackend(BaseBackend, ICapContent):
NAME = 'mediawiki' NAME = 'mediawiki'
MAINTAINER = u'Clément Schreiner' MAINTAINER = u'Clément Schreiner'
@ -42,6 +43,7 @@ class MediawikiBackend(BaseBackend, ICapContent):
ValueBackendPassword('password', label='Password', default='')) ValueBackendPassword('password', label='Password', default=''))
BROWSER = MediawikiBrowser BROWSER = MediawikiBrowser
def create_default_browser(self): def create_default_browser(self):
username = self.config['username'].get() username = self.config['username'].get()
if len(username) > 0: if len(username) > 0:

View file

@ -21,7 +21,6 @@ from urlparse import urlsplit
import urllib import urllib
import datetime import datetime
from weboob.tools.browser import BaseBrowser, BrowserIncorrectPassword from weboob.tools.browser import BaseBrowser, BrowserIncorrectPassword
from weboob.capabilities.content import Revision from weboob.capabilities.content import Revision
@ -37,6 +36,7 @@ __all__ = ['MediawikiBrowser']
class APIError(Exception): class APIError(Exception):
pass pass
# Browser # Browser
class MediawikiBrowser(BaseBrowser): class MediawikiBrowser(BaseBrowser):
ENCODING = 'utf-8' ENCODING = 'utf-8'
@ -63,8 +63,6 @@ class MediawikiBrowser(BaseBrowser):
'intoken': 'edit', 'intoken': 'edit',
} }
result = self.API_get(data) result = self.API_get(data)
pageid = result['query']['pages'].keys()[0] pageid = result['query']['pages'].keys()[0]
if pageid == "-1": # Page does not exist if pageid == "-1": # Page does not exist
@ -85,7 +83,6 @@ class MediawikiBrowser(BaseBrowser):
pageid = result['query']['pages'].keys()[0] pageid = result['query']['pages'].keys()[0]
return result['query']['pages'][str(pageid)][_type + 'token'] return result['query']['pages'][str(pageid)][_type + 'token']
def set_wiki_source(self, content, message=None, minor=False): def set_wiki_source(self, content, message=None, minor=False):
if len(self.username) > 0 and not self.is_logged(): if len(self.username) > 0 and not self.is_logged():
self.login() self.login()
@ -138,7 +135,9 @@ class MediawikiBrowser(BaseBrowser):
self.API_post(data) self.API_post(data)
def iter_wiki_revisions(self, page, nb_entries): def iter_wiki_revisions(self, page, nb_entries):
'''Yield 'Revision' objects for the last <nb_entries> revisions of the specified page.''' """
Yield 'Revision' objects for the last <nb_entries> revisions of the specified page.
"""
if len(self.username) > 0 and not self.is_logged(): if len(self.username) > 0 and not self.is_logged():
self.login() self.login()
data = {'action': 'query', data = {'action': 'query',
@ -158,14 +157,11 @@ class MediawikiBrowser(BaseBrowser):
rev_content.revision = str(rev['revid']) rev_content.revision = str(rev['revid'])
rev_content.author = rev['user'] rev_content.author = rev['user']
rev_content.timestamp = datetime.datetime.strptime(rev['timestamp'], '%Y-%m-%dT%H:%M:%SZ') rev_content.timestamp = datetime.datetime.strptime(rev['timestamp'], '%Y-%m-%dT%H:%M:%SZ')
if rev.has_key('minor'): rev_content.minor = 'minor' in rev
rev_content.minor = True
else:
rev_content.minor = False
yield rev_content yield rev_content
def home(self): def home(self):
'''We don't need to change location, we're using the JSON API here.''' # We don't need to change location, we're using the JSON API here.
pass pass
def check_result(self, result): def check_result(self, result):
@ -173,17 +169,20 @@ class MediawikiBrowser(BaseBrowser):
raise APIError('%s' % result['error']['info']) raise APIError('%s' % result['error']['info'])
def API_get(self, data): def API_get(self, data):
'''Submit a GET request to the website """
The JSON data is parsed and returned as a dictionary''' Submit a GET request to the website
The JSON data is parsed and returned as a dictionary
"""
data['format'] = 'json' data['format'] = 'json'
result = simplejson.loads(self.readurl(self.buildurl(self.apiurl, **data)), 'utf-8') result = simplejson.loads(self.readurl(self.buildurl(self.apiurl, **data)), 'utf-8')
self.check_result(result) self.check_result(result)
return result return result
def API_post(self, data): def API_post(self, data):
'''Submit a POST request to the website """
The JSON data is parsed and returned as a dictionary''' Submit a POST request to the website
The JSON data is parsed and returned as a dictionary
"""
data['format'] = 'json' data['format'] = 'json'
result = simplejson.loads(self.readurl(self.apiurl, urllib.urlencode(data)), 'utf-8') result = simplejson.loads(self.readurl(self.apiurl, urllib.urlencode(data)), 'utf-8')
self.check_result(result) self.check_result(result)

View file

@ -18,7 +18,6 @@
# along with weboob. If not, see <http://www.gnu.org/licenses/>. # along with weboob. If not, see <http://www.gnu.org/licenses/>.
from weboob.tools.browser import BasePage from weboob.tools.browser import BasePage
from weboob.capabilities.weather import Forecast, Current, City from weboob.capabilities.weather import Forecast, Current, City
@ -69,7 +68,7 @@ class WeatherPage(BasePage):
Return the city from the forecastpage. Return the city from the forecastpage.
""" """
for div in self.document.getiterator('div'): for div in self.document.getiterator('div'):
if div.attrib.has_key("class") and div.attrib.get("class") == "choix": if div.attrib.get("class", "") == "choix":
for strong in div.getiterator("strong"): for strong in div.getiterator("strong"):
city_name = strong.text + " " + strong.tail.replace("(", "").replace(")", "") city_name = strong.text + " " + strong.tail.replace("(", "").replace(")", "")
city_id = self.url.split("/")[-1] city_id = self.url.split("/")[-1]

View file

@ -23,6 +23,7 @@ from weboob.tools.capabilities.messages.GenericBackend import GenericNewspaperBa
from .browser import Newspaper20minutesBrowser from .browser import Newspaper20minutesBrowser
from .tools import rssid from .tools import rssid
class Newspaper20minutesBackend(GenericNewspaperBackend, ICapMessages): class Newspaper20minutesBackend(GenericNewspaperBackend, ICapMessages):
MAINTAINER = 'Julien Hebert' MAINTAINER = 'Julien Hebert'
EMAIL = 'juke@free.fr' EMAIL = 'juke@free.fr'
@ -34,4 +35,3 @@ class Newspaper20minutesBackend(GenericNewspaperBackend, ICapMessages):
BROWSER = Newspaper20minutesBrowser BROWSER = Newspaper20minutesBrowser
RSS_FEED = 'http://www.20minutes.fr/rss/20minutes.xml' RSS_FEED = 'http://www.20minutes.fr/rss/20minutes.xml'
RSSID = rssid RSSID = rssid

View file

@ -21,6 +21,7 @@
from weboob.tools.capabilities.messages.genericArticle import NoAuthorElement, try_remove, NoneMainDiv from weboob.tools.capabilities.messages.genericArticle import NoAuthorElement, try_remove, NoneMainDiv
from .simple import SimplePage 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):
@ -42,4 +43,3 @@ class ArticlePage(SimplePage):
except NoAuthorElement: except NoAuthorElement:
pass pass
return self.parser.tostring(element_body) return self.parser.tostring(element_body)

View file

@ -20,6 +20,7 @@
from weboob.tools.capabilities.messages.genericArticle import GenericNewsPage 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):
@ -27,4 +28,3 @@ class SimplePage(GenericNewsPage):
self.element_title_selector = "h1" self.element_title_selector = "h1"
self.element_author_selector = "div.mna-signature" self.element_author_selector = "div.mna-signature"
self.element_body_selector = "div.mna-body" self.element_body_selector = "div.mna-body"

View file

@ -18,8 +18,9 @@
# 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/>.
import re import re
def id2url(_id): def id2url(_id):
"return an url from an id" "return an url from an id"
regexp2 = re.compile("(\w+).([0-9]+).(.*$)") regexp2 = re.compile("(\w+).([0-9]+).(.*$)")
@ -31,11 +32,13 @@ def id2url(_id):
else: else:
raise ValueError("id doesn't match") raise ValueError("id doesn't match")
def url2id(url): def url2id(url):
"return an id from an url" "return an id from an url"
regexp = re.compile("http://www.20minutes.fr/(\w+)/([0-9]+)/(.*$)") regexp = re.compile("http://www.20minutes.fr/(\w+)/([0-9]+)/(.*$)")
match = regexp.match(url) match = regexp.match(url)
return '%s.%d.%s' % (match.group(1), int(match.group(2)), match.group(3)) return '%s.%d.%s' % (match.group(1), int(match.group(2)), match.group(3))
def rssid(entry): def rssid(entry):
return url2id(entry.id) return url2id(entry.id)

View file

@ -20,10 +20,10 @@
from weboob.tools.test import BackendTest from weboob.tools.test import BackendTest
class NewsfeedTest(BackendTest): class NewsfeedTest(BackendTest):
BACKEND = 'newsfeed' BACKEND = 'newsfeed'
def test_newsfeed(self): def test_newsfeed(self):
for message in self.backend.iter_unread_messages(): for message in self.backend.iter_unread_messages():
pass pass

View file

@ -35,8 +35,8 @@ __all__ = ['VideoPage']
class ForbiddenVideo(Exception): class ForbiddenVideo(Exception):
pass pass
class VideoPage(BasePage):
class VideoPage(BasePage):
def get_video(self, video=None): def get_video(self, video=None):
_id = to_unicode(self.group_dict['id']) _id = to_unicode(self.group_dict['id'])
if video is None: if video is None:
@ -84,4 +84,3 @@ class VideoPage(BasePage):
video.url = values['url'] video.url = values['url']
return video return video

View file

@ -67,4 +67,3 @@ class AloesBackend(BaseBackend, ICapBook):
def search_books(self, _string): def search_books(self, _string):
raise NotImplementedError() raise NotImplementedError()

View file

@ -63,7 +63,6 @@ class AloesBrowser(BaseBrowser):
(self.is_on_page(LoginPage) and self.page.is_error()): (self.is_on_page(LoginPage) and self.page.is_error()):
raise BrowserIncorrectPassword() raise BrowserIncorrectPassword()
def get_rented_books_list(self): def get_rented_books_list(self):
if not self.is_on_page(RentedPage): if not self.is_on_page(RentedPage):
self.location('%s://%s/index.aspx?IdPage=45' \ self.location('%s://%s/index.aspx?IdPage=45' \

View file

@ -24,6 +24,7 @@ from weboob.tools.browser import BasePage
__all__ = ['ComposePage', 'ConfirmPage'] __all__ = ['ComposePage', 'ConfirmPage']
class ConfirmPage(BasePage): class ConfirmPage(BasePage):
def on_loaded(self): def on_loaded(self):
pass pass

View file

@ -21,6 +21,7 @@ from weboob.tools.capabilities.gallery.genericcomicreader import GenericComicRea
__all__ = ['SimplyreaditBackend'] __all__ = ['SimplyreaditBackend']
class SimplyreaditBackend(GenericComicReaderBackend): class SimplyreaditBackend(GenericComicReaderBackend):
NAME = 'simplyreadit' NAME = 'simplyreadit'
DESCRIPTION = 'SimplyReadIt manga reading website' DESCRIPTION = 'SimplyReadIt manga reading website'

View file

@ -19,8 +19,9 @@
from weboob.tools.capabilities.gallery.genericcomicreader import GenericComicReaderTest from weboob.tools.capabilities.gallery.genericcomicreader import GenericComicReaderTest
class SimplyreaditTest(GenericComicReaderTest): class SimplyreaditTest(GenericComicReaderTest):
BACKEND = 'simplyreadit' BACKEND = 'simplyreadit'
def test_download(self): def test_download(self):
return self._test_download('bonnouji/en/1/3') return self._test_download('bonnouji/en/1/3')

View file

@ -21,12 +21,14 @@
import hashlib import hashlib
import Image import Image
class TileError(Exception): class TileError(Exception):
def __init__(self, msg, tile=None): def __init__(self, msg, tile=None):
Exception.__init__(self, msg) Exception.__init__(self, msg)
self.tile = tile self.tile = tile
class Captcha:
class Captcha(object):
def __init__(self, file, infos): def __init__(self, file, infos):
self.inim = Image.open(file) self.inim = Image.open(file)
self.infos = infos self.infos = infos
@ -77,7 +79,7 @@ class Captcha:
self.map[num] = tile self.map[num] = tile
class Tile: class Tile(object):
hash = {'ff1441b2c5f90703ef04e688e399aca5': 1, hash = {'ff1441b2c5f90703ef04e688e399aca5': 1,
'53d7f3dfd64f54723b231fc398b6be57': 2, '53d7f3dfd64f54723b231fc398b6be57': 2,
'5bcba7fa2107ba9a606e8d0131c162eb': 3, '5bcba7fa2107ba9a606e8d0131c162eb': 3,
@ -116,4 +118,3 @@ class Tile:
def display(self): def display(self):
print self.checksum() print self.checksum()

View file

@ -21,7 +21,9 @@
from .accounts_list import AccountsList from .accounts_list import AccountsList
from .login import LoginPage, BadLoginPage from .login import LoginPage, BadLoginPage
class AccountPrelevement(AccountsList): pass
class AccountPrelevement(AccountsList):
pass
__all__ = ['LoginPage', __all__ = ['LoginPage',
'BadLoginPage', 'BadLoginPage',

View file

@ -79,5 +79,6 @@ class LoginPage(BasePage):
self.browser['cryptocvcs'] = infos["cryptogramme"] self.browser['cryptocvcs'] = infos["cryptogramme"]
self.browser.submit() self.browser.submit()
class BadLoginPage(BasePage): class BadLoginPage(BasePage):
pass pass

View file

@ -16,6 +16,3 @@
# #
# 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/>.

View file

@ -63,4 +63,3 @@ class VideoPage(BasePage):
video.url = video_file_urls[0] video.url = video_file_urls[0]
return video return video

View file

@ -44,6 +44,7 @@ class YoupornBackend(BaseBackend, ICapVideo):
return self.browser.get_video(_id) return self.browser.get_video(_id)
SORTBY = ['relevance', 'rating', 'views', 'time'] SORTBY = ['relevance', 'rating', 'views', 'time']
def search_videos(self, pattern=None, sortby=ICapVideo.SEARCH_RELEVANCE, nsfw=False, max_results=None): def search_videos(self, pattern=None, sortby=ICapVideo.SEARCH_RELEVANCE, nsfw=False, max_results=None):
if not nsfw: if not nsfw:
return set() return set()

View file

@ -47,6 +47,7 @@ class LoginPage(BasePage):
self.browser['Passwd'] = password self.browser['Passwd'] = password
self.browser.submit() self.browser.submit()
class LoginRedirectPage(BasePage): class LoginRedirectPage(BasePage):
pass pass
@ -64,6 +65,7 @@ class BaseYoutubePage(BasePage):
else: else:
return True return True
class ForbiddenVideoPage(BaseYoutubePage): class ForbiddenVideoPage(BaseYoutubePage):
def on_loaded(self): def on_loaded(self):
element = self.parser.select(self.document.getroot(), '.yt-alert-content', 1) element = self.parser.select(self.document.getroot(), '.yt-alert-content', 1)
@ -78,11 +80,13 @@ class VerifyAgePage(BaseYoutubePage):
self.browser.select_form(predicate=lambda form: form.attrs.get('id', '') == 'confirm-age-form') self.browser.select_form(predicate=lambda form: form.attrs.get('id', '') == 'confirm-age-form')
self.browser.submit() self.browser.submit()
class VerifyControversyPage(BaseYoutubePage): class VerifyControversyPage(BaseYoutubePage):
def on_loaded(self): def on_loaded(self):
self.browser.select_form(predicate=lambda form: 'verify_controversy' in form.attrs.get('action', '')) self.browser.select_form(predicate=lambda form: 'verify_controversy' in form.attrs.get('action', ''))
self.browser.submit() self.browser.submit()
class VideoPage(BaseYoutubePage): class VideoPage(BaseYoutubePage):
AVAILABLE_FORMATS = [38, 37, 45, 22, 43, 35, 34, 18, 6, 5, 17, 13] AVAILABLE_FORMATS = [38, 37, 45, 22, 43, 35, 34, 18, 6, 5, 17, 13]
FORMAT_EXTENSIONS = { FORMAT_EXTENSIONS = {

View file

@ -63,6 +63,7 @@ def check_executable_win(executable, error):
print >>sys.stderr, error print >>sys.stderr, error
sys.exit(1) sys.exit(1)
def check_executable_unix(executable, error): def check_executable_unix(executable, error):
with open('/dev/null', 'w') as devnull: with open('/dev/null', 'w') as devnull:
process = subprocess.Popen(['which', executable], stdout=devnull) process = subprocess.Popen(['which', executable], stdout=devnull)
@ -80,6 +81,7 @@ if sys.platform == 'win32':
else: else:
check_executable = check_executable_unix check_executable = check_executable_unix
def build_qt(): def build_qt():
print 'Building Qt applications' print 'Building Qt applications'
pyuic4 = check_executable('pyuic4', 'Install PyQt4-devel or disable Qt applications (with --no-qt).') pyuic4 = check_executable('pyuic4', 'Install PyQt4-devel or disable Qt applications (with --no-qt).')
@ -99,9 +101,11 @@ def build_qt():
subprocess.check_call(['make']+extraMakeFlag+['-C', 'weboob/applications/qflatboob/ui'], env=env) subprocess.check_call(['make']+extraMakeFlag+['-C', 'weboob/applications/qflatboob/ui'], env=env)
subprocess.check_call(['make']+extraMakeFlag+['-C', 'weboob/tools/application/qt'], env=env) subprocess.check_call(['make']+extraMakeFlag+['-C', 'weboob/tools/application/qt'], env=env)
class Options:
class Options(object):
pass pass
options = Options() options = Options()
options.hildon = False options.hildon = False
options.qt = True options.qt = True

View file

@ -20,8 +20,11 @@
from __future__ import with_statement from __future__ import with_statement
import sys, os, tempfile import sys
import imp, inspect import os
import tempfile
import imp
import inspect
import optparse import optparse
import re import re
import time import time
@ -31,6 +34,7 @@ from weboob.tools.application.base import BaseApplication
BASE_PATH = os.path.join(os.path.dirname(__file__), os.pardir) BASE_PATH = os.path.join(os.path.dirname(__file__), os.pardir)
DEST_DIR = 'man' DEST_DIR = 'man'
class ManpageHelpFormatter(optparse.HelpFormatter): class ManpageHelpFormatter(optparse.HelpFormatter):
def __init__(self, def __init__(self,
app, app,
@ -132,14 +136,18 @@ def main():
if (os.path.isfile(tmpfile + "c")): if (os.path.isfile(tmpfile + "c")):
os.unlink(tmpfile + "c") os.unlink(tmpfile + "c")
def format_title(title): def format_title(title):
return re.sub(r'^(.+):$', r'.SH \1\n.TP', title.group().upper()) return re.sub(r'^(.+):$', r'.SH \1\n.TP', title.group().upper())
# XXX useful because the PyQt QApplication destructor crashes sometimes. By # XXX useful because the PyQt QApplication destructor crashes sometimes. By
# keeping every applications until program end, it prevents to stop before # keeping every applications until program end, it prevents to stop before
# every manpages have been generated. If it crashes at exit, it's not a # every manpages have been generated. If it crashes at exit, it's not a
# really a problem. # really a problem.
applications = [] applications = []
def analyze_application(app, script_name): def analyze_application(app, script_name):
application = app() application = app()
applications.append(application) applications.append(application)

View file

@ -1 +0,0 @@

View file

@ -1 +0,0 @@

View file

@ -49,6 +49,7 @@ class QifFormatter(IFormatter):
self.count += 1 self.count += 1
return result return result
class TransactionsFormatter(IFormatter): class TransactionsFormatter(IFormatter):
MANDATORY_FIELDS = ('date', 'label', 'amount') MANDATORY_FIELDS = ('date', 'label', 'amount')
TYPES = ['', 'Transfer', 'Order', 'Check', 'Deposit', 'Payback', 'Withdrawal', 'Card', 'Loan', 'Bank'] TYPES = ['', 'Transfer', 'Order', 'Check', 'Deposit', 'Payback', 'Withdrawal', 'Card', 'Loan', 'Bank']
@ -82,6 +83,7 @@ class TransactionsFormatter(IFormatter):
result += ' %-10s %-12s %-50s %10.2f' % (item['date'].strftime('%Y-%m-%d'), _type, label[:50], item['amount']) result += ' %-10s %-12s %-50s %10.2f' % (item['date'].strftime('%Y-%m-%d'), _type, label[:50], item['amount'])
return result return result
class TransferFormatter(IFormatter): class TransferFormatter(IFormatter):
MANDATORY_FIELDS = ('id', 'date', 'origin', 'recipient', 'amount') MANDATORY_FIELDS = ('id', 'date', 'origin', 'recipient', 'amount')
@ -96,6 +98,7 @@ class TransferFormatter(IFormatter):
result += u'Amount: %.2f\n' % item['amount'] result += u'Amount: %.2f\n' % item['amount']
return result return result
class RecipientListFormatter(IFormatter): class RecipientListFormatter(IFormatter):
MANDATORY_FIELDS = ('id', 'label') MANDATORY_FIELDS = ('id', 'label')
@ -115,6 +118,7 @@ class RecipientListFormatter(IFormatter):
return u'%s %-30s %s %s' % (self.BOLD, id, self.NC, item['label']) return u'%s %-30s %s %s' % (self.BOLD, id, self.NC, item['label'])
class AccountListFormatter(IFormatter): class AccountListFormatter(IFormatter):
MANDATORY_FIELDS = ('id', 'label', 'balance', 'coming') MANDATORY_FIELDS = ('id', 'label', 'balance', 'coming')
@ -122,7 +126,6 @@ class AccountListFormatter(IFormatter):
tot_balance = 0.0 tot_balance = 0.0
tot_coming = 0.0 tot_coming = 0.0
def flush(self): def flush(self):
if self.count < 1: if self.count < 1:
return return
@ -156,6 +159,7 @@ class AccountListFormatter(IFormatter):
self.tot_coming += item['coming'] self.tot_coming += item['coming']
return result return result
class Boobank(ReplApplication): class Boobank(ReplApplication):
APPNAME = 'boobank' APPNAME = 'boobank'
VERSION = '0.b' VERSION = '0.b'

View file

@ -1,3 +1,4 @@
from .qwebcontentedit import QWebContentEdit from .qwebcontentedit import QWebContentEdit
__all__ = ['QWebContentEdit'] __all__ = ['QWebContentEdit']

View file

@ -22,6 +22,7 @@ from weboob.capabilities.content import ICapContent
from .main_window import MainWindow from .main_window import MainWindow
class QWebContentEdit(QtApplication): class QWebContentEdit(QtApplication):
APPNAME = 'qwebcontentedit' APPNAME = 'qwebcontentedit'
VERSION = '0.b' VERSION = '0.b'
@ -34,5 +35,3 @@ class QWebContentEdit(QtApplication):
self.main_window = MainWindow(self.config, self.weboob) self.main_window = MainWindow(self.config, self.weboob)
self.main_window.show() self.main_window.show()
return self.weboob.loop() return self.weboob.loop()

View file

@ -134,7 +134,6 @@ class WeboobRepos(ReplApplication):
else: else:
print 'Keyring is up to date' print 'Keyring is up to date'
for name, module in r.modules.iteritems(): for name, module in r.modules.iteritems():
tarname = os.path.join(repo_path, '%s.tar.gz' % name) tarname = os.path.join(repo_path, '%s.tar.gz' % name)
if r.signed: if r.signed:
@ -202,7 +201,6 @@ class WeboobRepos(ReplApplication):
os.utime(sigpath, (file_mtime, file_mtime)) os.utime(sigpath, (file_mtime, file_mtime))
print 'Signatures are up to date' print 'Signatures are up to date'
@staticmethod @staticmethod
def _find_gpg(): def _find_gpg():
if os.getenv('GPG_EXECUTABLE'): if os.getenv('GPG_EXECUTABLE'):
@ -221,4 +219,3 @@ class WeboobRepos(ReplApplication):
if filename.endswith('.png'): if filename.endswith('.png'):
return True return True
return False return False

View file

@ -64,6 +64,7 @@ class NotLoaded(object):
class IBaseCap(object): class IBaseCap(object):
pass pass
class CapBaseObject(object): class CapBaseObject(object):
FIELDS = None FIELDS = None
_attribs = None _attribs = None

View file

@ -24,6 +24,7 @@ from weboob.tools.ordereddict import OrderedDict
__all__ = ['ICapContact', 'Contact'] __all__ = ['ICapContact', 'Contact']
class ProfileNode(object): class ProfileNode(object):
HEAD = 0x01 HEAD = 0x01
SECTION = 0x02 SECTION = 0x02
@ -38,6 +39,7 @@ class ProfileNode(object):
def __getitem__(self, key): def __getitem__(self, key):
return self.value[key] return self.value[key]
class ContactPhoto(CapBaseObject): class ContactPhoto(CapBaseObject):
def __init__(self, name): def __init__(self, name):
CapBaseObject.__init__(self, name) CapBaseObject.__init__(self, name)
@ -59,6 +61,7 @@ class ContactPhoto(CapBaseObject):
len(self.data) if self.data else 0, len(self.data) if self.data else 0,
len(self.thumbnail_data) if self.thumbnail_data else 0) len(self.thumbnail_data) if self.thumbnail_data else 0)
class Contact(CapBaseObject): class Contact(CapBaseObject):
STATUS_ONLINE = 0x001 STATUS_ONLINE = 0x001
STATUS_AWAY = 0x002 STATUS_AWAY = 0x002
@ -83,14 +86,17 @@ class Contact(CapBaseObject):
for key, value in kwargs.iteritems(): for key, value in kwargs.iteritems():
setattr(photo, key, value) setattr(photo, key, value)
class QueryError(Exception): class QueryError(Exception):
pass pass
class Query(CapBaseObject): class Query(CapBaseObject):
def __init__(self, id, message): def __init__(self, id, message):
CapBaseObject.__init__(self, id) CapBaseObject.__init__(self, id)
self.add_field('message', basestring, message) self.add_field('message', basestring, message)
class ICapContact(IBaseCap): class ICapContact(IBaseCap):
def iter_contacts(self, status=Contact.STATUS_ALL, ids=None): def iter_contacts(self, status=Contact.STATUS_ALL, ids=None):
""" """

View file

@ -28,9 +28,11 @@ from logging import warning
__all__ = ['BackendsConfig', 'BackendAlreadyExists'] __all__ = ['BackendsConfig', 'BackendAlreadyExists']
class BackendAlreadyExists(Exception): class BackendAlreadyExists(Exception):
pass pass
class BackendsConfig(object): class BackendsConfig(object):
class WrongPermissions(Exception): class WrongPermissions(Exception):
pass pass
@ -129,5 +131,3 @@ class BackendsConfig(object):
with open(self.confpath, 'w') as f: with open(self.confpath, 'w') as f:
config.write(f) config.write(f)
return True return True

View file

@ -356,7 +356,7 @@ class Versions(object):
with open(os.path.join(self.path, self.VERSIONS_LIST), 'wb') as fp: with open(os.path.join(self.path, self.VERSIONS_LIST), 'wb') as fp:
config.write(fp) config.write(fp)
class IProgress: class IProgress(object):
def progress(self, percent, message): def progress(self, percent, message):
print '=== [%3.0f%%] %s' % (percent*100, message) print '=== [%3.0f%%] %s' % (percent*100, message)

View file

@ -1 +0,0 @@

View file

@ -1 +0,0 @@

View file

@ -62,6 +62,7 @@ class BackendStorage(object):
if self.storage: if self.storage:
return self.storage.save('backends', self.name) return self.storage.save('backends', self.name)
class BackendConfig(ValuesDict): class BackendConfig(ValuesDict):
modname = None modname = None
instname = None instname = None
@ -118,6 +119,7 @@ class BackendConfig(ValuesDict):
self.weboob.backends_config.add_backend(self.instname, self.modname, dump, edit) self.weboob.backends_config.add_backend(self.instname, self.modname, dump, edit)
class BaseBackend(object): class BaseBackend(object):
# Backend name. # Backend name.
NAME = None NAME = None
@ -149,7 +151,8 @@ class BaseBackend(object):
# NOT yet filled. # NOT yet filled.
OBJECTS = {} OBJECTS = {}
class ConfigError(Exception): pass class ConfigError(Exception):
pass
def __enter__(self): def __enter__(self):
self.lock.acquire() self.lock.acquire()
@ -184,6 +187,7 @@ class BaseBackend(object):
class classprop(object): class classprop(object):
def __init__(self, fget): def __init__(self, fget):
self.fget = fget self.fget = fget
def __get__(self, inst, objtype=None): def __get__(self, inst, objtype=None):
if inst: if inst:
return self.fget(inst) return self.fget(inst)

View file

@ -1 +0,0 @@

View file

@ -28,6 +28,7 @@ from weboob.tools.test import BackendTest
__all__ = ['GenericComicReaderBackend'] __all__ = ['GenericComicReaderBackend']
class DisplayPage(BasePage): class DisplayPage(BasePage):
def get_page(self, gallery): def get_page(self, gallery):
src = self.document.xpath(self.browser.params['img_src_xpath'])[0] src = self.document.xpath(self.browser.params['img_src_xpath'])[0]
@ -102,7 +103,6 @@ class GenericComicReaderBackend(BaseBackend, ICapGallery):
else: else:
return None return None
gallery = BaseGallery(_id, url=(self.ID_TO_URL % _id)) gallery = BaseGallery(_id, url=(self.ID_TO_URL % _id))
with self.browser: with self.browser:
return gallery return gallery
@ -126,4 +126,3 @@ class GenericComicReaderTest(BackendTest):
it.next() it.next()
img = it.next() img = it.next()
self.backend.fillobj(img, ('url', 'data')) self.backend.fillobj(img, ('url', 'data'))

View file

@ -25,6 +25,7 @@ from weboob.capabilities.messages import ICapMessages, Message, Thread
from weboob.tools.backend import BaseBackend from weboob.tools.backend import BaseBackend
from weboob.tools.newsfeed import Newsfeed from weboob.tools.newsfeed import Newsfeed
class GenericNewspaperBackend(BaseBackend, ICapMessages): class GenericNewspaperBackend(BaseBackend, ICapMessages):
"GenericNewspaperBackend class" "GenericNewspaperBackend class"
MAINTAINER = 'Julien Hebert' MAINTAINER = 'Julien Hebert'

View file

@ -33,6 +33,7 @@ def try_drop_tree(parser, base_element, selector):
for el in parser.select(base_element, selector): for el in parser.select(base_element, selector):
el.drop_tree() el.drop_tree()
def remove_from_selector_list(parser, base_element, selector_list): def remove_from_selector_list(parser, base_element, selector_list):
for selector in selector_list: for selector in selector_list:
base_element.remove(parser.select(base_element, selector, 1)) base_element.remove(parser.select(base_element, selector, 1))
@ -42,24 +43,28 @@ def try_remove_from_selector_list(parser, base_element, selector_list):
for selector in selector_list: for selector in selector_list:
try_remove(parser, base_element, selector) try_remove(parser, base_element, selector)
def drop_comments(base_element): def drop_comments(base_element):
for comment in base_element.getiterator(Comment): for comment in base_element.getiterator(Comment):
comment.drop_tree() comment.drop_tree()
class NoAuthorElement(BrokenPageError): class NoAuthorElement(BrokenPageError):
pass pass
class NoBodyElement(BrokenPageError): class NoBodyElement(BrokenPageError):
pass pass
class NoTitleException(BrokenPageError): class NoTitleException(BrokenPageError):
pass pass
class NoneMainDiv(AttributeError): class NoneMainDiv(AttributeError):
pass pass
class Article(object): class Article(object):
author = u'' author = u''
title = u'' title = u''
@ -71,6 +76,7 @@ class Article(object):
self.url = u'' self.url = u''
self.date = None self.date = None
class GenericNewsPage(BasePage): class GenericNewsPage(BasePage):
__element_body = NotImplementedError __element_body = NotImplementedError
__article = Article __article = Article

View file

@ -21,6 +21,7 @@
import hashlib import hashlib
import Image import Image
class VirtKeyboardError(Exception): class VirtKeyboardError(Exception):
def __init__(self, msg): def __init__(self, msg):
Exception.__init__(self, msg) Exception.__init__(self, msg)
@ -64,7 +65,7 @@ class VirtKeyboard(object):
empty_line = False empty_line = False
if newY1 == -1: if newY1 == -1:
newY1 = y newY1 = y
break; break
else: else:
break break
if newY1 != -1 and not empty_line: if newY1 != -1 and not empty_line:
@ -122,6 +123,7 @@ class VirtKeyboard(object):
matrix[x, y] = self.pixar[self.coords[i][0] + x, self.coords[i][1] + y] matrix[x, y] = self.pixar[self.coords[i][0] + x, self.coords[i][1] + y]
img.save(dir + "/" + self.md5[i] + ".png") img.save(dir + "/" + self.md5[i] + ".png")
class MappedVirtKeyboard(VirtKeyboard): class MappedVirtKeyboard(VirtKeyboard):
def __init__(self, file, document, img_element, color, map_attr="onclick"): def __init__(self, file, document, img_element, color, map_attr="onclick"):
map_id = img_element.attrib.get("usemap")[1:] map_id = img_element.attrib.get("usemap")[1:]

View file

@ -22,7 +22,7 @@ class ConfigError(Exception):
pass pass
class IConfig: class IConfig(object):
def load(self, default={}): def load(self, default={}):
raise NotImplementedError() raise NotImplementedError()

View file

@ -40,8 +40,7 @@ def retry(ExceptionToCheck, tries=4, delay=3, backoff=2):
try_one_last_time = False try_one_last_time = False
break break
except ExceptionToCheck, e: except ExceptionToCheck, e:
logging.debug(u'%s, Retrying in %d seconds...' % (e, logging.debug(u'%s, Retrying in %d seconds...' % (e, mdelay))
mdelay))
time.sleep(mdelay) time.sleep(mdelay)
mtries -= 1 mtries -= 1
mdelay *= backoff mdelay *= backoff

View file

@ -35,11 +35,13 @@ COLORS = {
'CRITICAL': COLOR_SEQ % ("\033[1;33m\033[1;41m"), 'CRITICAL': COLOR_SEQ % ("\033[1;33m\033[1;41m"),
} }
def getLogger(name, parent=None): def getLogger(name, parent=None):
if parent: if parent:
name = parent.name + '.' + name name = parent.name + '.' + name
return _getLogger(name) return _getLogger(name)
class ColoredFormatter(Formatter): class ColoredFormatter(Formatter):
""" """
Class written by airmind: Class written by airmind:
@ -52,9 +54,9 @@ class ColoredFormatter(Formatter):
msg = COLORS[levelname] % msg msg = COLORS[levelname] % msg
return msg return msg
def createColoredFormatter(stream, format): def createColoredFormatter(stream, format):
if (sys.platform != 'win32') and stream.isatty(): if (sys.platform != 'win32') and stream.isatty():
return ColoredFormatter(format) return ColoredFormatter(format)
else: else:
return Formatter(format) return Formatter(format)

View file

@ -68,6 +68,7 @@ try:
html2text = h2t.html2text html2text = h2t.html2text
except ImportError: except ImportError:
warning('python-html2text is not present. HTML pages will not be converted into text.') warning('python-html2text is not present. HTML pages will not be converted into text.')
def html2text(html): def html2text(html):
return html return html
@ -117,6 +118,7 @@ def utc2local(date):
date = date.astimezone(tz.tzlocal()) date = date.astimezone(tz.tzlocal())
return date return date
def limit(iterator, lim): def limit(iterator, lim):
count = 0 count = 0
iterator = iter(iterator) iterator = iter(iterator)
@ -125,6 +127,7 @@ def limit(iterator, lim):
count += 1 count += 1
raise StopIteration() raise StopIteration()
def ratelimit(group, delay): def ratelimit(group, delay):
""" """
Simple rate limiting. Simple rate limiting.

View file

@ -29,46 +29,46 @@ if feedparser.__version__ >= '5.0':
__all__ = ['Entry', 'Newsfeed'] __all__ = ['Entry', 'Newsfeed']
class Entry: class Entry(object):
def __init__(self, entry, rssid_func=None): def __init__(self, entry, rssid_func=None):
if hasattr(entry, 'id'): if hasattr(entry, 'id'):
self.id = entry.id self.id = entry.id
else: else:
self.id = None self.id = None
if entry.has_key("link"): if "link" in entry:
self.link = entry["link"] self.link = entry["link"]
else: else:
self.link = None self.link = None
if entry.has_key("title"): if "title" in entry:
self.title = entry["title"] self.title = entry["title"]
else: else:
self.title = None self.title = None
if entry.has_key("author"): if "author" in entry:
self.author = entry["author"] self.author = entry["author"]
else: else:
self.author = None self.author = None
if entry.has_key("updated_parsed"): if "updated_parsed" in entry:
self.datetime = datetime.datetime(*entry['updated_parsed'][:7]) self.datetime = datetime.datetime(*entry['updated_parsed'][:7])
else: else:
self.datetime = None self.datetime = None
if entry.has_key("summary"): if "summary" in entry:
self.summary = entry["summary"] self.summary = entry["summary"]
else: else:
self.summary = None self.summary = None
self.content = [] self.content = []
if entry.has_key("content"): if "content" in entry:
for i in entry["content"]: for i in entry["content"]:
self.content.append(i.value) self.content.append(i.value)
elif self.summary: elif self.summary:
self.content.append(self.summary) self.content.append(self.summary)
if entry.has_key("wfw_commentrss"): if "wfw_commentrss" in entry:
self.rsscomment = entry["wfw_commentrss"] self.rsscomment = entry["wfw_commentrss"]
else: else:
self.rsscomment = None self.rsscomment = None
@ -76,7 +76,8 @@ class Entry:
if rssid_func: if rssid_func:
self.id = rssid_func(self) self.id = rssid_func(self)
class Newsfeed:
class Newsfeed(object):
def __init__(self, url, rssid_func=None): def __init__(self, url, rssid_func=None):
self.feed = feedparser.parse(url) self.feed = feedparser.parse(url)
self.rssid_func = rssid_func self.rssid_func = rssid_func

View file

@ -30,7 +30,6 @@ except ImportError:
## {{{ http://code.activestate.com/recipes/576693/ (r6) ## {{{ http://code.activestate.com/recipes/576693/ (r6)
from UserDict import DictMixin from UserDict import DictMixin
class OrderedDict(dict, DictMixin): class OrderedDict(dict, DictMixin):
def __init__(self, *args, **kwds): def __init__(self, *args, **kwds):

View file

@ -24,34 +24,42 @@ import logging
__all__ = ['get_parser', 'NoParserFound'] __all__ = ['get_parser', 'NoParserFound']
class NoParserFound(Exception): pass class NoParserFound(Exception):
pass
def load_lxml(): def load_lxml():
from .lxmlparser import LxmlHtmlParser from .lxmlparser import LxmlHtmlParser
return LxmlHtmlParser return LxmlHtmlParser
def load_lxmlsoup(): def load_lxmlsoup():
from .lxmlsoupparser import LxmlSoupParser from .lxmlsoupparser import LxmlSoupParser
return LxmlSoupParser return LxmlSoupParser
def load_html5lib(): def load_html5lib():
from .html5libparser import Html5libParser from .html5libparser import Html5libParser
return Html5libParser return Html5libParser
def load_elementtidy(): def load_elementtidy():
from .elementtidyparser import ElementTidyParser from .elementtidyparser import ElementTidyParser
return ElementTidyParser return ElementTidyParser
def load_builtin(): def load_builtin():
from .htmlparser import HTMLParser from .htmlparser import HTMLParser
return HTMLParser return HTMLParser
def load_json(): def load_json():
# This parser doesn't read HTML, don't include it in the # This parser doesn't read HTML, don't include it in the
# preference_order default value below. # preference_order default value below.
from .jsonparser import JsonParser from .jsonparser import JsonParser
return JsonParser return JsonParser
def get_parser(preference_order=('lxml', 'lxmlsoup')): def get_parser(preference_order=('lxml', 'lxmlsoup')):
""" """
Get a parser from a preference order list. Get a parser from a preference order list.

View file

@ -38,8 +38,8 @@ class Html5libParser(HTMLParser, IParser):
""" """
# Default implementation for each type of API. # Default implementation for each type of API.
defaults = {'etree': ElementTree, defaults = {'etree': ElementTree}
}
def __init__(self, api='etree'): def __init__(self, api='etree'):
# if no default implementation is defined for this api, set it to None # if no default implementation is defined for this api, set it to None
# to let getTreeBuilder() using the corresponding implementation. # to let getTreeBuilder() using the corresponding implementation.

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# For Python 2.5-, this will enable the simliar property mechanism as in # For Python 2.5-, this will enable the similar property mechanism as in
# Python 2.6+/3.0+. The code is based on # Python 2.6+/3.0+. The code is based on
# http://bruynooghe.blogspot.com/2008/04/xsetter-syntax-in-python-25.html # http://bruynooghe.blogspot.com/2008/04/xsetter-syntax-in-python-25.html

View file

@ -23,7 +23,7 @@ from copy import deepcopy
from .config.yamlconfig import YamlConfig from .config.yamlconfig import YamlConfig
class IStorage: class IStorage(object):
def load(self, what, name, default={}): def load(self, what, name, default={}):
raise NotImplementedError() raise NotImplementedError()