From 357afeb700153aa712351099d13d39d90ea2bd3b Mon Sep 17 00:00:00 2001 From: geoffrey45 Date: Sun, 26 Mar 2023 08:25:00 +0300 Subject: [PATCH] break settings.py into classes --- app/api/folder.py | 2 +- app/api/imgserver.py | 4 +- app/api/settings.py | 2 +- app/arg_handler.py | 2 +- app/config.py | 4 +- app/db/sqlite/__init__.py | 4 +- app/db/sqlite/utils.py | 6 +- app/lib/artistlib.py | 10 +- app/lib/colorlib.py | 4 +- app/lib/playlistlib.py | 6 +- app/lib/populate.py | 2 +- app/lib/taglib.py | 10 +- app/lib/watchdogg.py | 2 +- .../__preinit/move_to_xdg_folder.py | 6 +- app/models/playlist.py | 2 +- app/models/track.py | 6 +- app/requests/artists.py | 2 +- app/settings.py | 101 ++++++++++-------- app/setup/files.py | 4 +- app/setup/sqlite.py | 6 +- app/start_info_logger.py | 11 +- app/utils/generators.py | 2 - 22 files changed, 102 insertions(+), 96 deletions(-) diff --git a/app/api/folder.py b/app/api/folder.py index f251124..4e55059 100644 --- a/app/api/folder.py +++ b/app/api/folder.py @@ -33,7 +33,7 @@ def get_folder_tree(): try: if req_dir == "$home" and root_dirs[0] == "$home": - req_dir = settings.USER_HOME_DIR + req_dir = settings.Paths.USER_HOME_DIR except IndexError: pass diff --git a/app/api/imgserver.py b/app/api/imgserver.py index 621f31b..ad66986 100644 --- a/app/api/imgserver.py +++ b/app/api/imgserver.py @@ -2,12 +2,12 @@ from pathlib import Path from flask import Blueprint, send_from_directory -from app.settings import APP_DIR +from app.settings import Paths api = Blueprint("imgserver", __name__, url_prefix="/img") SUPPORTED_IMAGES = (".jpg", ".png", ".webp", ".jpeg") -APP_DIR = Path(APP_DIR) +APP_DIR = Path(Paths.APP_DIR) IMG_PATH = APP_DIR / "images" ASSETS_PATH = APP_DIR / "assets" diff --git a/app/api/settings.py b/app/api/settings.py index 5fb51a8..c4fe23f 100644 --- a/app/api/settings.py +++ b/app/api/settings.py @@ -98,7 +98,7 @@ def add_root_dirs(): sdb.remove_root_dirs(db_dirs) if incoming_home: - finalize([_h], [], [settings.USER_HOME_DIR]) + finalize([_h], [], [settings.Paths.USER_HOME_DIR]) return {"root_dirs": [_h]} # --- diff --git a/app/arg_handler.py b/app/arg_handler.py index 5af4155..cd82f3e 100644 --- a/app/arg_handler.py +++ b/app/arg_handler.py @@ -109,5 +109,5 @@ class HandleArgs: @staticmethod def handle_version(): if any((a in ARGS for a in ALLARGS.version)): - print(settings.APP_VERSION) + print(settings.Release.APP_VERSION) sys.exit(0) diff --git a/app/config.py b/app/config.py index cb1ace6..8ea6e8c 100644 --- a/app/config.py +++ b/app/config.py @@ -6,7 +6,7 @@ import json from enum import Enum from typing import Type -from app.settings import JSON_CONFIG_PATH +from app.settings import Db class ConfigKeys(Enum): @@ -57,5 +57,5 @@ class ConfigManager: self.write_config(config_data) -settings = ConfigManager(JSON_CONFIG_PATH) +settings = ConfigManager(Db.JSON_CONFIG_PATH) a = settings.get_value(ConfigKeys.ROOT_DIRS) diff --git a/app/db/sqlite/__init__.py b/app/db/sqlite/__init__.py index 96f374a..f7c5d97 100644 --- a/app/db/sqlite/__init__.py +++ b/app/db/sqlite/__init__.py @@ -6,7 +6,7 @@ import sqlite3 from pathlib import Path from sqlite3 import Connection as SqlConn -from app.settings import APP_DB_PATH +from app.settings import Db def create_connection(db_file: str) -> SqlConn: @@ -22,7 +22,7 @@ def get_sqlite_conn(): It opens a connection to the database :return: A connection to the database. """ - return create_connection(APP_DB_PATH) + return create_connection(Db.APP_DB_PATH) def create_tables(conn: SqlConn, sql_query: str): diff --git a/app/db/sqlite/utils.py b/app/db/sqlite/utils.py index 900f27a..6c2c87c 100644 --- a/app/db/sqlite/utils.py +++ b/app/db/sqlite/utils.py @@ -7,7 +7,7 @@ from sqlite3 import Connection, Cursor import time from app.models import Album, Playlist, Track -from app.settings import APP_DB_PATH, USERDATA_DB_PATH +from app.settings import Db def tuple_to_track(track: tuple): @@ -78,10 +78,10 @@ class SQLiteManager: if self.conn is not None: return self.conn.cursor() - db_path = APP_DB_PATH + db_path = Db.APP_DB_PATH if self.userdata_db: - db_path = USERDATA_DB_PATH + db_path = Db.USERDATA_DB_PATH self.conn = sqlite3.connect( db_path, diff --git a/app/lib/artistlib.py b/app/lib/artistlib.py index 2011585..af4a5fc 100644 --- a/app/lib/artistlib.py +++ b/app/lib/artistlib.py @@ -42,8 +42,8 @@ def get_artist_image_link(artist: str): # TODO: Move network calls to utils/network.py class DownloadImage: def __init__(self, url: str, name: str) -> None: - sm_path = Path(settings.ARTIST_IMG_SM_PATH) / name - lg_path = Path(settings.ARTIST_IMG_LG_PATH) / name + sm_path = Path(settings.Paths.ARTIST_IMG_SM_PATH) / name + lg_path = Path(settings.Paths.ARTIST_IMG_LG_PATH) / name img = self.download(url) @@ -64,7 +64,7 @@ class DownloadImage: """ img.save(lg_path, format="webp") - sm_size = settings.SM_ARTIST_IMG_SIZE + sm_size = settings.Defaults.SM_ARTIST_IMG_SIZE img.resize((sm_size, sm_size), Image.ANTIALIAS).save(sm_path, format="webp") @@ -86,7 +86,7 @@ class CheckArtistImages: :param artist: The artist name """ - img_path = Path(settings.ARTIST_IMG_SM_PATH) / f"{artist.artisthash}.webp" + img_path = Path(settings.Paths.ARTIST_IMG_SM_PATH) / f"{artist.artisthash}.webp" if img_path.exists(): return @@ -99,7 +99,7 @@ class CheckArtistImages: # def fetch_album_bio(title: str, albumartist: str) -> str | None: """ Returns the album bio for a given album. """ # last_fm_url = "http://ws.audioscrobbler.com/2.0/?method=album.getinfo&api_key={}&artist={}&album={ -# }&format=json".format( settings.LAST_FM_API_KEY, albumartist, title ) +# }&format=json".format( settings.Paths.LAST_FM_API_KEY, albumartist, title ) # try: # response = requests.get(last_fm_url) diff --git a/app/lib/colorlib.py b/app/lib/colorlib.py index cd1ede4..203bdde 100644 --- a/app/lib/colorlib.py +++ b/app/lib/colorlib.py @@ -56,7 +56,7 @@ class ProcessAlbumColors: @staticmethod def process_color(album: Album): - path = Path(settings.SM_THUMB_PATH) / album.image + path = Path(settings.Paths.SM_THUMB_PATH) / album.image if not path.exists(): return @@ -78,7 +78,7 @@ class ProcessArtistColors: @staticmethod def process_color(artist: Artist): - path = Path(settings.ARTIST_IMG_SM_PATH) / artist.image + path = Path(settings.Paths.ARTIST_IMG_SM_PATH) / artist.image if not path.exists(): return diff --git a/app/lib/playlistlib.py b/app/lib/playlistlib.py index 104743b..b5c50ed 100644 --- a/app/lib/playlistlib.py +++ b/app/lib/playlistlib.py @@ -16,7 +16,7 @@ def create_thumbnail(image: Any, img_path: str) -> str: Creates a 250 x 250 thumbnail from a playlist image """ thumb_path = "thumb_" + img_path - full_thumb_path = os.path.join(settings.APP_DIR, "images", "playlists", thumb_path) + full_thumb_path = os.path.join(settings.Paths.APP_DIR, "images", "playlists", thumb_path) aspect_ratio = image.width / image.height @@ -33,7 +33,7 @@ def create_gif_thumbnail(image: Any, img_path: str): Creates a 250 x 250 thumbnail from a playlist image """ thumb_path = "thumb_" + img_path - full_thumb_path = os.path.join(settings.APP_DIR, "images", "playlists", thumb_path) + full_thumb_path = os.path.join(settings.Paths.APP_DIR, "images", "playlists", thumb_path) frames = [] @@ -60,7 +60,7 @@ def save_p_image(file, pid: str): filename = pid + str(random_str) + ".webp" - full_img_path = os.path.join(settings.PLAYLIST_IMG_PATH, filename) + full_img_path = os.path.join(settings.Paths.PLAYLIST_IMG_PATH, filename) if file.content_type == "image/gif": frames = [] diff --git a/app/lib/populate.py b/app/lib/populate.py index 26d2d33..5f15ba4 100644 --- a/app/lib/populate.py +++ b/app/lib/populate.py @@ -55,7 +55,7 @@ class Populate: try: if dirs_to_scan[0] == "$home": - dirs_to_scan = [settings.USER_HOME_DIR] + dirs_to_scan = [settings.Paths.USER_HOME_DIR] except IndexError: pass diff --git a/app/lib/taglib.py b/app/lib/taglib.py index f885a87..b0141a3 100644 --- a/app/lib/taglib.py +++ b/app/lib/taglib.py @@ -5,7 +5,7 @@ from io import BytesIO from PIL import Image, UnidentifiedImageError from tinytag import TinyTag -from app import settings +from app.settings import Defaults, Paths from app.utils.hashing import create_hash from app.utils.parsers import parse_title_from_filename, parse_artist_from_filename from app.utils.wintools import win_replace_slash @@ -27,11 +27,11 @@ def extract_thumb(filepath: str, webp_path: str) -> bool: """ Extracts the thumbnail from an audio file. Returns the path to the thumbnail. """ - img_path = os.path.join(settings.LG_THUMBS_PATH, webp_path) - sm_img_path = os.path.join(settings.SM_THUMB_PATH, webp_path) + img_path = os.path.join(Paths.LG_THUMBS_PATH, webp_path) + sm_img_path = os.path.join(Paths.SM_THUMB_PATH, webp_path) - tsize = settings.THUMB_SIZE - sm_tsize = settings.SM_THUMB_SIZE + tsize = Defaults.THUMB_SIZE + sm_tsize = Defaults.SM_THUMB_SIZE def save_image(img: Image.Image): img.resize((sm_tsize, sm_tsize), Image.ANTIALIAS).save(sm_img_path, "webp") diff --git a/app/lib/watchdogg.py b/app/lib/watchdogg.py index a15efa3..592cefc 100644 --- a/app/lib/watchdogg.py +++ b/app/lib/watchdogg.py @@ -70,7 +70,7 @@ class Watcher: # dirs = [settings.USER_HOME_DIR] if any([d == "$home" for d in dirs]): - dirs = [settings.USER_HOME_DIR] + dirs = [settings.Paths.USER_HOME_DIR] event_handler = Handler(root_dirs=dirs, dir_map=dir_map) diff --git a/app/migrations/__preinit/move_to_xdg_folder.py b/app/migrations/__preinit/move_to_xdg_folder.py index 78c5f0e..0d8cc45 100644 --- a/app/migrations/__preinit/move_to_xdg_folder.py +++ b/app/migrations/__preinit/move_to_xdg_folder.py @@ -6,7 +6,7 @@ It also handles moving the userdata and the downloaded artist images to the new import os import shutil -from app.settings import APP_DIR, USER_HOME_DIR +from app.settings import Paths from app.logger import log @@ -16,8 +16,8 @@ class MoveToXdgFolder: @staticmethod def migrate(): - old_config_dir = os.path.join(USER_HOME_DIR, ".swing") - new_config_dir = APP_DIR + old_config_dir = os.path.join(Paths.USER_HOME_DIR, ".swing") + new_config_dir = Paths.APP_DIR if not os.path.exists(old_config_dir): log.info("No old config folder found. Skipping migration.") diff --git a/app/models/playlist.py b/app/models/playlist.py index d8c8824..dcabfdb 100644 --- a/app/models/playlist.py +++ b/app/models/playlist.py @@ -33,7 +33,7 @@ class Playlist: self.count = len(self.trackhashes) self.has_gif = bool(int(self.has_gif)) - self.has_image = (Path(settings.PLAYLIST_IMG_PATH) / str(self.image)).exists() + self.has_image = (Path(settings.Paths.PLAYLIST_IMG_PATH) / str(self.image)).exists() if self.image is not None: self.thumb = "thumb_" + self.image diff --git a/app/models/track.py b/app/models/track.py index c85f350..81e91ce 100644 --- a/app/models/track.py +++ b/app/models/track.py @@ -1,7 +1,7 @@ import dataclasses from dataclasses import dataclass -from app import settings +from app.settings import FromFlags from .artist import ArtistMinimal from app.utils.hashing import create_hash from app.utils.parsers import split_artists, remove_prod, parse_feat_from_title @@ -41,12 +41,12 @@ class Track: artists = split_artists(self.artist) new_title = self.title - if settings.EXTRACT_FEAT: + if FromFlags.EXTRACT_FEAT: featured, new_title = parse_feat_from_title(self.title) original_lower = "-".join([a.lower() for a in artists]) artists.extend([a for a in featured if a.lower() not in original_lower]) - if settings.REMOVE_PROD: + if FromFlags.REMOVE_PROD: new_title = remove_prod(new_title) # if track is a single diff --git a/app/requests/artists.py b/app/requests/artists.py index d699b47..9ffb8ce 100644 --- a/app/requests/artists.py +++ b/app/requests/artists.py @@ -12,7 +12,7 @@ def fetch_similar_artists(name: str): Fetches similar artists from Last.fm """ url = f"https://ws.audioscrobbler.com/2.0/?method=artist.getsimilar&artist={name}&api_key=" \ - f"{settings.Keys.LASTFM_API_KEY}&format=json&limit=250" + f"{settings.Keys.LASTFM_API}&format=json&limit=250" response = requests.get(url, timeout=10) response.raise_for_status() diff --git a/app/settings.py b/app/settings.py index 21db4c4..a5f2c0e 100644 --- a/app/settings.py +++ b/app/settings.py @@ -3,6 +3,8 @@ Contains default configs """ import os +join = os.path.join + # ------- HELPER METHODS -------- def get_xdg_config_dir(): @@ -17,7 +19,7 @@ def get_xdg_config_dir(): return xdg_config_home try: - alt_dir = os.path.join(os.environ.get("HOME"), ".config") + alt_dir = join(os.environ.get("HOME"), ".config") if os.path.exists(alt_dir): return alt_dir @@ -25,59 +27,65 @@ def get_xdg_config_dir(): return os.path.expanduser("~") -# ------- HELPER METHODS -------- +# !------- HELPER METHODS --------! + +class Release: + APP_VERSION = "v1.2.0" -APP_VERSION = "v1.1.0" +class Paths: + XDG_CONFIG_DIR = get_xdg_config_dir() + USER_HOME_DIR = os.path.expanduser("~") -# paths -XDG_CONFIG_DIR = get_xdg_config_dir() -USER_HOME_DIR = os.path.expanduser("~") + CONFIG_FOLDER = "swingmusic" if XDG_CONFIG_DIR != USER_HOME_DIR else ".swingmusic" -CONFIG_FOLDER = "swingmusic" if XDG_CONFIG_DIR != USER_HOME_DIR else ".swingmusic" + APP_DIR = join(XDG_CONFIG_DIR, CONFIG_FOLDER) + IMG_PATH = join(APP_DIR, "images") -APP_DIR = os.path.join(XDG_CONFIG_DIR, CONFIG_FOLDER) -IMG_PATH = os.path.join(APP_DIR, "images") + ARTIST_IMG_PATH = join(IMG_PATH, "artists") + ARTIST_IMG_SM_PATH = join(ARTIST_IMG_PATH, "small") + ARTIST_IMG_LG_PATH = join(ARTIST_IMG_PATH, "large") -ARTIST_IMG_PATH = os.path.join(IMG_PATH, "artists") -ARTIST_IMG_SM_PATH = os.path.join(ARTIST_IMG_PATH, "small") -ARTIST_IMG_LG_PATH = os.path.join(ARTIST_IMG_PATH, "large") + PLAYLIST_IMG_PATH = join(IMG_PATH, "playlists") -PLAYLIST_IMG_PATH = os.path.join(IMG_PATH, "playlists") + THUMBS_PATH = join(IMG_PATH, "thumbnails") + SM_THUMB_PATH = join(THUMBS_PATH, "small") + LG_THUMBS_PATH = join(THUMBS_PATH, "large") -THUMBS_PATH = os.path.join(IMG_PATH, "thumbnails") -SM_THUMB_PATH = os.path.join(THUMBS_PATH, "small") -LG_THUMBS_PATH = os.path.join(THUMBS_PATH, "large") -MUSIC_DIR = os.path.join(USER_HOME_DIR, "Music") + # TEST_DIR = "/home/cwilvx/Downloads/Telegram Desktop" + # TEST_DIR = "/mnt/dfc48e0f-103b-426e-9bf9-f25d3743bc96/Music/Chill/Wolftyla Radio" + # HOME_DIR = TEST_DIR -# TEST_DIR = "/home/cwilvx/Downloads/Telegram Desktop" -# TEST_DIR = "/mnt/dfc48e0f-103b-426e-9bf9-f25d3743bc96/Music/Chill/Wolftyla Radio" -# HOME_DIR = TEST_DIR -# 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/" -IMG_PLAYLIST_URI = IMG_BASE_URI + "playlists/" +class 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/" + IMG_PLAYLIST_URI = IMG_BASE_URI + "playlists/" + # defaults -DEFAULT_ARTIST_IMG = IMG_ARTIST_URI + "0.webp" -THUMB_SIZE = 400 -SM_THUMB_SIZE = 64 -SM_ARTIST_IMG_SIZE = 64 -""" -The size of extracted images in pixels -""" +class Defaults: + DEFAULT_ARTIST_IMG = Urls.IMG_ARTIST_URI + "0.webp" + THUMB_SIZE = 400 + SM_THUMB_SIZE = 64 + SM_ARTIST_IMG_SIZE = 64 + """ + The size of extracted images in pixels + """ + FILES = ["flac", "mp3", "wav", "m4a", "ogg", "wma", "opus", "alac", "aiff"] SUPPORTED_FILES = tuple(f".{file}" for file in FILES) + # ===== SQLite ===== -APP_DB_NAME = "swing.db" -USER_DATA_DB_NAME = "userdata.db" -APP_DB_PATH = os.path.join(APP_DIR, APP_DB_NAME) -USERDATA_DB_PATH = os.path.join(APP_DIR, USER_DATA_DB_NAME) -JSON_CONFIG_PATH = os.path.join(APP_DIR, "config.json") +class Db: + APP_DB_NAME = "swing.db" + USER_DATA_DB_NAME = "userdata.db" + APP_DB_PATH = join(Paths.APP_DIR, APP_DB_NAME) + USERDATA_DB_PATH = join(Paths.APP_DIR, USER_DATA_DB_NAME) + JSON_CONFIG_PATH = join(Paths.APP_DIR, "config.json") class FLASKVARS: @@ -99,15 +107,16 @@ class ALLARGS: version = ["--version", "-v"] -EXTRACT_FEAT = True -""" -Whether to extract the featured artists from the song title. -""" +class FromFlags: + EXTRACT_FEAT = True + """ + Whether to extract the featured artists from the song title. + """ -REMOVE_PROD = True -""" -Whether to remove the producers from the song title. -""" + REMOVE_PROD = True + """ + Whether to remove the producers from the song title. + """ class TCOLOR: @@ -129,4 +138,4 @@ class TCOLOR: class Keys: # get last fm api key from os environment - LASTFM_API_KEY = os.environ.get("LASTFM_API_KEY") + LASTFM_API = os.environ.get("LASTFM_API_KEY") diff --git a/app/setup/files.py b/app/setup/files.py index 9aafb7e..d54273c 100644 --- a/app/setup/files.py +++ b/app/setup/files.py @@ -33,7 +33,7 @@ class CopyFiles: files = [ { "src": assets_dir, - "dest": os.path.join(settings.APP_DIR, "assets"), + "dest": os.path.join(settings.Paths.APP_DIR, "assets"), "is_dir": True, } ] @@ -83,7 +83,7 @@ def create_config_dir() -> None: ] for _dir in dirs: - path = os.path.join(settings.APP_DIR, _dir) + path = os.path.join(settings.Paths.APP_DIR, _dir) exists = os.path.exists(path) if not exists: diff --git a/app/setup/sqlite.py b/app/setup/sqlite.py index fc34be8..a1c158e 100644 --- a/app/setup/sqlite.py +++ b/app/setup/sqlite.py @@ -7,7 +7,7 @@ from app.db.sqlite import create_connection, create_tables, queries from app.migrations import apply_migrations, set_postinit_migration_versions from app.migrations.__preinit import run_preinit_migrations, set_preinit_migration_versions -from app.settings import APP_DB_PATH, USERDATA_DB_PATH +from app.settings import Db def setup_sqlite(): @@ -19,8 +19,8 @@ def setup_sqlite(): run_preinit_migrations() - app_db_conn = create_connection(APP_DB_PATH) - playlist_db_conn = create_connection(USERDATA_DB_PATH) + app_db_conn = create_connection(Db.APP_DB_PATH) + playlist_db_conn = create_connection(Db.USERDATA_DB_PATH) create_tables(app_db_conn, queries.CREATE_APPDB_TABLES) create_tables(playlist_db_conn, queries.CREATE_USERDATA_TABLES) diff --git a/app/start_info_logger.py b/app/start_info_logger.py index 24bd7d5..89b0818 100644 --- a/app/start_info_logger.py +++ b/app/start_info_logger.py @@ -1,7 +1,6 @@ import os -from app.settings import TCOLOR, APP_VERSION, FLASKVARS, APP_DIR -from app import settings +from app.settings import TCOLOR, Release, FLASKVARS, Paths, FromFlags from app.utils.network import get_ip @@ -11,7 +10,7 @@ def log_startup_info(): os.system("cls" if os.name == "nt" else "echo -e \\\\033c") print(lines) - print(f"{TCOLOR.HEADER}SwingMusic {APP_VERSION} {TCOLOR.ENDC}") + print(f"{TCOLOR.HEADER}SwingMusic {Release.APP_VERSION} {TCOLOR.ENDC}") adresses = [FLASKVARS.FLASK_HOST] @@ -31,11 +30,11 @@ def log_startup_info(): to_print = [ [ "Extract featured artists from titles", - settings.EXTRACT_FEAT + FromFlags.EXTRACT_FEAT ], [ "Remove prod. from titles", - settings.REMOVE_PROD + FromFlags.REMOVE_PROD ] ] @@ -45,7 +44,7 @@ def log_startup_info(): ) print( - f"{TCOLOR.YELLOW}Data folder: {APP_DIR}{TCOLOR.ENDC}" + f"{TCOLOR.YELLOW}Data folder: {Paths.APP_DIR}{TCOLOR.ENDC}" ) print("\n") diff --git a/app/utils/generators.py b/app/utils/generators.py index fa3b17b..ad89b5b 100644 --- a/app/utils/generators.py +++ b/app/utils/generators.py @@ -1,9 +1,7 @@ import string -from datetime import datetime import random - def get_random_str(length=5): """ Generates a random string of length `length`.