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.browser import BrowserBanned
from weboob.tools.browser2.page import HTMLPage, LoggedPage, method, ListElement, ItemElement 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 weboob.capabilities.bill import Subscription, Detail
from datetime import datetime from datetime import datetime
@ -28,7 +28,7 @@ __all__ = ['LoginPage', 'HomePage', 'HistoryPage', 'BillsPage', 'ErrorPage']
class ErrorPage(HTMLPage): class ErrorPage(HTMLPage):
pass pass
class LoginPage(HTMLPage): class LoginPage(HTMLPage):
@ -49,31 +49,6 @@ class LoginPage(HTMLPage):
form.submit() 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): class HomePage(LoggedPage, HTMLPage):
@method @method
@ -85,7 +60,7 @@ class HomePage(LoggedPage, HTMLPage):
obj_id = CleanText('//span[@class="welcome-text"]/b') obj_id = CleanText('//span[@class="welcome-text"]/b')
obj__balance = CleanDecimal(CleanText('//span[@class="balance"]'), replace_dots=False) 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): class HistoryPage(LoggedPage, HTMLPage):
@ -109,9 +84,9 @@ class HistoryPage(LoggedPage, HTMLPage):
obj_datetime = Env('datetime') obj_datetime = Env('datetime')
obj_price = CleanDecimal('td[7]', replace_dots=False, default=0) obj_price = CleanDecimal('td[7]', replace_dots=False, default=0)
obj_currency = u'EUR' obj_currency = u'EUR'
obj_label = InsertX([CleanText('td[3]'), CleanText('td[4]'), obj_label = Format(u"%s from %s to %s - %s",
CleanText('td[5]'), CleanText('td[6]')], CleanText('td[3]'), CleanText('td[4]'),
u"%s from %s to %s - %s") CleanText('td[5]'), CleanText('td[6]'))
def parse(self, el): def parse(self, el):
mydate = Date(CleanText('td[1]'))(el) mydate = Date(CleanText('td[1]'))(el)

View file

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