break settings.py into classes

This commit is contained in:
geoffrey45 2023-03-26 08:25:00 +03:00
parent 79029ae346
commit 357afeb700
22 changed files with 102 additions and 96 deletions

View File

@ -33,7 +33,7 @@ def get_folder_tree():
try: try:
if req_dir == "$home" and root_dirs[0] == "$home": if req_dir == "$home" and root_dirs[0] == "$home":
req_dir = settings.USER_HOME_DIR req_dir = settings.Paths.USER_HOME_DIR
except IndexError: except IndexError:
pass pass

View File

@ -2,12 +2,12 @@ from pathlib import Path
from flask import Blueprint, send_from_directory 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") api = Blueprint("imgserver", __name__, url_prefix="/img")
SUPPORTED_IMAGES = (".jpg", ".png", ".webp", ".jpeg") SUPPORTED_IMAGES = (".jpg", ".png", ".webp", ".jpeg")
APP_DIR = Path(APP_DIR) APP_DIR = Path(Paths.APP_DIR)
IMG_PATH = APP_DIR / "images" IMG_PATH = APP_DIR / "images"
ASSETS_PATH = APP_DIR / "assets" ASSETS_PATH = APP_DIR / "assets"

View File

@ -98,7 +98,7 @@ def add_root_dirs():
sdb.remove_root_dirs(db_dirs) sdb.remove_root_dirs(db_dirs)
if incoming_home: if incoming_home:
finalize([_h], [], [settings.USER_HOME_DIR]) finalize([_h], [], [settings.Paths.USER_HOME_DIR])
return {"root_dirs": [_h]} return {"root_dirs": [_h]}
# --- # ---

View File

@ -109,5 +109,5 @@ class HandleArgs:
@staticmethod @staticmethod
def handle_version(): def handle_version():
if any((a in ARGS for a in ALLARGS.version)): if any((a in ARGS for a in ALLARGS.version)):
print(settings.APP_VERSION) print(settings.Release.APP_VERSION)
sys.exit(0) sys.exit(0)

View File

@ -6,7 +6,7 @@ import json
from enum import Enum from enum import Enum
from typing import Type from typing import Type
from app.settings import JSON_CONFIG_PATH from app.settings import Db
class ConfigKeys(Enum): class ConfigKeys(Enum):
@ -57,5 +57,5 @@ class ConfigManager:
self.write_config(config_data) self.write_config(config_data)
settings = ConfigManager(JSON_CONFIG_PATH) settings = ConfigManager(Db.JSON_CONFIG_PATH)
a = settings.get_value(ConfigKeys.ROOT_DIRS) a = settings.get_value(ConfigKeys.ROOT_DIRS)

View File

@ -6,7 +6,7 @@ import sqlite3
from pathlib import Path from pathlib import Path
from sqlite3 import Connection as SqlConn 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: def create_connection(db_file: str) -> SqlConn:
@ -22,7 +22,7 @@ def get_sqlite_conn():
It opens a connection to the database It opens a connection to the database
:return: 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): def create_tables(conn: SqlConn, sql_query: str):

View File

@ -7,7 +7,7 @@ from sqlite3 import Connection, Cursor
import time import time
from app.models import Album, Playlist, Track 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): def tuple_to_track(track: tuple):
@ -78,10 +78,10 @@ class SQLiteManager:
if self.conn is not None: if self.conn is not None:
return self.conn.cursor() return self.conn.cursor()
db_path = APP_DB_PATH db_path = Db.APP_DB_PATH
if self.userdata_db: if self.userdata_db:
db_path = USERDATA_DB_PATH db_path = Db.USERDATA_DB_PATH
self.conn = sqlite3.connect( self.conn = sqlite3.connect(
db_path, db_path,

View File

@ -42,8 +42,8 @@ def get_artist_image_link(artist: str):
# TODO: Move network calls to utils/network.py # TODO: Move network calls to utils/network.py
class DownloadImage: class DownloadImage:
def __init__(self, url: str, name: str) -> None: def __init__(self, url: str, name: str) -> None:
sm_path = Path(settings.ARTIST_IMG_SM_PATH) / name sm_path = Path(settings.Paths.ARTIST_IMG_SM_PATH) / name
lg_path = Path(settings.ARTIST_IMG_LG_PATH) / name lg_path = Path(settings.Paths.ARTIST_IMG_LG_PATH) / name
img = self.download(url) img = self.download(url)
@ -64,7 +64,7 @@ class DownloadImage:
""" """
img.save(lg_path, format="webp") 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") img.resize((sm_size, sm_size), Image.ANTIALIAS).save(sm_path, format="webp")
@ -86,7 +86,7 @@ class CheckArtistImages:
:param artist: The artist name :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(): if img_path.exists():
return 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. """ # 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={ # 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: # try:
# response = requests.get(last_fm_url) # response = requests.get(last_fm_url)

View File

@ -56,7 +56,7 @@ class ProcessAlbumColors:
@staticmethod @staticmethod
def process_color(album: Album): 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(): if not path.exists():
return return
@ -78,7 +78,7 @@ class ProcessArtistColors:
@staticmethod @staticmethod
def process_color(artist: Artist): 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(): if not path.exists():
return return

View File

@ -16,7 +16,7 @@ def create_thumbnail(image: Any, img_path: str) -> str:
Creates a 250 x 250 thumbnail from a playlist image Creates a 250 x 250 thumbnail from a playlist image
""" """
thumb_path = "thumb_" + img_path 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 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 Creates a 250 x 250 thumbnail from a playlist image
""" """
thumb_path = "thumb_" + img_path 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 = [] frames = []
@ -60,7 +60,7 @@ def save_p_image(file, pid: str):
filename = pid + str(random_str) + ".webp" 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": if file.content_type == "image/gif":
frames = [] frames = []

View File

@ -55,7 +55,7 @@ class Populate:
try: try:
if dirs_to_scan[0] == "$home": if dirs_to_scan[0] == "$home":
dirs_to_scan = [settings.USER_HOME_DIR] dirs_to_scan = [settings.Paths.USER_HOME_DIR]
except IndexError: except IndexError:
pass pass

View File

@ -5,7 +5,7 @@ from io import BytesIO
from PIL import Image, UnidentifiedImageError from PIL import Image, UnidentifiedImageError
from tinytag import TinyTag from tinytag import TinyTag
from app import settings from app.settings import Defaults, Paths
from app.utils.hashing import create_hash from app.utils.hashing import create_hash
from app.utils.parsers import parse_title_from_filename, parse_artist_from_filename from app.utils.parsers import parse_title_from_filename, parse_artist_from_filename
from app.utils.wintools import win_replace_slash 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. Extracts the thumbnail from an audio file. Returns the path to the thumbnail.
""" """
img_path = os.path.join(settings.LG_THUMBS_PATH, webp_path) img_path = os.path.join(Paths.LG_THUMBS_PATH, webp_path)
sm_img_path = os.path.join(settings.SM_THUMB_PATH, webp_path) sm_img_path = os.path.join(Paths.SM_THUMB_PATH, webp_path)
tsize = settings.THUMB_SIZE tsize = Defaults.THUMB_SIZE
sm_tsize = settings.SM_THUMB_SIZE sm_tsize = Defaults.SM_THUMB_SIZE
def save_image(img: Image.Image): def save_image(img: Image.Image):
img.resize((sm_tsize, sm_tsize), Image.ANTIALIAS).save(sm_img_path, "webp") img.resize((sm_tsize, sm_tsize), Image.ANTIALIAS).save(sm_img_path, "webp")

View File

@ -70,7 +70,7 @@ class Watcher:
# dirs = [settings.USER_HOME_DIR] # dirs = [settings.USER_HOME_DIR]
if any([d == "$home" for d in dirs]): 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) event_handler = Handler(root_dirs=dirs, dir_map=dir_map)

View File

@ -6,7 +6,7 @@ It also handles moving the userdata and the downloaded artist images to the new
import os import os
import shutil import shutil
from app.settings import APP_DIR, USER_HOME_DIR from app.settings import Paths
from app.logger import log from app.logger import log
@ -16,8 +16,8 @@ class MoveToXdgFolder:
@staticmethod @staticmethod
def migrate(): def migrate():
old_config_dir = os.path.join(USER_HOME_DIR, ".swing") old_config_dir = os.path.join(Paths.USER_HOME_DIR, ".swing")
new_config_dir = APP_DIR new_config_dir = Paths.APP_DIR
if not os.path.exists(old_config_dir): if not os.path.exists(old_config_dir):
log.info("No old config folder found. Skipping migration.") log.info("No old config folder found. Skipping migration.")

View File

@ -33,7 +33,7 @@ class Playlist:
self.count = len(self.trackhashes) self.count = len(self.trackhashes)
self.has_gif = bool(int(self.has_gif)) 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: if self.image is not None:
self.thumb = "thumb_" + self.image self.thumb = "thumb_" + self.image

View File

@ -1,7 +1,7 @@
import dataclasses import dataclasses
from dataclasses import dataclass from dataclasses import dataclass
from app import settings from app.settings import FromFlags
from .artist import ArtistMinimal from .artist import ArtistMinimal
from app.utils.hashing import create_hash from app.utils.hashing import create_hash
from app.utils.parsers import split_artists, remove_prod, parse_feat_from_title from app.utils.parsers import split_artists, remove_prod, parse_feat_from_title
@ -41,12 +41,12 @@ class Track:
artists = split_artists(self.artist) artists = split_artists(self.artist)
new_title = self.title new_title = self.title
if settings.EXTRACT_FEAT: if FromFlags.EXTRACT_FEAT:
featured, new_title = parse_feat_from_title(self.title) featured, new_title = parse_feat_from_title(self.title)
original_lower = "-".join([a.lower() for a in artists]) original_lower = "-".join([a.lower() for a in artists])
artists.extend([a for a in featured if a.lower() not in original_lower]) 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) new_title = remove_prod(new_title)
# if track is a single # if track is a single

View File

@ -12,7 +12,7 @@ def fetch_similar_artists(name: str):
Fetches similar artists from Last.fm Fetches similar artists from Last.fm
""" """
url = f"https://ws.audioscrobbler.com/2.0/?method=artist.getsimilar&artist={name}&api_key=" \ 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 = requests.get(url, timeout=10)
response.raise_for_status() response.raise_for_status()

View File

@ -3,6 +3,8 @@ Contains default configs
""" """
import os import os
join = os.path.join
# ------- HELPER METHODS -------- # ------- HELPER METHODS --------
def get_xdg_config_dir(): def get_xdg_config_dir():
@ -17,7 +19,7 @@ def get_xdg_config_dir():
return xdg_config_home return xdg_config_home
try: 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): if os.path.exists(alt_dir):
return alt_dir return alt_dir
@ -25,43 +27,46 @@ def get_xdg_config_dir():
return os.path.expanduser("~") return os.path.expanduser("~")
# ------- HELPER METHODS -------- # !------- HELPER METHODS --------!
class Release:
APP_VERSION = "v1.2.0"
APP_VERSION = "v1.1.0" class Paths:
# paths
XDG_CONFIG_DIR = get_xdg_config_dir() XDG_CONFIG_DIR = get_xdg_config_dir()
USER_HOME_DIR = os.path.expanduser("~") 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 = os.path.join(XDG_CONFIG_DIR, CONFIG_FOLDER) APP_DIR = join(XDG_CONFIG_DIR, CONFIG_FOLDER)
IMG_PATH = os.path.join(APP_DIR, "images") IMG_PATH = join(APP_DIR, "images")
ARTIST_IMG_PATH = os.path.join(IMG_PATH, "artists") ARTIST_IMG_PATH = join(IMG_PATH, "artists")
ARTIST_IMG_SM_PATH = os.path.join(ARTIST_IMG_PATH, "small") ARTIST_IMG_SM_PATH = join(ARTIST_IMG_PATH, "small")
ARTIST_IMG_LG_PATH = os.path.join(ARTIST_IMG_PATH, "large") ARTIST_IMG_LG_PATH = join(ARTIST_IMG_PATH, "large")
PLAYLIST_IMG_PATH = os.path.join(IMG_PATH, "playlists") PLAYLIST_IMG_PATH = join(IMG_PATH, "playlists")
THUMBS_PATH = os.path.join(IMG_PATH, "thumbnails") THUMBS_PATH = join(IMG_PATH, "thumbnails")
SM_THUMB_PATH = os.path.join(THUMBS_PATH, "small") SM_THUMB_PATH = join(THUMBS_PATH, "small")
LG_THUMBS_PATH = os.path.join(THUMBS_PATH, "large") LG_THUMBS_PATH = join(THUMBS_PATH, "large")
MUSIC_DIR = os.path.join(USER_HOME_DIR, "Music")
# TEST_DIR = "/home/cwilvx/Downloads/Telegram Desktop" # TEST_DIR = "/home/cwilvx/Downloads/Telegram Desktop"
# TEST_DIR = "/mnt/dfc48e0f-103b-426e-9bf9-f25d3743bc96/Music/Chill/Wolftyla Radio" # TEST_DIR = "/mnt/dfc48e0f-103b-426e-9bf9-f25d3743bc96/Music/Chill/Wolftyla Radio"
# HOME_DIR = TEST_DIR # HOME_DIR = TEST_DIR
# URLS
class Urls:
IMG_BASE_URI = "http://127.0.0.1:8900/images/" IMG_BASE_URI = "http://127.0.0.1:8900/images/"
IMG_ARTIST_URI = IMG_BASE_URI + "artists/" IMG_ARTIST_URI = IMG_BASE_URI + "artists/"
IMG_THUMB_URI = IMG_BASE_URI + "thumbnails/" IMG_THUMB_URI = IMG_BASE_URI + "thumbnails/"
IMG_PLAYLIST_URI = IMG_BASE_URI + "playlists/" IMG_PLAYLIST_URI = IMG_BASE_URI + "playlists/"
# defaults # defaults
DEFAULT_ARTIST_IMG = IMG_ARTIST_URI + "0.webp" class Defaults:
DEFAULT_ARTIST_IMG = Urls.IMG_ARTIST_URI + "0.webp"
THUMB_SIZE = 400 THUMB_SIZE = 400
SM_THUMB_SIZE = 64 SM_THUMB_SIZE = 64
SM_ARTIST_IMG_SIZE = 64 SM_ARTIST_IMG_SIZE = 64
@ -69,15 +74,18 @@ SM_ARTIST_IMG_SIZE = 64
The size of extracted images in pixels The size of extracted images in pixels
""" """
FILES = ["flac", "mp3", "wav", "m4a", "ogg", "wma", "opus", "alac", "aiff"] FILES = ["flac", "mp3", "wav", "m4a", "ogg", "wma", "opus", "alac", "aiff"]
SUPPORTED_FILES = tuple(f".{file}" for file in FILES) SUPPORTED_FILES = tuple(f".{file}" for file in FILES)
# ===== SQLite ===== # ===== SQLite =====
class Db:
APP_DB_NAME = "swing.db" APP_DB_NAME = "swing.db"
USER_DATA_DB_NAME = "userdata.db" USER_DATA_DB_NAME = "userdata.db"
APP_DB_PATH = os.path.join(APP_DIR, APP_DB_NAME) APP_DB_PATH = join(Paths.APP_DIR, APP_DB_NAME)
USERDATA_DB_PATH = os.path.join(APP_DIR, USER_DATA_DB_NAME) USERDATA_DB_PATH = join(Paths.APP_DIR, USER_DATA_DB_NAME)
JSON_CONFIG_PATH = os.path.join(APP_DIR, "config.json") JSON_CONFIG_PATH = join(Paths.APP_DIR, "config.json")
class FLASKVARS: class FLASKVARS:
@ -99,6 +107,7 @@ class ALLARGS:
version = ["--version", "-v"] version = ["--version", "-v"]
class FromFlags:
EXTRACT_FEAT = True EXTRACT_FEAT = True
""" """
Whether to extract the featured artists from the song title. Whether to extract the featured artists from the song title.
@ -129,4 +138,4 @@ class TCOLOR:
class Keys: class Keys:
# get last fm api key from os environment # 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")

View File

@ -33,7 +33,7 @@ class CopyFiles:
files = [ files = [
{ {
"src": assets_dir, "src": assets_dir,
"dest": os.path.join(settings.APP_DIR, "assets"), "dest": os.path.join(settings.Paths.APP_DIR, "assets"),
"is_dir": True, "is_dir": True,
} }
] ]
@ -83,7 +83,7 @@ def create_config_dir() -> None:
] ]
for _dir in dirs: 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) exists = os.path.exists(path)
if not exists: if not exists:

View File

@ -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 import apply_migrations, set_postinit_migration_versions
from app.migrations.__preinit import run_preinit_migrations, set_preinit_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(): def setup_sqlite():
@ -19,8 +19,8 @@ def setup_sqlite():
run_preinit_migrations() run_preinit_migrations()
app_db_conn = create_connection(APP_DB_PATH) app_db_conn = create_connection(Db.APP_DB_PATH)
playlist_db_conn = create_connection(USERDATA_DB_PATH) playlist_db_conn = create_connection(Db.USERDATA_DB_PATH)
create_tables(app_db_conn, queries.CREATE_APPDB_TABLES) create_tables(app_db_conn, queries.CREATE_APPDB_TABLES)
create_tables(playlist_db_conn, queries.CREATE_USERDATA_TABLES) create_tables(playlist_db_conn, queries.CREATE_USERDATA_TABLES)

View File

@ -1,7 +1,6 @@
import os import os
from app.settings import TCOLOR, APP_VERSION, FLASKVARS, APP_DIR from app.settings import TCOLOR, Release, FLASKVARS, Paths, FromFlags
from app import settings
from app.utils.network import get_ip 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") os.system("cls" if os.name == "nt" else "echo -e \\\\033c")
print(lines) 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] adresses = [FLASKVARS.FLASK_HOST]
@ -31,11 +30,11 @@ def log_startup_info():
to_print = [ to_print = [
[ [
"Extract featured artists from titles", "Extract featured artists from titles",
settings.EXTRACT_FEAT FromFlags.EXTRACT_FEAT
], ],
[ [
"Remove prod. from titles", "Remove prod. from titles",
settings.REMOVE_PROD FromFlags.REMOVE_PROD
] ]
] ]
@ -45,7 +44,7 @@ def log_startup_info():
) )
print( print(
f"{TCOLOR.YELLOW}Data folder: {APP_DIR}{TCOLOR.ENDC}" f"{TCOLOR.YELLOW}Data folder: {Paths.APP_DIR}{TCOLOR.ENDC}"
) )
print("\n") print("\n")

View File

@ -1,9 +1,7 @@
import string import string
from datetime import datetime
import random import random
def get_random_str(length=5): def get_random_str(length=5):
""" """
Generates a random string of length `length`. Generates a random string of length `length`.