def _on_show_sub2(sub2_args, error=None): nodes, self.sub2_total = sub2_args if error or not nodes or not self.sub2_total: logger.error('nodes: %s, self.sub2_total: %s, error: %s' % (nodes, self.sub2_total, error)) return urls = [] tree_iters = [] for node in nodes: tree_iter = self.liststore_sub2.append([ Config.ANONYMOUS_PIXBUF, Widgets.unescape(node['name']), int(node['sourceid']), Widgets.unescape(node['info']), Widgets.set_tooltip_with_song_tips(node['name'], node['tips']) ]) urls.append(node['pic']) tree_iters.append(tree_iter) Net.async_call(Net.update_liststore_images, self.liststore_sub2, 0, tree_iters, urls) self.sub2_page += 1 if self.sub2_page < self.sub2_total - 1: self.show_sub2()
def _on_append_songs(info, error=None): if not info or error: logger.error('TopCategories.append_songs(): %s, %s' % (info, error)) return songs, self.songs_total = info if not songs or self.songs_total == 0 or self.use_album: Net.async_call(Net.get_album, self.curr_list_id, callback=_on_get_album) for song in songs: self.liststore_songs.append([ True, Widgets.unescape(song['name']), Widgets.unescape(song['artist']), Widgets.unescape(song['album']), int(song['id']), int(song['artistid']), int(song['albumid']), song['formats'], ]) self.songs_page += 1 if self.songs_page < self.songs_total - 1: self.append_songs()
def _on_show_sub1(info, error=None): if not info or not info[0] or not info[1] or error: logger.error('show_sub1(): %s, %s' % (info, error)) return nodes, self.sub1_total = info urls = [] tree_iters = [] for node in nodes: id_ = 'id' if self.use_sub2 else 'sourceid' if 'tips' in node and len(node['tips']) > 5: tooltip = Widgets.set_tooltip_with_song_tips( node['name'], node['tips']) else: tooltip = Widgets.set_tooltip(node['name'], node['info']) tree_iter = self.liststore_sub1.append([ Config.ANONYMOUS_PIXBUF, Widgets.unescape(node['name']), int(node[id_]), Widgets.unescape(node['info']), tooltip, ]) urls.append(node['pic']) tree_iters.append(tree_iter) Net.async_call(Net.update_liststore_images, self.liststore_sub1, 0, tree_iters, urls) self.sub1_page += 1 if self.sub1_page < self.sub1_total - 1: self.show_sub1()
def show_songs(self, init=False): if init: self.app.playlist.advise_new_playlist_name( self.label.get_text()) self.liststore_songs.clear() self.songs_page = 0 self.scrolled_sub.hide() self.button_sub.show_all() self.control_box.show_all() self.scrolled_songs.get_vadjustment().set_value(0.0) self.scrolled_songs.show_all() songs, self.songs_total = Net.get_themes_songs( self.curr_list_id, self.songs_page) if not songs: return for song in songs: self.liststore_songs.append([ True, Widgets.unescape(song['name']), Widgets.unescape(song['artist']), Widgets.unescape(song['album']), int(song['id']), int(song['artistid']), int(song['albumid']), ])
def show_albums(self, reset_status=False): keyword = self.search_entry.get_text() if len(keyword) == 0: return if reset_status: self.liststore_albums.clear() albums, hit, self.albums_total = Net.search_albums(keyword, self.albums_page) if hit == 0: self.albums_button.set_label('{0} (0)'.format(_('Albums'))) return self.albums_button.set_label('{0} ({1})'.format(_('Albums'), hit)) i = len(self.liststore_albums) for album in albums: if len(album['info']) == 0: tooltip = Widgets.tooltip(album['name']) else: tooltip = '<b>{0}</b>\n{1}'.format( Widgets.tooltip(album['name']), Widgets.tooltip(album['info'])) self.liststore_albums.append([self.app.theme['anonymous'], album['name'], int(album['albumid']), album['artist'], int(album['artistid']), tooltip, ]) Net.update_album_covers(self.liststore_albums, i, 0, album['pic']) i += 1
def _on_append_songs(info, error=None): if error or not info or not info[0] or not info[1]: logger.error('append_songs(): %s, %s' % (info, error)) return songs, self.songs_total = info urls = [] tree_iters = [] for song in songs: tree_iter = self.liststore_songs.append([ Config.ANONYMOUS_PIXBUF, Widgets.unescape(song['name']), Widgets.unescape(song['artist']), Widgets.unescape(song['album']), int(song['id']), int(song['artistid']), int(song['albumid']), Widgets.set_tooltip(song['name'], song['artist']), ]) tree_iters.append(tree_iter) urls.append(song['mvpic']) Net.async_call(Net.update_mv_images, self.liststore_songs, 0, tree_iters, urls) self.songs_page += 1 if self.songs_page < self.songs_total - 1: self.append_songs()
def _show_sub1(sub1_args, error=None): nodes, self.sub1_total = sub1_args if not nodes or self.sub1_total == 0: return i = len(self.liststore_sub1) for node in nodes: _id = 'id' if self.use_sub2 else 'sourceid' if 'tips' in node and len(node['tips']) > 5: _tooltip = Widgets.set_tooltip_with_song_tips( node['name'], node['tips']) else: _tooltip = Widgets.set_tooltip(node['name'], node['info']) self.liststore_sub1.append([ self.app.theme['anonymous'], Widgets.unescape(node['name']), int(node[_id]), Widgets.unescape(node['info']), _tooltip, ]) Net.update_liststore_image(self.liststore_sub1, i, 0, node['pic']) i += 1 self.sub1_page += 1 if self.sub1_page < self.sub1_total - 1: self.show_sub1()
def _show_sub1(sub1_args, error=None): nodes, self.sub1_total = sub1_args if not nodes or self.sub1_total == 0: return for i, node in enumerate(nodes): _id = 'id' if self.use_sub2 else 'sourceid' if 'tips' in node and len(node['tips']) > 5: _tooltip = Widgets.set_tooltip_with_song_tips( node['name'], node['tips']) else: _tooltip = Widgets.set_tooltip( node['name'], node['info']) self.liststore_sub1.append([ self.app.theme['anonymous'], Widgets.unescape(node['name']), int(node[_id]), Widgets.unescape(node['info']), _tooltip, ]) Net.update_liststore_image( self.liststore_sub1, i, 0, node['pic']) self.sub1_page += 1 if self.sub1_page < self.sub1_total - 1: self.show_sub1()
def update_player_info(self): def _update_pic(info, error=None): if not info or error: logger.error('update_player_info(): %s, %s' % (info, error)) return self.artist_pic.set_tooltip_text( Widgets.short_tooltip(info['info'], length=500)) if info['pic']: self.meta_artUrl = info['pic'] pix = GdkPixbuf.Pixbuf.new_from_file_at_size(info['pic'], 100, 100) self.artist_pic.set_from_pixbuf(pix) else: self.meta_artUrl = Config.ANONYMOUS_IMG self.notify.refresh() self.dbus.update_meta() song = self.curr_song name = Widgets.short_tooltip(song['name'], 45) if song['artist']: artist = Widgets.short_tooltip(song['artist'], 20) else: artist = _('Unknown') if song['album']: album = Widgets.short_tooltip(song['album'], 30) else: album = _('Unknown') label = '<b>{0}</b> <small>{1}</small> <span size="x-small">{2}</span>'.format( name, artist, album) self.label.set_label(label) self.app.window.set_title(name) self.artist_pic.set_from_pixbuf(Config.ANONYMOUS_PIXBUF) Net.async_call(Net.get_artist_info, song['artistid'], song['artist'], callback=_update_pic)
def update_player_info(self): def _update_pic(info, error=None): if info is None or error: return self.artist_pic.set_tooltip_text( Widgets.short_tooltip(info['info'], length=500)) if info['pic']: pix = GdkPixbuf.Pixbuf.new_from_file_at_size( info['pic'], 100, 100) self.artist_pic.set_from_pixbuf(pix) song = self.curr_song name = Widgets.short_tooltip(song['name'], 45) if len(song['artist']) > 0: artist = Widgets.short_tooltip(song['artist'], 20) else: artist = _('Unknown') if len(song['album']) > 0: album = Widgets.short_tooltip(song['album'], 30) else: album = _('Unknown') label = '<b>{0}</b> <i><small>by {1} from {2}</small></i>'.format( name, artist, album) self.label.set_label(label) self.artist_pic.set_from_pixbuf(self.app.theme['anonymous']) Net.async_call(Net.get_artist_info, _update_pic, song['artistid'], song['artist'])
def show_sub(self, init=False): if init: self.scrolled_main.hide() self.scrolled_songs.hide() self.buttonbox.show_all() self.button_sub.hide() self.control_box.hide() self.scrolled_sub.get_vadjustment().set_value(0) self.scrolled_sub.show_all() self.nodes_page = 0 self.liststore_sub.clear() nodes, self.nodes_total = Net.get_nodes(self.curr_sub_id, self.nodes_page) if not nodes: return i = len(self.liststore_sub) for node in nodes: self.liststore_sub.append([ self.app.theme['anonymous'], Widgets.unescape(node['name']), int(node['sourceid']), Widgets.unescape(node['info']), Widgets.set_tooltip_with_song_tips(node['name'], node['tips']), ]) Net.update_liststore_image(self.liststore_sub, i, 0, node['pic']) i += 1
def show_songs(self, init=False): if init: self.app.playlist.advise_new_playlist_name(self.label.get_text()) self.liststore_songs.clear() self.songs_page = 0 self.scrolled_sub.hide() self.button_sub.show_all() self.control_box.show_all() self.scrolled_songs.get_vadjustment().set_value(0.0) self.scrolled_songs.show_all() songs, self.songs_total = Net.get_themes_songs(self.curr_list_id, self.songs_page) if not songs: return for song in songs: self.liststore_songs.append([ True, Widgets.unescape(song['name']), Widgets.unescape(song['artist']), Widgets.unescape(song['album']), int(song['id']), int(song['artistid']), int(song['albumid']), ])
def update_player_info(self): def _update_pic(info, error=None): if not info or error: return self.artist_pic.set_tooltip_text( Widgets.short_tooltip(info['info'], length=500)) if info['pic']: self.meta_artUrl = info['pic'] pix = GdkPixbuf.Pixbuf.new_from_file_at_size( info['pic'], 100, 100) self.artist_pic.set_from_pixbuf(pix) else: self.meta_artUrl = self.app.theme_path['anonymous'] self.notify.refresh() self.dbus.update_meta() song = self.curr_song name = Widgets.short_tooltip(song['name'], 45) if song['artist']: artist = Widgets.short_tooltip(song['artist'], 20) else: artist = _('Unknown') if song['album']: album = Widgets.short_tooltip(song['album'], 30) else: album = _('Unknown') label = '<b>{0}</b> <small>by {1} from {2}</small>'.format( name, artist, album) self.label.set_label(label) self.app.window.set_title(name) self.artist_pic.set_from_pixbuf(self.app.theme['anonymous']) Net.async_call(Net.get_artist_info, _update_pic, song['artistid'], song['artist'])
def _show_sub1(sub1_args, error=None): nodes, self.sub1_total = sub1_args if error or not nodes or not self.sub1_total: return urls = [] tree_iters = [] for node in nodes: _id = 'id' if self.use_sub2 else 'sourceid' if 'tips' in node and len(node['tips']) > 5: tooltip = Widgets.set_tooltip_with_song_tips( node['name'], node['tips']) else: tooltip = Widgets.set_tooltip(node['name'], node['info']) tree_iter = self.liststore_sub1.append([ self.app.theme['anonymous'], Widgets.unescape(node['name']), int(node[_id]), Widgets.unescape(node['info']), tooltip, ]) urls.append(node['pic']) tree_iters.append(tree_iter) Net.update_liststore_images( self.liststore_sub1, 0, tree_iters, urls) self.sub1_page += 1 if self.sub1_page < self.sub1_total - 1: self.show_sub1()
def _failed_to_download(song_path, status): self.cache_enabled = False if status == 'URLError': Widget.network_error(self.app.window, _('Failed to cache song')) elif status == 'FileNotFoundError': Widgets.filesystem_error(self.app.window, song_path)
def _on_show_sub2(sub2_args, error=None): nodes, self.sub2_total = sub2_args if error or not nodes or not self.sub2_total: logger.error('nodes: %s, self.sub2_total: %s, error: %s' % (nodes, self.sub2_total, error)) return urls = [] tree_iters = [] for node in nodes: tree_iter = self.liststore_sub2.append([ self.app.theme['anonymous'], Widgets.unescape(node['name']), int(node['sourceid']), Widgets.unescape(node['info']), Widgets.set_tooltip_with_song_tips(node['name'], node['tips']) ]) urls.append(node['pic']) tree_iters.append(tree_iter) Net.async_call(Net.update_liststore_images, self.liststore_sub2, 0, tree_iters, urls) self.sub2_page += 1 if self.sub2_page < self.sub2_total - 1: self.show_sub2()
def _append_artist_albums(albums_args, error=None): albums, self.artist_albums_total = albums_args if self.artist_albums_total == 0: return i = len(self.artist_albums_liststore) for album in albums: if len(album['info']) == 0: tooltip = Widgets.tooltip(album['name']) else: tooltip = '<b>{0}</b>\n{1}'.format( Widgets.tooltip(album['name']), Widgets.tooltip(album['info'])) self.artist_albums_liststore.append([ self.app.theme['anonymous'], album['name'], int(album['albumid']), album['artist'], int(album['artistid']), tooltip, ]) Net.update_album_covers(self.artist_albums_liststore, i, 0, album['pic']) i += 1 self.artist_albums_page += 1 if self.artist_albums_page < self.artist_albums_total - 1: self.append_artist_albums()
def show_sub(self, init=False): if init: self.scrolled_main.hide() self.scrolled_songs.hide() self.buttonbox.show_all() self.button_sub.hide() self.control_box.hide() self.scrolled_sub.get_vadjustment().set_value(0) self.scrolled_sub.show_all() self.nodes_page = 0 self.liststore_sub.clear() nodes, self.nodes_total = Net.get_nodes( self.curr_sub_id, self.nodes_page) if not nodes: return for i, node in enumerate(nodes): self.liststore_sub.append([ self.app.theme['anonymous'], Widgets.unescape(node['name']), int(node['sourceid']), Widgets.unescape(node['info']), Widgets.set_tooltip_with_song_tips( node['name'], node['tips']), ]) Net.update_liststore_image( self.liststore_sub, i, 0, node['pic'])
def _append_artist_mv(mv_args, error=None): mvs, self.artist_mv_total = mv_args if error or self.artist_mv_total == 0: logger.error('append_artist_mv(): %s, %s' % (self.artist_mv_total, error)) return urls = [] tree_iters = [] for mv in mvs: tree_iter = self.artist_mv_liststore.append([ Config.ANONYMOUS_PIXBUF, Widgets.unescape(mv['name']), Widgets.unescape(mv['artist']), '', int(mv['musicid']), int(mv['artistid']), 0, Widgets.set_tooltip(mv['name'], mv['artist']), ]) tree_iters.append(tree_iter) urls.append(mv['pic']) Net.async_call(Net.update_mv_images, self.artist_mv_liststore, 0, tree_iters, urls) self.artist_mv_page += 1 if self.artist_mv_page < self.artist_mv_total - 1: self.append_artist_mv()
def _on_show_sub1(info, error=None): if not info or not info[0] or not info[1] or error: logger.error('show_sub1(): %s, %s' % (info, error)) return nodes, self.sub1_total = info urls = [] tree_iters = [] for node in nodes: id_ = 'id' if self.use_sub2 else 'sourceid' if 'tips' in node and len(node['tips']) > 5: tooltip = Widgets.set_tooltip_with_song_tips(node['name'], node['tips']) else: tooltip = Widgets.set_tooltip(node['name'], node['info']) tree_iter = self.liststore_sub1.append([ self.app.theme['anonymous'], Widgets.unescape(node['name']), int(node[id_]), Widgets.unescape(node['info']), tooltip, ]) urls.append(node['pic']) tree_iters.append(tree_iter) Net.async_call(Net.update_liststore_images, self.liststore_sub1, 0, tree_iters, urls) self.sub1_page += 1 if self.sub1_page < self.sub1_total - 1: self.show_sub1()
def _append_artist_similar(similar_args, error=None): artists, self.artist_similar_total = similar_args if error or not self.artist_similar_total: return urls = [] tree_iters = [] for artist in artists: _info = ''.join([ artist['songnum'], _(' songs'), ]) tree_iter = self.artist_similar_liststore.append([ self.app.theme['anonymous'], Widgets.unescape(artist['name']), int(artist['id']), _info, Widgets.set_tooltip(artist['name'], _info), ]) urls.append(artist['pic']) tree_iters.append(tree_iter) Net.update_artist_logos(self.artist_similar_liststore, 0, tree_iters, urls) self.artist_similar_page += 1 if self.artist_similar_page < self.artist_similar_total - 1: self.append_artist_similar()
def open_cache_folder(self, btn): try: subprocess.call(('xdg-open', self.app.conf['song-dir'], )) except Exception as e: print(e) Widgets.error(self.app, _('Failed to call `xdg-open` command'), str(e))
def append_artists(self, init=False): if init: self.artists_liststore.clear() self.artists_page = 0 self.artists_win.get_vadjustment().set_value(0) selection = self.cate_treeview.get_selection() result = selection.get_selected() if result is None or len(result) != 2: return model, _iter = result pref_index = self.pref_combo.get_active() catid = model[_iter][1] prefix = self.pref_liststore[pref_index][1] # TODO: use async_call() artists, self.artists_total = Net.get_artists(catid, self.artists_page, prefix) if self.artists_total == 0: return i = len(self.artists_liststore) for artist in artists: _info = ' '.join([ artist['music_num'], _(' songs'), ]) self.artists_liststore.append([ self.app.theme['anonymous'], Widgets.unescape(artist['name']), int(artist['id']), _info, Widgets.set_tooltip(artist['name'], _info), ]) Net.update_artist_logo(self.artists_liststore, i, 0, artist['pic']) i += 1
def first(self): if self.first_show: return self.first_show = True app = self.app self.buttonbox = Gtk.Box(spacing=5) self.pack_start(self.buttonbox, False, False, 0) button_home = Gtk.Button(_('MV')) button_home.connect('clicked', self.on_button_home_clicked) self.buttonbox.pack_start(button_home, False, False, 0) self.label = Gtk.Label('') self.buttonbox.pack_start(self.label, False, False, 0) # pic, name, artist, album, rid, artistid, albumid, tooltip self.liststore_songs = Gtk.ListStore(GdkPixbuf.Pixbuf, str, str, str, int, int, int, str) self.mv_control_box = Widgets.MVControlBox(self.liststore_songs, self.app) self.buttonbox.pack_end(self.mv_control_box, False, False, 0) self.scrolled_nodes = Gtk.ScrolledWindow() self.pack_start(self.scrolled_nodes, True, True, 0) # logo, name, nid, info, tooltip self.liststore_nodes = Gtk.ListStore(GdkPixbuf.Pixbuf, str, int, str, str) iconview_nodes = Widgets.IconView(self.liststore_nodes, tooltip=4) iconview_nodes.connect('item_activated', self.on_iconview_nodes_item_activated) self.scrolled_nodes.add(iconview_nodes) self.scrolled_songs = Gtk.ScrolledWindow() self.pack_start(self.scrolled_songs, True, True, 0) iconview_songs = Widgets.IconView(self.liststore_songs, info_pos=2, tooltip=7) iconview_songs.connect('item_activated', self.on_iconview_songs_item_activated) self.scrolled_songs.add(iconview_songs) self.show_all() self.buttonbox.hide() self.scrolled_songs.hide() nid = 3 nodes_wrap = Net.get_index_nodes(nid) if not nodes_wrap: return nodes = nodes_wrap['child'] self.liststore_nodes.clear() i = 0 for node in nodes: self.liststore_nodes.append([ self.app.theme['anonymous'], Widgets.unescape_html(node['disname']), int(node['sourceid']), Widgets.unescape_html(node['info']), Widgets.set_tooltip(node['disname'], node['info']), ]) Net.update_liststore_image(self.liststore_nodes, i, 0, node['pic']) i += 1
def _show_sub1(sub1_args, error=None): nodes, self.sub1_total = sub1_args if error or not nodes or not self.sub1_total: return urls = [] tree_iters = [] for node in nodes: _id = 'id' if self.use_sub2 else 'sourceid' if 'tips' in node and len(node['tips']) > 5: tooltip = Widgets.set_tooltip_with_song_tips( node['name'], node['tips']) else: tooltip = Widgets.set_tooltip(node['name'], node['info']) tree_iter = self.liststore_sub1.append([ self.app.theme['anonymous'], Widgets.unescape(node['name']), int(node[_id]), Widgets.unescape(node['info']), tooltip, ]) urls.append(node['pic']) tree_iters.append(tree_iter) Net.update_liststore_images(self.liststore_sub1, 0, tree_iters, urls) self.sub1_page += 1 if self.sub1_page < self.sub1_total - 1: self.show_sub1()
def _append_albums(albums_args, error=None): albums, hit, self.albums_total = albums_args if hit == 0: if reset_status: self.albums_button.set_label( '{0} (0)'.format(_('Albums'))) return self.albums_button.set_label( '{0} ({1})'.format(_('Albums'), hit)) i = len(self.liststore_albums) for album in albums: if 'info' in album and album['info']: tooltip = Widgets.set_tooltip(album['name'], album['info']) else: tooltip = Widgets.escape(album['name']) self.liststore_albums.append([ self.app.theme['anonymous'], Widgets.unescape(album['name']), int(album['albumid']), Widgets.unescape(album['artist']), int(album['artistid']), tooltip, ]) Net.update_album_covers( self.liststore_albums, i, 0, album['pic']) i += 1
def append_artists(self, init=False): if init: self.artists_liststore.clear() self.artists_page = 0 self.artists_win.get_vadjustment().set_value(0) selection = self.cate_treeview.get_selection() result = selection.get_selected() if result is None or len(result) != 2: return model, _iter = result pref_index = self.pref_combo.get_active() catid = model[_iter][1] prefix = self.pref_liststore[pref_index][1] # TODO: use async_call() artists, self.artists_total = Net.get_artists( catid, self.artists_page, prefix) if self.artists_total == 0: return i = len(self.artists_liststore) for artist in artists: _info = ' '.join([artist['music_num'], _(' songs'), ]) self.artists_liststore.append([ self.app.theme['anonymous'], Widgets.unescape(artist['name']), int(artist['id']), _info, Widgets.set_tooltip(artist['name'], _info), ]) Net.update_artist_logo( self.artists_liststore, i, 0, artist['pic']) i += 1
def _append_albums(albums_args, error=None): albums, hit, self.albums_total = albums_args if hit == 0: if reset_status: self.albums_button.set_label( '{0} (0)'.format(_('Albums'))) return self.albums_button.set_label( '{0} ({1})'.format(_('Albums'), hit)) i = len(self.liststore_albums) for album in albums: if len(album['info']) == 0: tooltip = Widgets.tooltip(album['name']) else: tooltip = '<b>{0}</b>\n{1}'.format( Widgets.tooltip(album['name']), Widgets.tooltip(album['info'])) self.liststore_albums.append([self.app.theme['anonymous'], album['name'], int(album['albumid']), album['artist'], int(album['artistid']), tooltip, ]) Net.update_album_covers(self.liststore_albums, i, 0, album['pic']) i += 1
def _append_artist_similar(similar_args, error=None): artists, self.artist_similar_total = similar_args if error or not self.artist_similar_total: logger.error('append_artist_similar(): %s, %s' % (self.artist_similar_total, error)) return urls = [] tree_iters = [] for artist in artists: _info = ''.join([ artist['songnum'], _(' songs'), ]) tree_iter = self.artist_similar_liststore.append([ Config.ANONYMOUS_PIXBUF, Widgets.unescape(artist['name']), int(artist['id']), _info, Widgets.set_tooltip(artist['name'], _info), ]) urls.append(artist['pic']) tree_iters.append(tree_iter) Net.async_call(Net.update_artist_logos, self.artist_similar_liststore, 0, tree_iters, urls) self.artist_similar_page += 1 if self.artist_similar_page < self.artist_similar_total - 1: self.append_artist_similar()
def update_player_info(self): def _update_pic(info, error=None): if not info or error: return self.artist_pic.set_tooltip_text( Widgets.short_tooltip(info['info'], length=500)) if info['pic']: self.meta_artUrl = info['pic'] pix = GdkPixbuf.Pixbuf.new_from_file_at_size( info['pic'], 100, 100) self.artist_pic.set_from_pixbuf(pix) else: self.meta_artUrl = self.app.theme_path['anonymous'] self.notify.refresh() self.dbus.update_meta() song = self.curr_song name = Widgets.short_tooltip(song['name'], 45) if song['artist']: artist = Widgets.short_tooltip(song['artist'], 20) else: artist = _('Unknown') if song['album']: album = Widgets.short_tooltip(song['album'], 30) else: album = _('Unknown') label = '<b>{0}</b> <small>by {1} from {2}</small>'.format( name, artist, album) self.label.set_label(label) self.app.window.set_title(name) self.artist_pic.set_from_pixbuf(self.app.theme['anonymous']) Net.async_call( Net.get_artist_info, _update_pic, song['artistid'], song['artist'])
def first(self): if self.first_show: return self.first_show = True app = self.app self.buttonbox = Gtk.Box(spacing=5) self.pack_start(self.buttonbox, False, False, 0) button_home = Gtk.Button(_('TopList')) button_home.connect('clicked', self.on_button_home_clicked) self.buttonbox.pack_start(button_home, False, False, 0) self.label = Gtk.Label('') self.buttonbox.pack_start(self.label, False, False, 0) # checked, name, artist, album, rid, artistid, albumid self.liststore_songs = Gtk.ListStore(bool, str, str, str, int, int, int) control_box = Widgets.ControlBox(self.liststore_songs, app) self.buttonbox.pack_end(control_box, False, False, 0) self.scrolled_nodes = Gtk.ScrolledWindow() self.pack_start(self.scrolled_nodes, True, True, 0) # logo, name, nid, info, tooltip self.liststore_nodes = Gtk.ListStore(GdkPixbuf.Pixbuf, str, int, str, str) iconview_nodes = Widgets.IconView(self.liststore_nodes, tooltip=4) iconview_nodes.connect('item_activated', self.on_iconview_nodes_item_activated) self.scrolled_nodes.add(iconview_nodes) self.scrolled_songs = Gtk.ScrolledWindow() self.pack_start(self.scrolled_songs, True, True, 0) treeview_songs = Widgets.TreeViewSongs(self.liststore_songs, app) self.scrolled_songs.add(treeview_songs) self.show_all() self.buttonbox.hide() self.scrolled_songs.hide() nid = 2 page = 0 nodes, total_pages = Net.get_nodes(nid, page) if total_pages == 0: return i = 0 for node in nodes: self.liststore_nodes.append([ self.app.theme['anonymous'], Widgets.unescape_html(node['name']), int(node['sourceid']), Widgets.unescape_html(node['info']), Widgets.set_tooltip_with_song_tips(node['name'], node['tips']), ]) Net.update_toplist_node_logo(self.liststore_nodes, i, 0, node['pic']) i += 1
def load_styles(self): '''Load default CssStyle.''' if Config.GTK_LE_36: css = '\n'.join([ 'GtkScale {', 'outline-color: transparent;', 'outline-offset: 0;', 'outline-style: none;', 'outline-width: 0;', '}', 'GtkTextView.lrc_tv {', 'font-size: {0};'.format(self.conf['lrc-text-size']), 'color: {0};'.format(self.conf['lrc-text-color']), 'border-radius: 0 25 0 50;', 'border-width: 5;', 'background-color: {0};'.format( self.conf['lrc-back-color']), '}', '.info-label {', 'color: rgb(136, 139, 132);', 'font-size: 9;', '}', ]) else: css = '\n'.join([ 'GtkScrolledWindow.lrc_window {', 'transition-property: background-image;', 'transition-duration: 1s;', '}', 'GtkScale {', 'outline-color: transparent;', 'outline-offset: 0;', 'outline-style: none;', 'outline-width: 0;', '}', 'GtkTextView.lrc_tv {', 'transition-property: font-size;', 'transition: 500ms ease-in-out;', 'font-size: {0}px;'.format(self.conf['lrc-text-size']), 'color: {0};'.format(self.conf['lrc-text-color']), 'border-radius: 0px 25px 0px 50px;', 'border-width: 5px;', 'background-color: {0};'.format( self.conf['lrc-back-color']), '}', '.info-label {', 'color: rgb(136, 139, 132);', 'font-size: 9px;', '}', ]) Widgets.apply_css(self.window, css, overall=True) settings = Gtk.Settings.get_default() settings.props.gtk_application_prefer_dark_theme = \ self.conf.get('use-dark-theme', False)
def _on_can_play(widget, song_path, status, error=None): if status == 'OK': return # stop cache service when error occurs self.cache_enabled = False if status == 'URLError': Widgets.network_error( self.app.window, _('Failed to cache song')) elif status == 'FileNotFoundError': Widgets.filesystem_error(self.app.window, song_path)
def _on_can_play(widget, song_path, status, error=None): if status == 'OK': return # stop cache service when error occurs self.cache_enabled = False if status == 'URLError': Widgets.network_error(self.app.window, _('Failed to cache song')) elif status == 'FileNotFoundError': Widgets.filesystem_error(self.app.window, song_path)
def failed_to_download(self, song_path, status): self.pause_player() if status == 'FileNotFoundError': Widgets.filesystem_error(self.app.window, song_path) elif status == 'URLError': if self.play_type == PlayType.MV: msg = _('Failed to download MV') elif self.play_type in (PlayType.SONG, PlayType.RADIO): msg = _('Failed to download song') Widgets.network_error(self.app.window, msg)
def first(self): app = self.app # left side panel scrolled_myradio = Gtk.ScrolledWindow() scrolled_myradio.props.hscrollbar_policy = Gtk.PolicyType.NEVER self.pack_start(scrolled_myradio, False, False, 0) # radios selected by user. self.box_myradio = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.box_myradio.props.margin_left = 10 scrolled_myradio.add(self.box_myradio) self.scrolled_radios = Gtk.ScrolledWindow() self.pack_start(self.scrolled_radios, True, True, 0) # pic, name, id, num of listeners, pic_url, tooltip self.liststore_radios = Gtk.ListStore( GdkPixbuf.Pixbuf, str, int, str, str, str) iconview_radios = Widgets.IconView( self.liststore_radios, tooltip=5) iconview_radios.connect( 'item_activated', self.on_iconview_radios_item_activated) self.scrolled_radios.add(iconview_radios) self.show_all() nid = 8 page = 0 radios, total_page = Net.get_nodes(nid, page) if total_page == 0: return urls = [] tree_iters = [] for radio in radios: tree_iter = self.liststore_radios.append([ self.app.theme['anonymous'], Widgets.unescape(radio['disname']), int(radio['sourceid'].split(',')[0]), Widgets.unescape(radio['info']), radio['pic'], Widgets.set_tooltip(radio['disname'], radio['info']), ]) tree_iters.append(tree_iter) urls.append(radio['pic']) self.liststore_radios.timestamp = time.time() Net.update_liststore_images( self.liststore_radios, 0, tree_iters, urls) for radio in self.playlists: radio_item = RadioItem(radio, self.app) self.box_myradio.pack_start(radio_item, False, False, 0) GLib.timeout_add(300000, self.dump_playlists)
def refresh(self): if not self.player.app.conf["use-notify"]: return notify = self.notify song = self.player.curr_song notify.clear_hints() # notify.set_timeout(4000) if song["artist"]: artist = Widgets.short_tooltip(song["artist"], 20) else: artist = _("Unknown") if song["album"]: album = Widgets.short_tooltip(song["album"], 30) else: album = _("Unknown") notify.update(song["name"], "by {0} from {1}".format(artist, album), self.player.meta_artUrl) notify.set_hint("image-path", GLib.Variant.new_string(self.player.meta_artUrl)) notify.clear_actions() try: notify.add_action("media-skip-backward", _("Previous"), self.on_prev_action_activated, None) if self.player.is_playing(): notify.add_action("media-playback-pause", _("Pause"), self.on_playpause_action_activated, None) else: notify.add_action("media-playback-start", _("Play"), self.on_playpause_action_activated, None) notify.add_action("media-skip-forward", _("Next"), self.on_next_action_activated, None) except TypeError: # For Fedora 19, which needs 6 parameters. notify.add_action("media-skip-backward", _("Previous"), self.on_prev_action_activated, None, None) if self.player.is_playing(): notify.add_action("media-playback-pause", _("Pause"), self.on_playpause_action_activated, None, None) else: notify.add_action("media-playback-start", _("Play"), self.on_playpause_action_activated, None, None) notify.add_action("media-skip-forward", _("Next"), self.on_next_action_activated, None, None) notify.set_hint("action-icons", GLib.Variant.new_boolean(True)) # gnome shell screenlocker will get `x-gnome.music` notification # and the whole notification content will be presented # from rhythmbox/plugins/rb-notification-plugin.c notify.set_category("x-gnome.music") # show on lock screen hint = "resident" # show on desktop # hint = 'transient' notify.set_hint(hint, GLib.Variant.new_boolean(True)) notify.show()
def _append_album_songs(songs, error=None): if not songs: return for song in songs: self.album_songs_liststore.append([ True, Widgets.unescape(song['name']), Widgets.unescape(song['artist']), Widgets.unescape(self.curr_album_name), int(song['id']), int(song['artistid']), int(self.curr_album_id), ])
def first(self): app = self.app # left side panel scrolled_myradio = Gtk.ScrolledWindow() scrolled_myradio.props.hscrollbar_policy = Gtk.PolicyType.NEVER self.pack_start(scrolled_myradio, False, False, 0) # radios selected by user. self.box_myradio = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.box_myradio.props.margin_left = 10 scrolled_myradio.add(self.box_myradio) self.scrolled_radios = Gtk.ScrolledWindow() self.pack_start(self.scrolled_radios, True, True, 0) # pic, name, id, num of listeners, pic_url, tooltip self.liststore_radios = Gtk.ListStore(GdkPixbuf.Pixbuf, str, int, str, str, str) iconview_radios = Widgets.IconView(self.liststore_radios, tooltip=5) iconview_radios.connect('item_activated', self.on_iconview_radios_item_activated) self.scrolled_radios.add(iconview_radios) self.show_all() nid = 8 page = 0 radios, total_page = Net.get_nodes(nid, page) if total_page == 0: return urls = [] tree_iters = [] for radio in radios: tree_iter = self.liststore_radios.append([ Config.ANONYMOUS_PIXBUF, Widgets.unescape(radio['disname']), int(radio['sourceid'].split(',')[0]), Widgets.unescape(radio['info']), radio['pic'], Widgets.set_tooltip(radio['disname'], radio['info']), ]) tree_iters.append(tree_iter) urls.append(radio['pic']) self.liststore_radios.timestamp = time.time() Net.async_call(Net.update_liststore_images, self.liststore_radios, 0, tree_iters, urls) for radio_rid in self.playlists: radio_item = RadioItem(radio_rid, self.app) self.box_myradio.pack_start(radio_item, False, False, 0) GLib.timeout_add(300000, self.dump_playlists)
def _append_album_songs(songs, error=None): if error or not songs: return for song in songs: self.album_songs_liststore.append([ True, Widgets.unescape(song['name']), Widgets.unescape(song['artist']), Widgets.unescape(self.curr_album_name), int(song['id']), int(song['artistid']), int(self.curr_album_id), ])
def failed_to_download(self, song_path, status): self.stop_player_cb() if status == 'FileNotFoundError': Widgets.filesystem_error(self.app.window, song_path) elif status == 'URLError': if self.play_type == PlayType.MV: msg = _('Failed to download MV') elif self.play_type in (PlayType.SONG, PlayType.RADIO): msg = _('Failed to download song') #Widgets.network_error(self.app.window, msg) print('Error:', msg) self.load_next_cb()
def __init__(self, parent, treeview, export_all=True): super().__init__(_('Export Songs'), parent.app.window, Gtk.DialogFlags.MODAL, ( Gtk.STOCK_CLOSE, Gtk.ResponseType.OK, )) self.parent = parent self.treeview = treeview self.export_all = export_all self.app = parent.app self.set_border_width(15) box = self.get_content_area() box.set_size_request(540, 260) box.set_spacing = 5 folder_label = Widgets.BoldLabel(_('Choose export folder:')) box.pack_start(folder_label, False, True, 2) self.folder_chooser = Widgets.FolderChooser(self.app.window) self.folder_chooser.props.margin_left = 20 box.pack_start(self.folder_chooser, False, True, 0) self.including_lrc = Gtk.CheckButton(_('Including lyrics')) self.including_lrc.set_tooltip_text( _('Export lyrics to the same folder')) self.including_lrc.props.margin_top = 20 box.pack_start(self.including_lrc, False, False, 0) export_box = Gtk.Box(spacing=5) export_box.props.margin_top = 20 box.pack_start(export_box, False, True, 0) self.export_prog = Gtk.ProgressBar() self.export_prog.props.show_text = True self.export_prog.props.text = '' export_box.pack_start(self.export_prog, True, True, 0) self.export_btn = Gtk.Button(_('Export')) self.export_btn.connect('clicked', self.do_export) export_box.pack_start(self.export_btn, False, False, 0) infobar = Gtk.InfoBar() infobar.props.margin_top = 20 box.pack_start(infobar, False, True, 0) info_content = infobar.get_content_area() info_label = Gtk.Label(_('Only cached songs will be exported')) info_content.pack_start(info_label, False, False, 0) box.show_all()
def _append_songs(songs_args, error=None): songs, hit, self.songs_total = songs_args if not error and songs and hit: for song in songs: self.liststore_songs.append([ False, Widgets.unescape(song['SONGNAME']), Widgets.unescape(song['ARTIST']), Widgets.unescape(song['ALBUM']), int(song['MUSICRID'][6:]), int(song['ARTISTID']), int(song['ALBUMID']), ]) self.songs_button.set_label('{0} ({1})'.format( _('Songs'), len(self.liststore_songs)))
def on_append_artists(info, error=None): artists, self.artists_total = info if error or not self.artists_total or not artists: return for i, artist in enumerate(artists): _info = ' '.join([artist['music_num'], _(' songs'), ]) self.artists_liststore.append([ self.app.theme['anonymous'], Widgets.unescape(artist['name']), int(artist['id']), _info, Widgets.set_tooltip(artist['name'], _info), ]) Net.update_artist_logo( self.artists_liststore, i, 0, artist['pic'])
def _append_album_songs(songs, error=None): if error or not songs: logger.error('append_album_songs(): %s, %s' % (songs, error)) return for song in songs: self.album_songs_liststore.append([ True, Widgets.unescape(song['name']), Widgets.unescape(song['artist']), Widgets.unescape(self.curr_album_name), int(song['id']), int(song['artistid']), int(self.curr_album_id), song['formats'], ])
def play_song(self, song, list_name='Default'): if not song: return liststore = self.tabs[list_name].liststore rid = song['rid'] path = self.get_song_path_in_liststore(liststore, rid) if path is not None: # curr_playing contains: listname, path self.curr_playing = [list_name, path] song = Widgets.song_row_to_dict(liststore[path], start=0) self.app.player.load(song) return liststore.append(Widgets.song_dict_to_row(song)) self.curr_playing = [list_name, len(liststore)-1, ] self.app.player.load(song)
def add_song_to_playlist(self, song, list_name='Default'): liststore = self.tabs[list_name].liststore rid = song['rid'] path = self.get_song_path_in_liststore(liststore, rid) if path > -1: return liststore.append(Widgets.song_dict_to_row(song))
def _append_artist_info(info, error=None): if error or not info: logger.error('appen_artist_info(): %s, %s' % (info, error)) return if info.get('pic', None): self.artist_info_pic.set_from_file(info['pic']) self.artist_info_name.set(info, 'name') self.artist_info_birthday.set(info, 'birthday') self.artist_info_birthplace.set(info, 'birthplace') self.artist_info_height.set(info, 'tall') self.artist_info_weight.set( info, 'weight', ) self.artist_info_country.set(info, 'country') self.artist_info_language.set(info, 'language') self.artist_info_gender.set( info, 'gender', ) self.artist_info_constellation.set(info, 'constellation') if info and 'info' in info: if html2text_imported: self.artist_info_textbuffer.set_text( html2text.html2text(info['info'])) else: self.artist_info_textbuffer.set_text( Widgets.escape(info['info'])) else: self.artist_info_textbuffer.set_text('')
def load_playlists(self): filepath = Config.PLS_JSON _default = { '_names_': [ [_('Caching'), 'Caching', False], [_('Default'), 'Default', False], [_('Favorite'), 'Favorite', False], ], 'Caching': [], 'Default': [], 'Favorite': [], } if os.path.exists(filepath): with open(filepath) as fh: playlists = json.loads(fh.read()) else: playlists = _default for playlist in playlists['_names_']: disname, list_name, editable = playlist tooltip = Widgets.escape(disname) self.liststore_left.append( [disname, list_name, editable, tooltip]) songs = playlists[list_name] self.init_tab(list_name, songs)
def add_song_to_playlist(self, song, list_name='Default'): liststore = self.tabs[list_name].liststore rid = song['rid'] path = self.get_song_path_in_liststore(liststore, rid) if path is not None: return liststore.append(Widgets.song_dict_to_row(song))
def on_song_downloaded(self, play=False): list_name = self.curr_playing[0] liststore = self.tabs[list_name].liststore iter_ = self.curr_playing[1] path = liststore.get_path(iter_) song = Widgets.song_row_to_dict(liststore[path], start=0) Gdk.Window.process_all_updates()
def _on_get_themes_songs(info, error): if not info or not info[0] or not info[1] or error: logger.error('show_songs(): %s, %s' % (info, error)) return songs, self.songs_total = info for song in songs: self.liststore_songs.append([ True, Widgets.unescape(song['name']), Widgets.unescape(song['artist']), Widgets.unescape(song['album']), int(song['id']), int(song['artistid']), int(song['albumid']), song['formats'], ])
def __init__(self, radio_id, app): super().__init__() self.app = app self.parent = app.radio self.playlists = self.parent.playlists self.connect('button-press-event', self.on_button_pressed) # radio_info contains: # pic, name, radio_id, offset self.radio_id = radio_id self.expanded = False self.box = Gtk.Box() self.box.props.margin_top = 5 self.box.props.margin_bottom = 5 self.add(self.box) self.img = Gtk.Image() self.img_path = Net.get_image(self.playlists[self.radio_id]['pic']) self.small_pix = GdkPixbuf.Pixbuf.new_from_file_at_size(self.img_path, 50, 50) self.big_pix = GdkPixbuf.Pixbuf.new_from_file_at_size(self.img_path, 75, 75) self.img.set_from_pixbuf(self.small_pix) self.box.pack_start(self.img, False, False, 0) box_right = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.box.pack_start(box_right, True, True, 0) radio_name = Gtk.Label( Widgets.short_str(self.playlists[self.radio_id]['name'], 8)) box_right.pack_start(radio_name, True, True, 0) self.label = Gtk.Label(_('song name')) self.label.get_style_context().add_class('info-label') box_right.pack_start(self.label, False, False, 0) self.toolbar = Gtk.Toolbar() self.toolbar.set_style(Gtk.ToolbarStyle.ICONS) self.toolbar.set_show_arrow(False) self.toolbar.set_icon_size(1) box_right.pack_start(self.toolbar, False, False, 0) button_play = Gtk.ToolButton() button_play.set_label(_('Play')) button_play.set_icon_name('media-playback-start-symbolic') button_play.connect('clicked', self.on_button_play_clicked) self.toolbar.insert(button_play, 0) button_delete = Gtk.ToolButton() button_delete.set_label(_('Delete')) button_delete.set_icon_name('user-trash-symbolic') button_delete.connect('clicked', self.on_button_delete_clicked) self.toolbar.insert(button_delete, 1) self.show_all() self.label.hide() self.toolbar.hide() self.init_songs()
def __init__(self, app, list_name): super().__init__() self.app = app self.list_name = list_name # name, artist, album, rid, artistid, albumid self.liststore = Gtk.ListStore(str, str, str, int, int, int) self.treeview = Gtk.TreeView(model=self.liststore) self.selection = self.treeview.get_selection() self.treeview.set_search_column(0) self.treeview.props.headers_clickable = True self.treeview.props.headers_visible = True self.treeview.props.reorderable = True self.treeview.props.rules_hint = True self.treeview.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE) self.treeview.enable_model_drag_source(Gdk.ModifierType.BUTTON1_MASK, DRAG_TARGETS, DRAG_ACTIONS) self.treeview.connect('drag-data-get', self.on_drag_data_get) self.treeview.enable_model_drag_dest(DRAG_TARGETS, DRAG_ACTIONS) self.treeview.connect('drag-data-received', self.on_drag_data_received) self.treeview.connect('row_activated', self.on_treeview_row_activated) self.add(self.treeview) song_cell = Gtk.CellRendererText() song_col = TreeViewColumnText(_('Title'), song_cell, text=0) self.treeview.append_column(song_col) artist_cell = Gtk.CellRendererText() artist_col = TreeViewColumnText(_('Aritst'), artist_cell, text=1) self.treeview.append_column(artist_col) album_cell = Gtk.CellRendererText() album_col = TreeViewColumnText(_('Album'), album_cell, text=2) self.treeview.append_column(album_col) delete_cell = Gtk.CellRendererPixbuf(icon_name='user-trash-symbolic') self.delete_col = Widgets.TreeViewColumnIcon(_('Delete'), delete_cell) self.treeview.append_column(self.delete_col) self.treeview.connect('key-press-event', self.on_treeview_key_pressed) self.treeview.connect('button-press-event', self.on_treeview_button_pressed) self.treeview.connect('button-release-event', self.on_treeview_button_released) self.popup_menu = Gtk.Menu() save_as_menu = Gtk.MenuItem(_('Save As..')) save_as_menu.connect('activate', self.on_save_as_menu_activated) self.popup_menu.append(save_as_menu) sep = Gtk.SeparatorMenuItem() self.popup_menu.append(sep) delete_song_menu = Gtk.MenuItem(_('Delete from Playlist')) delete_song_menu.connect('activate', self.on_delete_song_menu_activated) self.popup_menu.append(delete_song_menu) delete_cache_menu = Gtk.MenuItem(_('Delete Local Cache')) delete_cache_menu.connect('activate', self.on_delete_cache_menu_activated) self.popup_menu.append(delete_cache_menu)