def postprocess_covers(self): log.debug(u"Postprocessing covers ...") found = 0 s = session_get() for album in s.query(Album).filter_by(deleted=False): # Stop if quit is requested if not self._run: s.rollback() return # If album already has a cover, keep going if album.cover != 1: continue # Jump over PK 1, this is the unknown album if album.id == 1: continue # Try to find cover art for this album for track in s.query(Track).filter_by(album=album.id): mdir = s.query(Directory).get(track.dir) cover_art = self._cover_art.get(mdir.directory, None) if cover_art: cover = get_or_create(s, Cover, file=cover_art[0], deleted=False) found += 1 # Make thumbnails try: img = Image.open(cover_art[0]) size = 200, 200 out_file = os.path.join(settings.COVER_CACHE_DIRECTORY, '{}_small.jpg'.format(cover.id)) img.thumbnail(size, Image.ANTIALIAS) img.save(out_file, "JPEG") except IOError: log.error(u"Unable to create a small thumbnail for cover ID %d", cover.id) try: img = Image.open(cover_art[0]) size = 800, 800 out_file = os.path.join(settings.COVER_CACHE_DIRECTORY, '{}_medium.jpg'.format(cover.id)) img.thumbnail(size, Image.ANTIALIAS) img.save(out_file, "JPEG") except IOError: log.error(u"Unable to create a medium thumbnail for cover ID %d", cover.id) # Set new cover id for album, and update tracks and the album timestamp for sync s.query(Track).filter_by(album=album.id).update({'updated': utc_now()}) s.query(Album).filter_by(id=album.id).update({'updated': utc_now(), 'cover': cover.id}) # Cover lookup done for this album, continue with next break # That's that, commit changes for this album s.commit() s.close() self._cover_art = {} # Clear cover art cache log.debug(u"Found and attached %d new covers.", found)
def sync_table(self, name, table, remote_ts, push=False): # Send message containing all new data in the table s = session_get() self.send_message('sync', { 'query': 'request', 'table': name, 'ts': to_isodate(utc_now()), 'push': push, 'data': [t.serialize() for t in s.query(table).filter(table.updated > remote_ts)] }) s.close()
def sync_table(self, name, table, remote_ts, push=False): # Send message containing all new data in the table s = session_get() self.send_message( 'sync', { 'query': 'request', 'table': name, 'ts': to_isodate(utc_now()), 'push': push, 'data': [ t.serialize() for t in s.query(table).filter(table.updated > remote_ts) ] }) s.close()
class Session(Base): __tablename__ = "session" key = Column(String(32), primary_key=True) user = Column(ForeignKey('user.id')) start = Column(DateTime(timezone=True), default=utc_now())
class SyncMixin(object): deleted = Column(Boolean, default=False) updated = Column(DateTime(timezone=True), default=utc_now(), onupdate=utc_now())
def on_playlist_msg(self, packet_msg): if not self.authenticated: return query = packet_msg.get('query', '') # Creates a new playlist with a given name. Errors out if the name already exists. if query == 'add_playlist': name = packet_msg.get('name') s = session_get() if s.query(Playlist).filter_by(name=name, deleted=False).count() > 0: self.send_error('playlist', "Playlist with given name already exists", 500) log.warning(u"Playlist with given name already exists.") else: playlist = Playlist(name=name, updated=utc_now()) s.add(playlist) s.commit() self.sync_table('playlist', Playlist, utc_minus_delta(5), push=True) log.debug(u"A new playlist created!") s.close() return # Delete playlist and all related items if query == 'del_playlist': playlist_id = packet_msg.get('id') if id > 1: s = session_get() s.query(PlaylistItem).filter_by(playlist=playlist_id, deleted=False).update({ 'deleted': True, 'updated': utc_now() }) s.query(Playlist).filter_by(id=playlist_id).update({ 'deleted': True, 'updated': utc_now() }) s.commit() s.close() self.sync_table('playlist', Playlist, utc_minus_delta(5), push=True) self.sync_table('playlistitem', PlaylistItem, utc_minus_delta(5), push=True) self.notify_playlist_changes(playlist_id) log.debug(u"Playlist and items deleted!") return # Copy scratchpad playlist (id 1) to a new playlist if query == 'copy_scratchpad': to_id = packet_msg.get('id') s = session_get() s.query(PlaylistItem).filter_by(playlist=to_id, deleted=False).update({ 'deleted': True, 'updated': utc_now() }) s.commit() for item in s.query(PlaylistItem).filter_by(playlist=1, deleted=False): plitem = PlaylistItem(track=item.track, playlist=to_id, number=item.number, updated=utc_now()) s.add(plitem) s.commit() s.close() self.sync_table('playlistitem', PlaylistItem, utc_minus_delta(5), push=True) self.notify_playlist_changes(to_id) log.debug(u"Playlist copied!") return # Saves tracks to the given playlist. Clears existing tracks. if query == 'save_playlist': playlist_id = packet_msg.get('id') items = packet_msg.get('tracks') s = session_get() s.query(PlaylistItem).filter_by(playlist=playlist_id, deleted=False).update({ 'deleted': True, 'updated': utc_now() }) k = 0 for item in items: plitem = PlaylistItem(track=item['id'], playlist=playlist_id, number=k, updated=utc_now()) s.add(plitem) k += 1 s.commit() s.close() self.sync_table('playlistitem', PlaylistItem, utc_minus_delta(5), push=True) self.notify_playlist_changes(playlist_id) log.debug(u"Playlist updated!") return
def handle_cover_delete(self, cover): s = session_get() for album in s.query(Album).filter_by(cover=cover.id, deleted=False): album.cover = 1 s.query(Cover).filter_by(id=cover.id, deleted=False).update({'deleted': True, 'updated': utc_now()}) s.commit() s.close()
def handle_track_delete(self, track): s = session_get() if track.album != 1: # If album only has a single (this) track, remove album if s.query(Track).filter_by(album=track.album, deleted=False).count() == 0: s.query(Album).filter_by(id=track.album, deleted=False).update({'deleted': True, 'updated': utc_now()}) if track.artist != 1: # If artist only has a single (this) track, remove artist if s.query(Track).filter_by(artist=track.artist, deleted=False).count() == 0: s.query(Artist).filter_by(id=track.artist, deleted=False).update({'deleted': True, 'updated': utc_now()}) # That's that, delete the track. s.query(Track).filter_by(id=track.id, deleted=False).update({'deleted': True, 'updated': utc_now()}) # Save changes s.commit() s.close()