From 51a6d63140cc06a0988e2cab4711890ec0711b8b Mon Sep 17 00:00:00 2001 From: Vincent A Date: Wed, 19 Feb 2014 00:50:42 +0100 Subject: [PATCH] new image paste module: lut.im --- modules/lutim/__init__.py | 24 ++++++++++ modules/lutim/backend.py | 95 ++++++++++++++++++++++++++++++++++++++ modules/lutim/browser.py | 48 +++++++++++++++++++ modules/lutim/favicon.png | Bin 0 -> 597 bytes modules/lutim/pages.py | 36 +++++++++++++++ modules/lutim/test.py | 41 ++++++++++++++++ 6 files changed, 244 insertions(+) create mode 100644 modules/lutim/__init__.py create mode 100644 modules/lutim/backend.py create mode 100644 modules/lutim/browser.py create mode 100644 modules/lutim/favicon.png create mode 100644 modules/lutim/pages.py create mode 100644 modules/lutim/test.py diff --git a/modules/lutim/__init__.py b/modules/lutim/__init__.py new file mode 100644 index 00000000..83a0f1b9 --- /dev/null +++ b/modules/lutim/__init__.py @@ -0,0 +1,24 @@ +# -*- 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 .backend import LutimBackend + + +__all__ = ['LutimBackend'] diff --git a/modules/lutim/backend.py b/modules/lutim/backend.py new file mode 100644 index 00000000..6beb07e6 --- /dev/null +++ b/modules/lutim/backend.py @@ -0,0 +1,95 @@ +# -*- 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 BaseBackend, BackendConfig +from weboob.capabilities.paste import ICapPaste, 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 + + +__all__ = ['LutimBackend'] + + +class LutimBackend(BaseBackend, ICapPaste): + NAME = 'lutim' + DESCRIPTION = u'LUTIm website' + MAINTAINER = u'Vincent A' + EMAIL = 'dev@indigo.re' + LICENSE = 'AGPLv3+' + VERSION = '0.i' + + BROWSER = LutimBrowser + + CONFIG = BackendConfig(Value('base_url', label='Hoster base URL', default='http://lut.im/')) + + 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()) + + 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 and max_age < 86400: + return 0 # it cannot be shorter than one day + 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() + + class LutImage(BasePaste): + @classmethod + def id2url(cls, id): + return urljoin(base_url, id) + + @classmethod + def url2id(cls, url): + if url.startswith(base_url): + return url[len(base_url):] + + 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'] diff --git a/modules/lutim/browser.py b/modules/lutim/browser.py new file mode 100644 index 00000000..df04bf33 --- /dev/null +++ b/modules/lutim/browser.py @@ -0,0 +1,48 @@ +# -*- 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.browser import BaseBrowser +from StringIO import StringIO +import re + +from .pages import PageAll + + +__all__ = ['LutimBrowser'] + + +class LutimBrowser(BaseBrowser): + ENCODING = 'utf-8' + + def __init__(self, base_url, *args, **kw): + BaseBrowser.__init__(self, *args, **kw) + self.base_url = base_url + self.PAGES = {re.escape(self.base_url): PageAll} + + 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() + + assert self.is_on_page(PageAll) + return self.page.get_info() diff --git a/modules/lutim/favicon.png b/modules/lutim/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce9e1d363b4608ea77ce3fe182061b8fd8a444e0 GIT binary patch literal 597 zcmV-b0;>IqP)e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00F&8L_t(|+U=TAj>9krL?Oz- z_Glb!Z^r&4mFw76*ER-fkRnx0<7i%H3~CDy6&2M{{4GL`-60&iJE0cBqeb zMkC-J!l;$`0su(AE~9bGTF9#t4%obASoReIk5QQJ0B=zciGU{v+wTEl0KB+B)BzqK ztcn0{3m|Qg+d9B<6qa=Xs}Pp9L5mQU&jHpT#2}<`Q%f!g2WZ{ciVG|_fVTx;VM?^J z2k^E4v|V7S3#ho@)KYtWd0K*iUkxA?&P?y;kXlYa_W)YrA68&az@T3T. + + +from weboob.tools.browser import BasePage +import re + +__all__ = ['PageAll'] + + +class PageAll(BasePage): + def post(self, name, content, max_days): + pass + + def get_info(self): + for link in self.browser.links(): + linkurl = link.absolute_url + m = re.match(re.escape(self.url) + '([a-zA-Z0-9]+)$', linkurl) + if m: + return {'id': m.group(1)} diff --git a/modules/lutim/test.py b/modules/lutim/test.py new file mode 100644 index 00000000..eb224e9c --- /dev/null +++ b/modules/lutim/test.py @@ -0,0 +1,41 @@ +# -*- 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 LutimTest(BackendTest): + BACKEND = 'lutim' + + # small gif file + DATA = 'R0lGODlhAQABAIAAAP///wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==\n' + + 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 + 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')