Newer
Older
# This woob module 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.
#
# This woob module 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 this woob module. If not, see <http://www.gnu.org/licenses/>.
from woob.capabilities.base import StringField
from woob.capabilities.gallery import BaseGallery, BaseImage, CapGallery
from woob.capabilities.image import CapImage, Thumbnail
from woob.capabilities.paste import BasePaste, CapPaste
from woob.tools.backend import Module
from woob.tools.capabilities.paste import image_mime
from woob.tools.date import datetime
class ImgPaste(BasePaste):
delete_url = StringField('URL to delete the image')
@classmethod
def id2url(cls, id):
@property
def raw_url(self):
# TODO get the right extension
class Img(BaseImage):
@property
def thumbnail_url(self):
return ImgPaste(self.id + 't').raw_url
@property
def raw_url(self):
return 'https://i.imgur.com/%s.%s' % (self.id, self.ext)
class ImgGallery(BaseGallery):
def __init__(self, *args, **kwargs):
super(ImgGallery, self).__init__(*args, **kwargs)
self._imgs = []
@classmethod
def id2url(cls, id):
return 'https://imgur.com/gallery/%s' % id
def iter_image(self):
return self._imgs
class ImgurModule(Module, CapPaste, CapGallery, CapImage):
NAME = 'imgur'
DESCRIPTION = u'imgur image upload service'
MAINTAINER = u'Vincent A'
EMAIL = 'dev@indigo.re'
LICENSE = 'AGPLv3+'
IMGURL = re.compile(r'https?://(?:[a-z]+\.)?imgur.com/([a-zA-Z0-9]+)(?:\.[a-z]+)?$')
GALLURL = re.compile(r'https?://(?:[a-z]+\.)?imgur.com/a/([a-zA-Z0-9]+)/?$')
def new_paste(self, *a, **kw):
return ImgPaste(*a, **kw)
def can_post(self, contents, title=None, public=None, max_age=None):
if public is False:
return 0
elif re.search(r'[^a-zA-Z0-9=+/\s]', contents):
return 0
elif max_age:
return 0
else:
mime = image_mime(contents, ('gif', 'jpeg', 'png', 'tiff', 'xcf', 'pdf'))
return 20 * int(mime is not None)
def get_paste(self, id):
mtc = self.IMGURL.match(id)
if mtc:
id = mtc.group(1)
elif not self.ID.match(id):
return None
bin = self.browser.open_raw(paste.raw_url).content
return paste
def post_paste(self, paste, max_age=None):
res = self.browser.post_image(b64=paste.contents, title=paste.title)
paste.id = res['id']
paste.delete_url = res['delete_url']
# CapGallery
def _build_img(self, d, n, gallery):
img = Img(d['id'], gallery=gallery, url=d['link'], index=n)
img.title = d['title'] or u''
img.description = d['description'] or u''
img.ext = img.url.rsplit('.', 1)[-1]
img.thumbnail = Thumbnail(img.thumbnail_url)
img.nsfw = bool(d['nsfw'])
img.size = d['size']
return img
def _build_gallery(self, d):
gallery = ImgGallery(d['id'], url=d['link'])
gallery.title = d['title'] or u''
gallery.description = d['description'] or u''
gallery.date = datetime.fromtimestamp(d['datetime'])
gallery.thumbnail = Thumbnail(Img(d['cover']).thumbnail_url)
if 'images' in d:
for n, d in enumerate(d['images']):
img = self._build_img(d, n, gallery)
gallery._imgs.append(img)
gallery.cardinality = len(gallery._imgs)
return gallery
def get_gallery(self, id):
mtc = self.GALLURL.match(id)
if mtc:
id = mtc.group(1)
elif not self.ID.match(id):
return None
d = self.browser.get_gallery(id)
if d is None:
return None
return self._build_gallery(d)
def iter_gallery_images(self, gallery):
if not len(gallery._imgs):
new = self.get_gallery(gallery.id)
gallery._imgs = new._imgs
return gallery._imgs
def search_galleries(self, pattern, sortby=CapGallery.SEARCH_RELEVANCE):
d = self.browser.search_items(pattern, sortby)
for sub in d:
if sub['is_album']:
yield self._build_gallery(sub)
# CapImage
def get_file(self, id):
mtc = self.IMGURL.match(id)
if mtc:
id = mtc.group(1)
elif not self.ID.match(id):
return None
d = self.browser.get_image(id)
if d is None:
return None
return self._build_img(d, 0, None)
def search_file(self, pattern, sortby=CapGallery.SEARCH_RELEVANCE):
d = self.browser.search_items(pattern, sortby)
for sub in d:
if not sub['is_album']:
yield self._build_img(sub, 0, None)
def search_image(self, pattern, sortby=CapGallery.SEARCH_RELEVANCE, nsfw=False):
for img in self.search_file(pattern, sortby):
if nsfw or not img.nsfw:
yield img
def fill_img(self, img, fields):
if 'data' in fields:
self.browser.fill_file(img, fields)
if 'thumbnail' in fields and img.thumbnail:
self.fillobj(img.thumbnail, None)
OBJECTS = {Img: fill_img, Thumbnail: fill_img, BaseGallery: fill_img}