You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

72 lines
2.2KB

  1. import tweepy
  2. import requests
  3. import json
  4. import shutil
  5. import pathlib
  6. from os import path
  7. config = json.load(open("config.json"))
  8. pathlib.Path(config["output_dir"]).mkdir(parents=True, exist_ok=True)
  9. auth = tweepy.OAuthHandler(config["consumer_key"], config["consumer_secret"])
  10. auth.set_access_token(config["access_token"], config["access_secret"])
  11. api = tweepy.API(auth_handler=auth)
  12. class MediaStreamListener(tweepy.StreamListener):
  13. def on_status(self, status):
  14. media_entities = status.extended_entities["media"]
  15. # Get urls of actual photos that aren't video thumbnails that might be
  16. # present in the tweet.
  17. photo_urls = [
  18. item["media_url"]
  19. for item in media_entities
  20. if "ext_tw_video_thumb" not in item["media_url"] and
  21. item["type"] == "photo"
  22. ]
  23. video_entities = [
  24. item for item in media_entities if item["type"] == "video"
  25. ]
  26. video_urls = []
  27. for video in video_entities:
  28. # Video media involves "variants" with bitrates, so find the one with the
  29. # highest bitrate and pick out that URL for downloading.
  30. variants = video["video_info"]["variants"]
  31. best_bitrate = 0
  32. for variant in variants:
  33. try:
  34. if variant["bitrate"] > best_bitrate:
  35. best_bitrate = variant["bitrate"]
  36. best_url = variant["url"]
  37. except KeyError:
  38. pass
  39. video_urls.append(best_url)
  40. # Go through and download everything
  41. for url in photo_urls + video_urls:
  42. fname = url.split("/")[-1].split("?")[0]
  43. r = requests.get(url, stream=True)
  44. if r.status_code == 200:
  45. print(f"Successfully downloaded {fname}")
  46. with open(path.join(config["output_dir"], fname), 'wb') as outfile:
  47. r.raw.decode_content = True
  48. shutil.copyfileobj(r.raw, outfile)
  49. else:
  50. print(f"Whoops. Something went wrong downloading {fname}")
  51. # Optionally delete the tweet after doing the downloading
  52. if config["burn_after_reading"]:
  53. api.destroy_status(status.id)
  54. print(f"Tweet {status.id} deleted.")
  55. listener = MediaStreamListener()
  56. stream = tweepy.Stream(auth=auth, listener=listener)
  57. stream.filter(follow=[str(api.me().id)])