[deviantart] full resolution for non-downloadable images (#293)

Many thanks to @Ironchest337 for discovering this method
and providing a well-documented implementation.
pull/1975/head
Mike Fährmann 3 years ago
parent a7ddb5f5fa
commit 02a247f4e5
No known key found for this signature in database
GPG Key ID: 5680CA389D365A88

@ -1053,17 +1053,6 @@ Description
everything else (archives, etc.).
extractor.deviantart.quality
----------------------------
Type
``integer``
Default
``100``
Description
JPEG quality level of newer images for which
an original file download is not available.
extractor.deviantart.refresh-token
----------------------------------
Type

@ -76,7 +76,6 @@
"mature": true,
"metadata": false,
"original": true,
"quality": 100,
"wait-min": 0
},
"e621":

@ -14,6 +14,7 @@ from ..cache import cache, memcache
import collections
import itertools
import mimetypes
import binascii
import time
import re
@ -39,7 +40,6 @@ class DeviantartExtractor(Extractor):
self.offset = 0
self.flat = self.config("flat", True)
self.extra = self.config("extra", False)
self.quality = self.config("quality", "100")
self.original = self.config("original", True)
self.comments = self.config("comments", False)
self.user = match.group(1) or match.group(2)
@ -53,9 +53,6 @@ class DeviantartExtractor(Extractor):
else:
self.unwatch = None
if self.quality:
self.quality = ",q_{}".format(self.quality)
if self.original != "image":
self._update_content = self._update_content_default
else:
@ -104,19 +101,8 @@ class DeviantartExtractor(Extractor):
if self.original and deviation["is_downloadable"]:
self._update_content(deviation, content)
if content["src"].startswith("https://images-wixmp-"):
if deviation["index"] <= 790677560:
# https://github.com/r888888888/danbooru/issues/4069
intermediary, count = re.subn(
r"(/f/[^/]+/[^/]+)/v\d+/.*",
r"/intermediary\1", content["src"], 1)
if count:
deviation["_fallback"] = (content["src"],)
content["src"] = intermediary
if self.quality:
content["src"] = re.sub(
r",q_\d+", self.quality, content["src"], 1)
else:
self._update_token(deviation, content)
yield self.commit(deviation, content)
@ -302,6 +288,32 @@ class DeviantartExtractor(Extractor):
if mtype and mtype.startswith("image/"):
content.update(data)
def _update_token(self, deviation, content):
"""Replace JWT to be able to remove width/height limits
All credit goes to @Ironchest337
for discovering and implementing this method
"""
url, sep, _ = content["src"].partition("/v1/")
if not sep:
return
# header = b'{"typ":"JWT","alg":"none"}'
payload = (
b'{"sub":"urn:app:","iss":"urn:app:","obj":[[{"path":"/f/' +
url.partition("/f/")[2].encode() +
b'"}]],"aud":["urn:service:file.download"]}'
)
deviation["_fallback"] = (content["src"],)
content["src"] = (
"{}?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.{}.".format(
url,
# base64 of 'header' is precomputed as 'eyJ0eX...'
# binascii.a2b_base64(header).rstrip(b"=\n").decode(),
binascii.b2a_base64(payload).rstrip(b"=\n").decode())
)
def _limited_request(self, url, **kwargs):
"""Limits HTTP requests to one every 2 seconds"""
kwargs["fatal"] = None
@ -849,12 +861,8 @@ class DeviantartDeviationExtractor(DeviantartExtractor):
}),
# wixmp URL rewrite
(("https://www.deviantart.com/citizenfresh/art/Hverarond-789295466"), {
"pattern": (r"https://images-wixmp-\w+\.wixmp\.com"
r"/intermediary/f/[^/]+/[^.]+\.jpg")
}),
# wixmp URL rewrite v2 (#369)
(("https://www.deviantart.com/josephbiwald/art/Destiny-2-804940104"), {
"pattern": r"https://images-wixmp-\w+\.wixmp\.com/.*,q_100,"
"pattern": (r"https://images-wixmp-\w+\.wixmp\.com/f"
r"/[^/]+/[^.]+\.jpg\?token="),
}),
# GIF (#242)
(("https://www.deviantart.com/skatergators/art/COM-Moni-781571783"), {

Loading…
Cancel
Save