[\d]+)/?.*', url)
- if m:
- video = GDCVaultVideo(int(m.group(1)))
- else:
- raise BrowserUnavailable('Cannot find ID on page with redirection')
- video.url = redir_url
- video.set_empty_fields(NotAvailable)
- # best effort for now
- return video
-
- self.location(url)
- # redirects to /login means the video is not public
- if not self.is_on_page(VideoPage):
- raise BrowserUnavailable('Requires account')
- return self.page.get_video(video)
-
- def search_videos(self, pattern, sortby):
- post_data = {"firstfocus" : "",
- "category" : "free",
- "keyword" : pattern.encode('utf-8'),
- "conference_id" : "", }
- post_data = urlencode(post_data)
- # probably not required
- self.addheaders = [('Referer', 'http://gdcvault.com/'),
- ("Content-Type" , 'application/x-www-form-urlencoded') ]
-
- # is_logged assumes html page
- self.location('http://gdcvault.com/search.php',
- data=post_data, no_login=True)
-
- assert self.is_on_page(SearchPage)
- return self.page.iter_videos()
-
- def latest_videos(self):
- #self.home()
- self.location('/free')
- assert self.is_on_page(IndexPage)
- return self.page.iter_videos()
diff --git a/modules/gdcvault/favicon.png b/modules/gdcvault/favicon.png
deleted file mode 100644
index 70ef33e20bb41c825a43e51a42a0cdfc8c89dd36..0000000000000000000000000000000000000000
Binary files a/modules/gdcvault/favicon.png and /dev/null differ
diff --git a/modules/gdcvault/favicon.xcf b/modules/gdcvault/favicon.xcf
deleted file mode 100644
index 32695aaa5cfdb5863c913b5e077dbbc5859cf43d..0000000000000000000000000000000000000000
Binary files a/modules/gdcvault/favicon.xcf and /dev/null differ
diff --git a/modules/gdcvault/module.py b/modules/gdcvault/module.py
deleted file mode 100644
index 97b639d0fc7b90bb88718fe0aef0cd28e425e29a..0000000000000000000000000000000000000000
--- a/modules/gdcvault/module.py
+++ /dev/null
@@ -1,99 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2010-2011 Romain Bignon
-# Copyright(C) 2012 François Revol
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from weboob.capabilities.video import CapVideo, BaseVideo
-from weboob.tools.backend import Module, BackendConfig
-from weboob.capabilities.collection import CapCollection, CollectionNotFound
-from weboob.tools.value import Value, ValueBackendPassword
-
-from .browser import GDCVaultBrowser
-from .video import GDCVaultVideo
-
-
-__all__ = ['GDCVaultModule']
-
-
-class GDCVaultModule(Module, CapVideo, CapCollection):
- NAME = 'gdcvault'
- MAINTAINER = u'François Revol'
- EMAIL = 'revol@free.fr'
- VERSION = '1.4'
- DESCRIPTION = 'Game Developers Conferences Vault video streaming website'
- LICENSE = 'AGPLv3+'
- BROWSER = GDCVaultBrowser
- CONFIG = BackendConfig(Value('username', label='Username', default=''),
- ValueBackendPassword('password', label='Password', default=''))
-
- def create_default_browser(self):
- username = self.config['username'].get()
- if len(username) > 0:
- password = self.config['password'].get()
- else:
- password = None
- return self.create_browser(username, password)
-
- def deinit(self):
- # don't need to logout if the browser hasn't been used.
- if not self._browser:
- return
-
- with self.browser:
- self.browser.close_session()
-
- def get_video(self, _id):
- with self.browser:
- return self.browser.get_video(_id)
-
- SORTBY = ['relevance', 'rating', 'views', 'time']
-
- def search_videos(self, pattern, sortby=CapVideo.SEARCH_RELEVANCE, nsfw=False):
- with self.browser:
- return self.browser.search_videos(pattern, self.SORTBY[sortby])
-
- def fill_video(self, video, fields):
- if fields != ['thumbnail']:
- # if we don't want only the thumbnail, we probably want also every fields
- with self.browser:
- video = self.browser.get_video(GDCVaultVideo.id2url(video.id), video)
- if 'thumbnail' in fields and video.thumbnail:
- with self.browser:
- video.thumbnail.data = self.browser.readurl(video.thumbnail.url)
-
- return video
-
- def iter_resources(self, objs, split_path):
- if BaseVideo in objs:
- collection = self.get_collection(objs, split_path)
- if collection.path_level == 0:
- yield self.get_collection(objs, [u'latest'])
- if collection.split_path == [u'latest']:
- for video in self.browser.latest_videos():
- yield video
-
- def validate_collection(self, objs, collection):
- if collection.path_level == 0:
- return
- if BaseVideo in objs and collection.split_path == [u'latest']:
- collection.title = u'Latest GDCVault videos'
- return
- raise CollectionNotFound(collection.split_path)
-
- OBJECTS = {GDCVaultVideo: fill_video}
diff --git a/modules/gdcvault/pages.py b/modules/gdcvault/pages.py
deleted file mode 100644
index c9ee873a8e1dc3c8cfed5d6957b3d85b4f17c47b..0000000000000000000000000000000000000000
--- a/modules/gdcvault/pages.py
+++ /dev/null
@@ -1,367 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2010-2011 Romain Bignon
-# Copyright(C) 2012 François Revol
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from weboob.deprecated.browser import Page
-from weboob.tools.compat import quote
-
-import re
-import datetime
-from dateutil.parser import parse as parse_dt
-
-from weboob.capabilities.base import NotAvailable
-from weboob.capabilities.image import Thumbnail
-from weboob.deprecated.browser import BrokenPageError
-
-#HACK
-from urllib2 import HTTPError
-
-from .video import GDCVaultVideo
-
-#import lxml.etree
-
-# TODO: check title on 1439
-
-
-class IndexPage(Page):
- def iter_videos(self):
- for a in self.parser.select(self.document.getroot(), 'section.conference ul.media_items li.featured a.session_item'):
- href = a.attrib.get('href', '')
- # print href
- m = re.match('/play/(\d+)/.*', href)
- if not m:
- continue
- # print m.group(1)
- video = GDCVaultVideo(m.group(1))
-
- # get title
- try:
- video.title = unicode(self.parser.select(a, 'div.conference_info p strong', 1).text)
- except IndexError:
- video.title = NotAvailable
-
- # get description
- try:
- video.description = unicode(self.parser.select(a, 'div.conference_info p', 1).text)
- except IndexError:
- video.description = NotAvailable
-
- # get thumbnail
- img = self.parser.select(a, 'div.featured_image img', 1)
- if img is not None:
- video.thumbnail = Thumbnail(img.attrib['src'])
- video.thumbnail.url = video.thumbnail.id
- else:
- video.thumbnail = NotAvailable
-
- #m = re.match('id-(\d+)', a.attrib.get('class', ''))
- #if not m:
- # continue
- # FIXME
- yield video
-
-# the search page class uses a JSON parser,
-# since it's what search.php returns when POSTed (from Ajax)
-
-
-class SearchPage(Page):
- def iter_videos(self):
- if self.document is None or self.document['data'] is None:
- raise BrokenPageError('Unable to find JSON data')
- for data in self.document['data']:
- video = GDCVaultVideo.get_video_from_json(data)
- # TODO: split type 4 videos into id and id#slides
- if video is None:
- continue
- yield video
-
-
-class VideoPage(Page):
- def get_video(self, video=None):
- # check for slides id variant
- want_slides = False
- m = re.match('.*#slides', self.url)
- if m:
- want_slides = True
- # not sure it's safe
- self.group_dict['id'] += '#slides'
-
- if video is None:
- video = GDCVaultVideo(self.group_dict['id'])
-
- # the config file has it too, but in CDATA and only for type 4
- obj = self.parser.select(self.document.getroot(), 'title')
- title = None
- if len(obj) > 0:
- try:
- title = unicode(obj[0].text)
- except UnicodeDecodeError as e:
- title = None
-
- if title is None:
- obj = self.parser.select(self.document.getroot(), 'meta[name=title]')
- if len(obj) > 0:
- if 'content' in obj[0].attrib:
- try:
- # FIXME: 1013483 has buggus title (latin1)
- # for now we just pass it as-is
- title = obj[0].attrib['content']
- except UnicodeDecodeError as e:
- # XXX: this doesn't even works!?
- title = obj[0].attrib['content'].decode('iso-5589-15')
-
- if title is not None:
- title = title.strip()
- m = re.match('GDC Vault\s+-\s+(.*)', title)
- if m:
- title = m.group(1)
- video.title = title
-
- #TODO: POST back the title to /search.php and filter == id to get
- # cleaner (JSON) data... (though it'd be much slower)
-
- # try to find an iframe (type 3 and 4)
- obj = self.parser.select(self.document.getroot(), 'iframe')
- if len(obj) == 0:
- # type 1 or 2 (swf+js)
- # find which script element contains the swf args
- for script in self.parser.select(self.document.getroot(), 'script'):
- m = re.match(".*new SWFObject.*addVariable\('type', '(.*)'\).*", unicode(script.text), re.DOTALL)
- if m:
- video.ext = m.group(1)
-
- m = re.match(".*new SWFObject.*addVariable\(\"file\", encodeURIComponent\(\"(.*)\"\)\).*", unicode(script.text), re.DOTALL)
- if m:
- video.url = "http://gdcvault.com%s" % (m.group(1))
- # TODO: for non-free (like 769),
- # must be logged to use /mediaProxy.php
-
- # FIXME: doesn't seem to work yet, we get 2 bytes as html
- # 769 should give:
- # http://twvideo01.ubm-us.net/o1/gdcradio-net/2007/gdc/GDC07-4889.mp3
- # HACK: we use mechanize directly here for now... FIXME
- #print "asking for redirect on '%s'" % (video.url)
- #self.browser.addheaders += [['Referer', 'http://gdcvault.com/play/%s' % self.group_dict['id']]]
- #print self.browser.addheaders
- self.browser.set_handle_redirect(False)
- try:
- self.browser.open_novisit(video.url)
- # headers = req.info()
- # if headers.get('Content-Type', '') == 'text/html' and headers.get('Content-Length', '') == '2':
- # print 'BUG'
-
- #print req.code
- except HTTPError as e:
- #print e.getcode()
- if e.getcode() == 302 and hasattr(e, 'hdrs'):
- #print e.hdrs['Location']
- video.url = unicode(e.hdrs['Location'])
- self.browser.set_handle_redirect(True)
-
- video.set_empty_fields(NotAvailable)
- return video
-
- #XXX: raise error?
- return None
-
- obj = obj[0]
- if obj is None:
- return None
- # type 3 or 4 (iframe)
- # get the config file for the rest
- iframe_url = obj.attrib['src']
-
- # 1015020 has a boggus url
- m = re.match('http:/event(.+)', iframe_url)
- if m:
- iframe_url = 'http://event' + m.group(1)
-
- # print iframe_url
- # 1013798 has player169.html
- # 1012186 has player16x9.html
- # some other have /somethingplayer.html...
- # 1441 has a space in the xml filename, which we must not strip
- m = re.match('(http:.*/)[^/]*player[0-9a-z]*\.html\?.*xmlURL=([^&]+\.xml).*\&token=([^& ]+)', iframe_url)
-
- if not m:
- m = re.match('/play/mediaProxy\.php\?sid=(\d+)', iframe_url)
- if m is None:
- return None
- # TODO: must be logged to use /mediaProxy.php
- # type 3 (pdf slides)
- video.ext = u'pdf'
- video.url = "http://gdcvault.com%s" % (unicode(iframe_url))
-
- # HACK: we use mechanize directly here for now... FIXME
- # print "asking for redirect on '%s'" % (video.url)
- self.browser.set_handle_redirect(False)
- try:
- self.browser.open_novisit(video.url)
- except HTTPError as e:
- if e.getcode() == 302 and hasattr(e, 'hdrs'):
- video.url = unicode(e.hdrs['Location'])
- self.browser.set_handle_redirect(True)
-
- video.set_empty_fields(NotAvailable)
- return video
-
- # type 4 (dual screen video)
-
- # token doesn't actually seem required
- # 1441 has a space in the xml filename
- xml_filename = quote(m.group(2))
- config_url = m.group(1) + xml_filename + '?token=' + m.group(3)
-
- # self.browser.addheaders += [['Referer', 'http://gdcvault.com/play/%s' % self.group_dict['id']]]
- # print self.browser.addheaders
- # TODO: fix for 1015021 & others (forbidden)
- #config = self.browser.openurl(config_url).read()
- config = self.browser.get_document(self.browser.openurl(config_url))
-
- obj = self.parser.select(config.getroot(), 'akamaihost', 1)
- host = obj.text
- if host is None:
- raise BrokenPageError('Missing tag in xml config file')
-
- if host == "smil":
- # the rtmp URL is described in a smil file,
- # with several available bitrates
- obj = self.parser.select(config.getroot(), 'speakervideo', 1)
- smil = self.browser.get_document(self.browser.openurl(obj.text))
- obj = self.parser.select(smil.getroot(), 'meta', 1)
- # TODO: error checking
- base = obj.attrib.get('base', '')
- best_bitrate = 0
- path = None
- obj = self.parser.select(smil.getroot(), 'video')
- # choose the best bitrate
- for o in obj:
- rate = int(o.attrib.get('system-bitrate', 0))
- if rate > best_bitrate:
- path = o.attrib.get('src', '')
- video.url = unicode(base + '/' + path)
-
- else:
- # not smil, the rtmp url is directly here as host + path
- # for id 1373 host is missing '/ondemand'
- # only add it when only a domain is specified without path
- m = re.match('^[^\/]+$', host)
- if m:
- host += "/ondemand"
-
- videos = {}
-
- obj = self.parser.select(config.getroot(), 'speakervideo', 1)
- if obj.text is not None:
- videos['speaker'] = 'rtmp://' + host + '/' + quote(obj.text)
-
- obj = self.parser.select(config.getroot(), 'slidevideo', 1)
- if obj.text is not None:
- videos['slides'] = 'rtmp://' + host + '/' + quote(obj.text)
-
- # print videos
- # XXX
- if 'speaker' in videos:
- video.url = unicode(videos['speaker'])
- elif 'slides' in videos:
- # 1016627 only has slides, so fallback to them
- video.url = unicode(videos['slides'])
-
- if want_slides:
- if 'slides' in videos:
- video.url = unicode(videos['slides'])
- # if video.url is none: raise ? XXX
-
- obj = self.parser.select(config.getroot(), 'date', 1)
- if obj.text is not None:
- # 1016634 has "Invalid Date"
- try:
- video.date = parse_dt(obj.text)
- except ValueError as e:
- video.date = NotAvailable
-
- obj = self.parser.select(config.getroot(), 'duration', 1)
- m = re.match('(\d\d):(\d\d):(\d\d)', obj.text)
- if m:
- video.duration = datetime.timedelta(hours = int(m.group(1)),
- minutes = int(m.group(2)),
- seconds = int(m.group(3)))
-
- obj = self.parser.select(config.getroot(), 'speaker', 1)
- #print obj.text_content()
-
- #self.set_details(video)
-
- video.set_empty_fields(NotAvailable)
- return video
-
- obj = self.parser.select(self.document.getroot(), 'title')
- if len(obj) < 1:
- return None
- title = obj[0].text.strip()
- m = re.match('GDC Vault\s+-\s+(.*)', title)
- if m:
- title = m.group(1)
-
- def set_details(self, v):
- obj = self.parser.select(self.document.getroot(), 'meta[name=available]', 1)
- if obj is not None:
- value = obj.attrib['content']
- m = re.match('(\d\d)-(\d\d)-(\d\d\d\d)\s*(\d\d):(\d\d)', value)
- if not m:
- raise BrokenPageError('Unable to parse datetime: %r' % value)
- day = m.group(1)
- month = m.group(2)
- year = m.group(3)
- hour = m.group(4)
- minute = m.group(5)
- v.date = datetime.datetime(year=int(year),
- month=int(month),
- day=int(day),
- hour=int(hour),
- minute=int(minute))
-
- obj = self.parser.select(self.document.getroot(), 'span.ep_subtitle', 1)
- if obj is not None:
- span = self.parser.select(obj, 'span.ep_date', 1)
- value = span.text
- m = re.match('(\d\d):(\d\d)\s*\/\s*(\d\d):(\d\d)\s*-\s*(\d\d)-(\d\d)-(\d\d\d\d)', value)
- if not m:
- raise BrokenPageError('Unable to parse datetime: %r' % value)
- bhour = m.group(1)
- bminute = m.group(2)
- ehour = m.group(3)
- eminute = m.group(4)
- day = m.group(5)
- month = m.group(6)
- year = m.group(7)
-
- start = datetime.datetime(year=int(year),
- month=int(month),
- day=int(day),
- hour=int(bhour),
- minute=int(bminute))
- end = datetime.datetime(year=int(year),
- month=int(month),
- day=int(day),
- hour=int(ehour),
- minute=int(eminute))
-
- v.duration = end - start
diff --git a/modules/gdcvault/test.py b/modules/gdcvault/test.py
deleted file mode 100644
index 68125d8d86e41cbb282356359c0abac1de44b235..0000000000000000000000000000000000000000
--- a/modules/gdcvault/test.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2010-2011 Romain Bignon
-# Copyright(C) 2012 François Revol
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from weboob.tools.test import BackendTest
-#from weboob.capabilities.video import BaseVideo
-
-
-class GDCVaultTest(BackendTest):
- MODULE = 'gdcvault'
-
- # def test_search(self):
- # l = list(self.backend.search_videos('linux'))
- # self.assertTrue(len(l) > 0)
- # v = l[0]
- # self.backend.fillobj(v, ('url',))
- # self.assertTrue(v.url and v.url.startswith('http://'), 'URL for video "%s" not found: %s' % (v.id, v.url))
- # self.backend.browser.openurl(v.url)
-
- # def test_latest(self):
- # l = list(self.backend.iter_resources([BaseVideo], [u'latest']))
- # self.assertTrue(len(l) > 0)
- # v = l[0]
- # self.backend.fillobj(v, ('url',))
- # self.assertTrue(v.url and v.url.startswith('http://'), 'URL for video "%s" not found: %s' % (v.id, v.url))
diff --git a/modules/gdcvault/video.py b/modules/gdcvault/video.py
deleted file mode 100644
index 08d90a79c8a248d1fe01f2d927a4141bef97522c..0000000000000000000000000000000000000000
--- a/modules/gdcvault/video.py
+++ /dev/null
@@ -1,92 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2010-2011 Roger Philibert
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from weboob.capabilities.image import Thumbnail
-from weboob.capabilities.video import BaseVideo
-from weboob.capabilities.base import NotAvailable
-
-import re
-from dateutil.parser import parse as parse_dt
-
-
-class GDCVaultVideo(BaseVideo):
- def __init__(self, *args, **kwargs):
- BaseVideo.__init__(self, *args, **kwargs)
- # not always flv...
- self.ext = NotAvailable
-
- @classmethod
- def id2url(cls, _id):
- # attempt to enlarge the id namespace to differentiate
- # videos from the same page
- m = re.match('\d+#speaker', _id)
- if m:
- return u'http://www.gdcvault.com/play/%s#speaker' % _id
- m = re.match('\d+#slides', _id)
- if m:
- return u'http://www.gdcvault.com/play/%s#slides' % _id
- return u'http://www.gdcvault.com/play/%s' % _id
-
- @classmethod
- def get_video_from_json(self, data):
- # session_id is unique per talk
- # vault_media_id is unique per page
- # (but can refer to 2 video files for dual screen)
- # solr_id is "${vault_media_id}.${conference_id}.${session_id}.$vault_media_type_id{}"
-
- # XXX: do we filter them or let people know about them?
- #if 'anchor' in data:
- # if data['anchor']['href'] == '#':
- # # file will not be accessible (not free and not logged in)
- # return None
-
- if 'vault_media_id' not in data:
- return None
- media_id = int(data['vault_media_id'])
- video = GDCVaultVideo(media_id)
-
- # 1013679 has \n in title...
- video.title = unicode(data.get('session_name', '').replace('\n', ''))
-
- # TODO: strip out ,
and other html...
- # XXX: 1013422 has all 3 and !=
- if 'overview' in data:
- video.description = unicode(data['overview'])
- elif 'spell' in data:
- video.description = unicode(data['spell'])
- else:
- video.description = unicode(data.get('description', ''))
-
- if 'image' in data:
- video.thumbnail = Thumbnail(data['image'])
- video.thumbnail.url = video.thumbnail.id
-
- if 'speakers_name' in data:
- video.author = unicode(", ".join(data['speakers_name']))
-
- if 'start_date' in data:
- video.date = parse_dt(data['start_date'])
-
- if 'score' in data:
- video.rating = data['score']
-
- video.set_empty_fields(NotAvailable)
-
- return video
diff --git a/modules/gdfsuez/__init__.py b/modules/gdfsuez/__init__.py
deleted file mode 100644
index d16ad8608eaf02ee32bf652384b570880002332b..0000000000000000000000000000000000000000
--- a/modules/gdfsuez/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from .module import GdfSuezModule
-
-__all__ = ['GdfSuezModule']
diff --git a/modules/gdfsuez/browser.py b/modules/gdfsuez/browser.py
deleted file mode 100644
index 713a648124df31d4e8a676bfae2b3a8675b2ccf4..0000000000000000000000000000000000000000
--- a/modules/gdfsuez/browser.py
+++ /dev/null
@@ -1,99 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2013 Mathieu Jourdan
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-import StringIO
-from weboob.deprecated.browser import Browser, BrowserIncorrectPassword
-from .pages import LoginPage, HomePage, AccountPage, TimeoutPage, HistoryPage, PdfPage
-
-__all__ = ['GdfSuez']
-
-
-class GdfSuez(Browser):
- PROTOCOL = 'https'
- DOMAIN = 'www.gdfsuez-dolcevita.fr'
- PAGES = {'.*portail/clients.*?_nfpb=true&_pageLabel=page_identification': LoginPage,
- '.*portail/clients.*?_nfpb=true&_pageLabel=page_accueil_compte_en_ligne': HomePage,
- '.*p/visualiser_mes_contrats.*?_nfpb=true': AccountPage,
- '.*p/page_historique_de_mes_factures': HistoryPage,
- '.*clients.*?_nfpb=true&_nfls=false&_pageLabel=page_erreur_timeout_session': TimeoutPage
- }
-
- loginp = '/portailClients/appmanager/portail/clients'
- homep = '/portailClients/appmanager/portail/clients?_nfpb=true&_pageLabel=page_accueil_compte_en_ligne'
- accountp = '/portailClients/client/p/visualiser_mes_contrats?_nfpb=true'
- historyp = '/portailClients/client/p/page_historique_de_mes_factures'
-
- def __init__(self, *args, **kwargs):
- Browser.__init__(self, *args, **kwargs)
-
- def home(self):
- self.location(self.homep)
-
- def is_logged(self):
- if self.is_on_page(LoginPage) or self.is_on_page(TimeoutPage):
- return False
- return True
-
- def login(self):
- assert isinstance(self.username, basestring)
- assert isinstance(self.password, basestring)
- #assert isemail(self.username)
- if not self.is_on_page(LoginPage):
- self.location(self.loginp)
- self.page.login(self.username, self.password)
- if self.is_on_page(LoginPage):
- raise BrowserIncorrectPassword()
-
- def get_subscription_list(self):
- if not self.is_on_page(AccountPage):
- self.location(self.accountp)
- return self.page.get_subscription_list()
-
- def get_subscription(self, id):
- assert isinstance(id, basestring)
- for sub in self.get_subscription_list():
- if sub.id == id:
- return sub
-
- def get_history(self, subscription):
- if not self.is_on_page(HistoryPage):
- self.location(self.historyp)
- return self.page.get_history()
-
- def get_details(self, subscription):
- bills = self.iter_documents()
- id = bills[0].id
- if not self.is_on_page(HistoryPage):
- self.location(self.historyp)
- url = 'https://www.gdfsuez-dolcevita.fr/' + self.get_document(id).url
- response = self.openurl(url)
- pdf = PdfPage(StringIO.StringIO(response.read()))
- for detail in pdf.get_details(subscription.label):
- yield detail
-
- def iter_documents(self):
- if not self.is_on_page(HistoryPage):
- self.location(self.historyp)
- return self.page.get_documents()
-
- def get_document(self, id):
- assert isinstance(id, basestring)
- for b in self.iter_documents():
- if b.id == id:
- return b
diff --git a/modules/gdfsuez/favicon.png b/modules/gdfsuez/favicon.png
deleted file mode 100644
index 0222cea313f76834a03037fa0c69d87970a3a6c5..0000000000000000000000000000000000000000
Binary files a/modules/gdfsuez/favicon.png and /dev/null differ
diff --git a/modules/gdfsuez/module.py b/modules/gdfsuez/module.py
deleted file mode 100644
index 6e43d4a7864a62974f80fe0b547e99a351ca65b1..0000000000000000000000000000000000000000
--- a/modules/gdfsuez/module.py
+++ /dev/null
@@ -1,96 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2013 Mathieu Jourdan
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-from weboob.capabilities.bill import CapDocument, SubscriptionNotFound,\
- DocumentNotFound, Subscription, Bill
-from weboob.tools.backend import Module, BackendConfig
-from weboob.tools.value import ValueBackendPassword
-from .browser import GdfSuez
-
-__all__ = ['GdfSuezModule']
-
-
-class GdfSuezModule(Module, CapDocument):
- NAME = 'gdfsuez'
- MAINTAINER = u'Mathieu Jourdan'
- EMAIL = 'mathieu.jourdan@gresille.org'
- VERSION = '1.4'
- LICENSE = 'AGPLv3+'
- DESCRIPTION = u'GDF-Suez French energy provider'
- CONFIG = BackendConfig(ValueBackendPassword('login',
- label='Account ID (e-mail)',
- masked=False),
- ValueBackendPassword('password',
- label='Password',
- masked=True)
- )
- BROWSER = GdfSuez
-
- def create_default_browser(self):
- return self.create_browser(self.config['login'].get(),
- self.config['password'].get())
-
- def iter_subscription(self):
- for subscription in self.browser.get_subscription_list():
- yield subscription
-
- def get_subscription(self, _id):
- if not _id.isdigit():
- raise SubscriptionNotFound()
- with self.browser:
- subscription = self.browser.get_subscription(_id)
- if not subscription:
- raise SubscriptionNotFound()
- else:
- return subscription
-
- def iter_documents_history(self, subscription):
- if not isinstance(subscription, Subscription):
- subscription = self.get_subscription(subscription)
- with self.browser:
- for history in self.browser.get_history(subscription):
- yield history
-
- def get_details(self, subscription):
- if not isinstance(subscription, Subscription):
- subscription = self.get_subscription(subscription)
- with self.browser:
- for detail in self.browser.get_details(subscription):
- yield detail
-
- def iter_documents(self, subscription):
- if not isinstance(subscription, Subscription):
- subscription = self.get_subscription(subscription)
- with self.browser:
- for bill in self.browser.iter_documents():
- yield bill
-
- def get_document(self, id):
- with self.browser:
- bill = self.browser.get_document(id)
- if not bill:
- raise DocumentNotFound()
- else:
- return bill
-
- def download_document(self, bill):
- if not isinstance(bill, Bill):
- bill = self.get_document(bill)
- with self.browser:
- return self.browser.readurl(bill.url)
diff --git a/modules/gdfsuez/pages/__init__.py b/modules/gdfsuez/pages/__init__.py
deleted file mode 100644
index f77d26906cd4dbe0712774b44517dd5c5f852a29..0000000000000000000000000000000000000000
--- a/modules/gdfsuez/pages/__init__.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2013 Mathieu Jourdan
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-from .history import HistoryPage, PdfPage
-from .homepage import LoginPage, HomePage, AccountPage, TimeoutPage
-
-__all__ = ['LoginPage', 'HomePage', 'AccountPage', 'HistoryPage', 'PdfPage', 'TimeoutPage']
diff --git a/modules/gdfsuez/pages/history.py b/modules/gdfsuez/pages/history.py
deleted file mode 100644
index 8a3b77f2749ddea1941b06d1fa47f54cb855ecf9..0000000000000000000000000000000000000000
--- a/modules/gdfsuez/pages/history.py
+++ /dev/null
@@ -1,211 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2013 Mathieu Jourdan
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-import re
-import os
-import subprocess
-import tempfile
-import shutil
-
-from datetime import date
-from decimal import Decimal
-
-from weboob.deprecated.browser import Page
-from weboob.capabilities.base import NotAvailable
-from weboob.capabilities.bill import Detail, Bill
-
-
-class HistoryPage(Page):
-
- def on_loaded(self):
- self.details = []
- self.bills = []
-
- # Latest bill
- div = self.document.xpath('//div[@class="consulter_dernierefacture"]')[0]
- bdate = div.xpath('p[@class="date"]/span[@class="textetertiaire"]')[0].text
- bprice = div.xpath('p[@class="montant"]/span[@class="textetertiaire"]')[0].text
- link = div.xpath('a[@id="display_popin"]')[0].attrib['href']
- mydate = date(*reversed([int(x) for x in bdate.split("/")]))
- price = Decimal(bprice.strip(u' € TTC').replace(',', '.'))
- self.bills.append(self._create_bill(mydate, price, link))
-
- # Previous bills
- table = self.document.xpath('//table[@class="afficher_factures"]')[0]
- for tr in table[0].xpath('//tbody/tr'):
- cells = tr.xpath('td')
- bdate = unicode(cells[0].text.strip())
- mydate = date(*reversed([int(x) for x in bdate.split("/")]))
- bprice = unicode(cells[1].text)
- price = Decimal(bprice.strip(u' €').replace(',', '.'))
- link = cells[3].xpath('a')[0].attrib['href']
- self.bills.append(self._create_bill(mydate, price, link))
-
- def _create_bill(self, date, price, link):
- bill = Bill()
- bill.id = date.__str__().replace('-', '')
- bill.date = date
- bill._price = price
- bill.url = unicode(link)
- bill.format = u'pdf'
- bill.type = u'bill'
- bill.label = unicode(price)
- return bill
-
- def get_details(self):
- return self.details
-
- def get_documents(self):
- return self.bills
-
-
-class PdfPage():
-
- def __init__(self, file):
- self.pdf = file
-
- def _parse_pdf(self):
- pdffile = tempfile.NamedTemporaryFile(bufsize=100000, mode='w', suffix='.pdf')
- temptxt = pdffile.name.replace('.pdf', '.txt')
- cmd = "ebook-convert"
- stdout = open("/dev/null", "w")
- shutil.copyfileobj(self.pdf, pdffile)
- pdffile.flush()
- subprocess.call([cmd, pdffile.name, temptxt], stdout=stdout)
- pdffile.close()
- txtfile = open(temptxt, 'r')
- txt = txtfile.read()
- txtfile.close()
- os.remove(temptxt)
- return txt
-
- def _parse_page(self, page):
-
- # Regexp
- footnote = re.compile(r'\([0-9]\) ') # (f)
- ht = re.compile('HT par mois')
- base = re.compile('la base de')
- enddate = re.compile('\d\d\/\d\d\/\d\d') # YY/MM/DD
- endwithdigit = re.compile('\d+$') # blah blah 42
- textwithcoma = re.compile('([a-z]|\d{4})\,') # blah 2012, blah blah
-
- # Parsing
- details = []
- for title in ['Abonnement',
- 'Consommation',
- 'Contributions et taxes liées à l\'énergie']:
- section = page.split(title, 1)[1].split('Total ')[0]
-
- # When a line holds '(0)', a newline is missing.
- section = re.sub(footnote, '\n', section)
-
- lines = section.split('\n')
- lines = [x for x in lines if len(x) > 0] # Remove empty lines
- detail = None
-
- for line in lines:
- if re.match('[A-Za-z]', line[0]):
-
- # Things we want to merge with the one just before
- if 'facturées' in line:
- # Long lines are sometimes split, so we try to join them
- # That is the case for:
- # 'Déduction du montant des consommations
- # estimées facturées du 00/00/00 au 00/00/00'
- detail.label = detail.label + u' ' + unicode(line, encoding='utf-8')
-
- # Things for which we want a new detail
- else:
- # Entering here, we will instantiate a new detail.
- # We hadn't so before because of fragmented lines.
- if detail is not None and detail.label is not NotAvailable:
- # We have a new element, return the other one
- details.append(detail)
- detail = Detail()
- detail.price = Decimal(0)
-
- # If the coma is not a decimal separator, then
- # this is is probably a loooong sentence.
- # When it comes to jokes, keep it short and sweet.
- line = re.split(textwithcoma, line)[0]
-
- # Things we want for sure
- if re.findall(enddate, line):
- # When a line has been badly split after a date,
- # We want the label to end after the date, and maybe
- # the second part to be the info
- mydate = re.search(enddate, line).group(0)
- mylist = line.rpartition(mydate)
- label = mylist[0] + mylist[1]
- detail.label = unicode(label, encoding='utf-8')
- elif re.findall(endwithdigit, line):
- # What is this stupid number at the end of the line?
- # Line should have been split before the number
- detail.label = unicode(re.split(endwithdigit, line)[0], encoding='utf-8')
- # Things we don't want for sure
- elif ')' in line and '(' not in line:
- # First part of the parenthesis should have been drop before
- # Avoid to create a new empty detail
- detail.label = NotAvailable
- elif re.match(base, line):
- # This string should come always after a date,
- # usually, it will match one of the cases above.
- # Sometimes, it appears on a new line we don't need.
- detail.label = NotAvailable
- elif re.match(ht, line):
- # '00,00 € HT par mois' may have been split after HT
- # We don't need of the second line
- detail.label = NotAvailable
- # Things we probably want to keep
- else:
- # Well, maybe our line is correct, after all.
- # Not much to do.
- detail.label = unicode(line, encoding='utf-8')
- detail.infos = NotAvailable
- elif ' %' in line:
- if isinstance(detail, Detail):
- # Sometimes the vat is not on a new line:
- # '00,00 00,0 %' instead of '00,0 %'
- vat = line.split()[line.count(' ')-1].replace(',', '.')
- detail.infos = unicode('TVA: ' + vat)
- elif ' €' in line:
- price = line.replace(',', '.')
- if isinstance(detail, Detail):
- detail.price = Decimal(price.strip(' €'))
- elif re.match(enddate, line):
- # Line holding dates may have been mixed up
- label = detail.label.split(' au ')[0] + u' au ' + unicode(line, encoding='utf-8')
- detail.label = label
- if detail.label is not NotAvailable:
- # Do not append empty details to the list
- # It seemed easier to create details anyway than dealing
- # with None objects
- details.append(detail)
- return details
-
- def get_details(self, label):
- txt = self._parse_pdf()
- page = None
- if label == u'Gaz naturel':
- page = txt.split('GAZ NATUREL')[1].split('TOTAL GAZ NATUREL TTC')[0]
- elif label == u'Electricité':
- page = txt.split('ELECTRICITE')[1].split('TOTAL ELECTRICITE TTC')[0]
- else:
- pass
- return self._parse_page(page)
diff --git a/modules/gdfsuez/pages/homepage.py b/modules/gdfsuez/pages/homepage.py
deleted file mode 100644
index 8164dbea15ed15b914257f2b11003437c9cd4b6e..0000000000000000000000000000000000000000
--- a/modules/gdfsuez/pages/homepage.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2013 Mathieu Jourdan
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-from datetime import date
-
-from weboob.deprecated.browser import Page
-from weboob.capabilities.bill import Subscription
-
-
-class LoginPage(Page):
-
- def login(self, login, password):
- self.browser.select_form('symConnexionForm')
- self.browser["portlet_login_plein_page_3{pageFlow.mForm.login}"] = unicode(login)
- self.browser["portlet_login_plein_page_3{pageFlow.mForm.password}"] = unicode(password)
- self.browser.submit()
-
-
-class HomePage(Page):
-
- def on_loaded(self):
- pass
-
-
-class AccountPage(Page):
-
- def get_subscription_list(self):
- table = self.document.xpath('//table[@id="ensemble_contrat_N0"]')[0]
- if len(table) > 0:
- # some clients may have subscriptions to gas and electricity,
- # but they receive a single bill
- # to avoid "boobill details" and "boobill bills" returning the same
- # table twice, we could return only one subscription for both.
- # We do not, and "boobill details" will take care of parsing only the
- # relevant section in the bill files.
- for line in table[0].xpath('//tbody/tr'):
- cells = line.xpath('td')
- snumber = cells[2].attrib['id'].replace('Contrat_', '')
- slabel = cells[0].xpath('a')[0].text.replace('offre', '').strip()
- d = unicode(cells[3].xpath('strong')[0].text.strip())
- sdate = date(*reversed([int(x) for x in d.split("/")]))
- sub = Subscription(snumber)
- sub._id = snumber
- sub.label = slabel
- sub.subscriber = unicode(cells[1])
- sub.renewdate = sdate
- yield sub
-
-
-class TimeoutPage(Page):
-
- def on_loaded(self):
- pass
diff --git a/modules/gdfsuez/test.py b/modules/gdfsuez/test.py
deleted file mode 100644
index 70f66fd66cf68d145c0dde6dec30313ac3865281..0000000000000000000000000000000000000000
--- a/modules/gdfsuez/test.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2013 Mathieu Jourdan
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-# This is a clone of freemobile/test.py for the gdfsuez module
-from weboob.tools.test import BackendTest
-
-
-class GdfSuezTest(BackendTest):
- MODULE = 'gdfsuez'
-
- def test_gdfsuez(self):
- for subscription in self.backend.iter_subscription():
- list(self.backend.iter_history(subscription.id))
- for bill in self.backend.iter_documents(subscription.id):
- self.backend.download_document(bill.id)
diff --git a/modules/izneo/__init__.py b/modules/izneo/__init__.py
deleted file mode 100644
index 8da0d5594ce092aefcda8c44a0effcf41fde3f39..0000000000000000000000000000000000000000
--- a/modules/izneo/__init__.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2010-2011 Roger Philibert
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-from .module import IzneoModule
-
-__all__ = ['IzneoModule']
diff --git a/modules/izneo/favicon.png b/modules/izneo/favicon.png
deleted file mode 100644
index c883a32d6046f12c582c8927179825a31cb94f4e..0000000000000000000000000000000000000000
Binary files a/modules/izneo/favicon.png and /dev/null differ
diff --git a/modules/izneo/module.py b/modules/izneo/module.py
deleted file mode 100644
index 03840bb4f5acb3d175b584fce806c8ff45c7af69..0000000000000000000000000000000000000000
--- a/modules/izneo/module.py
+++ /dev/null
@@ -1,96 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2010-2011 Roger Philibert
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-import re
-
-from weboob.capabilities.gallery import CapGallery, BaseGallery, BaseImage
-from weboob.tools.json import json
-from weboob.tools.backend import Module
-from weboob.deprecated.browser import Browser, Page
-
-__all__ = ['IzneoModule']
-
-
-class ReaderV2(Page):
- def get_ean(self):
- return self.document.xpath("//div[@id='viewer']/attribute::rel")[0]
-
- def iter_gallery_images(self, gallery):
- ean = self.get_ean()
- pages = json.load(self.browser.openurl(
- 'http://www.izneo.com/playerv2/ajax.php?ean=%s&action=get_list_jpg'
- % ean))
-
- for page in pages['list']:
- width = 1200 # maximum width
- yield BaseImage(page['page'],
- gallery=gallery,
- url=("http://www.izneo.com/playerv2/%s/%s/%s/%d/%s" %
- (page['expires'], page['token'], ean, width, page['page'])))
-
-
-class IzneoBrowser(Browser):
- PAGES = {r'http://.+\.izneo.\w+/readv2-.+': ReaderV2}
-
- def iter_gallery_images(self, gallery):
- self.location(gallery.url)
- assert self.is_on_page(ReaderV2)
- return self.page.iter_gallery_images(gallery)
-
- def fill_image(self, image, fields):
- if 'data' in fields:
- image.data = self.readurl(self.request_class(
- image.url, None, {'Referer': image.gallery.url}))
-
-
-class IzneoModule(Module, CapGallery):
- NAME = 'izneo'
- MAINTAINER = u'Roger Philibert'
- EMAIL = 'roger.philibert@gmail.com'
- VERSION = '1.4'
- DESCRIPTION = 'Izneo digital comics'
- LICENSE = 'AGPLv3+'
- BROWSER = IzneoBrowser
-
- def iter_gallery_images(self, gallery):
- with self.browser:
- return self.browser.iter_gallery_images(gallery)
-
- def get_gallery(self, _id):
- match = re.match(r'(?:(?:.+izneo.com/)?readv2-)?(\d+-\d+)/?$', _id)
- if match is None:
- return None
-
- _id = match.group(1)
-
- gallery = BaseGallery(_id, url=('http://www.izneo.com/readv2-%s' % _id))
- with self.browser:
- return gallery
-
- def fill_gallery(self, gallery, fields):
- gallery.title = gallery.id
-
- def fill_image(self, image, fields):
- with self.browser:
- self.browser.fill_image(image, fields)
-
- OBJECTS = {
- BaseGallery: fill_gallery,
- BaseImage: fill_image}
diff --git a/modules/jacquieetmichel/__init__.py b/modules/jacquieetmichel/__init__.py
deleted file mode 100644
index c2c25391a84f6bdaab9939445f34faedb66865d8..0000000000000000000000000000000000000000
--- a/modules/jacquieetmichel/__init__.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2013 Romain Bignon
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-from .module import JacquieEtMichelModule
-
-__all__ = ['JacquieEtMichelModule']
diff --git a/modules/jacquieetmichel/browser.py b/modules/jacquieetmichel/browser.py
deleted file mode 100644
index 21a379bda38f0b9b8a171037f1abc74627c828a2..0000000000000000000000000000000000000000
--- a/modules/jacquieetmichel/browser.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2013 Roger Philibert
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-from weboob.deprecated.browser import Browser
-from weboob.deprecated.browser.decorators import id2url
-from weboob.tools.compat import quote
-
-from .video import JacquieEtMichelVideo
-from .pages import VideoPage, ResultsPage
-
-
-__all__ = ['JacquieEtMichelBrowser']
-
-
-class JacquieEtMichelBrowser(Browser):
- DOMAIN = u'jacquieetmicheltv.net'
- ENCODING = None
- PAGES = {r'https?://.*jacquieetmicheltv.net/': ResultsPage,
- r'https?://.*jacquieetmicheltv.net/videolist/.*': ResultsPage,
- r'https?://.*jacquieetmicheltv.net/showvideo/(?P\d+)/.*': VideoPage,
- }
-
- @id2url(JacquieEtMichelVideo.id2url)
- def get_video(self, url, video=None):
- self.location(url)
- assert self.is_on_page(VideoPage), 'Should be on video page.'
- return self.page.get_video(video)
-
- def search_videos(self, pattern):
- self.location('/videolist/searchmodevideo/query%s/' % (quote(pattern.encode('utf-8'))))
- assert self.is_on_page(ResultsPage)
- return self.page.iter_videos()
-
- def latest_videos(self):
- self.home()
- assert self.is_on_page(ResultsPage)
- return self.page.iter_videos()
diff --git a/modules/jacquieetmichel/favicon.png b/modules/jacquieetmichel/favicon.png
deleted file mode 100644
index cb8548498dcbd0b26e12b255770a7c0a4d1ee03c..0000000000000000000000000000000000000000
Binary files a/modules/jacquieetmichel/favicon.png and /dev/null differ
diff --git a/modules/jacquieetmichel/module.py b/modules/jacquieetmichel/module.py
deleted file mode 100644
index 77823bcd4d77582f37cf985d88d1a9082d2bc97f..0000000000000000000000000000000000000000
--- a/modules/jacquieetmichel/module.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2013 Roger Philibert
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-from weboob.capabilities.video import CapVideo, BaseVideo
-from weboob.capabilities.collection import CapCollection, CollectionNotFound
-from weboob.tools.backend import Module
-
-from .browser import JacquieEtMichelBrowser
-from .video import JacquieEtMichelVideo
-
-
-__all__ = ['JacquieEtMichelModule']
-
-
-class JacquieEtMichelModule(Module, CapVideo, CapCollection):
- NAME = 'jacquieetmichel'
- MAINTAINER = u'Roger Philibert'
- EMAIL = 'roger.philibert@gmail.com'
- VERSION = '1.4'
- DESCRIPTION = 'Jacquie et Michel TV'
- LICENSE = 'AGPLv3+'
- BROWSER = JacquieEtMichelBrowser
-
- def get_video(self, _id):
- with self.browser:
- video = self.browser.get_video(_id)
- return video
-
- def search_videos(self, pattern, sortby=CapVideo.SEARCH_RELEVANCE, nsfw=False):
- if not nsfw:
- return iter([])
-
- with self.browser:
- return self.browser.search_videos(pattern)
-
- def fill_video(self, video, fields):
- if fields != ['thumbnail']:
- # if we don't want only the thumbnail, we probably want also every fields
- with self.browser:
- video = self.browser.get_video(JacquieEtMichelVideo.id2url(video.id), video)
- if 'thumbnail' in fields and video.thumbnail:
- with self.browser:
- video.thumbnail.data = self.browser.readurl(video.thumbnail.url)
-
- return video
-
- def iter_resources(self, objs, split_path):
- if BaseVideo in objs:
- collection = self.get_collection(objs, split_path)
- if collection.path_level == 0:
- yield self.get_collection(objs, [u'latest_nsfw'])
- if collection.split_path == [u'latest_nsfw']:
- for video in self.browser.latest_videos():
- yield video
-
- def validate_collection(self, objs, collection):
- if collection.path_level == 0:
- return
- if BaseVideo in objs and collection.split_path == [u'latest_nsfw']:
- collection.title = u'Latest Jacquie & Michel videos (NSFW)'
- return
- raise CollectionNotFound(collection.split_path)
-
- OBJECTS = {JacquieEtMichelVideo: fill_video}
diff --git a/modules/jacquieetmichel/pages.py b/modules/jacquieetmichel/pages.py
deleted file mode 100644
index 834395203169f56f4faf0568719989a6a847c35a..0000000000000000000000000000000000000000
--- a/modules/jacquieetmichel/pages.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2013 Roger Philibert
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-import re
-
-from weboob.capabilities.base import NotAvailable
-from weboob.capabilities.image import Thumbnail
-from weboob.deprecated.browser import Page, BrokenPageError
-from weboob.tools.misc import to_unicode
-
-from .video import JacquieEtMichelVideo
-
-
-class ResultsPage(Page):
- def iter_videos(self):
- for span in self.document.xpath('//ul[@id="list"]/li'):
- a = self.parser.select(span, 'a', 1)
- url = a.attrib['href']
- _id = re.sub(r'/showvideo/(\d+)/.*', r'\1', url)
-
- video = JacquieEtMichelVideo(_id)
-
- url = span.find('.//img').attrib['src']
- video.thumbnail = Thumbnail(url)
- video.thumbnail.url = video.thumbnail.id
-
- title_el = self.parser.select(span, 'h2', 1)
- video.title = to_unicode(title_el.text.strip())
- video.description = self.parser.tocleanstring(span.xpath('.//div[@class="desc"]')[0])
- video.set_empty_fields(NotAvailable, ('url,'))
-
- yield video
-
-
-class VideoPage(Page):
- def get_video(self, video=None):
- _id = to_unicode(self.group_dict['id'])
- if video is None:
- video = JacquieEtMichelVideo(_id)
- title_el = self.parser.select(self.document.getroot(), 'h1', 1)
- video.title = to_unicode(title_el.text.strip())
- video.description = self.document.xpath('//meta[@name="description"]')[0].attrib['content']
-
- for script in self.document.xpath('.//script'):
- if script.text is None:
- continue
- m = re.search('"(http://[^"]+.mp4)"', script.text, re.MULTILINE)
- if m:
- video.url = to_unicode(m.group(1))
- break
-
- if not video.url:
- raise BrokenPageError('Unable to find URL')
-
- video.set_empty_fields(NotAvailable)
-
- return video
diff --git a/modules/jacquieetmichel/test.py b/modules/jacquieetmichel/test.py
deleted file mode 100644
index 9e3b3ee5345e8df1f24ae718751ac8bcb6952338..0000000000000000000000000000000000000000
--- a/modules/jacquieetmichel/test.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2013 Roger Philibert
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from weboob.tools.test import BackendTest
-from weboob.capabilities.video import BaseVideo
-
-
-class JacquieEtMichelTest(BackendTest):
- MODULE = 'jacquieetmichel'
-
- def test_search(self):
- self.assertTrue(len(list(self.backend.search_videos('anus', nsfw=False))) == 0)
-
- l = list(self.backend.search_videos('anus', nsfw=True))
- self.assertTrue(len(l) > 0)
- v = l[0]
- self.backend.fillobj(v, ('url',))
- self.assertTrue(v.url and v.url.startswith('http://'), 'URL for video "%s" not found: %s' % (v.id, v.url))
- self.backend.browser.openurl(v.url)
-
- def test_latest(self):
- l = list(self.backend.iter_resources([BaseVideo], [u'latest_nsfw']))
- self.assertTrue(len(l) > 0)
- v = l[0]
- self.backend.fillobj(v, ('url',))
- self.assertTrue(v.url and v.url.startswith('http://'), 'URL for video "%s" not found: %s' % (v.id, v.url))
diff --git a/modules/jacquieetmichel/video.py b/modules/jacquieetmichel/video.py
deleted file mode 100644
index 838f5ad5b4fd076bafdff3f10f579810929f7453..0000000000000000000000000000000000000000
--- a/modules/jacquieetmichel/video.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2013 Roger Philibert
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from weboob.capabilities.video import BaseVideo
-
-
-class JacquieEtMichelVideo(BaseVideo):
- def __init__(self, *args, **kwargs):
- BaseVideo.__init__(self, *args, **kwargs)
- self.ext = u'mp4'
- self.nsfw = True
-
- @classmethod
- def id2url(cls, _id):
- return 'http://jacquieetmicheltv.net/showvideo/%s/t/' % _id
diff --git a/modules/jvmalin/__init__.py b/modules/jvmalin/__init__.py
deleted file mode 100644
index 8e89bd6fa4534997c33cac953b9af5d0635b2e36..0000000000000000000000000000000000000000
--- a/modules/jvmalin/__init__.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2013 Alexandre Lissy
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from .module import JVMalinModule
-
-__all__ = ['JVMalinModule']
diff --git a/modules/jvmalin/browser.py b/modules/jvmalin/browser.py
deleted file mode 100644
index d01934f73fafce65b32985ac069ff8b33cf8359a..0000000000000000000000000000000000000000
--- a/modules/jvmalin/browser.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2013 Alexandre Lissy
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from weboob.deprecated.browser import Browser
-from .pages import RoadmapSearchPage, RoadmapResultsPage, RoadmapPage, RoadmapAmbiguity
-
-
-__all__ = ['JVMalin']
-
-
-class JVMalin(Browser):
- DOMAIN = 'www.jvmalin.fr'
- PAGES = {
- 'http://www\.jvmalin\.fr/Itineraires/Recherche.*': RoadmapSearchPage,
- 'http://www\.jvmalin\.fr/Itineraires/Precision.*': RoadmapResultsPage,
- 'http://www\.jvmalin\.fr/route/vuesearch/result.*': RoadmapPage
- }
-
- def __init__(self, **kwargs):
- Browser.__init__(self, '', **kwargs)
-
- def get_roadmap(self, departure, arrival, filters):
- self.location('/Itineraires/Recherche')
-
- assert self.is_on_page(RoadmapSearchPage)
- self.page.search(departure, arrival, filters.departure_time, filters.arrival_time)
-
- assert self.is_on_page(RoadmapResultsPage)
-
- dest = ''
- try:
- dest = self.page.find_best()
- except RoadmapAmbiguity:
- self.page.resubmit_best_form()
- assert self.is_on_page(RoadmapResultsPage)
- dest = self.page.find_best()
-
- self.location(dest)
-
- roadmap = {}
- roadmap['steps'] = list(self.page.get_steps())
- return roadmap
-
- def is_logged(self):
- """ Do not need to be logged """
- return True
diff --git a/modules/jvmalin/favicon.png b/modules/jvmalin/favicon.png
deleted file mode 100644
index d51f867f111684158b9427d8f24f60cd7e0d6bac..0000000000000000000000000000000000000000
Binary files a/modules/jvmalin/favicon.png and /dev/null differ
diff --git a/modules/jvmalin/module.py b/modules/jvmalin/module.py
deleted file mode 100644
index 3e3092650b7fcc39afb30c3c52b9d3a2c9b0afaf..0000000000000000000000000000000000000000
--- a/modules/jvmalin/module.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2013 Alexandre Lissy
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-from weboob.capabilities.travel import CapTravel, RoadStep
-from weboob.tools.backend import Module
-
-from .browser import JVMalin
-
-
-__all__ = ['JVMalinModule']
-
-
-class JVMalinModule(Module, CapTravel):
- NAME = 'jvmalin'
- MAINTAINER = u'Alexandre Lissy'
- EMAIL = 'github@lissy.me'
- VERSION = '1.4'
- LICENSE = 'AGPLv3+'
- DESCRIPTION = u"Multimodal public transportation for whole Région Centre, France"
- BROWSER = JVMalin
-
- def iter_roadmap(self, departure, arrival, filters):
- with self.browser:
- roadmap = self.browser.get_roadmap(departure, arrival, filters)
-
- for s in roadmap['steps']:
- step = RoadStep(s['id'])
- step.line = s['line']
- step.start_time = s['start_time']
- step.end_time = s['end_time']
- step.departure = s['departure']
- step.arrival = s['arrival']
- step.duration = s['duration']
- yield step
diff --git a/modules/jvmalin/pages.py b/modules/jvmalin/pages.py
deleted file mode 100644
index 6184405e3e0cffdb33a132d18a4903da7f097c8a..0000000000000000000000000000000000000000
--- a/modules/jvmalin/pages.py
+++ /dev/null
@@ -1,208 +0,0 @@
-# -*- coding: utf-8 -*-
-
-import datetime
-import re
-
-from mechanize import ItemNotFoundError
-
-from weboob.capabilities.travel import RoadmapError
-from weboob.deprecated.browser import Page
-from weboob.tools.misc import to_unicode
-
-
-class RoadmapAmbiguity(RoadmapError):
- def __init__(self, error):
- RoadmapError.__init__(self, error)
-
-
-class RoadmapSearchPage(Page):
- def search(self, departure, arrival, departure_time, arrival_time):
- match = -1
- i = 0
- for form in self.browser.forms():
- try:
- if form.attrs['id'] == 'rech-iti':
- match = i
- except KeyError:
- pass
- i += 1
-
- self.browser.select_form(nr=match)
- self.browser['Departure'] = departure
- self.browser['Destination'] = arrival
-
- time = None
- if departure_time:
- self.browser['sens'] = ['1']
- time = departure_time
- elif arrival_time:
- self.browser['sens'] = ['-1']
- time = arrival_time
-
- if time:
- try:
- self.browser['dateFull'] = '%02d/%02d/%d' % (time.day, time.month, time.year)
- self.browser['hour'] = ['%02d' % time.hour]
- self.browser['minute'] = ['%02d' % (time.minute - (time.minute % 5))]
- except ItemNotFoundError:
- raise RoadmapError('Unable to establish a roadmap with %s time at "%s"' % ('departure' if departure_time else 'arrival', time))
- self.browser.submit()
-
-
-class RoadmapResultsPage(Page):
- def html_br_strip(self, text):
- return "".join([l.strip() for l in text.split("\n")]).strip().replace(' ', '%20')
-
- def find_best(self):
- if len(self.parser.select(self.document.getroot(), 'img.img-error')) > 0:
- if len(self.parser.select(self.document.getroot(), 'form#iti-ambi')) > 0:
- raise RoadmapAmbiguity('Ambigious stop name')
- else:
- raise RoadmapError('Error when submitting form')
-
- best = self.parser.select(self.document.getroot(), 'div.alerte-bloc-important div.bloc-iti')
- if len(best) == 0:
- best = self.parser.select(self.document.getroot(), 'div.bloc-iti')
- if len(best) == 0:
- raise RoadmapError('Unable to get the best roadmap')
-
- link = self.parser.select(best[0], 'a.btn-submit')
- if len(link) == 0:
- raise RoadmapError('Unable to get a link to best roadmap')
-
- return self.html_br_strip(link[0].attrib['href'])
-
- def resubmit_best_form(self):
- if len(self.parser.select(self.document.getroot(), 'img.img-error')) == 0:
- raise RoadmapError('No error reported!')
-
- ambi = None
- i = 0
- for form in self.parser.select(self.document.getroot(), 'form'):
- if 'id' in form.attrib and form.attrib['id'] == 'iti-ambi':
- ambi = form
- break
- i += 1
-
- if ambi is None:
- raise RoadmapError('No ambigous form!')
-
- props = self.parser.select(ambi, 'span.precision-arret input')
- if len(props) == 0:
- props = self.parser.select(ambi, 'span.precision-adresse input')
- if len(props) == 0:
- raise RoadmapError('Nothing to select to get a roadmap')
-
- self.browser.select_form(nr=i)
- propname = props[0].attrib['name']
- propvalue = props[0].attrib['value'].encode('utf-8')
- self.browser[propname] = [ propvalue ]
- self.browser.submit()
-
-
-class RoadmapPage(Page):
- def get_steps(self):
- errors = []
- # for p in self.parser.select(self.document.getroot(), 'p.errors'):
- # if p.text:
- # errors.append(p.text.strip())
-
- if len(errors) > 0:
- raise RoadmapError('Unable to establish a roadmap: %s' % ', '.join(errors))
-
- current_step = None
- i = 0
- for tr in self.parser.select(self.document.getroot(), 'table.itineraire-detail tr'):
- if current_step is None:
- current_step = {
- 'id': i,
- 'start_time': datetime.datetime.now(),
- 'end_time': datetime.datetime.now(),
- 'line': '',
- 'departure': '',
- 'arrival': '',
- 'duration': datetime.timedelta()
- }
-
- if 'class' in tr.attrib:
- if 'bg-ligne' in tr.attrib['class']:
- continue
-
- if 'iti-map' in tr.attrib['class']:
- continue
-
- for td in self.parser.select(tr, 'td'):
- if 'class' not in td.attrib:
- continue
-
- if 'iti-inner' in td.attrib['class']:
- continue
-
- if 'cell-infos' in td.attrib['class']:
- if 'id' in td.attrib:
- if td.attrib['id'].find('MapOpenLink') >= 0:
- hasA = self.parser.select(td, 'a')
- if len(hasA) == 0:
- if len(current_step['line']) > 0 and \
- len(current_step['departure']) > 0 and \
- len(current_step['arrival']) > 0:
- current_step['line'] = to_unicode("%s : %s" %
- (current_step['mode'], current_step['line']))
- del current_step['mode']
- yield current_step
- i += 1
- current_step = None
- continue
-
- if 'cell-horaires' in td.attrib['class']:
- # real start
- for heure in self.parser.select(td, 'span.heure'):
- if heure.attrib['id'].find('FromTime') >= 0:
- current_step['start_time'] = self.parse_time(heure.text)
- if heure.attrib['id'].find('ToTime') >= 0:
- current_step['end_time'] = self.parse_time(heure.text)
- for mode in self.parser.select(td, 'span.mode-locomotion img'):
- current_step['mode'] = mode.attrib['title']
-
- if 'cell-details' in td.attrib['class']:
- # If we get a span, it's a line indication,
- # otherwise check for id containing LibDeparture or
- # LibDestination
- spans = self.parser.select(td, 'span.itineraire-ligne')
- if len(spans) == 1:
- line = self.html_br_strip(spans[0].text, " ").replace('Ligne ', '')
- if line.index('- ') == 0:
- line = re.sub(r'^- ', '', line)
- current_step['line'] = line
-
- elif 'id' in td.attrib:
- stops = self.parser.select(td, 'strong')
- stop = self.html_br_strip(stops[0].text, " ")
-
- if td.attrib['id'].find('LibDeparture') >= 0:
- current_step['departure'] = to_unicode(stop)
-
- if td.attrib['id'].find('LibDestination') >= 0:
- current_step['arrival'] = to_unicode(stop)
-
- duree = self.parser.select(td, 'span.duree strong')
- if len(duree) == 1:
- current_step['duration'] = self.parse_duration(duree[0].text)
-
- def html_br_strip(self, text, joining=""):
- return joining.join([l.strip() for l in text.split("\n")]).strip()
-
- def parse_time(self, time):
- time = self.html_br_strip(time)
- h, m = time.split('h')
- return datetime.time(int(h), int(m))
-
- def parse_duration(self, dur):
- dur = self.html_br_strip(dur)
- m = re.match('(\d+)min', dur)
- if m:
- return datetime.timedelta(minutes=int(m.group(1)))
- m = re.match('(\d+)h(\d+)', dur)
- if m:
- return datetime.timedelta(hours=int(m.group(1)),
- minutes=int(m.group(2)))
diff --git a/modules/jvmalin/test.py b/modules/jvmalin/test.py
deleted file mode 100644
index b0b954ac7567358419c8fe9a7a62c7832baf8b85..0000000000000000000000000000000000000000
--- a/modules/jvmalin/test.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2013 Alexandre Lissy
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-import datetime
-
-from weboob.capabilities.travel import RoadmapFilters
-from weboob.tools.test import BackendTest
-
-
-class JVMalinTest(BackendTest):
- MODULE = 'jvmalin'
-
- def test_roadmap_cities(self):
- filters = RoadmapFilters()
- roadmap = list(self.backend.iter_roadmap('Tours', 'Orléans', filters))
- self.assertTrue(len(roadmap) > 0)
-
- def test_roadmap_stop_intercity(self):
- filters = RoadmapFilters()
- roadmap = list(self.backend.iter_roadmap('Tours Jean-Jaurès', 'Orléans', filters))
- self.assertTrue(len(roadmap) > 0)
-
- def test_roadmap_stop_intracity(self):
- filters = RoadmapFilters()
- roadmap = list(self.backend.iter_roadmap('Tours Jean-Jaurès', 'Polytech Tours', filters))
- self.assertTrue(len(roadmap) > 0)
-
- def test_roadmap_stop_intracity2(self):
- filters = RoadmapFilters()
- roadmap = list(self.backend.iter_roadmap('J.P.Rameau', 'Polytech Tours', filters))
- self.assertTrue(len(roadmap) > 0)
-
- def test_roadmap_names(self):
- filters = RoadmapFilters()
- roadmap = list(self.backend.iter_roadmap('Artannes Mairie', 'Château de Blois', filters))
- self.assertTrue(len(roadmap) > 0)
-
- def test_roadmap_long(self):
- filters = RoadmapFilters()
- roadmap = list(self.backend.iter_roadmap('Chartres', 'Ballan-Miré', filters))
- self.assertTrue(len(roadmap) > 0)
-
- def test_roadmap_departure(self):
- filters = RoadmapFilters()
- filters.departure_time = datetime.datetime.now() + datetime.timedelta(days=1)
- roadmap = list(self.backend.iter_roadmap('Chartres', 'Ballan-Miré', filters))
- self.assertTrue(len(roadmap) > 0)
-
- def test_roadmap_arrival(self):
- filters = RoadmapFilters()
- filters.arrival_time = datetime.datetime.now() + datetime.timedelta(days=1)
- roadmap = list(self.backend.iter_roadmap('Chartres', 'Ballan-Miré', filters))
- self.assertTrue(len(roadmap) > 0)
diff --git a/modules/leclercmobile/__init__.py b/modules/leclercmobile/__init__.py
deleted file mode 100644
index 709018936ef7df6bd9f37b26e96e7e5c01a0850e..0000000000000000000000000000000000000000
--- a/modules/leclercmobile/__init__.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2012 Florent Fourcot
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from .module import LeclercMobileModule
-
-__all__ = ['LeclercMobileModule']
diff --git a/modules/leclercmobile/browser.py b/modules/leclercmobile/browser.py
deleted file mode 100644
index e134bd86aa5a10226f40e6bce83f480ec336ac21..0000000000000000000000000000000000000000
--- a/modules/leclercmobile/browser.py
+++ /dev/null
@@ -1,152 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2012 Fourcot Florent
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-import time
-from io import BytesIO
-
-from weboob.deprecated.browser import Browser, BrowserIncorrectPassword
-from .pages import HomePage, LoginPage, HistoryPage, PdfPage
-from weboob.capabilities.bill import Detail
-from weboob.capabilities.base import NotAvailable
-
-
-__all__ = ['Leclercmobile']
-
-
-class Leclercmobile(Browser):
- DOMAIN = 'www.securelmobile.fr'
- PROTOCOL = 'https'
- ENCODING = 'utf-8'
- PAGES = {'.*pgeWERL008_Login.aspx.*': LoginPage,
- '.*EspaceClient/pgeWERL013_Accueil.aspx': HomePage,
- '.*pgeWERL009_ReleveConso.aspx.*': HistoryPage,
- '.*ReleveConso.ashx.*': PdfPage
- }
- accueil = "/EspaceClient/pgeWERL013_Accueil.aspx"
- login = "/EspaceClient/pgeWERL008_Login.aspx"
- conso = "/EspaceClient/pgeWERL009_ReleveConso.aspx"
- bills = '/EspaceClient/pgeWERL015_RecupReleveConso.aspx?m=-'
-
- def __init__(self, *args, **kwargs):
- Browser.__init__(self, *args, **kwargs)
-
- def home(self):
- self.location(self.accueil)
-
- def is_logged(self):
- return not self.is_on_page(LoginPage)
-
- def login(self):
- assert isinstance(self.username, basestring)
- assert isinstance(self.password, basestring)
- assert self.username.isdigit()
-
- if not self.is_on_page(LoginPage):
- self.location(self.login)
-
- form = self.page.login(self.username, self.password)
-
- # Site display a javascript popup to wait
- while self.page.iswait():
- # In this popup can be an error displayed
- if self.page.iserror():
- raise BrowserIncorrectPassword()
- time.sleep(1)
- self.page.next(self.username, form)
-
- # The last document contain a redirect url in the javascript
- self.location(self.page.getredirect())
-
- if self.is_on_page(LoginPage):
- raise BrowserIncorrectPassword()
-
- def viewing_html(self):
- # To prevent unknown mimetypes sent by server, we assume we
- # are always on a HTML document.
- return True
-
- def get_subscription_list(self):
- if not self.is_on_page(HomePage):
- self.location(self.acceuil)
-
- return self.page.get_list()
-
- def get_subscription(self, id):
- assert isinstance(id, basestring)
-
- if not self.is_on_page(HomePage):
- self.location(self.accueil)
-
- l = self.page.get_list()
- for a in l:
- if a.id == id:
- return a
-
- return None
-
- def get_history(self):
- if not self.is_on_page(HistoryPage):
- self.location(self.conso)
- maxid = self.page.getmaxid()
-
- for i in range(maxid + 1):
- response = self.openurl(self.bills + str(i))
- mimetype = response.info().get('Content-Type', '').split(';')[0]
- if mimetype == "application/pdf":
- pdf = PdfPage(BytesIO(response.read()))
- for call in pdf.get_calls():
- call.label = call.label.strip()
- yield call
-
- def get_details(self):
- if not self.is_on_page(HistoryPage):
- self.location(self.conso)
- response = self.openurl(self.bills + "0")
- mimetype = response.info().get('Content-Type', '').split(';')[0]
- if mimetype == "application/pdf":
- pdf = PdfPage(BytesIO(response.read()))
- for detail in pdf.get_details():
- yield detail
-
- def iter_documents(self, parentid):
- if not self.is_on_page(HistoryPage):
- self.location(self.conso)
- return self.page.date_bills(parentid)
-
- def get_document(self, id):
- assert isinstance(id, basestring)
- if not self.is_on_page(HistoryPage):
- self.location(self.conso)
- parentid = id[0:10]
- l = self.page.date_bills(parentid)
- for a in l:
- if a.id == id:
- return a
-
- def get_balance(self):
- if not self.is_on_page(HistoryPage):
- self.location(self.conso)
- detail = Detail()
- detail.label = u"Balance"
- for calls in self.get_history():
- if "Votre solde" in calls.label:
- detail.price = calls.price
- return detail
- detail.price = NotAvailable
- return detail
diff --git a/modules/leclercmobile/favicon.png b/modules/leclercmobile/favicon.png
deleted file mode 100644
index b2d0c897f6c9921696abd59ec8d53e6a91b8c3d4..0000000000000000000000000000000000000000
Binary files a/modules/leclercmobile/favicon.png and /dev/null differ
diff --git a/modules/leclercmobile/module.py b/modules/leclercmobile/module.py
deleted file mode 100644
index c9db7639400b56b240df1483039b58b1691b4ece..0000000000000000000000000000000000000000
--- a/modules/leclercmobile/module.py
+++ /dev/null
@@ -1,109 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2012 Florent Fourcot
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from weboob.capabilities.bill import CapDocument, SubscriptionNotFound,\
- DocumentNotFound, Subscription, Bill
-from weboob.tools.backend import Module, BackendConfig
-from weboob.tools.value import ValueBackendPassword
-
-from .browser import Leclercmobile
-
-
-__all__ = ['LeclercMobileModule']
-
-
-class LeclercMobileModule(Module, CapDocument):
- NAME = 'leclercmobile'
- MAINTAINER = u'Florent Fourcot'
- EMAIL = 'weboob@flo.fourcot.fr'
- VERSION = '1.4'
- LICENSE = 'AGPLv3+'
- DESCRIPTION = 'Leclerc Mobile website'
- CONFIG = BackendConfig(ValueBackendPassword('login',
- label='Account ID',
- masked=False,
- regexp='^(\d{10}|)$'),
- ValueBackendPassword('password',
- label='Password')
- )
- BROWSER = Leclercmobile
-
- def create_default_browser(self):
- return self.create_browser(self.config['login'].get(),
- self.config['password'].get())
-
- def iter_subscription(self):
- for subscription in self.browser.get_subscription_list():
- yield subscription
-
- def get_subscription(self, _id):
- if not _id.isdigit():
- raise SubscriptionNotFound()
- with self.browser:
- subscription = self.browser.get_subscription(_id)
- if subscription:
- return subscription
- else:
- raise SubscriptionNotFound()
-
- def iter_documents_history(self, subscription):
- with self.browser:
- for history in self.browser.get_history():
- if history.label != "Votre solde":
- yield history
-
- def get_document(self, id):
- with self.browser:
- bill = self.browser.get_document(id)
- if bill:
- return bill
- else:
- raise DocumentNotFound()
-
- def iter_documents(self, subscription):
- if not isinstance(subscription, Subscription):
- subscription = self.get_subscription(subscription)
-
- with self.browser:
- for bill in self.browser.iter_documents(subscription.id):
- yield bill
-
- # The subscription is actually useless, but maybe for the futur...
- def get_details(self, subscription):
- with self.browser:
- for detail in self.browser.get_details():
- yield detail
-
- def download_document(self, bill):
- if not isinstance(bill, Bill):
- bill = self.get_document(bill)
-
- with self.browser:
- return self.browser.readurl(bill.url)
-
- def get_balance(self, subscription):
- if not isinstance(subscription, Subscription):
- subscription = self.get_subscription(subscription)
- with self.browser:
- balance = self.browser.get_balance()
- balance.label = u"Balance %s" % subscription.id
- balance.id = "%s-balance" % subscription.id
- balance.currency = u'EUR'
- return balance
diff --git a/modules/leclercmobile/pages/__init__.py b/modules/leclercmobile/pages/__init__.py
deleted file mode 100644
index 05e6c00e302cafe739bc396e5fbafa73fe34f08c..0000000000000000000000000000000000000000
--- a/modules/leclercmobile/pages/__init__.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2012 Florent Fourcot
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from .homepage import HomePage
-from .history import HistoryPage, PdfPage
-from .login import LoginPage
-
-__all__ = ['LoginPage', 'HomePage', 'HistoryPage', 'PdfPage']
diff --git a/modules/leclercmobile/pages/history.py b/modules/leclercmobile/pages/history.py
deleted file mode 100644
index c824b77441cbbaafc33fef021ead20a855370fc2..0000000000000000000000000000000000000000
--- a/modules/leclercmobile/pages/history.py
+++ /dev/null
@@ -1,181 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2012 Florent Fourcot
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-import re
-import os
-import subprocess
-import tempfile
-import shutil
-
-from datetime import datetime, date, time
-from decimal import Decimal
-
-from weboob.deprecated.browser import Page
-from weboob.capabilities.bill import Detail, Bill
-
-
-def _get_date(detail):
- return detail.datetime
-
-
-class PdfPage():
- def __init__(self, file):
- self.pdf = file
-
- def _parse_pdf(self):
- pdffile = tempfile.NamedTemporaryFile(bufsize=100000, mode='w', suffix='.pdf')
- temptxt = pdffile.name.replace('.pdf', '.txt')
- cmd = "ebook-convert"
- stdout = open("/dev/null", "w")
- shutil.copyfileobj(self.pdf, pdffile)
- pdffile.flush()
- subprocess.call([cmd, pdffile.name, temptxt], stdout=stdout)
- pdffile.close()
- txtfile = open(temptxt, 'r')
- txt = txtfile.read()
- txtfile.close()
- os.remove(temptxt)
- return txt
-
- def get_details(self):
- txt = self._parse_pdf()
- page = txt.split('CONSOMMATION')[2].split('ACTIVITE DETAILLEE')[0]
- lines = page.split('\n')
- lines = [x for x in lines if len(x) > 0] # Remove empty lines
- details = []
- detail = None
- lines.pop(-1) # Line to describes pictures
- twolines = False
- for line in lines:
- if "Votre consommation" in line:
- line = line.split(": ", 1)[1]
- if twolines:
- twolines = False
- detail.infos = unicode(line, encoding='utf-8')
- elif re.match('[A-Za-z]', line[0]):
- # We have a new element, return the other one
- if detail is not None:
- details.append(detail)
- detail = Detail()
- split = re.split("(\d)", line, maxsplit=1)
- detail.price = Decimal(0)
- if len(split) > 2:
- detail.infos = unicode(split[1] + split[2], encoding='utf-8')
- else:
- twolines = True
- if '€' in line:
- specialprice = split[1] + split[2]
- detail.price = Decimal(specialprice.replace('€', ''))
- detail.label = unicode(split[0], encoding='utf-8')
- elif '€' in line:
- detail.price = Decimal(line.replace('€', ''))
- else:
- detail.infos = unicode(line, encoding='utf-8')
- details.append(detail)
- return details
-
- # Standard pdf text extractor take text line by line
- # But the position in the file is not always the "real" position to display...
- # It produce some unsorted and unparsable data
- # Example of bad software: pdfminer and others python tools
- # This is why we have to use "ebook-convert" from calibre software,
- # it is the only one to 'reflow" text and give some relevant results
- # The bad new is that ebook-convert doesn't support simple use with stdin/stdout
- def get_calls(self):
- txt = self._parse_pdf()
- pages = txt.split("DEBIT")
- pages.pop(0) # remove headers
- details = []
- for page in pages:
- page = page.split('RÉGLO MOBILE')[0].split('N.B. Prévoir')[0] # remove footers
- lines = page.split('\n')
- lines = [x for x in lines if len(x) > 0] # Remove empty lines
- numitems = (len(lines) + 1) / 4 # Each line has five columns
- lines.pop(0) # remove the extra € symbol
- modif = 0
- i = 0
- while i < numitems:
- if modif != 0:
- numitems = ((len(lines) + 1 + modif) / 4)
- base = i * 4 - modif
- dateop = base
- corres = base + 1
- duree = base + 2
- price = base + 3
- if "Changement vers le Forfait" in lines[base]:
- modif += 1
- i += 1
- continue
- # Special case with 5 columns, the operation date is not in the first one
- if len(re.split("(\d+\/\d+\/\d+)", lines[dateop])) < 2:
- lines[base + 1] = lines[base] + " " + lines[base + 1]
- dateop = base + 1
- corres = base + 2
- duree = base + 3
- price = base + 4
- modif -= 1
- detail = Detail()
- splits = re.split("(\d+\/\d+\/\d+)", lines[dateop])
- mydate = date(*reversed([int(x) for x in splits[1].split("/")]))
- mytime = time(*[int(x) for x in splits[2].split(":")])
- detail.datetime = datetime.combine(mydate, mytime)
- if lines[corres] == '-':
- lines[corres] = ""
- if lines[duree] == '-':
- lines[duree] = ''
- detail.label = unicode(splits[0], encoding='utf-8', errors='replace') + u" " + lines[corres] + u" " + lines[duree]
- # Special case with only 3 columns, we insert a price
- if "Activation de votre ligne" in detail.label or u"Résiliation" in detail.label:
- lines.insert(price, '0')
- try:
- detail.price = Decimal(lines[price].replace(',', '.'))
- except:
- # In some special cases, there are no price column. Try to detect it
- if "Inclus" not in lines[price]:
- modif += 1
- detail.price = Decimal(0)
-
- details.append(detail)
- i += 1
- return sorted(details, key=_get_date, reverse=True)
-
-
-class HistoryPage(Page):
- def on_loaded(self):
- pass
-
- def getmaxid(self):
- max = 1
- while len(self.document.xpath('//li[@id="liMois%s"]' % max)) > 0:
- max += 1
- return max - 1
-
- def date_bills(self, parentid):
- max = 1
- while len(self.document.xpath('//li[@id="liMois%s"]' % max)) > 0:
- li = self.document.xpath('//li[@id="liMois%s"]' % max)[0]
- max += 1
- link = li.xpath('a')[0]
- bill = Bill()
- bill.url = unicode(link.attrib['href'])
- bill.label = unicode(link.text)
- bill.format = u"pdf"
- bill.type = u"bill"
- bill.id = parentid + bill.label.replace(' ', '')
- yield bill
diff --git a/modules/leclercmobile/pages/homepage.py b/modules/leclercmobile/pages/homepage.py
deleted file mode 100644
index c3002a5ac28a10cc9be764e46a0a8a9ed874c579..0000000000000000000000000000000000000000
--- a/modules/leclercmobile/pages/homepage.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2012 Florent Fourcot
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-from weboob.capabilities.bill import Subscription
-from weboob.deprecated.browser import Page
-
-
-class HomePage(Page):
- def on_loaded(self):
- pass
-
- def get_list(self):
- l = []
- phone = unicode(self.document.xpath('//span[@id="ctl00_ctl00_cMain_cEspCli_lblMsIsdn"]')[0].text.replace(' ', ''))
- self.browser.logger.debug('Found ' + phone + ' has phone number')
- phoneplan = unicode(self.document.xpath('//span[@id="ctl00_ctl00_cMain_cEspCli_aoaOffreActuelle_aooOffreEtOptions"]/dl/dd/span')[0].text)
- self.browser.logger.debug('Found ' + phoneplan + ' has subscription type')
-
- subscription = Subscription(phone)
- subscription.label = phone + ' - ' + phoneplan
-
- l.append(subscription)
-
- return l
diff --git a/modules/leclercmobile/pages/login.py b/modules/leclercmobile/pages/login.py
deleted file mode 100644
index 4f60ba05c579d5dd602a201bd7ab09a5d6ff209b..0000000000000000000000000000000000000000
--- a/modules/leclercmobile/pages/login.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2012 Florent Fourcot
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-import StringIO
-
-from mechanize import TextControl
-
-from weboob.deprecated.browser import Page
-
-
-class LoginPage(Page):
- def on_loaded(self):
- pass
-
- def login(self, login, password):
- form = list(self.browser.forms())[0]
- self.browser.select_form("aspnetForm")
- self.browser.set_all_readonly(False)
- self.browser.controls.append(TextControl('text', '__ASYNCPOST', {'value': "true"}))
- self.browser['__EVENTTARGET'] = "ctl00$cMain$lnkValider"
- self.browser['ctl00$cMain$ascSaisieMsIsdn$txtMsIsdn'] = login.encode('iso-8859-1')
- self.browser['ctl00$cMain$txtMdp'] = password.encode('iso-8859-1')
- self.browser.submit(nologin=True)
- return form
-
- def iswait(self):
- spanwait = self.document.xpath('//span[@id="ctl00_ascAttente_timerAttente"]')
- return len(spanwait) > 0
-
- def iserror(self):
- error = self.document.xpath('//span[@id="ctl00_cMain_ascLibErreur_lblErreur"]')
- return len(error) > 0
-
- def getredirect(self):
- string = StringIO.StringIO()
- self.document.write(string)
- try:
- redirect = string.getvalue().split('pageRedirect')[1].split('|')[2]
- except:
- redirect = ''
- return redirect
-
- def next(self, login, form):
- self.browser.form = form
- string = StringIO.StringIO()
- self.document.write(string)
- controlvalue = string.getvalue().split('__EVENTVALIDATION')[1].split('|')[1]
- state = string.getvalue().split('__VIEWSTATE')[1].split('|')[1]
- self.browser.controls.append(TextControl('text', 'ctl00$objScriptManager', {'value': "ctl00$ascAttente$panelAttente|ctl00$ascAttente$timerAttente"}))
- self.browser['__VIEWSTATE'] = state
- self.browser['__EVENTTARGET'] = "ctl00$ascAttente$timerAttente"
- self.browser['__EVENTVALIDATION'] = controlvalue
- self.browser['ctl00$cMain$ascSaisieMsIsdn$txtMsIsdn'] = login.encode('iso-8859-1')
- self.browser['ctl00$cMain$txtMdp'] = ""
- self.browser.submit(nologin=True)
diff --git a/modules/leclercmobile/test.py b/modules/leclercmobile/test.py
deleted file mode 100644
index c9276354bacad4f0dff4cf892246b9eadab3c649..0000000000000000000000000000000000000000
--- a/modules/leclercmobile/test.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2012-2013 Fourcot Florent
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from weboob.tools.test import BackendTest
-
-
-class LeclercMobileTest(BackendTest):
- MODULE = 'leclercmobile'
-
- def test_list(self):
- """
- Test listing of subscriptions .
- No support of multi-account on the website, we could assume to
- have only one subscription.
- Check the balance if the subscription is ok.
- """
- subscriptions = list(self.backend.iter_subscription())
- self.assertTrue(len(subscriptions) == 1, msg="Account listing failed")
- self.assertTrue(self.backend.get_balance(subscriptions[0]) > 0,
- msg="Get balance failed")
-
- def test_downloadbills(self):
- """
- Iter all bills and try to download it.
- """
- for subscription in self.backend.iter_subscription():
- for bill in self.backend.iter_documents(subscription.id):
- self.backend.download_document(bill.id)
-
- def test_history(self):
- for subscription in self.backend.iter_subscription():
- self.assertTrue(len(list(self.backend.iter_documents_history(subscription))) > 0)
-
- def test_details(self):
- for subscription in self.backend.iter_subscription():
- details = list(self.backend.get_details(subscription))
- self.assertTrue(len(details) > 5, msg="Not enough details")
- total = 0
- for d in details:
- total += d.price
- self.assertTrue(total > 0, msg="Parsing of price failed")
diff --git a/modules/nettokom/__init__.py b/modules/nettokom/__init__.py
deleted file mode 100644
index c994d9617b5dd4205e0df3192ea8ec87a0e919e1..0000000000000000000000000000000000000000
--- a/modules/nettokom/__init__.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2012 Florent Fourcot
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from .module import NettoKomModule
-
-__all__ = ['NettoKomModule']
diff --git a/modules/nettokom/browser.py b/modules/nettokom/browser.py
deleted file mode 100644
index 1eded0f01dd653373971056399618ff3c786ffda..0000000000000000000000000000000000000000
--- a/modules/nettokom/browser.py
+++ /dev/null
@@ -1,109 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2012 Fourcot Florent
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from weboob.deprecated.browser import Browser, BrowserIncorrectPassword
-from .pages import HomePage, LoginPage, HistoryPage, DetailsPage, BillsPage
-
-__all__ = ['Nettokom']
-
-
-class Nettokom(Browser):
- DOMAIN = 'konto.nettokom.de'
- PROTOCOL = 'https'
- ENCODING = None # refer to the HTML encoding
- PAGES = {'.*login.html.*': LoginPage,
- '.*start.html': HomePage,
- '.*guthabenverbrauch.html': DetailsPage,
- '.*/verbindungsnachweis/.*': HistoryPage,
- '.*verbindungsnachweis.html': BillsPage
- }
-
- def __init__(self, *args, **kwargs):
- Browser.__init__(self, *args, **kwargs)
-
- def home(self):
- self.location('/start.html')
-
- def is_logged(self):
- return not self.is_on_page(LoginPage)
-
- def login(self):
- assert isinstance(self.username, basestring)
- assert isinstance(self.password, basestring)
- assert self.username.isdigit()
-
- if not self.is_on_page(LoginPage):
- self.location('/login.html')
-
- self.page.login(self.username, self.password)
-
- if self.is_on_page(LoginPage):
- raise BrowserIncorrectPassword()
-
- def get_subscription_list(self):
- if not self.is_on_page(HomePage):
- self.location('/start.html')
-
- return self.page.get_list()
-
- def get_subscription(self, id):
- assert isinstance(id, basestring)
-
- if not self.is_on_page(HomePage):
- self.location('/start.html')
-
- l = self.page.get_list()
- for a in l:
- if a.id == id:
- return a
-
- return None
-
- def get_history(self):
- if not self.is_on_page(HistoryPage):
- self.location('/verbindungsnachweis/alle-verbindungen.html')
- return self.page.get_calls()
-
- def get_details(self):
- if not self.is_on_page(DetailsPage):
- self.location('/guthabenverbrauch.html')
- return self.page.get_details()
-
- def iter_documents(self, parentid):
- if not self.is_on_page(BillsPage):
- self.location('/verbindungsnachweis.html')
- return self.page.date_bills()
-
- def get_document(self, id):
- assert isinstance(id, basestring)
-
- if not self.is_on_page(BillsPage):
- self.location('/verbindungsnachweis.html')
- l = self.page.date_bills()
- for a in l:
- if a.id == id:
- return a
-
-# Todo : url depends of file format
-# def download_document(self, id):
-# assert isinstance(id, basestring)
-# date = id.split('.')[1]
-#
-# return self.readurl('/moncompte/ajax.php?page=facture&mode=html&date=' + date)
diff --git a/modules/nettokom/favicon.png b/modules/nettokom/favicon.png
deleted file mode 100644
index 55bfe52a7f9a341d9809ad520ad207fd683db7c4..0000000000000000000000000000000000000000
Binary files a/modules/nettokom/favicon.png and /dev/null differ
diff --git a/modules/nettokom/module.py b/modules/nettokom/module.py
deleted file mode 100644
index 38b2bd14e0e741d93889e04f531d7eee94ba5832..0000000000000000000000000000000000000000
--- a/modules/nettokom/module.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2012 Florent Fourcot
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from weboob.capabilities.bill import CapDocument, Subscription, SubscriptionNotFound, Detail
-from weboob.tools.backend import Module, BackendConfig
-from weboob.tools.value import ValueBackendPassword
-
-from .browser import Nettokom
-
-
-__all__ = ['NettoKomModule']
-
-
-class NettoKomModule(Module, CapDocument):
- NAME = 'nettokom'
- MAINTAINER = u'Florent Fourcot'
- EMAIL = 'weboob@flo.fourcot.fr'
- VERSION = '1.4'
- LICENSE = 'AGPLv3+'
- DESCRIPTION = 'Nettokom website'
- CONFIG = BackendConfig(ValueBackendPassword('login',
- label='Account ID (phone number)',
- masked=False,
- regexp='^(\d{8,13})$'),
- ValueBackendPassword('password',
- label='Password')
- )
- BROWSER = Nettokom
-
- def create_default_browser(self):
- return self.create_browser(self.config['login'].get(),
- self.config['password'].get())
-
- def iter_subscription(self):
- for subscription in self.browser.get_subscription_list():
- yield subscription
-
- def get_subscription(self, _id):
- with self.browser:
- subscription = self.browser.get_subscription(_id)
- if subscription:
- return subscription
- else:
- raise SubscriptionNotFound()
-
- def iter_documents_history(self, subscription):
- with self.browser:
- for history in self.browser.get_history():
- yield history
-
- # The subscription is actually useless, but maybe for the futur...
- def get_details(self, subscription):
- with self.browser:
- for detail in self.browser.get_details():
- yield detail
-
- def get_balance(self, subscription):
- if not isinstance(subscription, Subscription):
- subscription = self.get_subscription(subscription)
- balance = Detail()
- balance.id = "%s-balance" % subscription.id
- balance.price = subscription._balance
- balance.label = u"Balance %s" % subscription.id
- balance.currency = u'EUR'
- return balance
diff --git a/modules/nettokom/pages/__init__.py b/modules/nettokom/pages/__init__.py
deleted file mode 100644
index 996912ad066ae617e7c4b2d6b53944a978eae1a1..0000000000000000000000000000000000000000
--- a/modules/nettokom/pages/__init__.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2012 Florent Fourcot
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from .homepage import HomePage
-from .history import HistoryPage, DetailsPage, BillsPage
-from .login import LoginPage
-
-__all__ = ['LoginPage', 'HomePage', 'HistoryPage', 'DetailsPage', 'BillsPage']
diff --git a/modules/nettokom/pages/history.py b/modules/nettokom/pages/history.py
deleted file mode 100644
index dc25b9f38680e9f87caced3dbb382613d57b7649..0000000000000000000000000000000000000000
--- a/modules/nettokom/pages/history.py
+++ /dev/null
@@ -1,89 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2012 Florent Fourcot
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from datetime import datetime, date, time
-from decimal import Decimal
-
-from weboob.deprecated.browser import Page
-from weboob.capabilities.bill import Detail
-
-
-class DetailsPage(Page):
-
- def on_loaded(self):
- self.details = []
- table = self.document.xpath('//table[@id="reportTable"]')
-
- if len(table) > 0:
- for tr in table[0].xpath('tbody/tr'):
- detail = Detail()
- # Skip global category
- if tr.find('td/a') is not None:
- continue
- if tr.attrib["class"] == "totalAmount":
- continue
- tds = tr.xpath('td')
- detail.label = unicode(tds[0].text.strip())
- detail.infos = unicode(tds[1].text.strip())
- detail.price = Decimal(tds[2].text.split(' ')[0].replace(',', '.'))
-
- self.details.append(detail)
-
- def get_details(self):
- return self.details
-
-
-def _get_date(detail):
- return detail.datetime
-
-
-class BillsPage(Page):
- def on_loaded(self):
- pass
-
-
-class HistoryPage(Page):
-
- def on_loaded(self):
- self.calls = []
- for tr in self.document.xpath('//tr'):
- try:
- attrib = tr.attrib["class"]
- except:
- continue
- if attrib == "even" or attrib == "odd":
- label = u''
- tddate = tr.find('td[@class="middle nowrap"]')
- for td in tr.xpath('td[@class="long"]'):
- label += unicode(td.text.strip()) + u' '
- tdprice = tr.xpath('td[@class="price"]')
- label += u'(' + unicode(tdprice[0].text.strip()) + u')'
- price = Decimal(tdprice[1].text.strip().replace(',', '.'))
- detail = Detail()
- mydate = date(*reversed([int(x) for x in tddate.text.strip().split(' ')[0].split(".")]))
- mytime = time(*[int(x) for x in tddate.text.strip().split(' ')[1].split(":")])
- detail.datetime = datetime.combine(mydate, mytime)
- detail.label = label
- detail.price = price
-
- self.calls.append(detail)
-
- def get_calls(self):
- return sorted(self.calls, key=_get_date, reverse=True)
diff --git a/modules/nettokom/pages/homepage.py b/modules/nettokom/pages/homepage.py
deleted file mode 100644
index 0851c73971f36b9416a4f4486deb2d5a624ae1b7..0000000000000000000000000000000000000000
--- a/modules/nettokom/pages/homepage.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2012 Florent Fourcot
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-from weboob.capabilities.bill import Subscription
-from weboob.tools.capabilities.bank.transactions import FrenchTransaction
-from weboob.deprecated.browser import Page
-from datetime import date
-from decimal import Decimal
-
-
-class HomePage(Page):
- def on_loaded(self):
- pass
-
- def get_list(self):
- l = []
- divabo = self.document.xpath('//div[@id="accountSummary"]')[0]
- owner = divabo.xpath('a/h3')[0].text
- phone = divabo.xpath('dl/dd')[0].text
- credit = divabo.xpath('dl/dd')[1].text
- expiredate = divabo.xpath('dl/dd')[2].text
- phoneplan = divabo.xpath('dl/dd')[3].text
- self.browser.logger.debug('Found ' + owner + ' as subscriber')
- self.browser.logger.debug('Found ' + phone + ' as phone number')
- self.browser.logger.debug('Found ' + credit + ' as available credit')
- self.browser.logger.debug('Found ' + expiredate + ' as expire date ')
- self.browser.logger.debug('Found %s as subscription type', phoneplan)
-
- subscription = Subscription(phone)
- subscription.label = unicode(u'%s - %s - %s - %s' %
- (phone, credit, phoneplan, expiredate))
- subscription.subscriber = unicode(owner)
- expiredate = date(*reversed([int(x) for x in expiredate.split(".")]))
- subscription.validity = expiredate
- subscription._balance = Decimal(FrenchTransaction.clean_amount(credit))
-
- l.append(subscription)
-
- return l
diff --git a/modules/nettokom/pages/login.py b/modules/nettokom/pages/login.py
deleted file mode 100644
index f4a9218c099ec2cf7de536a4b919f7435db70bf5..0000000000000000000000000000000000000000
--- a/modules/nettokom/pages/login.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2012 Florent Fourcot
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from weboob.deprecated.browser import Page
-
-
-class LoginPage(Page):
- def on_loaded(self):
- pass
-
- def login(self, login, password):
- self.browser.select_form(nr=0)
- self.browser.set_all_readonly(False)
- self.browser['number'] = login.encode('iso-8859-1')
- self.browser['password'] = password.encode('iso-8859-1')
- self.browser.submit(nologin=True)
diff --git a/modules/nettokom/test.py b/modules/nettokom/test.py
deleted file mode 100644
index 8b962c21b819b1d888c48452c4dfdb6ffea96c78..0000000000000000000000000000000000000000
--- a/modules/nettokom/test.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2013-2014 Florent Fourcot
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from weboob.tools.test import BackendTest
-
-
-class NettokomTest(BackendTest):
- MODULE = 'nettokom'
-
- def test_details(self):
- for subscription in self.backend.iter_subscription():
- details = list(self.backend.get_details(subscription))
- self.assertTrue(len(details) > 1, msg="Not enough details")
-
- def test_history(self):
- for subscription in self.backend.iter_subscription():
- self.assertTrue(len(list(self.backend.iter_documents_history(subscription))) > 0)
-
- def test_list(self):
- """
- Test listing of subscriptions.
- """
- subscriptions = list(self.backend.iter_subscription())
- self.assertTrue(len(subscriptions) > 0, msg="Account listing failed")
diff --git a/modules/nihonnooto/__init__.py b/modules/nihonnooto/__init__.py
deleted file mode 100644
index 9da0a9089d3ef442e31145873bbb9bcc24008ec3..0000000000000000000000000000000000000000
--- a/modules/nihonnooto/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from .module import NihonNoOtoModule
-
-__all__ = ['NihonNoOtoModule']
diff --git a/modules/nihonnooto/browser.py b/modules/nihonnooto/browser.py
deleted file mode 100644
index 9baa089aec68a8f9d57a43985616ad3afd0842b2..0000000000000000000000000000000000000000
--- a/modules/nihonnooto/browser.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# * -*- coding: utf-8 -*-
-
-# Copyright(C) 2013 Thomas Lecavelier
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-from weboob.deprecated.browser import Browser
-from .pages import LivePage, ProgramPage
-
-__all__ = ['NihonNoOtoBrowser']
-
-
-class NihonNoOtoBrowser(Browser):
- DOMAIN = 'www.nihon-no-oto.com'
- PROTOCOL = 'http'
- ENCODING = 'utf-8'
- USER_AGENT = Browser.USER_AGENTS['desktop_firefox']
- PAGES = {
- 'http://www\.nihon-no-oto\.com/': LivePage,
- 'http://www\.nihon-no-oto\.com/app/playlist.php': ProgramPage,
- }
-
- def home(self):
- self.location('/')
-
- assert self.is_on_page(LivePage)
-
- def iter_radios_list(self):
- self.location('/')
-
- assert self.is_on_page(LivePage)
- return self.page.iter_radios_list()
-
- def get_current_emission(self):
- self.location('/app/playlist.php')
- assert self.is_on_page(ProgramPage)
- return self.page.get_current_emission()
diff --git a/modules/nihonnooto/favicon.png b/modules/nihonnooto/favicon.png
deleted file mode 100644
index 312fff79f60601900d2f0ba6d34ab06d6c7b26de..0000000000000000000000000000000000000000
Binary files a/modules/nihonnooto/favicon.png and /dev/null differ
diff --git a/modules/nihonnooto/module.py b/modules/nihonnooto/module.py
deleted file mode 100644
index 81223e2d2fdb06375bb07c0602df8888bfcc7c4b..0000000000000000000000000000000000000000
--- a/modules/nihonnooto/module.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright(C) 2013 Thomas Lecavelier
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-from weboob.capabilities.radio import CapRadio, Radio
-from weboob.capabilities.collection import CapCollection
-from weboob.tools.backend import Module
-from .browser import NihonNoOtoBrowser
-
-__all__ = ['NihonNoOtoModule']
-
-
-class NihonNoOtoModule(Module, CapRadio, CapCollection):
- NAME = 'nihonnooto'
- MAINTAINER = u'Thomas Lecavelier'
- EMAIL = 'thomas-weboob@lecavelier.name'
- VERSION = '1.4'
- DESCRIPTION = u'« Le son du Japon » french operated web radio, diffusing japanese music'
- # License of your module
- LICENSE = 'AGPLv3+'
-
- BROWSER = NihonNoOtoBrowser
- _RADIOS = {'nihonnooto': (u'Nihon no OTO', True) }
-
- def iter_resources(self, objs, split_path):
- if Radio in objs:
- self._restrict_level(split_path)
- for radio in self.browser.iter_radios_list():
- self.browser.get_current_emission()
- radio.current = self.browser.get_current_emission()
- yield radio
-
- def iter_radios_search(self, pattern):
- for radio in self.browser.iter_radios_list():
- if pattern.lower() in radio.title.lower() or pattern.lower() in radio.description.lower():
- self.browser.get_current_emission()
- radio.current = self.browser.get_current_emission()
-
- yield radio
-
- def get_radio(self, radio):
- if not isinstance(radio, Radio):
- for rad in self.browser.iter_radios_list():
- if rad.id == radio:
- return rad
- return None
-
- def fill_radio(self, radio, fields):
- if 'current' in fields:
- return self.get_radio(radio.id)
- return radio
-
- OBJECTS = {Radio: fill_radio}
diff --git a/modules/nihonnooto/pages.py b/modules/nihonnooto/pages.py
deleted file mode 100644
index 06b6e58c8c795e3579121501263e3cdc2f0d03cd..0000000000000000000000000000000000000000
--- a/modules/nihonnooto/pages.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# * -*- coding: utf-8 -*-
-
-# Copyright(C) 2013 Thomas Lecavelier
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-from weboob.deprecated.browser import Page
-from weboob.capabilities.radio import Radio
-from weboob.capabilities.audiostream import BaseAudioStream
-from weboob.tools.capabilities.streaminfo import StreamInfo
-
-
-class LivePage(Page):
- def iter_radios_list(self):
- radio = Radio('nihon')
- radio.title = u'Nihon no Oto'
- radio.description = u'Nihon no Oto: le son du Japon'
- radio.streams = []
-
- index = -1
-
- for el in self.document.xpath('//source'):
- index += 1
- mime_type = unicode(el.attrib['type'])
- stream_url = unicode(el.attrib['src'])
- stream = BaseAudioStream(index)
- stream.bitrate = 128
- if (mime_type == u'audio/mpeg'):
- stream.format = u'mp3'
- elif (mime_type == u'audio/ogg'):
- stream.format = u'vorbis'
- stream.title = radio.title + ' ' + mime_type
- stream.url = stream_url
- radio.streams.append(stream)
-
- yield radio
-
-
-class ProgramPage(Page):
- def get_current_emission(self):
- current = StreamInfo(0)
- two_or_more = unicode(self.document.xpath('//p')[0].text).split('/////')[0].split(' - ')
- # Consider that if String(' - ') appears it'll be in title rather in the artist name
- if len(two_or_more) > 2:
- current.who = two_or_more.pop(0)
- current.what = ' - '.join(two_or_more)
- else:
- current.who, current.what = two_or_more
- return current
diff --git a/modules/nihonnooto/test.py b/modules/nihonnooto/test.py
deleted file mode 100644
index 93d3e6b5246facba5ea0aca80603a6cad520c713..0000000000000000000000000000000000000000
--- a/modules/nihonnooto/test.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2013 Thomas Lecavelier
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from weboob.tools.test import BackendTest
-
-
-class NihonNoOtoTest(BackendTest):
- MODULE = 'nihonnooto'
-
- def test_nihonnooto(self):
- l = list(self.backend.iter_radios_search(''))
- self.assertTrue(len(l) > 0)
diff --git a/modules/opacwebaloes/__init__.py b/modules/opacwebaloes/__init__.py
deleted file mode 100644
index 4994110be06a12164757b55ba0bbfb88dbe1fbfb..0000000000000000000000000000000000000000
--- a/modules/opacwebaloes/__init__.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2010-2011 Jeremy Monnet
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from .module import AloesModule
-
-__all__ = ['AloesModule']
diff --git a/modules/opacwebaloes/browser.py b/modules/opacwebaloes/browser.py
deleted file mode 100644
index fc2ed81c6c5e78fbcf3f2bfdc6dd7766a81011f2..0000000000000000000000000000000000000000
--- a/modules/opacwebaloes/browser.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2010-2012 Jeremy Monnet
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from weboob.deprecated.browser import Browser, BrowserIncorrectPassword
-
-from .pages import LoginPage, HomePage, RentedPage, HistoryPage, BookedPage
-
-
-__all__ = ['AloesBrowser']
-
-
-# Browser
-class AloesBrowser(Browser):
- PROTOCOL = 'http'
- ENCODING = 'utf-8'
- USER_AGENT = Browser.USER_AGENTS['desktop_firefox']
- #DEBUG_HTTP = True
- DEBUG_HTTP = False
- PAGES = {
- 'http://.*/index.aspx': LoginPage,
- 'http://.*/index.aspx\?IdPage=1': HomePage,
- 'http://.*/index.aspx\?IdPage=45': RentedPage,
- 'http://.*/index.aspx\?IdPage=429': HistoryPage,
- 'http://.*/index.aspx\?IdPage=44': BookedPage
- }
-
- def __init__(self, baseurl, *args, **kwargs):
- self.BASEURL = baseurl
- Browser.__init__(self, *args, **kwargs)
-
- def is_logged(self):
-
- return self.page \
- and not self.page.document.getroot().xpath('//input[contains(@id, "ctl00_ContentPlaceHolder1_ctl00_ctl08_ctl00_TextSaisie")]')
- #return True
-
- def login(self):
- assert isinstance(self.username, basestring)
- assert isinstance(self.password, basestring)
- if not self.is_on_page(HomePage):
- self.location('%s://%s/index.aspx'
- % (self.PROTOCOL, self.BASEURL),
- no_login=True)
- if not self.page.login(self.username, self.password) or \
- not self.is_logged() or \
- (self.is_on_page(LoginPage) and self.page.is_error()):
- raise BrowserIncorrectPassword()
-
- def get_rented_books_list(self):
- if not self.is_on_page(RentedPage):
- self.location('%s://%s/index.aspx?IdPage=45'
- % (self.PROTOCOL, self.BASEURL)
- )
- return self.page.get_list()
-
- def get_booked_books_list(self):
- if not self.is_on_page(BookedPage):
- self.location('%s://%s/index.aspx?IdPage=44'
- % (self.PROTOCOL, self.BASEURL))
- return self.page.get_list()
diff --git a/modules/opacwebaloes/favicon.png b/modules/opacwebaloes/favicon.png
deleted file mode 100644
index beb49765fedb9f26637f9ee95ec30d7b77b1fdc5..0000000000000000000000000000000000000000
Binary files a/modules/opacwebaloes/favicon.png and /dev/null differ
diff --git a/modules/opacwebaloes/module.py b/modules/opacwebaloes/module.py
deleted file mode 100644
index 5f1571e937e6ad333a66d4431d3267a71aecf711..0000000000000000000000000000000000000000
--- a/modules/opacwebaloes/module.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2010-2012 Jeremy Monnet
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from weboob.capabilities.library import CapBook
-from weboob.tools.backend import Module, BackendConfig
-from weboob.tools.value import ValueBackendPassword, Value
-
-from .browser import AloesBrowser
-
-
-__all__ = ['AloesModule']
-
-
-class AloesModule(Module, CapBook):
- NAME = 'opacwebaloes'
- MAINTAINER = u'Jeremy Monnet'
- EMAIL = 'jmonnet@gmail.com'
- VERSION = '1.4'
- DESCRIPTION = 'Aloes Library software'
- LICENSE = 'AGPLv3+'
- CONFIG = BackendConfig(Value('login', label='Account ID', regexp='^\d{1,8}\w$'),
- ValueBackendPassword('password', label='Password of account'),
- Value('baseurl', label='Base URL')
- )
- BROWSER = AloesBrowser
-
- def create_default_browser(self):
- return self.create_browser(self.config['baseurl'].get(),
- self.config['login'].get(),
- self.config['password'].get())
-
- def iter_rented(self):
- for book in self.browser.get_rented_books_list():
- yield book
-
- def iter_booked(self):
- for book in self.browser.get_booked_books_list():
- yield book
-
- def iter_books(self):
- for book in self.iter_booked():
- yield book
- for book in self.iter_rented():
- yield book
-
- def get_book(self, _id):
- raise NotImplementedError()
-
- def search_books(self, _string):
- raise NotImplementedError()
diff --git a/modules/opacwebaloes/pages.py b/modules/opacwebaloes/pages.py
deleted file mode 100644
index f05b6226dce4a1eec8ddb47bf74f9ee971766166..0000000000000000000000000000000000000000
--- a/modules/opacwebaloes/pages.py
+++ /dev/null
@@ -1,117 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2010-2012 Jeremy Monnet
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-from datetime import date
-
-from mechanize import TextControl
-
-from weboob.capabilities.library import Book
-from weboob.deprecated.browser import BrowserUnavailable, Page
-
-
-class SkipPage(Page):
- pass
-
-
-class HomePage(Page):
- pass
-
-
-def txt2date(s):
- return date(*reversed([int(x) for x in s.split(' ')[-1].split('/')]))
-
-
-class RentedPage(Page):
- # TODO, table limited to 20 items, need to use pagination
- def get_list(self):
- for book in self.iter_books('//tr[contains(@id, "ctl00_ContentPlaceHolder1_ctl00_ctl07_COMPTE_PRET_1_1_GrillePrets_ctl00__")]', 1):
- book.late = False
- yield book
-
- for book in self.iter_books('//tr[contains(@id, "ctl00_ContentPlaceHolder1_ctl00_ctl08_COMPTE_RETARD_0_1_GrilleRetards_ctl00__")]', 0):
- book.late = True
- yield book
-
- def iter_books(self, el, start):
- for tr in self.document.getroot().xpath(el):
- book = Book(tr[start].text)
- book.name = tr[start+3].text
- book.author = tr[start+4].text
- book.date = txt2date(tr[start+5].text)
- yield book
-
-
-class HistoryPage(Page):
- pass
-
-
-class BookedPage(Page):
- # TODO, table limited to 20 items, need to use pagination
- def get_list(self):
- for tr in self.document.getroot().xpath('//tr[contains(@id, "ctl00_ContentPlaceHolder1_ctl00_ctl09_COMPTE_INFOS_0_GrilleInfos_ctl00__0")]'):
- username=tr[1].text+"_"+tr[0].text
-
- for i, tr in enumerate(self.document.getroot().xpath('//tr[contains(@id, "ctl00_ContentPlaceHolder1_ctl00_ctl10_COMPTE_RESA_1_1_GrilleResas_ctl00__")]')):
- book = Book('%s%d' % (username, i))
- # if all the books booked are available, there are only 7 columns.
- # if (at least ?) one book is still not available, yous can cancel, and the first column does contain the checkbox. So 8 columns.
- if (len(tr) == 7):
- start = 2
- if (len(tr) == 8):
- start = 3
- book.name = tr[start].text
- book.author = tr[start+1].text
- book.date = txt2date(tr[start+3].text)
- book.late = False
- yield book
-
-
-class LoginPage(Page):
- def login(self, login, passwd):
- self.browser.select_form(predicate=lambda x: x.attrs.get('id','')=='aspnetForm')
- self.browser.form.set_all_readonly(False)
- self.browser['ctl00$ContentPlaceHolder1$ctl00$ctl04$ctl00$TextSaisie'] = login
- self.browser['ctl00$ContentPlaceHolder1$ctl00$ctl04$ctl00$TextPass'] = passwd
- self.browser['ctl00_ScriptManager1_TSM']="%3B%3BSystem.Web.Extensions%2C%20Version%3D1.0.61025.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3D31bf3856ad364e35%3Afr-FR%3A1f0f78f9-0731-4ae9-b308-56936732ccb8%3Aea597d4b%3Ab25378d2%3BTelerik.Web.UI%2C%20Version%3D2009.3.1314.20%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3D121fae78165ba3d4%3Afr-FR%3Aec1048f9-7413-49ac-913a-b3b534cde186%3A16e4e7cd%3Aed16cbdc%3Af7645509%3A24ee1bba%3A19620875%3A874f8ea2%3A33108d14%3Abd8f85e4"
- self.browser.controls.append(TextControl('text', 'RadAJAXControlID', {'value': ''}))
- self.browser['RadAJAXControlID']="ctl00_ContentPlaceHolder1_ctl00_ctl04_ctl00_RadAjaxPanelConnexion"
- self.browser.controls.append(TextControl('text', 'ctl00$ScriptManager1', {'value': ''}))
- self.browser['ctl00$ScriptManager1']="ctl00$ContentPlaceHolder1$ctl00$ctl04$ctl00$ctl00$ContentPlaceHolder1$ctl00$ctl04$ctl00$RadAjaxPanelConnexionPanel|"
- self.browser.controls.append(TextControl('text', '__EVENTTARGET', {'value': ''}))
- self.browser.controls.append(TextControl('text', '__EVENTARGUMENT', {'value': ''}))
- self.browser.controls.append(TextControl('text', 'ctl00$ContentPlaceHolder1$ctl00$ctl04$ctl00$btnImgConnexion.x', {'value': ''}))
- self.browser['ctl00$ContentPlaceHolder1$ctl00$ctl04$ctl00$btnImgConnexion.x']="76"
- self.browser.controls.append(TextControl('text', 'ctl00$ContentPlaceHolder1$ctl00$ctl04$ctl00$btnImgConnexion.y', {'value': ''}))
- self.browser['ctl00$ContentPlaceHolder1$ctl00$ctl04$ctl00$btnImgConnexion.y']="10"
-
- try:
- self.browser.submit()
- except BrowserUnavailable:
- # Login is not valid
- return False
- return True
-
- def is_error(self):
- for text in self.document.find('body').itertext():
- text=text.strip()
- # Login seems valid, but password does not
- needle='Echec lors de l\'authentification'
- if text.startswith(needle.decode('utf-8')):
- return True
- return False
diff --git a/modules/sfr/__init__.py b/modules/sfr/__init__.py
deleted file mode 100644
index 1b5ffb1af9bfbbf37e7ee7e3b5b6ad5b486d8e09..0000000000000000000000000000000000000000
--- a/modules/sfr/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from .module import SfrModule
-
-__all__ = ['SfrModule']
diff --git a/modules/sfr/browser.py b/modules/sfr/browser.py
deleted file mode 100644
index bfc21ffd25fabc56cf2f1d8c306225a82e37d880..0000000000000000000000000000000000000000
--- a/modules/sfr/browser.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2010-2011 Christophe Benz
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from weboob.tools.compat import quote_plus
-
-from .pages.compose import ClosePage, ComposePage, ConfirmPage, SentPage
-from .pages.login import LoginPage
-
-from weboob.deprecated.browser import Browser, BrowserIncorrectPassword
-
-
-__all__ = ['SfrBrowser']
-
-
-class SfrBrowser(Browser):
- DOMAIN = 'www.sfr.fr'
- PAGES = {
- 'http://messagerie-.+.sfr.fr/webmail/close_xms_tab.html': ClosePage,
- 'http://www.sfr.fr/xmscomposer/index.html\?todo=compose': ComposePage,
- 'http://www.sfr.fr/xmscomposer/mc/envoyer-texto-mms/confirm.html': ConfirmPage,
- 'https://www.sfr.fr/cas/login\?service=.*': LoginPage,
- 'http://www.sfr.fr/xmscomposer/mc/envoyer-texto-mms/send.html': SentPage,
- }
-
- def get_nb_remaining_free_sms(self):
- if not self.is_on_page(ComposePage):
- self.home()
- return self.page.get_nb_remaining_free_sms()
-
- def home(self):
- self.location('http://www.sfr.fr/xmscomposer/index.html?todo=compose')
-
- def is_logged(self):
- return 'loginForm' not in [form.name for form in self.forms()]
-
- def login(self):
- service_url = 'http://www.sfr.fr/xmscomposer/j_spring_cas_security_check'
- self.location('https://www.sfr.fr/cas/login?service=%s' % quote_plus(service_url), no_login=True)
- self.page.login(self.username, self.password)
- if not self.is_logged():
- raise BrowserIncorrectPassword()
-
- def post_message(self, message):
- if not self.is_on_page(ComposePage):
- self.home()
- self.page.post_message(message)
- if self.is_on_page(ConfirmPage):
- self.page.confirm()
- assert self.is_on_page(ClosePage) or self.is_on_page(SentPage)
diff --git a/modules/sfr/favicon.png b/modules/sfr/favicon.png
deleted file mode 100644
index a1ef62f8b3078a07b3f13a780be1f94f6ad0d2a3..0000000000000000000000000000000000000000
Binary files a/modules/sfr/favicon.png and /dev/null differ
diff --git a/modules/sfr/module.py b/modules/sfr/module.py
deleted file mode 100644
index c85af633d092efc9876e12924d2fbbaa70321649..0000000000000000000000000000000000000000
--- a/modules/sfr/module.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2010-2011 Christophe Benz
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from weboob.capabilities.messages import CantSendMessage, CapMessages, CapMessagesPost
-from weboob.capabilities.account import CapAccount, StatusField
-from weboob.tools.backend import Module, BackendConfig
-from weboob.tools.value import Value, ValueBackendPassword
-
-from .browser import SfrBrowser
-
-
-__all__ = ['SfrModule']
-
-
-class SfrModule(Module, CapAccount, CapMessages, CapMessagesPost):
- NAME = 'sfr'
- MAINTAINER = u'Christophe Benz'
- EMAIL = 'christophe.benz@gmail.com'
- VERSION = '1.4'
- DESCRIPTION = 'SFR French mobile phone provider'
- LICENSE = 'AGPLv3+'
- CONFIG = BackendConfig(Value('login', label='Login'),
- ValueBackendPassword('password', label='Password'))
- BROWSER = SfrBrowser
- ACCOUNT_REGISTER_PROPERTIES = None
-
- def create_default_browser(self):
- return self.create_browser(self.config['login'].get(), self.config['password'].get())
-
- # CapMessagesPost methods
-
- def get_account_status(self):
- with self.browser:
- return (StatusField('nb_remaining_free_sms', 'Number of remaining free SMS',
- self.browser.get_nb_remaining_free_sms()),)
-
- def post_message(self, message):
- if not message.content.strip():
- raise CantSendMessage(u'Message content is empty.')
- with self.browser:
- self.browser.post_message(message)
diff --git a/modules/sfr/pages/__init__.py b/modules/sfr/pages/__init__.py
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/modules/sfr/pages/compose.py b/modules/sfr/pages/compose.py
deleted file mode 100644
index 6e089111591f74fc019d97d9684995cda44112d2..0000000000000000000000000000000000000000
--- a/modules/sfr/pages/compose.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2010-2011 Christophe Benz
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-import re
-
-from weboob.capabilities.messages import CantSendMessage
-from weboob.deprecated.browser import Page
-
-
-class ClosePage(Page):
- pass
-
-
-class ComposePage(Page):
- phone_regex = re.compile('^(\+33|0033|0)(6|7)(\d{8})$')
-
- def get_nb_remaining_free_sms(self):
- nbSms = self.parser.select(self.document.getroot(), '#freeSms',1).text.strip()
- return nbSms
-
- def post_message(self, message):
- receiver = message.thread.id
- if self.phone_regex.match(receiver) is None:
- raise CantSendMessage(u'Invalid receiver: %s' % receiver)
- self.browser.select_form(nr=0)
- self.browser['msisdns'] = receiver
- self.browser['textMessage'] = message.content.encode('utf-8')
- self.browser.submit()
-
-
-class ConfirmPage(Page):
- def confirm(self):
- self.browser.select_form(nr=0)
- self.browser.submit()
-
-
-class SentPage(Page):
- pass
diff --git a/modules/sfr/pages/login.py b/modules/sfr/pages/login.py
deleted file mode 100644
index dd868562dea98114abc51559240de10fb9dd1f76..0000000000000000000000000000000000000000
--- a/modules/sfr/pages/login.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2010-2011 Christophe Benz
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from weboob.deprecated.browser import Page
-
-
-class LoginPage(Page):
- def login(self, login, password):
- self.browser.select_form(nr=0)
- self.browser['username'] = login
- self.browser['password'] = password
- self.browser['remember-me'] = ['on']
- self.browser.submit()
diff --git a/modules/sfr/test.py b/modules/sfr/test.py
deleted file mode 100644
index 39685024ee6bead21360db98c77700cc7d628317..0000000000000000000000000000000000000000
--- a/modules/sfr/test.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2010-2011 Christophe Benz
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-from weboob.tools.test import BackendTest
-
-
-class SFRTest(BackendTest):
- MODULE = 'sfr'
-
- def test_sfr(self):
- pass
-
- def test_create_default_browser(self):
- connect = self.backend.create_default_browser()
- assert connect
-
- def test_get_account_status(self):
- nbSms = self.backend.get_account_status()
- assert nbSms
- assert isinstance(nbSms[0].value, str)
diff --git a/modules/trictractv/__init__.py b/modules/trictractv/__init__.py
deleted file mode 100644
index 35008fa3a8d6ecf068a63858715afb81befd37ee..0000000000000000000000000000000000000000
--- a/modules/trictractv/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from .module import TricTracTVModule
-
-__all__ = ['TricTracTVModule']
diff --git a/modules/trictractv/browser.py b/modules/trictractv/browser.py
deleted file mode 100644
index 900b4641bbb9bac65c5777633fd8f4ff24073bf7..0000000000000000000000000000000000000000
--- a/modules/trictractv/browser.py
+++ /dev/null
@@ -1,78 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2011-2012 Romain Bignon, Laurent Bachelier, Benjamin Drieu
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-import re
-
-from weboob.deprecated.browser import Browser
-from weboob.deprecated.browser.decorators import id2url
-
-from .pages import IndexPage, VideoPage
-from .video import TricTracTVVideo
-
-
-__all__ = ['TricTracTVBrowser']
-
-
-class TricTracTVBrowser(Browser):
- DOMAIN = 'trictrac.tv'
- ENCODING = 'ISO-8859-1'
- PAGES = {r'http://[w\.]*trictrac.tv/': IndexPage,
- r'http://[w\.]*trictrac.tv/home/listing.php.*': IndexPage,
- r'http://[w\.]*trictrac.tv/video-(.+)': VideoPage,
- }
-
- @id2url(TricTracTVVideo.id2url)
- def get_video(self, url, video=None):
- self.location(url)
- assert self.is_on_page(VideoPage)
-
- _id = self.page.get_id()
- if video is None:
- video = TricTracTVVideo(_id)
-
- infourl = self.page.get_info_url()
- if infourl is not None:
- self.parse_info(self.openurl(infourl).read(), video)
-
- return video
-
- def home(self):
- self.location(self.buildurl('http://www.trictrac.tv/home/listing.php', mot='%'))
-
- def search_videos(self, pattern):
- if not pattern:
- self.home()
- else:
- self.location(self.buildurl('http://www.trictrac.tv/home/listing.php', mot=pattern.encode('utf-8')))
-
- assert self.is_on_page(IndexPage)
- return self.page.iter_videos()
-
- def parse_info(self, data, video):
- m = re.match ( '.*fichier=(.*?)&', data )
- video.url = unicode ( r'http://src.povcon.net/videos/%s' % m.group ( 1 ) )
-
- video.description = self.page.get_descriptif()
- video.duration = self.page.get_duration()
- video.title = self.page.get_title()
- video.date = self.page.get_date()
- video.rating = self.page.get_rating()
- video.rating_max = 5
-
- return video
diff --git a/modules/trictractv/favicon.png b/modules/trictractv/favicon.png
deleted file mode 100644
index c7cae5f497436f242b9413efae9f2d2c43886687..0000000000000000000000000000000000000000
Binary files a/modules/trictractv/favicon.png and /dev/null differ
diff --git a/modules/trictractv/module.py b/modules/trictractv/module.py
deleted file mode 100644
index 611abc384843a3dcb43133fa0365a525d70004d7..0000000000000000000000000000000000000000
--- a/modules/trictractv/module.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2011 Romain Bignon
-# Copyright(C) 2012 Benjamin Drieu
-#
-# This file is *not yet* part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from weboob.capabilities.video import CapVideo
-from weboob.tools.backend import Module
-
-from .browser import TricTracTVBrowser
-from .video import TricTracTVVideo
-
-
-__all__ = ['TricTracTVModule']
-
-
-class TricTracTVModule(Module, CapVideo):
- NAME = 'trictractv'
- MAINTAINER = u'Benjamin Drieu'
- EMAIL = 'benjamin@drieu.org'
- VERSION = '1.4'
- DESCRIPTION = u'TricTrac.tv video website'
- LICENSE = 'AGPLv3+'
- BROWSER = TricTracTVBrowser
-
- def get_video(self, _id):
- with self.browser:
- return self.browser.get_video(_id)
-
- def search_videos(self, pattern=None, sortby=CapVideo.SEARCH_RELEVANCE, nsfw=False):
- with self.browser:
- return self.browser.search_videos(pattern)
-
- def fill_video(self, video, fields):
- if fields != ['thumbnail']:
- # if we don't want only the thumbnail, we probably want also every fields
- with self.browser:
- video = self.browser.get_video(TricTracTVVideo.id2url(video.id), video)
- if 'thumbnail' in fields and video.thumbnail:
- with self.browser:
- video.thumbnail.data = self.browser.readurl(video.thumbnail.url)
-
- return video
-
- OBJECTS = {TricTracTVVideo: fill_video}
diff --git a/modules/trictractv/pages.py b/modules/trictractv/pages.py
deleted file mode 100644
index c5f4db6108ea648d6946f24d6f76e0b636579e89..0000000000000000000000000000000000000000
--- a/modules/trictractv/pages.py
+++ /dev/null
@@ -1,128 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2011-2012 Romain Bignon, Laurent Bachelier
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-import datetime
-import re
-
-from weboob.capabilities.image import Thumbnail
-from weboob.deprecated.browser import Page, BrokenPageError
-
-
-from .video import TricTracTVVideo
-
-
-class IndexPage(Page):
- def iter_videos(self):
- for div in self.parser.select(self.document.getroot(), 'li#contentsearch'):
- title = self.parser.select(div, '#titlesearch span', 1)
-
- a = self.parser.select(div, 'a', 1)
- url = a.attrib['href']
- m = re.match('/video-(.*)', url)
- if not m:
- self.logger.debug('url %s does not match' % url)
- continue
- _id = m.group(1)
- video = TricTracTVVideo(_id)
- video.title = unicode(title.text)
-
- url = self.parser.select(div, 'img', 1).attrib['src']
- stars = self.parser.select(div, '.etoile_on')
- video.rating = len(stars)
- video.rating_max = 5
-
- video.thumbnail = Thumbnail('http://www.trictrac.tv/%s' % url)
- video.thumbnail.url = video.thumbnail.id
-
- yield video
-
-
-class VideoPage(Page):
- def on_loaded(self):
- p = self.parser.select(self.document.getroot(), 'p.alert')
- if len(p) > 0:
- raise Exception(p[0].text)
-
- def get_info_url(self):
- try:
- div = self.parser.select(self.document.getroot(), '#Content_Video object', 1)
- except BrokenPageError:
- return None
- else:
- for param in self.parser.select(div, 'param', None):
- if param.get('name') == 'flashvars':
- m = re.match('varplaymedia=([0-9]*)', param.attrib['value'])
- if m:
- return r'http://www.trictrac.tv/swf/listelement.php?idfile=%s' % m.group(1)
-
- def get_title(self):
- try:
- title = self.parser.select(self.document.getroot(), 'title', 1)
- except BrokenPageError:
- return None
- else:
- return title.text
-
- def get_descriptif(self):
- try:
- descriptif = self.parser.select(self.document.getroot(), '.video_descriptif p', 1)
- except BrokenPageError:
- return None
- else:
- return descriptif.text
-
- def get_duration(self):
- try:
- details = self.parser.select(self.document.getroot(), 'div#video_detail div')
- except BrokenPageError:
- return None
- else:
- duration = details[2]
- duration_string = duration.text [ duration.text.rfind ( ' ' ) + 1 : ]
- tokens = duration_string.split(':')
- if len(tokens) > 2:
- return datetime.timedelta(hours=int(tokens[0]), minutes=int(tokens[1]), seconds=int(tokens[2]))
- else:
- return datetime.timedelta(minutes=int(tokens[0]), seconds=int(tokens[1]))
-
- def get_date(self):
- try:
- date = self.parser.select(self.document.getroot(), 'div#video_detail div.date', 1)
- except BrokenPageError:
- return None
- else:
- string = date.text
- string = string [ string.rfind('le ') + 3 : ]
- months = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ]
- words = string.split ( ' ' )
- month_no = months.index ( words [ 1 ] ) + 1
- return datetime.datetime.strptime ( ( '%s %s %s %s' %
- ( words [ 0 ], month_no, words [ 2 ], words [ 3 ] ) ),
- '%d %m %Y, %H:%M:%S')
-
- def get_rating(self):
- try:
- stars = self.parser.select(self.document.getroot(), '#video_info .etoile_on')
- except BrokenPageError:
- return None
- else:
- return len(stars)
-
- def get_id(self):
- return self.groups[0]
diff --git a/modules/trictractv/test.py b/modules/trictractv/test.py
deleted file mode 100644
index cda4bae2c788df882c875707d29f8e2eb573eaed..0000000000000000000000000000000000000000
--- a/modules/trictractv/test.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2011-2012 Romain Bignon, Laurent Bachelier
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from weboob.tools.test import BackendTest
-
-
-class TricTracTVTest(BackendTest):
- MODULE = 'trictractv'
-
- def test_trictractv(self):
- l = list(self.backend.search_videos('TricTrac'))
- self.assertTrue(len(l) > 0)
- v = l[0]
- self.backend.fillobj(v, ('url',))
- self.assertTrue(v.url and v.url.startswith('http://'), 'URL for video "%s" not found: %s' % (v.id, v.url))
diff --git a/modules/trictractv/video.py b/modules/trictractv/video.py
deleted file mode 100644
index 1a38c257b19d5cfbf0330dc0e1272e08c032bb75..0000000000000000000000000000000000000000
--- a/modules/trictractv/video.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2011 Romain Bignon
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from weboob.capabilities.video import BaseVideo
-
-
-class TricTracTVVideo(BaseVideo):
- def __init__(self, *args, **kwargs):
- BaseVideo.__init__(self, *args, **kwargs)
- self.ext = u'flv'
-
- @classmethod
- def id2url(cls, _id):
- return 'http://www.trictrac.tv/video-%s' % _id
diff --git a/modules/unsee/__init__.py b/modules/unsee/__init__.py
deleted file mode 100644
index d3aa6c4f2c63ca175d22da1bf22084a7514d1782..0000000000000000000000000000000000000000
--- a/modules/unsee/__init__.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2014 Vincent A
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from .module import UnseeModule
-
-
-__all__ = ['UnseeModule']
diff --git a/modules/unsee/browser.py b/modules/unsee/browser.py
deleted file mode 100644
index a3c265361a8fef2833f30033cb4b42e37eab6682..0000000000000000000000000000000000000000
--- a/modules/unsee/browser.py
+++ /dev/null
@@ -1,94 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2014 Vincent A
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from weboob.deprecated.browser import Browser
-import os
-from uuid import uuid4
-from urllib2 import Request
-from weboob.tools.compat import urljoin
-from weboob.tools.json import json
-from weboob.deprecated.browser.parsers.lxmlparser import LxmlHtmlParser
-
-
-__all__ = ['UnseeBrowser']
-
-
-def to_bytes(s):
- if isinstance(s, unicode):
- return s.encode('utf-8')
- else:
- return s
-
-
-class FileField(object):
- def __init__(self, filename, contents=None, headers=None):
- self.filename = to_bytes(os.path.basename(filename))
- self.headers = headers or {}
- if contents is not None:
- self.contents = contents
- else:
- self.contents = open(filename).read()
-
-
-class UnseeBrowser(Browser):
- PROTOCOL = 'https'
- DOMAIN = 'unsee.cc'
- ENCODING = 'utf-8'
-
- def _make_boundary(self):
- return '==%s==' % uuid4()
-
- def _make_multipart(self, pairs, boundary):
- s = []
- for k, v in pairs:
- s.append('--%s' % boundary)
- if isinstance(v, FileField):
- s.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (k, v.filename))
- for hk, hv in v.headers.items():
- s.append('%s: %s' % (hk, hv))
- v = v.contents
- else:
- s.append('Content-Disposition: form-data; name="%s"' % k)
- s.append('')
- s.append(to_bytes(v))
- s.append('--%s--' % boundary)
- s.append('')
- return '\r\n'.join(s)
-
- def _multipart(self, url, fields):
- b = self._make_boundary()
- data = self._make_multipart(fields, b)
- headers = {'Content-type': 'multipart/form-data; boundary=%s' % b, 'Content-length': len(data)}
- return Request(url, data=self._make_multipart(fields, b), headers=headers)
-
- def post_image(self, name, contents, time):
- # time='first' for one-shot view
-
- params = [('time', time), ('image[]', FileField(name or '-', contents))]
- request = self._multipart('https://unsee.cc/upload/', params)
-
- d = json.loads(self.readurl(request))
- return {'id': d['hash']}
-
- def get_image(self, id):
- doc = self.get_document(self.openurl('https://unsee.cc/%s/' % id))
- images = LxmlHtmlParser.select(doc, '//img/@src[starts-with(., "/image/")]', method='xpath')
- url = urljoin('https://unsee.cc', images[0])
- return self.readurl(url)
diff --git a/modules/unsee/favicon.png b/modules/unsee/favicon.png
deleted file mode 100644
index 454f0b014a3fcd49fa40f6a64d0b12e85072e3dc..0000000000000000000000000000000000000000
Binary files a/modules/unsee/favicon.png and /dev/null differ
diff --git a/modules/unsee/module.py b/modules/unsee/module.py
deleted file mode 100644
index 5ca71add5d60af6a0123400735eb2fd41ed56638..0000000000000000000000000000000000000000
--- a/modules/unsee/module.py
+++ /dev/null
@@ -1,78 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2014 Vincent A
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from weboob.tools.backend import Module
-from weboob.capabilities.paste import BasePaste
-from weboob.tools.capabilities.paste import BasePasteModule
-from weboob.tools.capabilities.paste import image_mime
-from weboob.deprecated.browser.decorators import check_url
-import re
-
-from .browser import UnseeBrowser
-
-
-__all__ = ['UnseeModule']
-
-
-class UnPaste(BasePaste):
- @classmethod
- def id2url(cls, id):
- return 'https://unsee.cc/%s' % id
-
-
-class UnseeModule(Module, BasePasteModule):
- NAME = 'unsee'
- DESCRIPTION = u'unsee.cc expiring image hosting'
- MAINTAINER = u'Vincent A'
- EMAIL = 'dev@indigo.re'
- LICENSE = 'AGPLv3+'
- VERSION = '1.4'
-
- BROWSER = UnseeBrowser
-
- EXPIRATIONS = {3600: 'hour', 86400: 'day', 86400 * 7: 'week'}
-
- def can_post(self, contents, title=None, public=None, max_age=None):
- if re.search(r'[^a-zA-Z0-9=+/\s]', contents):
- return 0
- elif max_age is not None and not self.get_closest_expiration(max_age):
- return 0
- else:
- mime = image_mime(contents, ('gif', 'jpeg', 'png'))
- return 20 * int(mime is not None)
-
- @check_url('https?://unsee.cc/.+')
- def get_paste(self, id):
- paste = UnPaste(id)
- paste.contents = self.browser.get_image(id).encode('base64')
- return paste
-
- def new_paste(self, *a, **kw):
- return UnPaste(*a, **kw)
-
- def post_paste(self, paste, max_age=None):
- if max_age is None:
- max_code = 'week'
- else:
- max_code = self.EXPIRATIONS[self.get_closest_expiration(max_age)]
-
- d = self.browser.post_image(paste.title, paste.contents.decode('base64'), max_code)
- paste.id = d['id']
- return paste
diff --git a/modules/unsee/test.py b/modules/unsee/test.py
deleted file mode 100644
index 08a44ae420f967ad64880d5aba0eadb35efef1de..0000000000000000000000000000000000000000
--- a/modules/unsee/test.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2014 Vincent A
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from weboob.tools.test import BackendTest
-
-
-class UnseeTest(BackendTest):
- MODULE = 'unsee'
-
- # small gif file
- DATA = 'R0lGODlhAQABAIAAAP///wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==\n'
-
- def test_unsee(self):
- assert self.backend.can_post(self.DATA, max_age=3600)
-
- post = self.backend.new_paste(None)
- post.contents = self.DATA
- post = self.backend.post_paste(post, max_age=3600)
- assert post.id
-
- got = self.backend.get_paste(post.id)
- assert got
- assert got.contents.decode('base64').startswith('GIF89a')
- # we can't check the exact data, unsee.cc modifies the images...
diff --git a/modules/ups/__init__.py b/modules/ups/__init__.py
deleted file mode 100644
index aac6131314c120e93aeadac907defedc6176db20..0000000000000000000000000000000000000000
--- a/modules/ups/__init__.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2013 Romain Bignon
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from .module import UpsModule
-
-
-__all__ = ['UpsModule']
diff --git a/modules/ups/browser.py b/modules/ups/browser.py
deleted file mode 100644
index be6f533180064cc8efc41392b169936da5275296..0000000000000000000000000000000000000000
--- a/modules/ups/browser.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2013 Romain Bignon
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-from weboob.deprecated.browser import Browser
-from weboob.tools.compat import urlencode
-
-from .pages import TrackPage
-
-
-__all__ = ['UpsBrowser']
-
-
-class UpsBrowser(Browser):
- PROTOCOL = 'https'
- DOMAIN = 'wwwapps.ups.com'
- ENCODING = None
-
- PAGES = {
- 'https://wwwapps.ups.com/WebTracking/track': TrackPage,
- }
-
- def get_tracking_info(self, _id):
- data = {'HTMLVersion': '5.0',
- 'USER_HISTORY_LIST': '',
- 'loc': 'en_US',
- 'track.x': 'Track',
- 'trackNums': _id.encode('utf-8'),
- }
- self.location('https://wwwapps.ups.com/WebTracking/track', urlencode(data))
- assert self.is_on_page(TrackPage)
-
- return self.page.get_info(_id)
diff --git a/modules/ups/favicon.png b/modules/ups/favicon.png
deleted file mode 100644
index 17e6a4064115fe9c5d36947ad03ed5bdeaf20b7b..0000000000000000000000000000000000000000
Binary files a/modules/ups/favicon.png and /dev/null differ
diff --git a/modules/ups/module.py b/modules/ups/module.py
deleted file mode 100644
index 4ca9bc432ec12745779b2abb55699aaad493563e..0000000000000000000000000000000000000000
--- a/modules/ups/module.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2013 Romain Bignon
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-from weboob.capabilities.parcel import CapParcel
-from weboob.tools.backend import Module
-
-from .browser import UpsBrowser
-
-
-__all__ = ['UpsModule']
-
-
-class UpsModule(Module, CapParcel):
- NAME = 'ups'
- DESCRIPTION = u'UPS website'
- MAINTAINER = u'Romain Bignon'
- EMAIL = 'romain@weboob.org'
- VERSION = '1.4'
-
- BROWSER = UpsBrowser
-
- def get_parcel_tracking(self, id):
- with self.browser:
- return self.browser.get_tracking_info(id)
diff --git a/modules/ups/pages.py b/modules/ups/pages.py
deleted file mode 100644
index 907b4dab2630dfef57c41bf21fcd19a2cae880f2..0000000000000000000000000000000000000000
--- a/modules/ups/pages.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright(C) 2013 Romain Bignon
-#
-# This file is part of weboob.
-#
-# weboob is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# weboob is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with weboob. If not, see .
-
-
-import re
-from dateutil.parser import parse as parse_date
-
-from weboob.capabilities.parcel import Parcel, Event
-from weboob.deprecated.browser import Page
-
-
-class TrackPage(Page):
- def get_info(self, id):
- if len(self.parser.tocleanstring(self.document.xpath('//p[@class="error"]')[0])) > 0:
- return None
-
- p = Parcel(id)
- for dl in self.document.xpath('//dl'):
- dt = dl.find('dt')
- dd = dl.find('dd')
- if dt is None or dd is None:
- continue
- label = self.parser.tocleanstring(dt)
- if label == 'Scheduled Delivery:':
- p.status = p.STATUS_IN_TRANSIT
- elif label == u'Delivered On:':
- p.status = p.STATUS_ARRIVED
- else:
- continue
-
- m = re.search('(\d+/\d+/\d+)', dd.text)
- if m:
- p.arrival = parse_date(m.group(1))
-
- p.history = []
- for i, tr in enumerate(self.document.xpath('//table[@class="dataTable"]//tr')):
- tds = tr.findall('td')
- if len(tds) < 4:
- continue
-
- ev = Event(i)
- ev.location = self.parser.tocleanstring(tds[0])
- ev.activity = self.parser.tocleanstring(tds[-1])
- ev.date = parse_date('%s %s' % (tds[1].text, tds[2].text))
- p.history.append(ev)
-
- p.info = self.document.xpath('//a[@id="tt_spStatus"]')[0].text.strip()
-
- return p