1
0
mirror of https://github.com/mikf/gallery-dl.git synced 2024-11-26 04:32:51 +01:00
gallery-dl/gallery_dl/extractor/imagehosts.py

328 lines
11 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
# Copyright 2016-2023 Mike Fährmann
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
2016-11-03 18:14:33 +01:00
"""Collection of extractors for various imagehosts"""
from .common import Extractor, Message
from .. import text, exception
from ..cache import memcache
from os.path import splitext
2017-02-01 00:53:19 +01:00
class ImagehostImageExtractor(Extractor):
2016-11-03 18:14:33 +01:00
"""Base class for single-image extractors for various imagehosts"""
basecategory = "imagehost"
subcategory = "image"
archive_fmt = "{token}"
_https = True
_params = None
_cookies = None
_encoding = None
def __init__(self, match):
Extractor.__init__(self, match)
self.page_url = "http{}://{}".format(
"s" if self._https else "", match.group(1))
self.token = match.group(2)
2021-02-10 17:36:45 +01:00
if self._params == "simple":
self._params = {
"imgContinue": "Continue+to+image+...+",
}
elif self._params == "complex":
self._params = {
"op": "view",
"id": self.token,
"pre": "1",
"adb": "1",
"next": "Continue+to+image+...+",
}
def items(self):
page = self.request(
self.page_url,
method=("POST" if self._params else "GET"),
data=self._params,
cookies=self._cookies,
encoding=self._encoding,
).text
url, filename = self.get_info(page)
data = text.nameext_from_url(filename, {"token": self.token})
data.update(self.metadata(page))
if self._https and url.startswith("http:"):
url = "https:" + url[5:]
yield Message.Directory, data
yield Message.Url, url, data
2016-11-03 18:14:33 +01:00
def get_info(self, page):
"""Find image-url and string to get filename from"""
def metadata(self, page):
"""Return additional metadata"""
return ()
class ImxtoImageExtractor(ImagehostImageExtractor):
"""Extractor for single images from imx.to"""
category = "imxto"
pattern = (r"(?:https?://)?(?:www\.)?((?:imx\.to|img\.yt)"
r"/(?:i/|img-)(\w+)(\.html)?)")
example = "https://imx.to/i/ID"
_params = "simple"
_encoding = "utf-8"
def __init__(self, match):
ImagehostImageExtractor.__init__(self, match)
if "/img-" in self.page_url:
self.page_url = self.page_url.replace("img.yt", "imx.to")
self.url_ext = True
else:
self.url_ext = False
def get_info(self, page):
url, pos = text.extract(
page, '<div style="text-align:center;"><a href="', '"')
if not url:
raise exception.NotFoundError("image")
filename, pos = text.extract(page, ' title="', '"', pos)
if self.url_ext and filename:
filename += splitext(url)[1]
return url, filename or url
def metadata(self, page):
extr = text.extract_from(page, page.index("[ FILESIZE <"))
size = extr(">", "</span>").replace(" ", "")[:-1]
width, _, height = extr(">", " px</span>").partition("x")
return {
"size" : text.parse_bytes(size),
"width" : text.parse_int(width),
"height": text.parse_int(height),
"hash" : extr(">", "</span>"),
}
2017-02-01 00:53:19 +01:00
class ImxtoGalleryExtractor(ImagehostImageExtractor):
"""Extractor for image galleries from imx.to"""
category = "imxto"
subcategory = "gallery"
pattern = r"(?:https?://)?(?:www\.)?(imx\.to/g/([^/?#]+))"
example = "https://imx.to/g/ID"
def items(self):
page = self.request(self.page_url).text
title, pos = text.extract(page, '<div class="title', '<')
data = {
"_extractor": ImxtoImageExtractor,
"title": text.unescape(title.partition(">")[2]).strip(),
}
for url in text.extract_iter(page, "<a href=", " ", pos):
yield Message.Queue, url.strip("\"'"), data
class AcidimgImageExtractor(ImagehostImageExtractor):
2017-09-09 15:17:51 +02:00
"""Extractor for single images from acidimg.cc"""
category = "acidimg"
pattern = r"(?:https?://)?((?:www\.)?acidimg\.cc/img-([a-z0-9]+)\.html)"
example = "https://acidimg.cc/img-abc123.html"
_params = "simple"
_encoding = "utf-8"
def get_info(self, page):
url, pos = text.extract(page, "<img class='centred' src='", "'")
if not url:
url, pos = text.extract(page, '<img class="centred" src="', '"')
if not url:
raise exception.NotFoundError("image")
filename, pos = text.extract(page, "alt='", "'", pos)
if not filename:
filename, pos = text.extract(page, 'alt="', '"', pos)
return url, (filename + splitext(url)[1]) if filename else url
2017-09-09 15:17:51 +02:00
2016-11-28 22:30:00 +01:00
class ImagevenueImageExtractor(ImagehostImageExtractor):
"""Extractor for single images from imagevenue.com"""
category = "imagevenue"
pattern = (r"(?:https?://)?((?:www|img\d+)\.imagevenue\.com"
r"/([A-Z0-9]{8,10}|view/.*|img\.php\?.*))")
example = "https://www.imagevenue.com/ME123456789"
2016-11-28 22:30:00 +01:00
def get_info(self, page):
pos = page.index('class="card-body')
url, pos = text.extract(page, '<img src="', '"', pos)
2023-08-29 12:06:30 +02:00
if url.endswith("/loader.svg"):
url, pos = text.extract(page, '<img src="', '"', pos)
filename, pos = text.extract(page, 'alt="', '"', pos)
return url, text.unescape(filename)
2016-11-28 22:30:00 +01:00
2016-11-04 09:33:38 +01:00
class ImagetwistImageExtractor(ImagehostImageExtractor):
"""Extractor for single images from imagetwist.com"""
category = "imagetwist"
pattern = (r"(?:https?://)?((?:www\.|phun\.)?"
r"image(?:twist|haha)\.com/([a-z0-9]{12}))")
example = "https://imagetwist.com/123456abcdef/NAME.EXT"
2017-02-08 22:59:00 +01:00
@property
2019-03-14 22:21:49 +01:00
@memcache(maxage=3*3600)
def _cookies(self):
return self.request(self.page_url).cookies
2017-02-08 22:59:00 +01:00
def get_info(self, page):
2022-12-05 22:15:59 +01:00
url , pos = text.extract(page, '<img src="', '"')
2016-11-04 09:33:38 +01:00
filename, pos = text.extract(page, ' alt="', '"', pos)
return url, filename
2016-11-04 09:33:38 +01:00
class ImagetwistGalleryExtractor(ImagehostImageExtractor):
"""Extractor for galleries from imagetwist.com"""
category = "imagetwist"
subcategory = "gallery"
pattern = (r"(?:https?://)?((?:www\.|phun\.)?"
r"image(?:twist|haha)\.com/(p/[^/?#]+/\d+))")
example = "https://imagetwist.com/p/USER/12345/NAME"
def items(self):
data = {"_extractor": ImagetwistImageExtractor}
root = self.page_url[:self.page_url.find("/", 8)]
page = self.request(self.page_url).text
gallery = text.extr(page, 'class="gallerys', "</div")
for path in text.extract_iter(gallery, ' href="', '"'):
yield Message.Queue, root + path, data
2016-11-04 09:33:38 +01:00
class ImgspiceImageExtractor(ImagehostImageExtractor):
"""Extractor for single images from imgspice.com"""
category = "imgspice"
pattern = r"(?:https?://)?((?:www\.)?imgspice\.com/([^/?#]+))"
example = "https://imgspice.com/ID/NAME.EXT.html"
2016-11-04 09:33:38 +01:00
def get_info(self, page):
2019-03-09 20:29:23 +01:00
pos = page.find('id="imgpreview"')
if pos < 0:
raise exception.NotFoundError("image")
url , pos = text.extract(page, 'src="', '"', pos)
name, pos = text.extract(page, 'alt="', '"', pos)
return url, text.unescape(name)
2017-03-21 15:47:51 +01:00
2016-11-09 12:03:14 +01:00
class PixhostImageExtractor(ImagehostImageExtractor):
2018-05-23 18:32:34 +02:00
"""Extractor for single images from pixhost.to"""
2016-11-09 12:03:14 +01:00
category = "pixhost"
pattern = (r"(?:https?://)?((?:www\.)?pixhost\.(?:to|org)"
r"/show/\d+/(\d+)_[^/?#]+)")
example = "https://pixhost.to/show/123/12345_NAME.EXT"
_cookies = {"pixhostads": "1", "pixhosttest": "1"}
2016-11-09 12:03:14 +01:00
def get_info(self, page):
2017-04-21 13:54:10 +02:00
url , pos = text.extract(page, "class=\"image-img\" src=\"", "\"")
filename, pos = text.extract(page, "alt=\"", "\"", pos)
2016-12-06 10:03:33 +01:00
return url, filename
2016-11-09 12:03:14 +01:00
class PixhostGalleryExtractor(ImagehostImageExtractor):
"""Extractor for image galleries from pixhost.to"""
category = "pixhost"
subcategory = "gallery"
pattern = (r"(?:https?://)?((?:www\.)?pixhost\.(?:to|org)"
r"/gallery/([^/?#]+))")
example = "https://pixhost.to/gallery/ID"
def items(self):
page = text.extr(self.request(
self.page_url).text, 'class="images"', "</div>")
data = {"_extractor": PixhostImageExtractor}
for url in text.extract_iter(page, '<a href="', '"'):
yield Message.Queue, url, data
2016-12-06 12:46:41 +01:00
class PostimgImageExtractor(ImagehostImageExtractor):
2019-01-30 16:18:22 +01:00
"""Extractor for single images from postimages.org"""
2016-12-06 12:46:41 +01:00
category = "postimg"
2023-08-24 15:01:26 +02:00
pattern = (r"(?:https?://)?((?:www\.)?(?:postim(?:ages|g)|pixxxels)"
r"\.(?:cc|org)/(?!gallery/)(?:image/)?([^/?#]+)/?)")
example = "https://postimages.org/ID"
2016-12-06 12:46:41 +01:00
def get_info(self, page):
pos = page.index(' id="download"')
url , pos = text.rextract(page, ' href="', '"', pos)
filename, pos = text.extract(page, 'class="imagename">', '<', pos)
return url, text.unescape(filename)
2016-12-06 12:46:41 +01:00
class PostimgGalleryExtractor(ImagehostImageExtractor):
"""Extractor for images galleries from postimages.org"""
category = "postimg"
subcategory = "gallery"
pattern = (r"(?:https?://)?((?:www\.)?(?:postim(?:ages|g)|pixxxels)"
r"\.(?:cc|org)/gallery/([^/?#]+))")
example = "https://postimages.org/gallery/ID"
def items(self):
page = self.request(self.page_url).text
data = {"_extractor": PostimgImageExtractor}
for url in text.extract_iter(page, ' class="thumb"><a href="', '"'):
yield Message.Queue, url, data
2016-11-04 09:33:38 +01:00
class TurboimagehostImageExtractor(ImagehostImageExtractor):
"""Extractor for single images from www.turboimagehost.com"""
2016-11-04 09:33:38 +01:00
category = "turboimagehost"
pattern = (r"(?:https?://)?((?:www\.)?turboimagehost\.com"
r"/p/(\d+)/[^/?#]+\.html)")
example = "https://www.turboimagehost.com/p/12345/NAME.EXT.html"
2016-11-04 09:33:38 +01:00
def get_info(self, page):
2018-10-23 21:01:51 +02:00
url = text.extract(page, 'src="', '"', page.index("<img "))[0]
2016-11-04 09:33:38 +01:00
return url, url
class ViprImageExtractor(ImagehostImageExtractor):
"""Extractor for single images from vipr.im"""
category = "vipr"
2021-01-20 21:40:04 +01:00
pattern = r"(?:https?://)?(vipr\.im/(\w+))"
example = "https://vipr.im/abc123.html"
def get_info(self, page):
url = text.extr(page, '<img src="', '"')
return url, url
class ImgclickImageExtractor(ImagehostImageExtractor):
"""Extractor for single images from imgclick.net"""
category = "imgclick"
pattern = r"(?:https?://)?((?:www\.)?imgclick\.net/([^/?#]+))"
example = "http://imgclick.net/abc123/NAME.EXT.html"
_https = False
_params = "complex"
def get_info(self, page):
url , pos = text.extract(page, '<br><img src="', '"')
filename, pos = text.extract(page, 'alt="', '"', pos)
return url, filename
class FappicImageExtractor(ImagehostImageExtractor):
"""Extractor for single images from fappic.com"""
category = "fappic"
pattern = r"(?:https?://)?((?:www\.)?fappic\.com/(\w+)/[^/?#]+)"
example = "https://fappic.com/abc123/NAME.EXT"
def get_info(self, page):
2022-10-01 12:19:33 +02:00
url , pos = text.extract(page, '<a href="#"><img src="', '"')
filename, pos = text.extract(page, 'alt="', '"', pos)
if filename.startswith("Porn-Picture-"):
filename = filename[13:]
return url, filename