add filter Format in default formatters

This commit is contained in:
Romain Bignon 2014-03-21 08:29:39 +01:00
commit 38a99064b0
2 changed files with 43 additions and 38 deletions

View file

@ -19,7 +19,7 @@
from weboob.tools.browser import BrowserBanned
from weboob.tools.browser2.page import HTMLPage, LoggedPage, method, ListElement, ItemElement
from weboob.tools.browser2.filters import Env, CleanText, CleanDecimal, Field, Attr, Filter, Time, Date, Link
from weboob.tools.browser2.filters import Env, CleanText, CleanDecimal, Field, Attr, Time, Date, Link, Format
from weboob.capabilities.bill import Subscription, Detail
from datetime import datetime
@ -28,7 +28,7 @@ __all__ = ['LoginPage', 'HomePage', 'HistoryPage', 'BillsPage', 'ErrorPage']
class ErrorPage(HTMLPage):
pass
pass
class LoginPage(HTMLPage):
@ -49,31 +49,6 @@ class LoginPage(HTMLPage):
form.submit()
class InsertX(Filter):
"""
Insert a list of Filters inside a string
"""
def __init__(self, selectors, string):
self.string = string
self.selectors = selectors
def map_filter(self, selector, item):
if isinstance(selector, basestring):
value = item.xpath(selector)
elif callable(selector):
value = selector(item)
else:
value = selector
return value
def __call__(self, item):
myliste = [self.map_filter(selector, item) for selector in self.selectors]
return self.filter(tuple(myliste))
def filter(self, mytupple):
return self.string % mytupple
class HomePage(LoggedPage, HTMLPage):
@method
@ -85,7 +60,7 @@ class HomePage(LoggedPage, HTMLPage):
obj_id = CleanText('//span[@class="welcome-text"]/b')
obj__balance = CleanDecimal(CleanText('//span[@class="balance"]'), replace_dots=False)
obj_label = InsertX([Field('id'), Field('_balance')], u"Poivy - %s - %s")
obj_label = Format(u"Poivy - %s - %s", Field('id'), Field('_balance'))
class HistoryPage(LoggedPage, HTMLPage):
@ -109,9 +84,9 @@ class HistoryPage(LoggedPage, HTMLPage):
obj_datetime = Env('datetime')
obj_price = CleanDecimal('td[7]', replace_dots=False, default=0)
obj_currency = u'EUR'
obj_label = InsertX([CleanText('td[3]'), CleanText('td[4]'),
CleanText('td[5]'), CleanText('td[6]')],
u"%s from %s to %s - %s")
obj_label = Format(u"%s from %s to %s - %s",
CleanText('td[3]'), CleanText('td[4]'),
CleanText('td[5]'), CleanText('td[6]'))
def parse(self, el):
mydate = Date(CleanText('td[1]'))(el)

View file

@ -54,15 +54,17 @@ class Filter(_Filter):
super(Filter, self).__init__()
self.selector = selector
def __call__(self, item):
if isinstance(self.selector, basestring):
value = item.xpath(self.selector)
elif callable(self.selector):
value = self.selector(item)
@classmethod
def select(cls, selector, item):
if isinstance(selector, basestring):
return item.xpath(selector)
elif callable(selector):
return selector(item)
else:
value = self.selector
return selector
return self.filter(value)
def __call__(self, item):
return self.filter(self.select(self.selector, item))
def filter(self, value):
"""
@ -85,6 +87,7 @@ class Env(_Filter):
def __call__(self, item):
return item.env[self.name]
class TableCell(_Filter):
"""
Used with TableElement, it get the cell value from its name.
@ -119,6 +122,7 @@ class TableCell(_Filter):
return self.default
raise KeyError('Unable to find column %s' % ' or '.join(self.names))
class CleanText(Filter):
"""
Get a cleaned text from an element.
@ -152,6 +156,7 @@ class CleanText(Filter):
txt = txt.replace(symbol, '')
return txt
class CleanDecimal(CleanText):
"""
Get a cleaned Decimal value from an element.
@ -173,6 +178,7 @@ class CleanDecimal(CleanText):
else:
raise InvalidOperation(e)
class Attr(Filter):
def __init__(self, selector, attr, default=_NO_DEFAULT):
super(Attr, self).__init__(selector)
@ -245,6 +251,7 @@ class Regexp(Filter):
else:
return mobj.expand(self.template)
class Map(Filter):
def __init__(self, selector, map_dict, default=_NO_DEFAULT):
super(Map, self).__init__(selector)
@ -260,12 +267,14 @@ class Map(Filter):
else:
raise KeyError('Unable to handle %r' % txt)
class Date(Filter):
def filter(self, txt):
if empty(txt):
return txt
return parse_date(txt)
class Time(Filter):
klass = datetime.time
regexp = re.compile(ur'(?P<hh>\d+):?(?P<mm>\d+)(:(?P<ss>\d+))?')
@ -293,3 +302,24 @@ class Duration(Time):
klass = datetime.timedelta
regexp = re.compile(ur'((?P<hh>\d+)[:;])?(?P<mm>\d+)[;:](?P<ss>\d+)')
kwargs = {'hours': 'hh', 'minutes': 'mm', 'seconds': 'ss'}
class MultiFilter(Filter):
def __init__(self, *args):
super(MultiFilter, self).__init__(args)
def __call__(self, item):
values = [self.select(selector, item) for selector in self.selector]
return self.filter(tuple(values))
def filter(self, values):
raise NotImplementedError()
class Format(MultiFilter):
def __init__(self, fmt, *args):
super(Format, self).__init__(*args)
self.fmt = fmt
def filter(self, values):
return self.fmt % values