def load_from_id(klass, song_id, sid = None): if sid is not None: d = db.c.fetch_row("SELECT * FROM r4_songs JOIN r4_song_sid USING (song_id) WHERE r4_songs.song_id = %s AND r4_song_sid.sid = %s", (song_id, sid)) else: d = db.c.fetch_row("SELECT * FROM r4_songs WHERE song_id = %s", (song_id,)) if not d: raise SongNonExistent try: s = klass() s.id = song_id s.sid = sid s.filename = d['song_filename'] s.verified = d['song_verified'] s.replay_gain = d['song_replay_gain'] s.data['sids'] = db.c.fetch_list("SELECT sid FROM r4_song_sid WHERE song_id = %s", (song_id,)) s.data['sid'] = sid s.data['rank'] = None s._assign_from_dict(d) if 'album_id' in d and d['album_id']: if sid is not None: s.albums = [ Album.load_from_id_sid(d['album_id'], s.sid) ] else: s.albums = [ Album.load_from_id(d['album_id']) ] s.artists = Artist.load_list_from_song_id(song_id) s.groups = SongGroup.load_list_from_song_id(song_id) except Exception as e: log.exception("song", "Song ID %s failed to load, sid %s." % (song_id, sid), e) s.disable() raise return s
def load_from_id(klass, song_id, sid = None): if sid: d = db.c.fetch_row("SELECT * FROM r4_songs JOIN r4_song_sid USING (song_id) WHERE r4_songs.song_id = %s AND r4_song_sid.sid = %s", (song_id, sid)) else: d = db.c.fetch_row("SELECT * FROM r4_songs WHERE song_id = %s", (song_id,)) if not d: raise SongNonExistent try: s = klass() s.id = song_id s.sid = sid s.filename = d['song_filename'] s.verified = d['song_verified'] s.replay_gain = d['song_replay_gain'] s.data['sids'] = db.c.fetch_list("SELECT sid FROM r4_song_sid WHERE song_id = %s", (song_id,)) s.data['sid'] = sid s.data['rank'] = None s._assign_from_dict(d) if 'album_id' in d and d['album_id']: if sid: s.albums = [ Album.load_from_id_sid(d['album_id'], s.sid) ] else: s.albums = [ Album.load_from_id(d['album_id']) ] s.artists = Artist.load_list_from_song_id(song_id) s.groups = SongGroup.load_list_from_song_id(song_id) except Exception as e: log.exception("song", "Song failed to load.", e) db.c.update("UPDATE r4_songs SET song_verified = FALSE WHERE song_id = song_id") raise return s
def load_from_id(klass, song_id, sid = None, all_categories = False): if sid is not None: d = db.c.fetch_row("SELECT * FROM r4_songs JOIN r4_song_sid USING (song_id) WHERE r4_songs.song_id = %s AND r4_song_sid.sid = %s", (song_id, sid)) else: d = db.c.fetch_row("SELECT * FROM r4_songs WHERE song_id = %s", (song_id,)) sid = d['song_origin_sid'] if not d: raise SongNonExistent try: s = klass() s.id = song_id s.sid = sid s.filename = d['song_filename'] s.verified = d['song_verified'] s.replay_gain = d['song_replay_gain'] s.data['sids'] = db.c.fetch_list("SELECT sid FROM r4_song_sid WHERE song_id = %s", (song_id,)) s.data['sid'] = sid s.data['rank'] = None s._assign_from_dict(d) if 'album_id' in d and d['album_id']: s.albums = [ Album.load_from_id_sid(d['album_id'], sid) ] s.artists = Artist.load_list_from_song_id(song_id) s.groups = SongGroup.load_list_from_song_id(song_id, sid, all_categories = all_categories) except Exception as e: log.exception("song", "Song ID %s failed to load, sid %s." % (song_id, sid), e) s.disable() raise return s
def load_from_file(klass, filename, sids): """ Produces an instance of the Song class with all album, group, and artist IDs loaded from only a filename. All metadata is saved to the database and updated where necessary. """ # log.debug("playlist", u"sids {} loading song from file {}".format(sids, filename)) kept_artists = [] kept_groups = [] matched_entry = db.c.fetch_row( "SELECT song_id FROM r4_songs WHERE song_filename = %s", (filename, )) if matched_entry: log.debug( "playlist", "this filename matches an existing database entry, song_id {}". format(matched_entry['song_id'])) s = klass.load_from_id(matched_entry['song_id']) for metadata in s.artists: try: if not metadata.is_tag: kept_artists.append(metadata) metadata.disassociate_song_id(s.id) except MetadataUpdateError: pass for metadata in s.groups: try: if not metadata.is_tag: kept_groups.append(metadata) metadata.disassociate_song_id(s.id) except MetadataUpdateError: pass elif len(sids) == 0: raise SongHasNoSIDsException else: s = klass() s.load_tag_from_file(filename) s.save(sids) new_artists = Artist.load_list_from_tag(s.artist_tag) new_groups = SongGroup.load_list_from_tag(s.genre_tag) s.artists = zip_metadata(new_artists, kept_artists) s.groups = zip_metadata(new_groups, kept_groups) i = 0 for metadata in s.artists: metadata.associate_song_id(s.id, order=i) i += 1 for metadata in s.groups: metadata.associate_song_id(s.id) s.albums = [Album.load_from_name(s.album_tag)] s.albums[0].associate_song_id(s.id) s.update_artist_parseable() return s
def load_from_file(klass, filename, sids): """ Produces an instance of the Song class with all album, group, and artist IDs loaded from only a filename. All metadata is saved to the database and updated where necessary. """ # log.debug("playlist", u"sids {} loading song from file {}".format(sids, filename)) kept_artists = [] kept_groups = [] matched_entry = db.c.fetch_row("SELECT song_id FROM r4_songs WHERE song_filename = %s", (filename,)) if matched_entry: log.debug("playlist", "this filename matches an existing database entry, song_id {}".format(matched_entry['song_id'])) s = klass.load_from_id(matched_entry['song_id']) for metadata in s.artists: try: if metadata.is_tag: metadata.disassociate_song_id(s.id) else: kept_artists.append(metadata) except MetadataUpdateError: pass for metadata in s.groups: try: if metadata.is_tag: metadata.disassociate_song_id(s.id) else: kept_groups.append(metadata) except MetadataUpdateError: pass elif len(sids) == 0: raise SongHasNoSIDsException else: s = klass() s.load_tag_from_file(filename) s.save(sids) new_artists = Artist.load_list_from_tag(s.artist_tag) new_groups = SongGroup.load_list_from_tag(s.genre_tag) i = 0 for metadata in new_artists: metadata.associate_song_id(s.id, order=i) i += 1 for metadata in new_groups: metadata.associate_song_id(s.id) s.artists = new_artists + kept_artists s.groups = new_groups + kept_groups s.albums = [ Album.load_from_name(s.album_tag) ] s.albums[0].associate_song_id(s.id) s.update_artist_parseable() return s
def load_from_file(cls, filename, sids): """ Produces an instance of the Song class with all album, group, and artist IDs loaded from only a filename. All metadata is saved to the database and updated where necessary. """ kept_artists = [] kept_groups = [] matched_entry = db.c.fetch_row( "SELECT song_id FROM r4_songs WHERE song_filename = %s", (filename, )) if matched_entry: log.debug( "playlist", "this filename matches an existing database entry, song_id {}". format(matched_entry["song_id"]), ) s = cls.load_from_id(matched_entry["song_id"]) for metadata in s.artists: try: if not metadata.is_tag: kept_artists.append(metadata) metadata.disassociate_song_id(s.id) except MetadataUpdateError: pass for metadata in s.groups: try: if not metadata.is_tag: kept_groups.append(metadata) metadata.disassociate_song_id(s.id) except MetadataUpdateError: pass elif len(sids) == 0: raise SongHasNoSIDsException else: s = cls() s.load_tag_from_file(filename) s.save(sids) new_artists = Artist.load_list_from_tag(s.artist_tag) new_groups = SongGroup.load_list_from_tag(s.genre_tag) s.artists = zip_metadata(new_artists, kept_artists) s.groups = zip_metadata(new_groups, kept_groups) i = 0 for metadata in s.artists: metadata.associate_song_id(s.id, order=i) i += 1 for metadata in s.groups: metadata.associate_song_id(s.id) s.albums = [Album.load_from_name(s.album_tag)] s.albums[0].associate_song_id(s.id) s.update_artist_parseable() # do not get replay gain earlier in case an exception is thrown above # it means a lot of wasted CPU time in that scenario if db.c.fetch_var( "SELECT song_replay_gain FROM r4_songs WHERE song_id = %s", (s.id, )) is None: s.replay_gain = s.get_replay_gain() db.c.update( "UPDATE r4_songs SET song_replay_gain = %s WHERE song_id = %s", (s.replay_gain, s.id)) return s
from libs import config from libs import db from libs import cache from rainwave.playlist_objects.album import clear_updated_albums from rainwave.playlist_objects.songgroup import SongGroup if __name__ == "__main__": parser = argparse.ArgumentParser(description="Rainwave DB migration script for speeding up text searches by adding an index.") parser.add_argument("--config", default=None) args = parser.parse_args() config.load(args.config) for sid in config.station_ids: clear_updated_albums(sid) db.connect() cache.connect() print "Adding r4_group_sid table." db._create_group_sid_table() print "Populating r4_group_sid." for group_id in db.c.fetch_list("SELECT group_id FROM r4_groups"): g = SongGroup.load_from_id(group_id) g.reconcile_sids() print "Done"