def add(self, *urls): if not urls: return def readfile(url): with closing(urlopen(url) if url.startswith(('http://', 'https://')) else open(url, 'r')) as f: return f.read().splitlines() clean_playlist = lambda lines: ifilter(None, imap(str.strip, imap(str, lines))) parse_null = lambda url: (url,) parsers = { '.m3u': lambda url: ifilter(lambda line: not line.startswith('#'), readfile(url)), '.pls': lambda url: imap(lambda line: line.split('=')[1], ifilter(lambda line: line.startswith('File'), readfile(url))), } urls = flatten(imap(lambda url: clean_playlist(parsers.get(os.path.splitext(url)[1], parse_null)(url)), urls)) cmds = imap(lambda url: ('addid', url), urls) try: self._mpd.bulk_do(cmds) except CommandError: self.context.notify('error', _('Songs not found')) else: self.refresh()
def refresh(self, areas=()): if not areas: update = ['playlistinfo', 'status', 'currentsong', 'listplaylists', 'outputs'] defaults = [[], Status.EMPTY, Song.EMPTY, [], []] else: update = list(set(ifilter(bool, flatten( ('playlistinfo',) if area in (MPD.EV_QUEUE_CHANGED,) else ('listplaylists',) if area in (MPD.EV_PLAYLIST_CHANGED,) else ('status',) if area in (MPD.EV_VOLUME_CHANGED, MPD.EV_OPTIONS_CHANGED) else ('status', 'currentsong') if area in (MPD.EV_PLAYER_CHANGED,) else ('outputs',) if area in (MPD.EV_OUTPUT_CHANGED,) else None for area in areas)))) defaults = map(lambda n: {} if n in ('status', 'currentsong') else [], update) data = UpdateInfo(izip(update, self._mpd.bulk_do(*update, defaults=defaults))) for key in update: setattr(self, { 'playlistinfo': 'playlist', 'listplaylists': 'playlists', 'currentsong': 'song', }.get(key, key), getattr(data, key)) if 'status' in update: # reset icons if not all playlist is to be updated if 'playlistinfo' not in update: for song in self.playlist: song.icon = 'music' try: if self.status.state == 'play': self.find('play').visible = False self.find('pause').visible = True self.playlist[self.status.song].icon = 'play' else: self.find('play').visible = True self.find('pause').visible = False except AttributeError: pass self.binder.populate()