diff --git a/gallery_dl/extractor/vsco.py b/gallery_dl/extractor/vsco.py index c48a8b5b..41141c6f 100644 --- a/gallery_dl/extractor/vsco.py +++ b/gallery_dl/extractor/vsco.py @@ -139,8 +139,8 @@ class VscoCollectionExtractor(VscoExtractor): subcategory = "collection" directory_fmt = ("{category}", "{user}", "collection") archive_fmt = "c_{user}_{id}" - pattern = USER_PATTERN + r"/collection/" - example = "https://vsco.co/USER/collection/12345" + pattern = USER_PATTERN + r"/collection" + example = "https://vsco.co/USER/collection/1" def images(self): url = "{}/{}/collection/1".format(self.root, self.user) @@ -208,6 +208,36 @@ class VscoSpaceExtractor(VscoExtractor): data = self.request(url, params=params, headers=headers).json() +class VscoSpacesExtractor(VscoExtractor): + """Extractor for a vsco.co user's spaces""" + subcategory = "spaces" + pattern = USER_PATTERN + r"/spaces" + example = "https://vsco.co/USER/spaces" + + def items(self): + url = "{}/{}/spaces".format(self.root, self.user) + data = self._extract_preload_state(url) + + tkn = data["users"]["currentUser"]["tkn"] + uid = data["sites"]["siteByUsername"][self.user]["site"]["userId"] + + headers = { + "Accept" : "application/json", + "Referer" : url, + "Content-Type" : "application/json", + "Authorization": "Bearer " + tkn, + } + # this would theoretically need to be paginated + url = "{}/grpc/spaces/user/{}".format(self.root, uid) + data = self.request(url, headers=headers).json() + + for space in data["spacesWithRoleList"]: + space = space["space"] + url = "{}/spaces/{}".format(self.root, space["id"]) + space["_extractor"] = VscoSpaceExtractor + yield Message.Queue, url, space + + class VscoImageExtractor(VscoExtractor): """Extractor for individual images on vsco.co""" subcategory = "image" diff --git a/scripts/supportedsites.py b/scripts/supportedsites.py index e12b65c2..2a5f24ed 100755 --- a/scripts/supportedsites.py +++ b/scripts/supportedsites.py @@ -290,6 +290,9 @@ SUBCATEGORY_MAP = { "vk": { "tagged": "Tagged Photos", }, + "vsco": { + "spaces": "", + }, "wallhaven": { "collections": "", "uploads" : "", diff --git a/test/results/vsco.py b/test/results/vsco.py index 721ebd86..ed42f1fa 100644 --- a/test/results/vsco.py +++ b/test/results/vsco.py @@ -46,6 +46,17 @@ __tests__ = ( "#count" : range(100, 150), }, +{ + "#url" : "https://vsco.co/vscotest39/spaces", + "#category": ("", "vsco", "spaces"), + "#class" : vsco.VscoSpacesExtractor, + "#urls" : ( + "https://vsco.co/spaces/62991a535a9ee215340fa2b0", + "https://vsco.co/spaces/62b35bfb54f97cbfbd5c1e62", + "https://vsco.co/spaces/629674a6875ebddb8f1320c1", + ), +}, + { "#url" : "https://vsco.co/erenyildiz/media/5d34b93ef632433030707ce2", "#category": ("", "vsco", "image"),