112 lines
2.9 KiB
Python
112 lines
2.9 KiB
Python
# 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()
|