mirror of
https://github.com/Dvorinka/swingmusic-extended.git
synced 2026-06-04 04:23:01 +00:00
handle watching ~/ dir
+ fix bug that caused duplicate album colors in db
This commit is contained in:
+27
-3
@@ -3,10 +3,14 @@ Contains all the folder routes.
|
||||
"""
|
||||
import os
|
||||
|
||||
from pathlib import Path
|
||||
from flask import Blueprint, request
|
||||
|
||||
from app import settings
|
||||
from app.lib.folderslib import GetFilesAndDirs
|
||||
from app.db.sqlite.settings import SettingsSQLMethods as db
|
||||
from app.models import Folder
|
||||
from app.utils import create_folder_hash
|
||||
|
||||
api = Blueprint("folder", __name__, url_prefix="/")
|
||||
|
||||
@@ -19,12 +23,32 @@ def get_folder_tree():
|
||||
data = request.get_json()
|
||||
|
||||
if data is not None:
|
||||
req_dir: str = data["folder"]
|
||||
else:
|
||||
try:
|
||||
req_dir: str = data["folder"]
|
||||
except KeyError:
|
||||
req_dir = "$home"
|
||||
|
||||
root_dirs = db.get_root_dirs()
|
||||
|
||||
if req_dir == "$home" and root_dirs[0] == "$home":
|
||||
req_dir = settings.USER_HOME_DIR
|
||||
|
||||
if req_dir == "$home":
|
||||
req_dir = settings.USER_HOME_DIR
|
||||
folders = [Path(f) for f in root_dirs]
|
||||
|
||||
return {
|
||||
"folders": [
|
||||
Folder(
|
||||
name=f.name,
|
||||
path=str(f),
|
||||
has_tracks=True,
|
||||
is_sym=f.is_symlink(),
|
||||
path_hash=create_folder_hash(*f.parts[1:]),
|
||||
)
|
||||
for f in folders
|
||||
],
|
||||
"tracks": [],
|
||||
}
|
||||
|
||||
tracks, folders = GetFilesAndDirs(req_dir)()
|
||||
|
||||
|
||||
+52
-5
@@ -1,6 +1,12 @@
|
||||
from flask import Blueprint, request
|
||||
from app import settings
|
||||
|
||||
from app.db.sqlite.settings import SettingsSQLMethods as sdb
|
||||
from app.lib import populate
|
||||
from app.logger import log
|
||||
|
||||
from app.db.store import Store
|
||||
from app.utils import background
|
||||
|
||||
api = Blueprint("settings", __name__, url_prefix="/")
|
||||
|
||||
@@ -8,7 +14,22 @@ api = Blueprint("settings", __name__, url_prefix="/")
|
||||
def get_child_dirs(parent: str, children: list[str]):
|
||||
"""Returns child directories in a list, given a parent directory"""
|
||||
|
||||
return [dir for dir in children if dir.startswith(parent)]
|
||||
return [dir for dir in children if dir.startswith(parent) and dir != parent]
|
||||
|
||||
|
||||
@background
|
||||
def rebuild_store(db_dirs: list[str]):
|
||||
log.info("Rebuilding library...")
|
||||
Store.remove_tracks_by_dir_except(db_dirs)
|
||||
|
||||
Store.load_all_tracks()
|
||||
Store.process_folders()
|
||||
Store.load_albums()
|
||||
Store.load_artists()
|
||||
|
||||
populate.Populate()
|
||||
|
||||
log.info("Rebuilding library... ✅")
|
||||
|
||||
|
||||
@api.route("/settings/add-root-dirs", methods=["POST"])
|
||||
@@ -29,16 +50,42 @@ def add_root_dirs():
|
||||
except KeyError:
|
||||
return msg, 400
|
||||
|
||||
# --- Unregister child directories ---
|
||||
def finalize(new_dirs: list[str], removed_dirs: list[str], db_dirs: list[str]):
|
||||
sdb.remove_root_dirs(removed_dirs)
|
||||
sdb.add_root_dirs(new_dirs)
|
||||
rebuild_store(db_dirs)
|
||||
|
||||
# ---
|
||||
db_dirs = sdb.get_root_dirs()
|
||||
|
||||
if db_dirs[0] == "$home" and new_dirs[0] == "$home".strip():
|
||||
return {"msg": "Not changed!"}
|
||||
|
||||
if db_dirs[0] == "$home":
|
||||
sdb.remove_root_dirs(db_dirs)
|
||||
|
||||
try:
|
||||
if new_dirs[0] == "$home":
|
||||
finalize(["$home"], db_dirs, [settings.USER_HOME_DIR])
|
||||
|
||||
return {"msg": "Updated!"}
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
for _dir in new_dirs:
|
||||
children = get_child_dirs(_dir, db_dirs)
|
||||
removed_dirs.extend(children)
|
||||
# ------------------------------------
|
||||
# ---
|
||||
|
||||
sdb.add_root_dirs(new_dirs)
|
||||
sdb.remove_root_dirs(removed_dirs)
|
||||
for _dir in removed_dirs:
|
||||
try:
|
||||
db_dirs.remove(_dir)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
db_dirs.extend(new_dirs)
|
||||
|
||||
finalize(new_dirs, removed_dirs, db_dirs)
|
||||
|
||||
return {"msg": "Updated!"}
|
||||
|
||||
|
||||
+5
-11
@@ -130,15 +130,9 @@ class SQLiteTrackMethods:
|
||||
cur.execute("DELETE FROM tracks WHERE filepath=?", (filepath,))
|
||||
|
||||
@staticmethod
|
||||
def track_exists(filepath: str):
|
||||
"""
|
||||
Checks if a track exists in the database using its filepath.
|
||||
"""
|
||||
def remove_tracks_by_folders(folders: list[str]):
|
||||
sql = "DELETE FROM tracks WHERE folder = ?"
|
||||
|
||||
with SQLiteManager() as cur:
|
||||
cur.execute("SELECT * FROM tracks WHERE filepath=?", (filepath,))
|
||||
row = cur.fetchone()
|
||||
|
||||
if row is not None:
|
||||
return True
|
||||
|
||||
return False
|
||||
for folder in folders:
|
||||
cur.execute(sql, (folder,))
|
||||
|
||||
+19
-3
@@ -88,6 +88,17 @@ class Store:
|
||||
cls.tracks.remove(track)
|
||||
break
|
||||
|
||||
@classmethod
|
||||
def remove_tracks_by_dir_except(cls, dirs: list[str]):
|
||||
"""Removes all tracks not in the root directories."""
|
||||
to_remove = set()
|
||||
|
||||
for track in cls.tracks:
|
||||
if not track.folder.startswith(tuple(dirs)):
|
||||
to_remove.add(track.folder)
|
||||
|
||||
tdb.remove_tracks_by_folders(to_remove)
|
||||
|
||||
@classmethod
|
||||
def count_tracks_by_hash(cls, trackhash: str) -> int:
|
||||
"""
|
||||
@@ -197,6 +208,8 @@ class Store:
|
||||
"""
|
||||
Creates a list of folders from the tracks in the store.
|
||||
"""
|
||||
cls.folders.clear()
|
||||
|
||||
all_folders = [track.folder for track in cls.tracks]
|
||||
all_folders = set(all_folders)
|
||||
|
||||
@@ -212,6 +225,7 @@ class Store:
|
||||
|
||||
cls.folders.append(folder)
|
||||
|
||||
|
||||
@classmethod
|
||||
def get_folder(cls, path: str): # type: ignore
|
||||
"""
|
||||
@@ -277,6 +291,8 @@ class Store:
|
||||
Loads all albums from the database into the store.
|
||||
"""
|
||||
|
||||
cls.albums = []
|
||||
|
||||
albumhashes = set(t.albumhash for t in cls.tracks)
|
||||
|
||||
for albumhash in tqdm(albumhashes, desc="Loading albums"):
|
||||
@@ -291,9 +307,9 @@ class Store:
|
||||
albumhash = album[1]
|
||||
colors = json.loads(album[2])
|
||||
|
||||
for al in cls.albums:
|
||||
if al.albumhash == albumhash:
|
||||
al.set_colors(colors)
|
||||
for _al in cls.albums:
|
||||
if _al.albumhash == albumhash:
|
||||
_al.set_colors(colors)
|
||||
break
|
||||
|
||||
@classmethod
|
||||
|
||||
+7
-3
@@ -38,9 +38,13 @@ class ProcessAlbumColors:
|
||||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
db_colors = db.get_all_albums()
|
||||
db_albumhashes = "-".join([album[1] for album in db_colors])
|
||||
|
||||
albums = [a for a in Store.albums if a.albumhash not in db_albumhashes]
|
||||
|
||||
with SQLiteManager() as cur:
|
||||
for album in tqdm(Store.albums, desc="Processing album colors"):
|
||||
for album in tqdm(albums, desc="Processing unprocessed album colors"):
|
||||
if len(album.colors) == 0:
|
||||
colors = self.process_color(album)
|
||||
|
||||
@@ -71,9 +75,9 @@ class ProcessArtistColors:
|
||||
def __init__(self) -> None:
|
||||
db_colors: list[tuple] = list(adb.get_all_artists())
|
||||
db_artisthashes = "-".join([artist[1] for artist in db_colors])
|
||||
all_artists = Store.artists
|
||||
all_artists = [a for a in Store.artists if a.artisthash not in db_artisthashes]
|
||||
|
||||
for artist in tqdm(all_artists, desc="Processing artist colors"):
|
||||
for artist in tqdm(all_artists, desc="Processing unprocessed artist colors"):
|
||||
if artist.artisthash not in db_artisthashes:
|
||||
self.process_color(artist)
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import os
|
||||
import pathlib
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
|
||||
from app.db.store import Store
|
||||
|
||||
+11
-5
@@ -25,7 +25,7 @@ class Populate:
|
||||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
messages = {
|
||||
text = {
|
||||
"root_unset": "The root directory is not set. Trying to scan the default directory: %s",
|
||||
"default_not_exists": "The directory: %s does not exist. Please open the app in your web browser to set the root directory.",
|
||||
"no_tracks": "No tracks found in: %s. Please open the app in your web browser to set the root directory.",
|
||||
@@ -40,17 +40,23 @@ class Populate:
|
||||
def_dir = "~/Music"
|
||||
|
||||
if len(dirs_to_scan) == 0:
|
||||
log.warning(messages["root_unset"], def_dir)
|
||||
log.warning(text["root_unset"], def_dir)
|
||||
print("...")
|
||||
|
||||
exists = os.path.exists(settings.MUSIC_DIR)
|
||||
|
||||
if not exists:
|
||||
log.warning(messages["default_not_exists"], def_dir)
|
||||
log.warning(text["default_not_exists"], def_dir)
|
||||
return
|
||||
|
||||
dirs_to_scan = [settings.MUSIC_DIR]
|
||||
|
||||
try:
|
||||
if dirs_to_scan[0] == "$home":
|
||||
dirs_to_scan = [settings.USER_HOME_DIR]
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
files = []
|
||||
|
||||
for _dir in dirs_to_scan:
|
||||
@@ -59,7 +65,7 @@ class Populate:
|
||||
untagged = self.filter_untagged(tracks, files)
|
||||
|
||||
if initial_dirs_count == 0 and len(untagged) == 0:
|
||||
log.warning(messages["no_tracks"], def_dir)
|
||||
log.warning(text["no_tracks"], def_dir)
|
||||
return
|
||||
|
||||
if initial_dirs_count == 0 and len(untagged) > 0:
|
||||
@@ -76,7 +82,7 @@ class Populate:
|
||||
settings.TCOLOR.ENDC,
|
||||
)
|
||||
sdb.add_root_dirs(dirs_to_scan)
|
||||
return
|
||||
# return
|
||||
|
||||
if len(untagged) == 0:
|
||||
log.info("All clear, no unread files.")
|
||||
|
||||
Reference in New Issue
Block a user