home *** CD-ROM | disk | FTP | other *** search
/ Freelog 125 / Freelog_MarsAvril2015_No125.iso / Internet / gpodder / gpodder-portable.exe / gpodder-portable / src / gpodder / coverart.py < prev    next >
Text File  |  2014-10-30  |  4KB  |  122 lines

  1. # -*- coding: utf-8 -*-
  2. #
  3. # gPodder - A media aggregator and podcast client
  4. # Copyright (c) 2005-2014 Thomas Perl and the gPodder Team
  5. #
  6. # gPodder is free software; you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation; either version 3 of the License, or
  9. # (at your option) any later version.
  10. #
  11. # gPodder is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18. #
  19.  
  20.  
  21. #
  22. #  gpodder.coverart - Unified cover art downloading module (2012-03-04)
  23. #
  24.  
  25.  
  26. import gpodder
  27. _ = gpodder.gettext
  28.  
  29. import logging
  30. logger = logging.getLogger(__name__)
  31.  
  32. from gpodder import util
  33. from gpodder import youtube
  34.  
  35. import os
  36.  
  37. class CoverDownloader(object):
  38.     # File name extension dict, lists supported cover art extensions
  39.     # Values: functions that check if some data is of that file type
  40.     SUPPORTED_EXTENSIONS = {
  41.         '.png': lambda d: d.startswith('\x89PNG\r\n\x1a\n\x00'),
  42.         '.jpg': lambda d: d.startswith('\xff\xd8'),
  43.         '.gif': lambda d: d.startswith('GIF89a') or d.startswith('GIF87a'),
  44.     }
  45.  
  46.     EXTENSIONS = SUPPORTED_EXTENSIONS.keys()
  47.     ALL_EPISODES_ID = ':gpodder:all-episodes:'
  48.  
  49.     # Low timeout to avoid unnecessary hangs of GUIs
  50.     TIMEOUT = 5
  51.  
  52.     def __init__(self):
  53.         pass
  54.  
  55.     def get_cover_all_episodes(self):
  56.         return self._default_filename('podcast-all.png')
  57.  
  58.     def get_cover(self, filename, cover_url, feed_url, title,
  59.             username=None, password=None, download=False):
  60.         # Detection of "all episodes" podcast
  61.         if filename == self.ALL_EPISODES_ID:
  62.             return self.get_cover_all_episodes()
  63.  
  64.         # Return already existing files
  65.         for extension in self.EXTENSIONS:
  66.             if os.path.exists(filename + extension):
  67.                 return filename + extension
  68.  
  69.         # If allowed to download files, do so here
  70.         if download:
  71.             # YouTube-specific cover art image resolver
  72.             youtube_cover_url = youtube.get_real_cover(feed_url)
  73.             if youtube_cover_url is not None:
  74.                 cover_url = youtube_cover_url
  75.  
  76.             if not cover_url:
  77.                 return self._fallback_filename(title)
  78.  
  79.             # We have to add username/password, because password-protected
  80.             # feeds might keep their cover art also protected (bug 1521)
  81.             if username is not None and password is not None:
  82.                 cover_url = util.url_add_authentication(cover_url,
  83.                         username, password)
  84.  
  85.             try:
  86.                 logger.info('Downloading cover art: %s', cover_url)
  87.                 data = util.urlopen(cover_url, timeout=self.TIMEOUT).read()
  88.             except Exception, e:
  89.                 logger.warn('Cover art download failed: %s', e)
  90.                 return self._fallback_filename(title)
  91.  
  92.             try:
  93.                 extension = None
  94.  
  95.                 for filetype, check in self.SUPPORTED_EXTENSIONS.items():
  96.                     if check(data):
  97.                         extension = filetype
  98.                         break
  99.  
  100.                 if extension is None:
  101.                     msg = 'Unknown file type: %s (%r)' % (cover_url, data[:6])
  102.                     raise ValueError(msg)
  103.  
  104.                 # Successfully downloaded the cover art - save it!
  105.                 fp = open(filename + extension, 'wb')
  106.                 fp.write(data)
  107.                 fp.close()
  108.  
  109.                 return filename + extension
  110.             except Exception, e:
  111.                 logger.warn('Cannot save cover art', exc_info=True)
  112.  
  113.         # Fallback to cover art based on the podcast title
  114.         return self._fallback_filename(title)
  115.  
  116.     def _default_filename(self, basename):
  117.         return os.path.join(gpodder.images_folder, basename)
  118.  
  119.     def _fallback_filename(self, title):
  120.         return self._default_filename('podcast-%d.png' % (hash(title)%5))
  121.  
  122.