def on_moved(self, event): library_path = self.indexer.library_path src = file.track_path(event.src_path, library_path) dst = file.track_path(event.dest_path, library_path) track = self.indexer.db_session.query( db.Track).filter(db.Track.file_path == src) track.file_path = dst
def reindex_sync(self): """ Reindex new or changed tracks. """ files = file.collect_files([self.library_path], recursive=True) # Query {file_path: mtime} mappings query = self.db_session.query(db.Track.file_path, db.Track.mtime) mtimes = {t.file_path: t.mtime for t in query.all()} for path in files: path = os.path.realpath(path) last_mtime = int(os.path.getmtime(path)) short_path = file.track_path(path, self.library_path) # Track is unchanged if short_path in mtimes and mtimes[short_path] == last_mtime: continue try: self.add_or_update(path) self.db_session.commit() except Exception as e: log.warn(f"Failed to update {short_path}: {e}")
def mediafile_to_track(media, library_path): """ Converts a MediaFile object into a Track object """ path = media.file_path with open(path, "rb") as track_file: file_hash = hashlib.md5(track_file.read()).hexdigest() # Compute artwork hash artwork = media.mg_file.tags.getall("APIC") art_hash = None if len(artwork) > 0: art_hash = hashlib.md5(artwork[0].data).hexdigest() track = db.Track() # Columns are gathered as a direct mapping from attributes in the MediaFile # object to the columns in the track model. for k in (k for k in dir(media) if hasattr(track, k)): setattr(track, k, str(getattr(media, k))) track.mtime = int(os.path.getmtime(path)) track.file_path = file.track_path(path, library_path) track.file_hash = file_hash track.artwork_hash = art_hash return track
def on_deleted(self, event): library_path = self.indexer.library_path self.indexer.db_session.query( db.Track).filter(db.Track.file_path == file.track_path( event.src_path, library_path)).delete() self.indexer.db_session.commit()