diff --git a/docs/supportedsites.md b/docs/supportedsites.md index daf07cf3..6b403dc3 100644 --- a/docs/supportedsites.md +++ b/docs/supportedsites.md @@ -148,7 +148,7 @@ Consider all sites to be NSFW unless otherwise known. DeviantArt https://www.deviantart.com/ - Collections, Deviations, Favorites, Folders, Galleries, Journals, Popular Images, Scraps, Search Results, Sta.sh, Status Updates, Tag Searches, User Profiles, Watches + Collections, Deviations, Favorites, Folders, Galleries, Gallery Searches, Journals, Popular Images, Scraps, Search Results, Sta.sh, Status Updates, Tag Searches, User Profiles, Watches OAuth diff --git a/gallery_dl/extractor/deviantart.py b/gallery_dl/extractor/deviantart.py index 8aba27aa..15bdd3a2 100644 --- a/gallery_dl/extractor/deviantart.py +++ b/gallery_dl/extractor/deviantart.py @@ -1123,6 +1123,7 @@ class DeviantartScrapsExtractor(DeviantartExtractor): subcategory = "scraps" directory_fmt = ("{category}", "{username}", "Scraps") archive_fmt = "s_{_username}_{index}.{extension}" + cookiedomain = ".deviantart.com" pattern = BASE_PATTERN + r"/gallery/(?:\?catpath=)?scraps\b" test = ( ("https://www.deviantart.com/shimoda7/gallery/scraps", { @@ -1131,7 +1132,6 @@ class DeviantartScrapsExtractor(DeviantartExtractor): ("https://www.deviantart.com/shimoda7/gallery/?catpath=scraps"), ("https://shimoda7.deviantart.com/gallery/?catpath=scraps"), ) - cookiedomain = ".deviantart.com" def deviations(self): self.login() @@ -1146,13 +1146,13 @@ class DeviantartSearchExtractor(DeviantartExtractor): subcategory = "search" directory_fmt = ("{category}", "Search", "{search_tags}") archive_fmt = "Q_{search_tags}_{index}.{extension}" + cookiedomain = ".deviantart.com" pattern = (r"(?:https?://)?www\.deviantart\.com" r"/search(?:/deviations)?/?\?([^#]+)") test = ( ("https://www.deviantart.com/search?q=tree"), ("https://www.deviantart.com/search/deviations?order=popular-1-week"), ) - cookiedomain = ".deviantart.com" def deviations(self): self.login() @@ -1170,6 +1170,46 @@ class DeviantartSearchExtractor(DeviantartExtractor): deviation["search_tags"] = self.search +class DeviantartGallerySearchExtractor(DeviantartExtractor): + """Extractor for deviantart gallery searches""" + subcategory = "gallery-search" + archive_fmt = "g_{_username}_{index}.{extension}" + cookiedomain = ".deviantart.com" + pattern = BASE_PATTERN + r"/gallery/?\?(q=[^#]+)" + test = ( + ("https://www.deviantart.com/shimoda7/gallery?q=memory", { + "options": (("original", 0),), + "content": "6a7c74dc823ebbd457bdd9b3c2838a6ee728091e", + }), + ("https://www.deviantart.com/shimoda7/gallery?q=memory&sort=popular"), + ) + + def __init__(self, match): + DeviantartExtractor.__init__(self, match) + self.query = match.group(3) + + def deviations(self): + self.login() + + eclipse_api = DeviantartEclipseAPI(self) + info = eclipse_api.user_info(self.user) + + query = text.parse_query(self.query) + self.search = query["q"] + + return self._eclipse_to_oauth( + eclipse_api, eclipse_api.galleries_search( + info["user"]["userId"], + self.search, + self.offset, + query.get("sort", "most-recent"), + )) + + def prepare(self, deviation): + DeviantartExtractor.prepare(self, deviation) + deviation["search_tags"] = self.search + + class DeviantartFollowingExtractor(DeviantartExtractor): """Extractor for user's watched users""" subcategory = "following" @@ -1647,10 +1687,29 @@ class DeviantartEclipseAPI(): } return self._pagination(endpoint, params) + def galleries_search(self, user_id, query, + offset=None, order="most-recent"): + endpoint = "/shared_api/galleries/search" + params = { + "userid": user_id, + "order" : order, + "q" : query, + "offset": offset, + "limit" : 24, + } + return self._pagination(endpoint, params) + def search_deviations(self, params): endpoint = "/da-browse/api/networkbar/search/deviations" return self._pagination(endpoint, params, key="deviations") + def user_info(self, user, expand=False): + endpoint = "/shared_api/user/info" + params = {"username": user} + if expand: + params["expand"] = "user.stats,user.profile,user.watch" + return self._call(endpoint, params) + def user_watching(self, user, offset=None): endpoint = "/da-user-profile/api/module/watching" params = { diff --git a/scripts/supportedsites.py b/scripts/supportedsites.py index c5c093e2..041a5131 100755 --- a/scripts/supportedsites.py +++ b/scripts/supportedsites.py @@ -163,6 +163,7 @@ SUBCATEGORY_MAP = { "site": "", }, "deviantart": { + "gallery-search": "Gallery Searches", "stash" : "Sta.sh", "status": "Status Updates", "watch-posts": "",