summaryrefslogtreecommitdiffstats
path: root/gallery_dl/extractor/twitter.py
diff options
context:
space:
mode:
Diffstat (limited to 'gallery_dl/extractor/twitter.py')
-rw-r--r--gallery_dl/extractor/twitter.py74
1 files changed, 59 insertions, 15 deletions
diff --git a/gallery_dl/extractor/twitter.py b/gallery_dl/extractor/twitter.py
index a7d2de5..c323fe0 100644
--- a/gallery_dl/extractor/twitter.py
+++ b/gallery_dl/extractor/twitter.py
@@ -113,19 +113,18 @@ class TwitterExtractor(Extractor):
"url" : base + "orig",
"width" : width,
"height" : height,
- "_fallback": self._image_fallback(base, url),
+ "_fallback": self._image_fallback(base, url + ":"),
}))
else:
files.append({"url": media["media_url"]})
@staticmethod
- def _image_fallback(base, url):
- url += ":"
- yield url + "orig"
+ def _image_fallback(new, old):
+ yield old + "orig"
for size in ("large", "medium", "small"):
- yield base + size
- yield url + size
+ yield new + size
+ yield old + size
def _extract_card(self, tweet, files):
card = tweet["card"]
@@ -139,7 +138,7 @@ class TwitterExtractor(Extractor):
if key in bvals:
files.append(bvals[key]["image_value"])
return
- else:
+ elif self.videos:
url = "ytdl:{}/i/web/status/{}".format(self.root, tweet["id_str"])
files.append({"url": url})
@@ -224,6 +223,22 @@ class TwitterExtractor(Extractor):
}
return cache[uid]
+ def _users_result(self, users):
+ userfmt = self.config("users")
+ if not userfmt or userfmt == "timeline":
+ cls = TwitterTimelineExtractor
+ fmt = (self.root + "/i/user/{rest_id}").format_map
+ elif userfmt == "media":
+ cls = TwitterMediaExtractor
+ fmt = (self.root + "/id:{rest_id}/media").format_map
+ else:
+ cls = None
+ fmt = userfmt.format_map
+
+ for user in users:
+ user["_extractor"] = cls
+ yield Message.Queue, fmt(user), user
+
def metadata(self):
"""Return general metadata"""
return {}
@@ -261,6 +276,10 @@ class TwitterExtractor(Extractor):
response = self.request(
url, method="POST", cookies=cookies, data=data)
+ if "/account/login_verification" in response.url:
+ raise exception.AuthenticationError(
+ "Login with two-factor authentication is not supported")
+
cookies = {
cookie.name: cookie.value
for cookie in self.session.cookies
@@ -320,6 +339,9 @@ class TwitterLikesExtractor(TwitterExtractor):
pattern = BASE_PATTERN + r"/(?!search)([^/?#]+)/likes(?!\w)"
test = ("https://twitter.com/supernaturepics/likes",)
+ def metadata(self):
+ return {"user_likes": self.user}
+
def tweets(self):
return TwitterAPI(self).timeline_favorites(self.user)
@@ -356,10 +378,7 @@ class TwitterListMembersExtractor(TwitterExtractor):
def items(self):
self.login()
- for user in TwitterAPI(self).list_members(self.user):
- user["_extractor"] = TwitterTimelineExtractor
- url = "{}/i/user/{}".format(self.root, user["rest_id"])
- yield Message.Queue, url, user
+ return self._users_result(TwitterAPI(self).list_members(self.user))
class TwitterFollowingExtractor(TwitterExtractor):
@@ -373,10 +392,7 @@ class TwitterFollowingExtractor(TwitterExtractor):
def items(self):
self.login()
- for user in TwitterAPI(self).user_following(self.user):
- user["_extractor"] = TwitterTimelineExtractor
- url = "{}/i/user/{}".format(self.root, user["rest_id"])
- yield Message.Queue, url, user
+ return self._users_result(TwitterAPI(self).user_following(self.user))
class TwitterSearchExtractor(TwitterExtractor):
@@ -485,6 +501,34 @@ class TwitterTweetExtractor(TwitterExtractor):
return TwitterAPI(self).tweet(self.tweet_id)
+class TwitterImageExtractor(Extractor):
+ category = "twitter"
+ subcategory = "image"
+ pattern = r"https?://pbs\.twimg\.com/media/([\w-]+)(?:\?format=|\.)(\w+)"
+ test = (
+ ("https://pbs.twimg.com/media/EqcpviCVoAAG-QG?format=jpg%name=orig"),
+ ("https://pbs.twimg.com/media/EqcpviCVoAAG-QG.jpg:orig"),
+ )
+
+ def __init__(self, match):
+ Extractor.__init__(self, match)
+ self.id, self.fmt = match.groups()
+
+ def items(self):
+ base = "https://pbs.twimg.com/media/" + self.id
+ new = base + "?format=" + self.fmt + "&name="
+ old = base + "." + self.fmt + ":"
+
+ data = {
+ "filename": self.id,
+ "extension": self.fmt,
+ "_fallback": TwitterExtractor._image_fallback(new, old),
+ }
+
+ yield Message.Directory, data
+ yield Message.Url, new + "orig", data
+
+
class TwitterAPI():
def __init__(self, extractor):