Default cover art for coverless podcasts
Makes the subscription list look way better. Improvement ideas for the "all episodes" icon are welcome. The SVG source file is included.
|
@ -62,6 +62,7 @@ if __name__ == '__main__':
|
|||
locale_dir = os.path.join(prefix, 'share', 'locale')
|
||||
ui_folder = os.path.join(prefix, 'share', 'gpodder', 'ui')
|
||||
credits_file = os.path.join(prefix, 'share', 'gpodder', 'credits.txt')
|
||||
images_folder = os.path.join(prefix, 'share', 'gpodder')
|
||||
icon_file = os.path.join(prefix, 'share', 'icons', 'hicolor', 'scalable', 'apps', 'gpodder.svg')
|
||||
|
||||
# The existence of this file tells us we're running on Maemo
|
||||
|
@ -76,6 +77,7 @@ if __name__ == '__main__':
|
|||
locale_dir = os.path.join(data_dir, 'locale')
|
||||
ui_folder = os.path.join(data_dir, 'ui')
|
||||
credits_file = os.path.join(data_dir, 'credits.txt')
|
||||
images_folder = os.path.join(data_dir, 'images')
|
||||
icon_file = os.path.join(data_dir, 'gpodder.svg')
|
||||
|
||||
# Set up the path to translation files
|
||||
|
@ -89,6 +91,7 @@ if __name__ == '__main__':
|
|||
# Set up paths to folder with GtkBuilder files and gpodder.svg
|
||||
gpodder.ui_folders.append(ui_folder)
|
||||
gpodder.credits_file = credits_file
|
||||
gpodder.images_folder = images_folder
|
||||
gpodder.icon_file = icon_file
|
||||
|
||||
s_usage = 'usage: %%prog [options]\n\n%s' % ( __doc__.strip() )
|
||||
|
|
BIN
data/images/podcast-0.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
data/images/podcast-1.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
data/images/podcast-2.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
data/images/podcast-3.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
data/images/podcast-4.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
data/images/podcast-all.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
1068
data/images/podcast-source.svg
Normal file
After Width: | Height: | Size: 147 KiB |
2
setup.py
|
@ -58,7 +58,7 @@ inst_share_ui = glob.glob('data/ui/*.ui')
|
|||
inst_share_ui_desktop = glob.glob('data/ui/desktop/*.ui')
|
||||
inst_share_ui_maemo = glob.glob('data/ui/maemo/*.ui')
|
||||
inst_share_ui_frmntl = glob.glob('data/ui/frmntl/*.ui')
|
||||
inst_share_gpodder = [ 'data/credits.txt' ]
|
||||
inst_share_gpodder = [ 'data/credits.txt' ] + glob.glob('data/images/*.png')
|
||||
inst_desktop = [ 'data/gpodder.desktop' ]
|
||||
inst_desktop_maemo = [ 'data/maemo/gpodder.desktop' ]
|
||||
inst_share_dbus_services = ['data/org.gpodder.service']
|
||||
|
|
|
@ -116,6 +116,7 @@ del SOCKET_TIMEOUT
|
|||
ui_folders = []
|
||||
credits_file = None
|
||||
icon_file = None
|
||||
images_folder = None
|
||||
|
||||
# Episode states used in the database
|
||||
STATE_NORMAL, STATE_DOWNLOADED, STATE_DELETED = range(3)
|
||||
|
|
|
@ -184,8 +184,6 @@ gPodderSettings = {
|
|||
("The name of the coverart file accepted by the user's FS-based player.")),
|
||||
'custom_player_coverart_format' : (str, 'JPEG',
|
||||
("The image format accepted by the user's FS-based player.")),
|
||||
'podcast_list_icon_size': (int, 32,
|
||||
("The width of the icon used in the podcast channel list.")),
|
||||
'cmd_all_downloads_complete': (str, '',
|
||||
("The path to a command that gets run after all downloads are completed.")),
|
||||
'cmd_download_complete': (str, '',
|
||||
|
|
|
@ -414,7 +414,7 @@ class PodcastChannelProxy(object):
|
|||
self.id = None
|
||||
self._save_dir_size_set = False
|
||||
self.save_dir_size = 0L
|
||||
self.icon = None
|
||||
self.cover_file = os.path.join(gpodder.images_folder, 'podcast-all.png')
|
||||
|
||||
def __getattribute__(self, name):
|
||||
try:
|
||||
|
@ -453,7 +453,7 @@ class PodcastListModel(gtk.ListStore):
|
|||
def row_separator_func(cls, model, iter):
|
||||
return model.get_value(iter, cls.C_SEPARATOR)
|
||||
|
||||
def __init__(self, max_image_side, cover_downloader):
|
||||
def __init__(self, cover_downloader):
|
||||
gtk.ListStore.__init__(self, str, str, str, gtk.gdk.Pixbuf, \
|
||||
object, gtk.gdk.Pixbuf, str, bool, bool, bool, bool, bool, bool)
|
||||
|
||||
|
@ -467,7 +467,7 @@ class PodcastListModel(gtk.ListStore):
|
|||
if gpodder.ui.fremantle:
|
||||
self._max_image_side = 64
|
||||
else:
|
||||
self._max_image_side = max_image_side
|
||||
self._max_image_side = 40
|
||||
self._cover_downloader = cover_downloader
|
||||
|
||||
def _filter_visible_func(self, model, iter):
|
||||
|
@ -604,7 +604,7 @@ class PodcastListModel(gtk.ListStore):
|
|||
self.set(iter, \
|
||||
self.C_URL, all_episodes.url, \
|
||||
self.C_CHANNEL, all_episodes, \
|
||||
self.C_COVER, all_episodes.icon, \
|
||||
self.C_COVER, self._get_cover_image(all_episodes), \
|
||||
self.C_SEPARATOR, False)
|
||||
self.update_by_iter(iter)
|
||||
|
||||
|
|
|
@ -135,12 +135,15 @@ class CoverDownloader(ObservableService):
|
|||
self.remove_cover(channel)
|
||||
self.request_cover(channel, custom_url)
|
||||
|
||||
def get_default_cover(self, channel):
|
||||
# "randomly" choose a cover based on the podcast title
|
||||
basename = 'podcast-%d.png' % (hash(channel.title)%5)
|
||||
filename = os.path.join(gpodder.images_folder, basename)
|
||||
return gtk.gdk.pixbuf_new_from_file(filename)
|
||||
|
||||
def __get_cover(self, channel, url, async=False, avoid_downloading=False):
|
||||
if not async and avoid_downloading and not os.path.exists(channel.cover_file):
|
||||
return (channel.url, None)
|
||||
|
||||
loader = gtk.gdk.PixbufLoader()
|
||||
pixbuf = None
|
||||
return (channel.url, self.get_default_cover(channel))
|
||||
|
||||
if not os.path.exists(channel.cover_file):
|
||||
if url is None:
|
||||
|
@ -181,16 +184,12 @@ class CoverDownloader(ObservableService):
|
|||
|
||||
if os.path.exists(channel.cover_file):
|
||||
try:
|
||||
loader.write(open(channel.cover_file, 'rb').read())
|
||||
loader.close()
|
||||
pixbuf = loader.get_pixbuf()
|
||||
pixbuf = gtk.gdk.pixbuf_new_from_file(channel.cover_file)
|
||||
except:
|
||||
log('Data error while loading %s', channel.cover_file, sender=self)
|
||||
else:
|
||||
try:
|
||||
loader.close()
|
||||
except:
|
||||
pass
|
||||
|
||||
if pixbuf is None:
|
||||
pixbuf = self.get_default_cover(channel)
|
||||
|
||||
if async:
|
||||
self.notify('cover-available', channel.url, pixbuf)
|
||||
|
|
|
@ -272,7 +272,7 @@ class gPodder(BuilderWidget, dbus.service.Object):
|
|||
self.cover_downloader = CoverDownloader()
|
||||
|
||||
# Generate list models for podcasts and their episodes
|
||||
self.podcast_list_model = PodcastListModel(self.config.podcast_list_icon_size, self.cover_downloader)
|
||||
self.podcast_list_model = PodcastListModel(self.cover_downloader)
|
||||
|
||||
self.cover_downloader.register('cover-available', self.cover_download_finished)
|
||||
self.cover_downloader.register('cover-removed', self.cover_file_removed)
|
||||
|
|
|
@ -42,6 +42,7 @@ if __name__ == '__main__':
|
|||
locale_dir = os.path.join(data_dir, 'locale')
|
||||
ui_folder = os.path.join(data_dir, 'ui')
|
||||
credits_file = os.path.join(data_dir, 'credits.txt')
|
||||
images_folder = os.path.join(data_dir, 'images')
|
||||
icon_file = os.path.join(data_dir, 'gpodder.svg')
|
||||
|
||||
# Set up the path to translation files
|
||||
|
@ -61,6 +62,7 @@ if __name__ == '__main__':
|
|||
gpodder.ui_folders.append(os.path.join(ui_folder, 'desktop'))
|
||||
gpodder.icon_file = icon_file
|
||||
gpodder.credits_file = credits_file
|
||||
gpodder.images_folder = images_folder
|
||||
gpodder.ui.desktop = True
|
||||
|
||||
# Portable version support
|
||||
|
|