diff --git a/modules/lutim/__init__.py b/modules/lutim/__init__.py index 44051dff..c6151e94 100644 --- a/modules/lutim/__init__.py +++ b/modules/lutim/__init__.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -# Copyright(C) 2014 Vincent A +# Copyright(C) 2015 Vincent A # # This file is part of weboob. # diff --git a/modules/lutim/browser.py b/modules/lutim/browser.py index 90f119c1..50518c6b 100644 --- a/modules/lutim/browser.py +++ b/modules/lutim/browser.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -# Copyright(C) 2014 Vincent A +# Copyright(C) 2015 Vincent A # # This file is part of weboob. # @@ -18,31 +18,39 @@ # along with weboob. If not, see . -from weboob.deprecated.browser import Browser +import math +from urlparse import urljoin from StringIO import StringIO -import re +from weboob.browser import PagesBrowser, URL -from .pages import PageAll +from .pages import ImagePage, UploadPage -__all__ = ['LutimBrowser'] +class LutimBrowser(PagesBrowser): + BASEURL = 'https://lut.im' + VERIFY = False # XXX SNI is not supported - -class LutimBrowser(Browser): - ENCODING = 'utf-8' + image_page = URL('/(?P.+)', ImagePage) + upload_page = URL('/', UploadPage) def __init__(self, base_url, *args, **kw): - Browser.__init__(self, *args, **kw) - self.base_url = base_url - self.PAGES = {re.escape(self.base_url): PageAll} + PagesBrowser.__init__(self, *args, **kw) + self.base_url = self.BASEURL = base_url - def post(self, name, content, max_days): - self.location(self.base_url) - assert self.is_on_page(PageAll) - self.select_form(nr=0) - self.form['delete-day'] = [str(max_days)] - self.form.find_control('file').add_file(StringIO(content), filename=name) - self.submit() + def fetch(self, paste): + self.location(paste.id) + assert self.image_page.is_here() + paste.contents = unicode(self.page.contents.encode('base64')) + paste.title = self.page.filename - assert self.is_on_page(PageAll) - return self.page.get_info() + def post(self, paste, max_age=0): + bin = paste.contents.decode('base64') + name = paste.title or 'file' # filename is mandatory + filefield = {'file': (name, StringIO(bin))} + params = {'format': 'json'} + if max_age: + params['delete-day'] = math.ceil(max_age / 86400.) + self.location('/', data=params, files=filefield) + assert self.upload_page.is_here() + info = self.page.fetch_info() + paste.id = urljoin(self.base_url, info['short']) diff --git a/modules/lutim/module.py b/modules/lutim/module.py index 737fecd2..537031ee 100644 --- a/modules/lutim/module.py +++ b/modules/lutim/module.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -# Copyright(C) 2014 Vincent A +# Copyright(C) 2015 Vincent A # # This file is part of weboob. # @@ -18,12 +18,12 @@ # along with weboob. If not, see . +import re +from urlparse import urljoin from weboob.tools.backend import Module, BackendConfig from weboob.capabilities.paste import CapPaste, BasePaste from weboob.tools.capabilities.paste import image_mime from weboob.tools.value import Value -import re -from urlparse import urljoin from .browser import LutimBrowser @@ -33,7 +33,7 @@ __all__ = ['LutimModule'] class LutimModule(Module, CapPaste): NAME = 'lutim' - DESCRIPTION = u'LUTIm website' + DESCRIPTION = u'lutim website' MAINTAINER = u'Vincent A' EMAIL = 'dev@indigo.re' LICENSE = 'AGPLv3+' @@ -41,55 +41,45 @@ class LutimModule(Module, CapPaste): BROWSER = LutimBrowser - CONFIG = BackendConfig(Value('base_url', label='Hoster base URL', default='http://lut.im/')) + CONFIG = BackendConfig(Value('base_url', label='Hoster base URL', default='https://lut.im/')) - def _base_url(self): + @property + def base_url(self): url = self.config['base_url'].get() if not url.endswith('/'): url = url + '/' return url def create_default_browser(self): - return self.create_browser(self._base_url()) + return self.create_browser(self.base_url) def can_post(self, contents, title=None, public=None, max_age=None): - if re.search(r'[^a-zA-Z0-9=+/\s]', contents): + if public: return 0 elif max_age and max_age < 86400: return 0 # it cannot be shorter than one day + elif re.search(r'[^a-zA-Z0-9=+/\s]', contents): + return 0 # not base64, thus not binary else: mime = image_mime(contents, ('gif', 'jpeg', 'png')) return 20 * int(mime is not None) - def new_paste(self, *a, **kw): - base_url = self._base_url() + def get_paste(self, url): + if not url.startswith('http'): + url = urljoin(self.base_url, url) + paste = self.new_paste(url) + self.browser.fetch(paste) + return paste - class LutImage(BasePaste): - @classmethod - def id2url(cls, id): - return urljoin(base_url, id) + def new_paste(self, _id): + paste = LutimPaste(_id) + return paste - @classmethod - def url2id(cls, url): - if url.startswith(base_url): - return url[len(base_url):] + def post_paste(self, paste, max_age): + return self.browser.post(paste, max_age) - return LutImage(*a, **kw) - def get_paste(self, id): - paste = self.new_paste(id) - - if '/' in id: - paste.id = paste.url2id(id) - if not paste.id: - return None - - response = self.browser.readurl(paste.page_url) - if response: - paste.contents = response.encode('base64') - return paste - - def post_paste(self, paste, max_age=None): - d = self.browser.post(paste.title or None, paste.contents.decode('base64'), (max_age or 0) // 86400) - if d: - paste.id = d['id'] +class LutimPaste(BasePaste): + @classmethod + def id2url(cls, id): + return id diff --git a/modules/lutim/pages.py b/modules/lutim/pages.py index bb6d4070..72f61262 100644 --- a/modules/lutim/pages.py +++ b/modules/lutim/pages.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -# Copyright(C) 2014 Vincent A +# Copyright(C) 2015 Vincent A # # This file is part of weboob. # @@ -18,17 +18,26 @@ # along with weboob. If not, see . -from weboob.deprecated.browser import Page import re +from weboob.browser.pages import JsonPage, RawPage +from weboob.capabilities.base import UserError -class PageAll(Page): - def post(self, name, content, max_days): - pass +class ImagePage(RawPage): + @property + def contents(self): + return self.doc - def get_info(self): - for link in self.browser.links(): - linkurl = link.absolute_url - m = re.match(re.escape(self.url) + r'([a-zA-Z0-9]+)\?dl$', linkurl) - if m: - return {'id': m.group(1)} + @property + def filename(self): + header = self.response.headers['content-disposition'] + m = re.match('inline;filename="(.*)"', header) + return unicode(m.group(1)) + + +class UploadPage(JsonPage): + def fetch_info(self): + if not self.doc['success']: + raise UserError(self.doc['msg']['msg']) + + return self.doc['msg'] diff --git a/modules/lutim/test.py b/modules/lutim/test.py index 8e729167..42093180 100644 --- a/modules/lutim/test.py +++ b/modules/lutim/test.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -# Copyright(C) 2014 Vincent A +# Copyright(C) 2015 Vincent A # # This file is part of weboob. # @@ -25,17 +25,29 @@ class LutimTest(BackendTest): MODULE = 'lutim' # small gif file - DATA = 'R0lGODlhAQABAIAAAP///wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==\n' + DATA = u'R0lGODlhAQABAIAAAP///wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==\n' + TITLE = u'foo.gif' def test_lutim(self): - assert self.backend.can_post(self.DATA, max_age=86400) - post = self.backend.new_paste(None) post.contents = self.DATA - post.public = True + post.title = self.TITLE + assert self.backend.can_post(post.contents, post.title) self.backend.post_paste(post, max_age=86400) assert post.id got = self.backend.get_paste(post.id) assert got - assert got.contents.decode('base64') == self.DATA.decode('base64') + assert got.title == self.TITLE + assert got.contents == self.DATA + + # test with an empty name + post.title = u'' + self.backend.post_paste(post, max_age=86400) + + def test_invalid(self): + post = self.backend.new_paste(None) + post.contents = u'FAIL' + post.title = self.TITLE + + assert not self.backend.can_post(post.contents, post.title)