diff --git a/docs/supportedsites.md b/docs/supportedsites.md
index 50ad231c..90a20202 100644
--- a/docs/supportedsites.md
+++ b/docs/supportedsites.md
@@ -214,7 +214,7 @@ Consider all sites to be NSFW unless otherwise known.
Gfycat |
https://gfycat.com/ |
- individual Images, Search Results, User Profiles |
+ Collections, individual Images, Search Results, User Profiles |
|
diff --git a/gallery_dl/extractor/gfycat.py b/gallery_dl/extractor/gfycat.py
index 501d1146..f81bc885 100644
--- a/gallery_dl/extractor/gfycat.py
+++ b/gallery_dl/extractor/gfycat.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# Copyright 2017-2021 Mike Fährmann
+# Copyright 2017-2022 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
@@ -73,7 +73,7 @@ class GfycatUserExtractor(GfycatExtractor):
"""Extractor for gfycat user profiles"""
subcategory = "user"
directory_fmt = ("{category}", "{username|userName}")
- pattern = r"(?:https?://)?gfycat\.com/@([^/?#]+)"
+ pattern = r"(?:https?://)?gfycat\.com/@([^/?#]+)/?(?:$|\?|#)"
test = ("https://gfycat.com/@gretta", {
"pattern": r"https://giant\.gfycat\.com/[A-Za-z]+\.mp4",
"count": ">= 100",
@@ -86,6 +86,34 @@ class GfycatUserExtractor(GfycatExtractor):
return GfycatAPI(self).user(self.key)
+class GfycatCollectionExtractor(GfycatExtractor):
+ """Extractor for gfycat collections"""
+ subcategory = "collection"
+ directory_fmt = ("{category}", "{collection_owner}",
+ "{collection_name|collection_id}")
+ pattern = (r"(?:https?://)?gfycat\.com/@([^/?#]+)/collections"
+ r"/(\w+)(?:/([^/?#]+))?")
+ test = ("https://gfycat.com/@reactions/collections/nHgy2DtE/no-text", {
+ "pattern": r"https://\w+\.gfycat\.com/[A-Za-z]+\.mp4",
+ "count": ">= 100",
+ })
+
+ def __init__(self, match):
+ GfycatExtractor.__init__(self, match)
+ self.collection_id = match.group(2)
+ self.collection_name = match.group(3)
+
+ def metadata(self):
+ return {
+ "collection_owner": self.key,
+ "collection_name" : self.collection_name,
+ "collection_id" : self.collection_id,
+ }
+
+ def gfycats(self):
+ return GfycatAPI(self).collection(self.key, self.collection_id)
+
+
class GfycatSearchExtractor(GfycatExtractor):
"""Extractor for gfycat search results"""
subcategory = "search"
@@ -188,6 +216,12 @@ class GfycatAPI():
params = {"count": 100}
return self._pagination(endpoint, params)
+ def collection(self, user, collection):
+ endpoint = "/v1/users/{}/collections/{}/gfycats".format(
+ user, collection)
+ params = {"count": 100}
+ return self._pagination(endpoint, params)
+
def search(self, query):
endpoint = "/v1/gfycats/search"
params = {"search_text": query, "count": 150}