You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
gallery-dl/gallery_dl/extractor/imgur.py

126 lines
4.4 KiB

# -*- coding: utf-8 -*-
# Copyright 2015-2017 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.
"""Extract images from https://imgur.com/"""
from .common import Extractor, Message
from .. import text, exception
import json
class ImgurExtractor(Extractor):
"""Base class for imgur extractors"""
category = "imgur"
def __init__(self, match):
Extractor.__init__(self)
self.item_id = match.group(1)
self.mp4 = self.config("mp4", True)
def _get_data(self, urlpart):
response = self.request("https://imgur.com/" + urlpart, fatal=False)
if response.status_code == 404:
raise exception.NotFoundError(self.subcategory)
data = text.extract(response.text, "image : ", ",\n")[0]
return self._clean(json.loads(data))
def _prepare(self, image):
if image["ext"] == ".gif" and (
(self.mp4 and image["prefer_video"]) or self.mp4 == "always"):
image["ext"] = ".mp4"
url = "https://i.imgur.com/" + image["hash"] + image["ext"]
image["extension"] = image["ext"][1:]
return url
@staticmethod
def _clean(data):
try:
del data["views"]
del data["adConfig"]
del data["isAd"]
del data["date"]
except KeyError:
pass
return data
class ImgurImageExtractor(ImgurExtractor):
"""Extractor for individual images from imgur.com"""
subcategory = "image"
filename_fmt = "{category}_{hash}{title:?_//}.{extension}"
pattern = [(r"(?:https?://)?(?:m\.|www\.)?imgur\.com/"
r"(?:gallery/)?((?!gallery)[^/?&#]{7})/?"),
(r"(?:https?://)?i\.imgur\.com/([^/?&#.]{5,7})\.")]
test = [
("https://imgur.com/21yMxCS", {
"url": "6f2dcfb86815bdd72808c313e5f715610bc7b9b2",
"keyword": "834b6714d6daf0f8df99f6261e9bb5f3ccbbcfdb",
"content": "0c8768055e4e20e7c7259608b67799171b691140",
}),
("https://i.imgur.com/21yMxCS.png", { # direct link
"url": "6f2dcfb86815bdd72808c313e5f715610bc7b9b2",
"keyword": "834b6714d6daf0f8df99f6261e9bb5f3ccbbcfdb",
}),
("http://imgur.com/0gybAXR", { # gifv/mp4 video
"url": "a2220eb265a55b0c95e0d3d721ec7665460e3fd7",
"keyword": "94c3d9df06db5ffd1840be3b94c100ced19b4751",
"content": "a3c080e43f58f55243ab830569ba02309d59abfc",
}),
("https://imgur.com/zzzzzzz", {
"exception": exception.NotFoundError,
}),
]
def items(self):
image = self._get_data(self.item_id)
url = self._prepare(image)
yield Message.Version, 1
yield Message.Directory, image
yield Message.Url, url, image
class ImgurAlbumExtractor(ImgurExtractor):
"""Extractor for image albums from imgur.com"""
subcategory = "album"
directory_fmt = ["{category}", "{album[hash]}{album[title]:? - //}"]
filename_fmt = "{category}_{album[hash]}_{num:>03}_{hash}.{extension}"
pattern = [r"(?:https?://)?(?:m\.|www\.)?imgur\.com/"
r"(?:a|gallery)/([^/?&#]{5})/?$"]
test = [
("https://imgur.com/a/TcBmP", {
"url": "ce3552f550a5b5316bd9c7ae02e21e39f30c0563",
"keyword": "4fb9d3089810ce5d230f2706b3b37edf529061bf",
}),
("https://imgur.com/gallery/eD9CT", { # large album
"url": "4ee94de31ff26be416271bc0b1ea27b9349c9937",
"keyword": "577f15a6320b7717bd9fd04e7fde56f9519e3def",
}),
("https://imgur.com/a/TcBmQ", {
"exception": exception.NotFoundError,
}),
]
def items(self):
album = self._get_data("a/" + self.item_id + "/all")
images = album["album_images"]["images"]
del album["album_images"]
if int(album["num_images"]) > len(images):
url = ("https://imgur.com/ajaxalbums/getimages/" +
self.item_id + "/hit.json")
images = self.request(url).json()["data"]["images"]
yield Message.Version, 1
yield Message.Directory, {"album": album, "count": len(images)}
for num, image in enumerate(images, 1):
url = self._prepare(image)
image["num"] = num
image["album"] = album
yield Message.Url, url, image