# Copyright 2020 (c) Anna Schumaker. from . import allocator from . import stack from . import tags from . import track import db import lib import pathlib import scanner import threading File = "tagdb.pickle" Bus = lib.bus.Bus(500) Tracks = allocator.TrackAllocator() Stack = stack.TagStack() class LibraryTag(lib.tag.Tag): def __init__(self, path): super().__init__(path) self.clear = lib.thread.Thread(self.__do_clear__) self.scan = lib.thread.Thread(self.__do_scan__) def __setstate__(self, state): super().__setstate__(state) self.clear = lib.thread.Thread(self.__do_clear__) self.scan = lib.thread.Thread(self.__do_scan__) def __do_scan__(self): for trak in Tracks.autoremove(self): self.remove_track(trak) track_set = set([ t.filepath() for t in Tracks.list_tracks(self) ]) for f in self.name.rglob("*"): if f not in track_set and f.is_file(): if (track := Tracks.allocate(self, f)) != None: self.add_track(track) def __do_clear__(self): for trak in self.tracks: Tracks.remove(trak) self.tracks.clear() def fix_tracks(self): for (index, trak) in enumerate(self.tracks): t = Tracks[trak] if t is not None: self.tracks[index] = t class LibraryStore(lib.tagstore.TagStore): def __alloc_tag__(self, name, sort): return LibraryTag(name) def add(self, name): return super().__add_tag__(name, None, None) def remove(self, lib): lib.clear() super().remove(lib) def fix_tracks(self): for (id, tag) in self.store.items(): tag.fix_tracks() Library = LibraryStore() def _do_save(): try: with lib.data.DataFile(File, lib.data.WRITE) as f: f.pickle([ tags.get_state(), Tracks, Library, Stack ]) except Exception as e: return lib.bus.RETRY def save(*args): Bus.board(_do_save) def load(): global Library global Tracks global Stack if not db.new_db(): return with lib.data.DataFile(File, lib.data.READ) as f: if f.exists(): (tagstate, Tracks, Library, Stack) = f.unpickle() tags.set_state(*tagstate) Tracks.load_tags() Library.fix_tracks() __register_callbacks() scanner.Queue.push(scanner.task.CommitTask()) def __register_callbacks(): for store in [ Library, tags.User, Tracks ]: store.Added.register(save) store.Removed.register(save) Tracks.Updated.register(save) Stack.PushPop.register(save) Stack.NextTrack.register(save) __register_callbacks() def reset(): Tracks.reset() Library.reset() Stack.reset() tags.reset() Bus.clear() lib.data.DataFile(File, lib.data.READ).remove() __register_callbacks()