def lastfm_get_album_tags(args): tracks = parser.parse(' '.join(args.collection)) albums_albumartists = set() for track in tracks: album, albumartist = mpd.get_tags(track, tags_list=['album','albumartist']) if album and albumartist: albums_albumartists.add((album, albumartist)) for item in albums_albumartists: if item in lastfm.albums_tags and lastfm.albums_tags[item]: album, albumartist = item print(':: %s — %s:' % (albumartist, album)) print(', '.join(lastfm.albums_tags[item]))
def display_songs(filenames, metadata=False, prefix=None): for song in filenames: if metadata: tags = ('artist', 'album', 'title') artist, album, title = mpd.get_tags(song, tags) print('%s - %s - %s' % (colorize(artist, colors[0]), colorize(album, colors[1]), colorize(title, colors[2]))) elif prefix is not None: print(prefix + song) else: print(song)
def lastfm_get_artist_tags(args): tracks = parser.parse(' '.join(args.collection)) artists = set() for track in tracks: albumartist, artist = mpd.get_tags(track, tags_list=['albumartist','artist']) if artist: artists.add(artist) if albumartist: artists.add(albumartist) for artist in artists: if artist in lastfm.artists_tags and lastfm.artists_tags[artist]: print(':: %s:' % artist) print(', '.join(lastfm.artists_tags[artist]))
def lastfm_get_track_tags(args): tracks = parser.parse(' '.join(args.collection)) tracks_artists = set() for trackfile in tracks: trackname, artist, albumartist = mpd.get_tags(trackfile, tags_list=['title','artist','albumartist']) if trackname and albumartist: tracks_artists.add((trackname, albumartist)) if trackname and artist: tracks_artists.add((trackname, artist)) for item in tracks_artists: if item in lastfm.tracks_tags and lastfm.tracks_tags[item]: track, artist = item print(':: %s — %s:' % (artist, track)) print(', '.join(lastfm.tracks_tags[item]))
def add_songs(self, alias, songs_files): if not alias in self.c or not 'mpd_playlist' in self.c[alias]: for song in songs_files[:]: if not all(mpd.get_tags(song)): warning('[{}] was not added (missing tags)'.format(song)) songs_files.remove(song) if alias in self.c: if 'songs' in self.c[alias]: self.collections[alias]['songs'].extend(songs_files) else: self.collections[alias]['songs'] = songs_files if 'mpd_playlist' in self.c[alias]: mpd.add_songs_stored_playlist(alias, songs_files) else: info('Collection [{}] will be created'.format(alias)) self.collections[alias] = {} self.collections[alias]['songs'] = songs_files self.need_update = True
def add_songs(self, alias, songs_files): if (not alias in self.collections or not 'mpd_playlist' in self.collections[alias]): for song in songs_files[:]: if not all(mpd.get_tags(song)): warning('File not added, missing tag(s): [%s]' % song) songs_files.remove(song) if alias in self.collections: if 'songs' in self.collections[alias]: self.collections[alias]['songs'].extend(songs_files) else: self.collections[alias]['songs'] = songs_files if 'mpd_playlist' in self.collections[alias]: mpd.add_songs_stored_playlist(alias, songs_files) else: info('Collection [%s] will be created' % alias) self.collections[alias] = {} self.collections[alias]['songs'] = songs_files self.need_update = True
def optimized_to_raw(collections_optimized): raw = '' for alias, collection in collections_optimized.items(): if 'mpd_playlist' in collection: continue if 'sort' in collection: raw += '--@%s' % alias else: raw += '--%s' % alias if 'expression' in collection: raw += '\n' + collection['expression'].rstrip() if 'command' in collection: raw += '\ncommand: ' + collection['command'] if 'songs' in collection and collection['songs']: raw += '\nsongs:' for song in collection['songs']: song_tags = mpd.get_tags(song) raw += '\n ' + repr_tags(song_tags) raw += '\n\n\n' return raw.strip()
def p_expression_modifier(p): 'expression : expression MODIFIER' modifier = (p[2][1:]).lstrip() # Sorting modifier if modifier == 's': p[0] = mpd.set_sort(p[1]) # N-random songs modifier elif re.match(r'^r[0-9]+$', modifier): try: p[0] = OrderedSet(random.sample(p[1], int(modifier[1:]))) except ValueError: p[0] = p[1] # N-random artists modifier elif re.match(r'^ra[0-9]+$', modifier): artists = OrderedSet() for song in p[1]: artists.add(mpd.get_tag(song, 'artist')) try: r_artists = OrderedSet(random.sample(artists, int(modifier[2:]))) except ValueError: p[0] = p[1] else: songs = [] for artist in r_artists: songs.extend(mpd.find('artist', artist)) p[0] = OrderedSet([song for song in p[1] if song in songs]) # N-random albums modifier elif re.match(r'^rb[0-9]+$', modifier): albums = OrderedSet() for song in p[1]: albums.add(mpd.get_tags(song, ('album', 'artist'))) try: r_albums = OrderedSet(random.sample(albums, int(modifier[2:]))) except ValueError: p[0] = p[1] else: songs = [] for album, artist in r_albums: songs.extend(mpd.find_multiple(album=album, artist=artist)) p[0] = OrderedSet([song for song in p[1] if song in songs]) # N-minutes-long modifier elif re.match(r'^d[0-9]+$', modifier): total_duration = int(modifier[1:]) * 60 d = 0 p[0] = OrderedSet() p[1] = list(p[1]) random.shuffle(p[1]) for song in p[1]: if d < total_duration: p[0].add(song) d += int(mpd.get_tag(song, 'time')) else: break # N-similar artists modifier elif re.match(r'^i?sa[0-9]+$', modifier): include = True if modifier[0] == 'i' else False limit = int((modifier[3:] if include else modifier[2:])) w_tags = defaultdict(int) for song in p[1]: tags = lastfm.get_artist_tags(mpd.get_tag(song, 'artist')) for tag in tags: w_tags[tag] += tags[tag] if not w_tags: p[0] = p[1] if include else OrderedSet() else: songs = [] similar_artists = lastfm.get_similar_artists(w_tags) for artist, score in similar_artists: if not limit: break matched_songs = mpd.find('artist', artist) if not include: matched_songs = OrderedSet(matched_songs) - p[1] if matched_songs: songs.extend(matched_songs) limit -= 1 p[0] = OrderedSet(songs) # N-similar albums modifier elif re.match(r'^i?sb[0-9]+$', modifier): include = True if modifier[0] == 'i' else False limit = int((modifier[3:] if include else modifier[2:])) w_tags = defaultdict(int) for song in p[1]: tags = lastfm.get_album_tags(mpd.get_tag(song, 'album'), mpd.get_tag(song, 'artist')) for tag in tags: w_tags[tag] += tags[tag] if not w_tags: p[0] = p[1] if include else OrderedSet() else: songs = [] for (album, artist), score in lastfm.get_similar_albums(w_tags): if not limit: break matched_songs = mpd.find_multiple(album=album, artist=artist) if not include: matched_songs = OrderedSet(matched_songs) - p[1] if matched_songs: songs.extend(matched_songs) limit -= 1 p[0] = OrderedSet(songs) else: warning('Modifier [%s] doesn\'t exist' % modifier) sys.exit(0)
def p_expression_modifier(p): 'expression : expression MODIFIER' modifier = (p[2][1:]).lstrip() # Sorting modifier if modifier == 's': p[0] = mpd.set_sort(p[1]) # N-random songs modifier elif re.match(r'^r[0-9]+$', modifier): p[1] = exclude_songs(p[1]) try: p[0] = OrderedSet(random.sample(p[1], int(modifier[1:]))) except ValueError: p[0] = p[1] # N-random artists modifier elif re.match(r'^ra[0-9]+$', modifier): p[1] = exclude_songs(p[1]) artists = OrderedSet() for song in p[1]: artists.add(mpd.get_tag(song, 'artist')) try: r_artists = OrderedSet(random.sample(artists, int(modifier[2:]))) except ValueError: p[0] = p[1] else: songs = [] for artist in r_artists: songs.extend(mpd.find('artist', artist)) p[0] = OrderedSet([song for song in p[1] if song in songs]) # N-random albums modifier elif re.match(r'^rb[0-9]+$', modifier): p[1] = exclude_songs(p[1]) albums = OrderedSet() for song in p[1]: albums.add(mpd.get_tags(song, ('album', 'albumartist'))) try: r_albums = OrderedSet(random.sample(albums, int(modifier[2:]))) except ValueError: p[0] = p[1] else: songs = [] for album, artist in r_albums: matched_songs = mpd.find_multiple(album=album, albumartist=artist) if not matched_songs: matched_songs = mpd.find_multiple(album=album, artist=artist) songs.extend(matched_songs) p[0] = OrderedSet([song for song in p[1] if song in songs]) # N-minutes-long modifier elif re.match(r'^d[0-9]+$', modifier): p[1] = exclude_songs(p[1]) total_duration = int(modifier[1:]) * 60 d = 0 p[0] = OrderedSet() p[1] = list(p[1]) random.shuffle(p[1]) for song in p[1]: if d < total_duration: p[0].add(song) d += int(mpd.get_tag(song, 'time')) else: break # N-similar artists modifier elif re.match(r'^i?sa[0-9]+$', modifier): include = True if modifier[0] == 'i' else False limit = int(modifier[3:] if include else modifier[2:]) w_tags = collections.defaultdict(int) for song in p[1]: tags = lastfm.get_artist_tags(mpd.get_tag(song, 'artist')) for tag, w in tags.items(): w_tags[tag] += w if not w_tags: p[0] = p[1] if include else OrderedSet() else: songs = [] for artist, _ in lastfm.get_similar_artists(w_tags): if not limit: break matched_songs = mpd.find('artist', artist) if not include: matched_songs = OrderedSet(matched_songs) - p[1] if matched_songs: songs.extend(matched_songs) limit -= 1 p[0] = OrderedSet(songs) # N-similar albums modifier elif re.match(r'^i?sb[0-9]+$', modifier): include = True if modifier[0] == 'i' else False limit = int(modifier[3:] if include else modifier[2:]) w_tags = collections.defaultdict(int) for song in p[1]: tags = lastfm.get_album_tags(mpd.get_tag(song, 'album'), mpd.get_tag(song, 'albumartist')) for tag, w in tags.items(): w_tags[tag] += w if not w_tags: p[0] = p[1] if include else OrderedSet() else: songs = [] for (album, artist), score in lastfm.get_similar_albums(w_tags): if not limit: break matched_songs = mpd.find_multiple(album=album, albumartist=artist) if not matched_songs: matched_songs = mpd.find_multiple(album=album, artist=artist) if not include: matched_songs = OrderedSet(matched_songs) - p[1] if matched_songs: songs.extend(matched_songs) limit -= 1 p[0] = OrderedSet(songs) # N-top tracks modifier elif re.match(r'^p[0-9]+$', modifier): p[0] = OrderedSet() artists = OrderedSet(mpd.get_tag(song, 'artist') for song in p[1]) for artist in artists: limit = int(modifier[1:]) for track in lastfm.get_artist_top_tracks(artist): if not limit: break matched_songs = mpd.search_multiple(artist=artist, title=track) if len(matched_songs) > 1: matched_songs = mpd.find_multiple(artist=artist, title=track) \ or matched_songs if matched_songs: p[0].add(matched_songs[0]) limit -= 1 else: warning('Modifier [{}] does not exist'.format(modifier)) sys.exit(0)