fix: absolute config path not resolving

+ skip through empty directories in folder browser
+ handle timestamp table error in migration
This commit is contained in:
mungai-njoroge
2024-04-01 11:02:27 +03:00
parent 95a8e9b215
commit 2f6e705c75
9 changed files with 64 additions and 35 deletions
+9 -5
View File
@@ -64,12 +64,16 @@ def get_folder_tree(body: FolderTree):
else: else:
req_dir = "/" + req_dir + "/" if not req_dir.startswith("/") else req_dir + "/" req_dir = "/" + req_dir + "/" if not req_dir.startswith("/") else req_dir + "/"
tracks, folders = GetFilesAndDirs(req_dir, tracks_only=tracks_only)() res = GetFilesAndDirs(req_dir, tracks_only=tracks_only)()
res['folders'] = sorted(res['folders'], key=lambda i: i.name)
return { return res
"tracks": tracks,
"folders": sorted(folders, key=lambda i: i.name), # return {
} # "path": req_dir,
# "tracks": tracks,
# "folders": sorted(folders, key=lambda i: i.name),
# }
def get_all_drives(is_win: bool = False): def get_all_drives(is_win: bool = False):
+5 -4
View File
@@ -58,7 +58,7 @@ class HandleArgs:
if not value: if not value:
log.error(f"WARNING: {key} not set in environment") log.error(f"WARNING: {key} not set in environment")
#sys.exit(0) sys.exit(0)
lines.append(f'{key} = "{value}"\n') lines.append(f'{key} = "{value}"\n')
@@ -132,12 +132,13 @@ class HandleArgs:
try: try:
config_path = ARGS[index + 1] config_path = ARGS[index + 1]
resolved = os.path.abspath(config_path)
if os.path.exists(config_path): if os.path.exists(resolved):
settings.Paths.set_config_dir(config_path) settings.Paths.set_config_dir(resolved)
return return
log.warn(f"Config path {config_path} doesn't exist") log.warn(f"Config path {resolved} doesn't exist")
sys.exit(0) sys.exit(0)
except IndexError: except IndexError:
pass pass
+26 -4
View File
@@ -48,11 +48,20 @@ class GetFilesAndDirs:
self.path = path self.path = path
self.tracks_only = tracks_only self.tracks_only = tracks_only
def __call__(self) -> tuple[list[Track], list[Folder]]: def get_files_and_dirs(self, path: str, skip_empty_folders=True):
"""
Given a path, returns a list of tracks and folders in that immediate path.
Can recursively call itself to skip through empty folders.
"""
try: try:
entries = os.scandir(self.path) entries = os.scandir(path)
except FileNotFoundError: except FileNotFoundError:
return [], [] return {
"path": path,
"tracks": [],
"folders": [],
}
dirs, files = [], [] dirs, files = [], []
@@ -86,4 +95,17 @@ class GetFilesAndDirs:
if not self.tracks_only: if not self.tracks_only:
folders = get_folders(dirs) folders = get_folders(dirs)
return tracks, folders if skip_empty_folders and len(folders) == 1 and len(tracks) == 0:
# INFO: When we only have one folder and no tracks,
# skip through empty folders.
# Call recursively with the first folder in the list.
return self.get_files_and_dirs(folders[0].path)
return {
"path": path,
"tracks": tracks,
"folders": folders,
}
def __call__(self):
return self.get_files_and_dirs(self.path)
+9 -2
View File
@@ -10,14 +10,20 @@ class AddTimestampToFavoritesTable(Migration):
@staticmethod @staticmethod
def migrate(): def migrate():
# INFO: add timestamp column with automatic current timestamp # INFO: add timestamp column with automatic current timestamp
sql = f"ALTER TABLE favorites ADD COLUMN timestamp INTEGER NOT NULL DEFAULT 0" sql = f"ALTER TABLE favorites ADD COLUMN IF NOT EXISTS timestamp INTEGER NOT NULL DEFAULT 0"
# INFO: execute the sql # INFO: execute the sql
with SQLiteManager(userdata_db=True) as cur: with SQLiteManager(userdata_db=True) as cur:
try:
# INFO: Add the timestamp column to the favorites table
cur.execute(sql) cur.execute(sql)
# INFO: Update the timestamp column with the current timestamp # INFO: Set all the timestamps to the current time
cur.execute("UPDATE favorites SET timestamp = strftime('%s', 'now')") cur.execute("UPDATE favorites SET timestamp = strftime('%s', 'now')")
except Exception as e:
# INFO: timestamp column already exists
pass
finally:
cur.close() cur.close()
@@ -28,6 +34,7 @@ class MoveHashesToSha1(Migration):
Thanks to [@tcsenpai](https:github.com/tcsenpai) for the contribution. Thanks to [@tcsenpai](https:github.com/tcsenpai) for the contribution.
""" """
pass pass
# INFO: Apparentlly, every single table is affected by this migration. # INFO: Apparentlly, every single table is affected by this migration.
+1 -5
View File
@@ -1,12 +1,12 @@
""" """
Requests related to artists Requests related to artists
""" """
import urllib.parse import urllib.parse
import requests import requests
from requests import ConnectionError, HTTPError, ReadTimeout from requests import ConnectionError, HTTPError, ReadTimeout
#from app import settings
from app.utils.hashing import create_hash from app.utils.hashing import create_hash
@@ -16,10 +16,6 @@ def fetch_similar_artists(name: str):
""" """
url = f"https://kerve.last.fm/kerve/similarartists?artist={urllib.parse.quote_plus(name, safe='')}&autocorrect=1&tracks=1&image_size=large&limit=250&format=json" url = f"https://kerve.last.fm/kerve/similarartists?artist={urllib.parse.quote_plus(name, safe='')}&autocorrect=1&tracks=1&image_size=large&limit=250&format=json"
# REVIEW This is the old way of doing it. The new way is to use the Kerve API.
#url = f"https://ws.audioscrobbler.com/2.0/?method=artist.getsimilar&artist={urllib.parse.quote_plus(name, safe='')}&api_key={settings.Keys.LASTFM_API_KEY}&format=json&limit=250"
# TODO Cannot be tested due to PR message
url = f"https://kerve.last.fm/kerve/similarartists?artist={urllib.parse.quote_plus(name, safe='')}&autocorrect=1&tracks=1&image_size=large&limit=250&format=json"
try: try:
response = requests.get(url, timeout=10) response = requests.get(url, timeout=10)
response.raise_for_status() response.raise_for_status()
-3
View File
@@ -275,9 +275,6 @@ class Keys:
@classmethod @classmethod
def load(cls): def load(cls):
# TODO Remove this. Just an handy flag to test the app without the API key
# IS_BUILD = True
if IS_BUILD: if IS_BUILD:
cls.SWINGMUSIC_APP_VERSION = configs.SWINGMUSIC_APP_VERSION cls.SWINGMUSIC_APP_VERSION = configs.SWINGMUSIC_APP_VERSION
cls.GIT_LATEST_COMMIT_HASH = configs.GIT_LATEST_COMMIT_HASH cls.GIT_LATEST_COMMIT_HASH = configs.GIT_LATEST_COMMIT_HASH
+5 -6
View File
@@ -33,10 +33,9 @@ def create_hash(*args: str, decode=False, limit=10) -> str:
str_ = str_.encode("utf-8") str_ = str_.encode("utf-8")
str_ = hashlib.sha1(str_).hexdigest() str_ = hashlib.sha1(str_).hexdigest()
# REVIEW Switched to sha1 hashlib.sha256(str_).hexdigest()
# REVIEW Take the first limit/2 and last limit/2 characters return (
# This is to avoid collisions str_[: limit // 2] + str_[-limit // 2 :]
return str_[:limit // 2] + str_[-limit // 2:] if limit % 2 == 0 else str_[:limit // 2] + str_[-limit // 2 - 1:] if limit % 2 == 0
else str_[: limit // 2] + str_[-limit // 2 - 1 :]
# return str_[-limit:] )
+4 -1
View File
@@ -1,7 +1,7 @@
import os import os
def get_xdg_config_dir(): def get_xdg_config_dir() -> str:
""" """
Returns the XDG_CONFIG_HOME environment variable if it exists, otherwise Returns the XDG_CONFIG_HOME environment variable if it exists, otherwise
returns the default config directory. If none of those exist, returns the returns the default config directory. If none of those exist, returns the
@@ -19,3 +19,6 @@ def get_xdg_config_dir():
return alt_dir return alt_dir
except TypeError: except TypeError:
return os.path.expanduser("~") return os.path.expanduser("~")
# Fallback to current directory
return os.path.abspath(".")
Regular → Executable
View File