gallery.py 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. #!/usr/bin/env python3
  2. import logging
  3. from typing import Optional
  4. import requests
  5. from praw.models import Submission
  6. from bdfr.exceptions import SiteDownloaderError
  7. from bdfr.resource import Resource
  8. from bdfr.site_authenticator import SiteAuthenticator
  9. from bdfr.site_downloaders.base_downloader import BaseDownloader
  10. logger = logging.getLogger(__name__)
  11. class Gallery(BaseDownloader):
  12. def __init__(self, post: Submission):
  13. super().__init__(post)
  14. def find_resources(self, authenticator: Optional[SiteAuthenticator] = None) -> list[Resource]:
  15. try:
  16. image_urls = self._get_links(self.post.gallery_data['items'])
  17. except (AttributeError, TypeError):
  18. try:
  19. image_urls = self._get_links(self.post.crosspost_parent_list[0]['gallery_data']['items'])
  20. except (AttributeError, IndexError, TypeError, KeyError):
  21. logger.error(f'Could not find gallery data in submission {self.post.id}')
  22. logger.exception('Gallery image find failure')
  23. raise SiteDownloaderError('No images found in Reddit gallery')
  24. if not image_urls:
  25. raise SiteDownloaderError('No images found in Reddit gallery')
  26. return [Resource(self.post, url, Resource.retry_download(url)) for url in image_urls]
  27. @ staticmethod
  28. def _get_links(id_dict: list[dict]) -> list[str]:
  29. out = []
  30. for item in id_dict:
  31. image_id = item['media_id']
  32. possible_extensions = ('.jpg', '.png', '.gif', '.gifv', '.jpeg')
  33. for extension in possible_extensions:
  34. test_url = f'https://i.redd.it/{image_id}{extension}'
  35. response = requests.head(test_url)
  36. if response.status_code == 200:
  37. out.append(test_url)
  38. break
  39. return out