diff --git a/server/app/api/__init__.py b/server/app/api/__init__.py index b8cfb9ee..38416d8a 100644 --- a/server/app/api/__init__.py +++ b/server/app/api/__init__.py @@ -16,7 +16,7 @@ def initialize() -> None: """ functions.start_watchdog() prep.create_config_dir() - functions.reindex_tracks() + functions.run_checks() initialize() diff --git a/server/app/functions.py b/server/app/functions.py index e8520266..dc29a355 100644 --- a/server/app/functions.py +++ b/server/app/functions.py @@ -3,33 +3,33 @@ This module contains functions for the server """ import os import time +from concurrent.futures import ThreadPoolExecutor from io import BytesIO import requests -from app import helpers -from app import settings -from app.lib import watchdoge -from app.lib.populate import Populate, CreateAlbums from PIL import Image -from concurrent.futures import ThreadPoolExecutor -from app.lib import trackslib +from app import helpers, settings +from app.lib import watchdoge +from app.lib.albumslib import ValidateThumbs @helpers.background -def reindex_tracks(): +def run_checks(): """ Checks for new songs every 5 minutes. """ # while True: - trackslib.validate_tracks() + # trackslib.validate_tracks() - Populate() - CreateAlbums() + # Populate() + # CreateAlbums() - if helpers.Ping()(): - CheckArtistImages()() + # if helpers.Ping()(): + # CheckArtistImages()() + + ValidateThumbs() @helpers.background diff --git a/server/app/helpers.py b/server/app/helpers.py index a3c5a520..12fe7d73 100644 --- a/server/app/helpers.py +++ b/server/app/helpers.py @@ -104,7 +104,7 @@ def create_safe_name(name: str) -> str: """ Creates a url-safe name from a name. """ - return "".join([i for i in name if i not in '/\\:*?"<>|']) + return "".join([i for i in name if i not in '/\\:*?"<>|#']) class UseBisection: diff --git a/server/app/lib/albumslib.py b/server/app/lib/albumslib.py index 5c389833..e8f2f28d 100644 --- a/server/app/lib/albumslib.py +++ b/server/app/lib/albumslib.py @@ -1,37 +1,95 @@ """ This library contains all the functions related to albums. """ -from pprint import pprint +from dataclasses import dataclass +import os import random from typing import List -from app import helpers, instances, models +from app import helpers, models from app.lib import taglib from tqdm import tqdm +from app.settings import THUMBS_PATH +from app import instances -def get_all_albums() -> List[models.Album]: + +# def get_all_albums() -> List[models.Album]: +# """ +# Returns a list of album objects for all albums in the database. +# """ +# print("Getting all albums...") + +# albums: List[models.Album] = [] + +# db_albums = instances.album_instance.get_all_albums() + +# for album in tqdm(db_albums, desc="Creating albums"): +# aa = models.Album(album) +# albums.append(aa) + +# return albums + + +@dataclass +class Thumbnail: + filename: str + + +class RipAlbumImage: """ - Returns a list of album objects for all albums in the database. + Rips a thumbnail for the given album hash. """ - print("Getting all albums...") - albums: List[models.Album] = [] + def __init__(self, hash: str) -> None: + tracks = instances.tracks_instance.find_tracks_by_hash(hash) + tracks = [models.Track(track) for track in tracks] - db_albums = instances.album_instance.get_all_albums() + for track in tracks: + ripped = taglib.extract_thumb(track.filepath, hash + ".webp") - for album in tqdm(db_albums, desc="Creating albums"): - aa = models.Album(album) - albums.append(aa) - - return albums + if ripped: + break -def validate() -> None: - """ - Creates album objects for all albums and returns - a list of track objects - """ +class ValidateThumbs: + @staticmethod + def remove_obsolete(): + """ + Removes unreferenced thumbnails from the thumbnails folder. + """ + entries = os.scandir(THUMBS_PATH) + entries = [entry for entry in entries if entry.is_file()] + + albums = helpers.Get.get_all_albums() + thumbs = [Thumbnail(album.hash + ".webp") for album in albums] + + for entry in tqdm(entries, desc="Validating thumbnails"): + e = helpers.UseBisection(thumbs, "filename", [entry.name])() + if e is not None: + os.remove(entry.path) + + @staticmethod + def find_lost_thumbnails(): + """ + Re-rip lost album thumbnails + """ + entries = os.scandir(THUMBS_PATH) + entries = [Thumbnail(entry) for entry in entries if entry.is_file()] + + albums = helpers.Get.get_all_albums() + thumbs = [(album.hash + ".webp") for album in albums] + + for t in thumbs: + e = helpers.UseBisection(entries, "filename", [t]) + + if e is None: + hash = t.split(".")[0] + RipAlbumImage(hash) + + def __init__(self) -> None: + self.remove_obsolete() + self.find_lost_thumbnails() def get_album_duration(album: List[models.Track]) -> int: diff --git a/server/app/settings.py b/server/app/settings.py index de2e0450..f6eb0ff7 100644 --- a/server/app/settings.py +++ b/server/app/settings.py @@ -2,7 +2,6 @@ Contains default configs """ import os -from dataclasses import dataclass import multiprocessing @@ -15,7 +14,8 @@ IMG_PATH = os.path.join(APP_DIR, "images") THUMBS_PATH = os.path.join(IMG_PATH, "thumbnails") TEST_DIR = "/home/cwilvx/Music/Link to Music/Chill/Wolftyla Radio" # HOME_DIR = TEST_DIR -# URL + +# URLS IMG_BASE_URI = "http://127.0.0.1:8900/images/" IMG_ARTIST_URI = IMG_BASE_URI + "artists/" IMG_THUMB_URI = IMG_BASE_URI + "thumbnails/"