diff --git a/gallery_dl/extractor/deviantart.py b/gallery_dl/extractor/deviantart.py index 45beddf3..a8ffa636 100644 --- a/gallery_dl/extractor/deviantart.py +++ b/gallery_dl/extractor/deviantart.py @@ -854,7 +854,9 @@ class DeviantartDeviationExtractor(DeviantartExtractor): """Extractor for single deviations""" subcategory = "deviation" archive_fmt = "g_{_username}_{index}.{extension}" - pattern = BASE_PATTERN + r"/(art|journal)/(?:[^/?#]+-)?(\d+)" + pattern = (BASE_PATTERN + r"/(art|journal)/(?:[^/?#]+-)?(\d+)" + r"|(?:https?://)?(?:www\.)?deviantart\.com/" + r"(?:view/|view(?:-full)?\.php/*\?(?:[^#]+&)?id=)(\d+)") test = ( (("https://www.deviantart.com/shimoda7/art/For-the-sake-10073852"), { "options": (("original", 0),), @@ -920,12 +922,28 @@ class DeviantartDeviationExtractor(DeviantartExtractor): "url": "e2e0044bd255304412179b6118536dbd9bb3bb0e", "pattern": "text:\n", }), + # /view/ URLs + ("https://deviantart.com/view/904858796/", { + "content": "8770ec40ad1c1d60f6b602b16301d124f612948f", + }), + ("http://www.deviantart.com/view/890672057", { + "content": "1497e13d925caeb13a250cd666b779a640209236", + }), + ("https://www.deviantart.com/view/706871727", { + "content": "3f62ae0c2fca2294ac28e41888ea06bb37c22c65", + }), + ("https://www.deviantart.com/view/1", { + "exception": exception.NotFoundError, + }), # old-style URLs ("https://shimoda7.deviantart.com" "/art/For-the-sake-of-a-memory-10073852"), ("https://myria-moon.deviantart.com" "/art/Aime-Moi-part-en-vadrouille-261986576"), ("https://zzz.deviantart.com/art/zzz-1234567890"), + # old /view/ URLs from the Wayback Machine + ("https://www.deviantart.com/view.php?id=14864502"), + ("http://www.deviantart.com/view-full.php?id=100842"), ) skip = Extractor.skip @@ -933,11 +951,12 @@ class DeviantartDeviationExtractor(DeviantartExtractor): def __init__(self, match): DeviantartExtractor.__init__(self, match) self.type = match.group(3) - self.deviation_id = match.group(4) + self.deviation_id = match.group(4) or match.group(5) def deviations(self): url = "{}/{}/{}/{}".format( - self.root, self.user, self.type, self.deviation_id) + self.root, self.user or "u", self.type or "art", self.deviation_id) + uuid = text.extract(self._limited_request(url).text, '"deviationUuid\\":\\"', '\\')[0] if not uuid: