diff --git a/weboob/backends/aum/backend.py b/weboob/backends/aum/backend.py index f04663a7..77ca504e 100644 --- a/weboob/backends/aum/backend.py +++ b/weboob/backends/aum/backend.py @@ -268,7 +268,6 @@ class AuMBackend(BaseBackend, ICapMessages, ICapMessagesPost, ICapDating, ICapCh contact = Contact(_id, profile.get_name(), s) contact.status_msg = u'%s old' % profile.table['details']['old'] contact.summary = profile.description - contact.avatar = None for photo in profile.photos: contact.set_photo(photo.split('/')[-1], url=photo, thumbnail_url=photo.replace('image', 'thumb1_')) contact.profile = [] diff --git a/weboob/backends/fourchan/pages/board.py b/weboob/backends/fourchan/pages/board.py index b11adb83..918f96ec 100644 --- a/weboob/backends/fourchan/pages/board.py +++ b/weboob/backends/fourchan/pages/board.py @@ -15,6 +15,8 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +from datetime import datetime + import re from logging import warning @@ -26,7 +28,7 @@ class Message(object): self.browser = browser self.board = board self.filename = filename - self.datetime = 0 + self.datetime = datetime.now() self.url = url self.author = u'' self.text = u'' diff --git a/weboob/backends/geolocip/backend.py b/weboob/backends/geolocip/backend.py index 2a357982..31ed43db 100644 --- a/weboob/backends/geolocip/backend.py +++ b/weboob/backends/geolocip/backend.py @@ -18,6 +18,7 @@ from __future__ import with_statement from weboob.capabilities.geolocip import ICapGeolocIp, IpLocation +from weboob.capabilities.base import NotAvailable from weboob.tools.backend import BaseBackend from weboob.tools.browser import BaseBrowser @@ -66,5 +67,8 @@ class GeolocIpBackend(BaseBackend, ICapGeolocIp): iploc.lg = float(tab['lg']) iploc.host = tab['host'] iploc.tld = tab['tld'] - iploc.isp = tab['fai'] + if 'fai' in tab: + iploc.isp = tab['fai'] + else: + iploc.isp = NotAvailable return iploc diff --git a/weboob/backends/ouifm/backend.py b/weboob/backends/ouifm/backend.py index 93f28115..2bfee773 100644 --- a/weboob/backends/ouifm/backend.py +++ b/weboob/backends/ouifm/backend.py @@ -36,11 +36,11 @@ class OuiFMBackend(BaseBackend, ICapRadio): LICENSE = 'GPLv3' BROWSER = OuiFMBrowser - _RADIOS = {'general': (u'OUÏ FM', u'OUI FM', 'http://ouifm.ice.infomaniak.ch/ouifm-high.mp3'), - 'alternatif': (u'OUÏ FM Alternatif', u'OUI FM - L\'Alternative Rock', 'http://ouifm.ice.infomaniak.ch/ouifm2.mp3'), - 'collector': (u'OUÏ FM Collector', u'OUI FM - Classic Rock', 'http://ouifm.ice.infomaniak.ch/ouifm3.mp3'), - 'blues': (u'OUÏ FM Blues', u'OUI FM - Blues', 'http://ouifm.ice.infomaniak.ch/ouifm4.mp3'), - 'inde': (u'OUÏ FM Indé', u'OUI FM - Rock Indé', 'http://ouifm.ice.infomaniak.ch/ouifm5.mp3'), + _RADIOS = {'general': (u'OUÏ FM', u'OUI FM', u'http://ouifm.ice.infomaniak.ch/ouifm-high.mp3'), + 'alternatif': (u'OUÏ FM Alternatif', u'OUI FM - L\'Alternative Rock', u'http://ouifm.ice.infomaniak.ch/ouifm2.mp3'), + 'collector': (u'OUÏ FM Collector', u'OUI FM - Classic Rock', u'http://ouifm.ice.infomaniak.ch/ouifm3.mp3'), + 'blues': (u'OUÏ FM Blues', u'OUI FM - Blues', u'http://ouifm.ice.infomaniak.ch/ouifm4.mp3'), + 'inde': (u'OUÏ FM Indé', u'OUI FM - Rock Indé', u'http://ouifm.ice.infomaniak.ch/ouifm5.mp3'), } def iter_radios(self): @@ -70,7 +70,7 @@ class OuiFMBackend(BaseBackend, ICapRadio): radio.current = current stream = Stream(0) - stream.title = '128kbits/s' + stream.title = u'128kbits/s' stream.url = url radio.streams = [stream] return radio diff --git a/weboob/backends/ouifm/pages.py b/weboob/backends/ouifm/pages.py index 8f834e6d..4a94844b 100644 --- a/weboob/backends/ouifm/pages.py +++ b/weboob/backends/ouifm/pages.py @@ -31,4 +31,4 @@ class PlayerPage(BasePage): _radio = '_%s' % radio title = select(self.document.getroot(), 'div#titre%s' % _radio, 1).text.strip() artist = select(self.document.getroot(), 'div#artiste%s' % _radio, 1).text.strip() - return artist, title + return unicode(artist), unicode(title) diff --git a/weboob/capabilities/bank.py b/weboob/capabilities/bank.py index 430aa105..fa6d3eb7 100644 --- a/weboob/capabilities/bank.py +++ b/weboob/capabilities/bank.py @@ -17,9 +17,7 @@ import sys -if sys.version_info[:2] <= (2, 5): - from weboob.tools.property import property - +from datetime import datetime from .base import IBaseCap, CapBaseObject @@ -29,68 +27,33 @@ __all__ = ['Account', 'AccountNotFound', 'NotEnoughMoney', 'ICapBank', 'Operatio class AccountNotFound(Exception): pass - + class NotEnoughMoney(Exception): pass class Account(CapBaseObject): - FIELDS = ('label', 'balance', 'coming') def __init__(self): CapBaseObject.__init__(self, 0) - self.label = '' - self._balance = 0.0 - self._coming = 0.0 - self.link_id = '' - - @property - def balance(self): - return self._balance - - @balance.setter - def balance(self, value): - self._balance = float(value) - - @property - def coming(self): - return self._coming - - @coming.setter - def coming(self, value): - self._coming = float(value) + self.add_field('label', (str,unicode)) + self.add_field('balance', float) + self.add_field('coming', float) + self.add_field('link_id', (str,unicode)) def __repr__(self): return u"" % (self.id, self.label) class Operation(CapBaseObject): - FIELDS = ('date', 'label', 'amount') def __init__(self, id): CapBaseObject.__init__(self, id) - self.date = None - self._label = u'' - self._amount = 0.0 + self.add_field('date', (str,unicode,datetime)) + self.add_field('label', unicode) + self.add_field('amount', float) def __repr__(self): return "" % (self.date, self.label, self.amount) - @property - def label(self): - return self._label - - @label.setter - def label(self, value): - self._label = unicode(value) - - @property - def amount(self): - return self._amount - - @amount.setter - def amount(self, value): - self._amount = float(value) - - class ICapBank(IBaseCap): def iter_accounts(self): raise NotImplementedError() @@ -103,6 +66,6 @@ class ICapBank(IBaseCap): def iter_history(self, id): raise NotImplementedError() - + def transfer(self, id_from, id_to, amount): raise NotImplementedError() diff --git a/weboob/capabilities/chat.py b/weboob/capabilities/chat.py index 60613e40..afe69f6a 100644 --- a/weboob/capabilities/chat.py +++ b/weboob/capabilities/chat.py @@ -29,14 +29,15 @@ class ChatException(Exception): class ChatMessage(CapBaseObject): - FIELDS = ('id_from', 'id_to', 'date', 'message') - def __init__(self, id_from, id_to, message, date=None): CapBaseObject.__init__(self, '%s.%s' % (id_from, id_to)) - self.id_from = id_from - self.id_to = id_to - self.message = message - self.date = datetime.datetime.utcnow() if date is None else date + self.add_field('id_from', (str,unicode), id_from) + self.add_field('id_to', (str,unicode), id_to) + self.add_field('message', (str,unicode), message) + self.add_field('date', datetime.datetime, date) + + if self.date is None: + self.date = datetime.datetime.utcnow() class ICapChat(IBaseCap): diff --git a/weboob/capabilities/contact.py b/weboob/capabilities/contact.py index 3a87c3c4..ecef9b22 100644 --- a/weboob/capabilities/contact.py +++ b/weboob/capabilities/contact.py @@ -36,11 +36,11 @@ class ProfileNode(object): class ContactPhoto(CapBaseObject): def __init__(self, name): CapBaseObject.__init__(self, name) - self.name = name #useless, but keep compatibility - self.url = u'' - self.data = '' - self.thumbnail_url = u'' - self.thumbnail_data = u'' + self.add_field('name', (str,unicode), name) + self.add_field('url', (str,unicode)) + self.add_field('data', str) + self.add_field('thumbnail_url', (str,unicode)) + self.add_field('thumbnail_data', (str,unicode)) def __iscomplete__(self): return (self.data and (not self.thumbnail_url or self.thumbnail_data)) @@ -49,11 +49,11 @@ class ContactPhoto(CapBaseObject): return self.url def __repr__(self): - return u'' % (self.name, len(self.data), len(self.thumbnail_data)) + return u'' % (self.id, + len(self.data) if self.data else 0, + len(self.thumbnail_data) if self.thumbnail_data else 0) class Contact(CapBaseObject): - FIELDS = ('name', 'status', 'status_msg', 'summary', 'avatar', 'photos', 'profile') - STATUS_ONLINE = 0x001 STATUS_AWAY = 0x002 STATUS_OFFLINE = 0x004 @@ -61,13 +61,12 @@ class Contact(CapBaseObject): def __init__(self, id, name, status): CapBaseObject.__init__(self, id) - self.name = name - self.status = status - self.status_msg = NotLoaded - self.summary = NotLoaded - self.avatar = NotLoaded - self.photos = OrderedDict() - self.profile = NotLoaded + self.add_field('name', (str,unicode), name) + self.add_field('status', int, status) + self.add_field('status_msg', (str,unicode)) + self.add_field('summary', (str,unicode)) + self.add_field('photos', dict, OrderedDict()) + self.add_field('profile', list) def set_photo(self, name, **kwargs): if not name in self.photos: diff --git a/weboob/capabilities/geolocip.py b/weboob/capabilities/geolocip.py index e8fb042c..3556a576 100644 --- a/weboob/capabilities/geolocip.py +++ b/weboob/capabilities/geolocip.py @@ -19,23 +19,23 @@ from .base import IBaseCap, CapBaseObject -__all__ = ('IpLocation', 'ICapGeolocIp') +__all__ = ['IpLocation', 'ICapGeolocIp'] + class IpLocation(CapBaseObject): - FIELDS = ('city', 'region', 'zipcode', 'country', 'lt', 'lg', 'host', 'tls', 'isp') def __init__(self, ipaddr): CapBaseObject.__init__(self, ipaddr) self.ipaddr = ipaddr - self.city = None - self.region = None - self.zipcode = None - self.country = None - self.lt = None - self.lg = None - self.host = None - self.tld = None - self.isp = None + self.add_field('city', (str,unicode)) + self.add_field('region', (str,unicode)) + self.add_field('zipcode', (str,unicode)) + self.add_field('country', (str,unicode)) + self.add_field('lt', float) + self.add_field('lg', float) + self.add_field('host', (str,unicode)) + self.add_field('tld', (str,unicode)) + self.add_field('isp', (str,unicode)) class ICapGeolocIp(IBaseCap): def get_location(self, ipaddr): diff --git a/weboob/capabilities/messages.py b/weboob/capabilities/messages.py index 8e3de899..aad9a59e 100644 --- a/weboob/capabilities/messages.py +++ b/weboob/capabilities/messages.py @@ -31,8 +31,6 @@ class Message(CapBaseObject): IS_ACCUSED = 0x004 # The receiver has read this message IS_NOT_ACCUSED = 0x008 # The receiver has not read this message - FIELDS = ('thread', 'title', 'sender', 'receiver', 'date', 'parent', 'content', 'signature', 'children', 'flags') - def __init__(self, thread, id, title=NotLoaded, sender=NotLoaded, @@ -44,10 +42,16 @@ class Message(CapBaseObject): children=NotLoaded, flags=0): CapBaseObject.__init__(self, id) - self.thread = thread - self.title = title - self.sender = sender - self.receiver = receiver + self.add_field('thread', Thread, thread) + self.add_field('title', (str,unicode), title) + self.add_field('sender', (str,unicode), sender) + self.add_field('receiver', (str,unicode), receiver) + self.add_field('date', datetime.datetime, date) + self.add_field('parent', Message, parent) + self.add_field('content', (str,unicode), content) + self.add_field('signature', (str,unicode), signature) + self.add_field('children', list, children) + self.add_field('flags', int, flags) if date is None: date = datetime.datetime.utcnow() @@ -59,11 +63,6 @@ class Message(CapBaseObject): self.parent = NotLoaded self._parent_id = parent - self.content = content - self.signature = signature - self.children = children - self.flags = flags - @property def date_int(self): return int(time.strftime('%Y%m%d%H%M%S', self.date.timetuple())) @@ -92,15 +91,13 @@ class Message(CapBaseObject): return result.encode('utf-8') class Thread(CapBaseObject): - FIELDS = ('root', 'title', 'date', 'nb_messages', 'nb_unread') - def __init__(self, id): CapBaseObject.__init__(self, id) - self.root = NotLoaded - self.title = NotLoaded - self.date = NotLoaded - self.nb_messages = NotLoaded - self.nb_unread = NotLoaded + self.add_field('root', Message) + self.add_field('title', (str,unicode)) + self.add_field('date', datetime.datetime) + self.add_field('nb_messages', int) + self.add_field('nb_unread', int) def iter_all_messages(self): if self.root: diff --git a/weboob/capabilities/radio.py b/weboob/capabilities/radio.py index 8e3c2af1..2a172408 100644 --- a/weboob/capabilities/radio.py +++ b/weboob/capabilities/radio.py @@ -16,19 +16,17 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -from .base import IBaseCap, NotLoaded, CapBaseObject +from .base import IBaseCap, CapBaseObject __all__ = ['Emission', 'Stream', 'Radio', 'ICapRadio'] class Emission(CapBaseObject): - FIELDS = ('artist', 'title') - def __init__(self, id): CapBaseObject.__init__(self, id) - self.artist = NotLoaded - self.title = NotLoaded + self.add_field('artist', unicode) + self.add_field('title', unicode) def __iscomplete__(self): # This volatile information may be reloaded everytimes. @@ -38,12 +36,10 @@ class Emission(CapBaseObject): return u'%s - %s' % (self.artist, self.title) class Stream(CapBaseObject): - FIELDS = ('title', 'url') - def __init__(self, id): CapBaseObject.__init__(self, id) - self.title = NotLoaded - self.url = NotLoaded + self.add_field('title', unicode) + self.add_field('url', unicode) def __unicode__(self): return u'%s (%s)' % (self.title, self.url) @@ -52,14 +48,12 @@ class Stream(CapBaseObject): return self.__unicode__() class Radio(CapBaseObject): - FIELDS = ('title', 'description', 'current', 'streams') - def __init__(self, id): CapBaseObject.__init__(self, id) - self.title = NotLoaded - self.description = NotLoaded - self.streams = NotLoaded - self.current = NotLoaded + self.add_field('title', unicode) + self.add_field('description', unicode) + self.add_field('current', Emission) + self.add_field('streams', list) class ICapRadio(IBaseCap): def iter_radios(self): diff --git a/weboob/capabilities/torrent.py b/weboob/capabilities/torrent.py index 754117db..ddd49ee2 100644 --- a/weboob/capabilities/torrent.py +++ b/weboob/capabilities/torrent.py @@ -15,6 +15,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +from datetime import datetime from .base import IBaseCap, CapBaseObject, NotLoaded @@ -23,21 +24,18 @@ __all__ = ['ICapTorrent', 'Torrent'] class Torrent(CapBaseObject): - FIELDS = ('name', 'size', 'date', 'url', 'seeders', 'leechers', 'files', 'description') - def __init__(self, id, name, date=NotLoaded, size=NotLoaded, url=NotLoaded, seeders=NotLoaded, leechers=NotLoaded, files=NotLoaded, description=NotLoaded): CapBaseObject.__init__(self, id) - self.name = name - self.date = date - self.size = size - self.url = url - self.seeders = seeders - self.leechers = leechers - self.files = files - self.description = description - + self.add_field('name', (str,unicode), name) + self.add_field('size', (int,long,float), size) + self.add_field('date', datetime, date) + self.add_field('url', (str,unicode), url) + self.add_field('seeders', int, seeders) + self.add_field('leechers', int, leechers) + self.add_field('files', list, files) + self.add_field('description', (str,unicode), description) class ICapTorrent(IBaseCap): def iter_torrents(self, pattern): diff --git a/weboob/capabilities/travel.py b/weboob/capabilities/travel.py index 9cbaf947..1627710b 100644 --- a/weboob/capabilities/travel.py +++ b/weboob/capabilities/travel.py @@ -16,7 +16,7 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -from datetime import time +from datetime import time, datetime from .base import IBaseCap, CapBaseObject @@ -24,6 +24,31 @@ from .base import IBaseCap, CapBaseObject __all__ = ['Departure', 'ICapTravel', 'Station'] +class Station(CapBaseObject): + def __init__(self, id, name): + CapBaseObject.__init__(self, id) + self.add_field('name', (str,unicode), name) + + def __repr__(self): + return "" % (self.id, self.name) + + +class Departure(CapBaseObject): + def __init__(self, id, _type, _time): + CapBaseObject.__init__(self, id) + + self.add_field('type', (str,unicode), _type) + self.add_field('time', datetime, _time) + self.add_field('departure_station', (str,unicode)) + self.add_field('arrival_station', (str,unicode)) + self.add_field('late', time, time()) + self.add_field('information', (str,unicode)) + self.add_field('plateform', (str,unicode)) + + def __repr__(self): + return u"" % ( + self.id, self.type, self.time.strftime('%H:%M'), self.departure_station, self.arrival_station) + class ICapTravel(IBaseCap): def iter_station_search(self, pattern): """ @@ -43,33 +68,3 @@ class ICapTravel(IBaseCap): @return [iter] result of Departure objects """ raise NotImplementedError() - - -class Station(CapBaseObject): - FIELDS = ('name',) - - def __init__(self, id, name): - CapBaseObject.__init__(self, id) - self.name = name - - def __repr__(self): - return "" % (self.id, self.name) - - -class Departure(CapBaseObject): - FIELDS = ('type', 'time', 'departure_station', 'arrival_station', 'late', 'information', 'plateform') - - def __init__(self, id, _type, _time): - CapBaseObject.__init__(self, id) - - self.type = _type - self.time = _time - self.departure_station = u'' - self.arrival_station = u'' - self.late = time() - self.information = u'' - self.plateform = u'' - - def __repr__(self): - return u"" % ( - self.id, self.type, self.time.strftime('%H:%M'), self.departure_station, self.arrival_station) diff --git a/weboob/capabilities/video.py b/weboob/capabilities/video.py index f092c4d9..f6ee0e36 100644 --- a/weboob/capabilities/video.py +++ b/weboob/capabilities/video.py @@ -16,7 +16,9 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -from .base import IBaseCap, NotLoaded, CapBaseObject +from datetime import datetime, timedelta + +from .base import IBaseCap, CapBaseObject, NotLoaded __all__ = ['BaseVideo', 'ICapVideo'] @@ -25,8 +27,8 @@ __all__ = ['BaseVideo', 'ICapVideo'] class VideoThumbnail(CapBaseObject): def __init__(self, url): CapBaseObject.__init__(self, url) - self.url = url.replace(' ', '%20') - self.data = NotLoaded + self.add_field('url', (unicode,str), url.replace(' ', '%20')) + self.add_field('data', str) def __str__(self): return self.url @@ -39,22 +41,23 @@ class VideoThumbnail(CapBaseObject): class BaseVideo(CapBaseObject): - FIELDS = ('title', 'url', 'author', 'duration', 'date', 'rating', 'rating_max', 'thumbnail', 'nsfw') - def __init__(self, _id, title=NotLoaded, url=NotLoaded, author=NotLoaded, duration=NotLoaded, date=NotLoaded, rating=NotLoaded, rating_max=NotLoaded, thumbnail=NotLoaded, thumbnail_url=None, nsfw=False): CapBaseObject.__init__(self, unicode(_id)) - self.title = title - self.url = url - self.author = author - self.duration = duration - self.date = date - self.rating = rating - self.rating_max = rating_max - self.thumbnail = thumbnail + + self.add_field('title', (str,unicode), title) + self.add_field('url', (str,unicode), url) + self.add_field('author', (str,unicode), author) + self.add_field('duration', (int,long,timedelta), duration) + self.add_field('date', datetime, date) + self.add_field('rating', (int,long,float), rating) + self.add_field('rating_max', (int,long,float), rating_max) + self.add_field('thumbnail', VideoThumbnail, thumbnail) + self.add_field('nsfw', bool, nsfw) + + # XXX remove this and fix all backends if thumbnail_url is not None and self.thumbnail is NotLoaded: self.thumbnail = VideoThumbnail(thumbnail_url) - self.nsfw = nsfw @classmethod def id2url(cls, _id):