check if track exists in db before sending file

This commit is contained in:
mungai-njoroge 2023-06-19 21:49:13 +03:00
parent a201303bd9
commit cc6552cb94
17 changed files with 96 additions and 31 deletions

1
.gitignore vendored
View File

@ -22,3 +22,4 @@ encoderx.py
dist
build
client
.gitignore

View File

@ -185,20 +185,13 @@ def get_all_favorites():
artists = remove_none(artists)
recents = []
first_n = favs[:album_limit]
# first_n = favs
for fav in first_n:
if fav[2] == FavType.track:
try:
track = [t for t in tracks if t.trackhash == fav[1]][0]
recents.append({
"type": "track",
"item": recent_fav_track_serializer(track)
})
except IndexError:
pass
for fav in favs:
if len(recents) >= largest:
break
elif fav[2] == FavType.album:
if fav[2] == FavType.album:
try:
album = [a for a in albums if a.albumhash == fav[1]][0]
recents.append({
@ -206,8 +199,9 @@ def get_all_favorites():
"item": recent_fav_album_serializer(album)
})
except IndexError:
pass
elif fav[2] == FavType.artist:
continue
if fav[2] == FavType.artist:
try:
artist = [a for a in artists if a.artisthash == fav[1]][0]
recents.append({
@ -215,7 +209,7 @@ def get_all_favorites():
"item": recent_fav_artist_serializer(artist)
})
except IndexError:
pass
continue
return {
"recents": recents[:album_limit],

View File

@ -24,9 +24,17 @@ def send_track_file(trackhash: str):
filepath = request.args.get("filepath")
if filepath is not None and os.path.exists(filepath):
audio_type = get_mime(filepath)
return send_file(filepath, mimetype=audio_type)
if filepath is not None:
try:
track = TrackStore.get_tracks_by_filepaths([filepath])[0]
except IndexError:
track = None
track_exists = track is not None and os.path.exists(track.filepath)
if track_exists:
audio_type = get_mime(filepath)
return send_file(filepath, mimetype=audio_type)
if trackhash is None:
return msg, 404

View File

@ -151,7 +151,9 @@ class HandleArgs:
@staticmethod
def handle_periodic_scan_interval():
if any((a in ARGS for a in ALLARGS.periodic_scan_interval.value)):
index = [ARGS.index(a) for a in ALLARGS.periodic_scan_interval.value if a in ARGS][0]
index = [
ARGS.index(a) for a in ALLARGS.periodic_scan_interval.value if a in ARGS
][0]
try:
interval = ARGS[index + 1]

View File

@ -17,13 +17,17 @@ class SQLiteAlbumMethods:
"""
cur.execute(sql, (albumhash, colors))
return cur.lastrowid
lastrowid = cur.lastrowid
cur.close()
return lastrowid
@classmethod
def get_all_albums(cls):
with SQLiteManager() as cur:
cur.execute("SELECT * FROM albums")
albums = cur.fetchall()
cur.close()
if albums is not None:
return albums
@ -35,6 +39,7 @@ class SQLiteAlbumMethods:
with SQLiteManager() as cur:
cur.execute("SELECT * FROM albums WHERE albumartist=?", (albumartist,))
albums = cur.fetchall()
cur.close()
if albums is not None:
return tuples_to_albums(albums)

View File

@ -21,6 +21,7 @@ class SQLiteArtistMethods:
"""
colors = json.dumps(colors)
cur.execute(sql, (artisthash, colors))
cur.close()
@staticmethod
def get_all_artists():
@ -34,3 +35,5 @@ class SQLiteArtistMethods:
for artist in cur.fetchall():
yield artist
cur.close()

View File

@ -14,6 +14,7 @@ class SQLiteFavoriteMethods:
with SQLiteManager(userdata_db=True) as cur:
cur.execute(sql, (itemhash, fav_type))
items = cur.fetchall()
cur.close()
return len(items) > 0
@classmethod
@ -28,6 +29,7 @@ class SQLiteFavoriteMethods:
sql = """INSERT INTO favorites(type, hash) VALUES(?,?)"""
with SQLiteManager(userdata_db=True) as cur:
cur.execute(sql, (fav_type, fav_hash))
cur.close()
@classmethod
def get_all(cls) -> list[tuple]:
@ -38,6 +40,7 @@ class SQLiteFavoriteMethods:
with SQLiteManager(userdata_db=True) as cur:
cur.execute(sql)
favs = cur.fetchall()
cur.close()
return [fav for fav in favs if fav[1] != ""]
@classmethod
@ -48,7 +51,9 @@ class SQLiteFavoriteMethods:
sql = """SELECT * FROM favorites WHERE type = ?"""
with SQLiteManager(userdata_db=True) as cur:
cur.execute(sql, (fav_type,))
return cur.fetchall()
all_favs = cur.fetchall()
cur.close()
return all_favs
@classmethod
def get_fav_tracks(cls) -> list[tuple]:
@ -80,3 +85,4 @@ class SQLiteFavoriteMethods:
with SQLiteManager(userdata_db=True) as cur:
cur.execute(sql, (fav_hash, fav_type))
cur.close()

View File

@ -21,7 +21,10 @@ class MigrationManager:
"""
with SQLiteManager() as cur:
cur.execute(cls.all_get_sql)
return int(cur.fetchone()[1])
ver = int(cur.fetchone()[1])
cur.close()
return ver
@classmethod
def get_maindb_postinit_version(cls) -> int:
@ -30,7 +33,10 @@ class MigrationManager:
"""
with SQLiteManager() as cur:
cur.execute(cls.all_get_sql)
return int(cur.fetchone()[2])
ver = int(cur.fetchone()[2])
cur.close()
return ver
@classmethod
def get_userdatadb_postinit_version(cls) -> int:
@ -39,7 +45,10 @@ class MigrationManager:
"""
with SQLiteManager(userdata_db=True) as cur:
cur.execute(cls.all_get_sql)
return cur.fetchone()[2]
ver = cur.fetchone()[2]
cur.close()
return ver
# 👇 Setters 👇
@classmethod
@ -49,6 +58,7 @@ class MigrationManager:
"""
with SQLiteManager() as cur:
cur.execute(cls.pre_init_set_sql, (version,))
cur.close()
@classmethod
def set_maindb_postinit_version(cls, version: int):

View File

@ -31,6 +31,7 @@ class SQLitePlaylistMethods:
with SQLiteManager(userdata_db=True) as cur:
cur.execute(sql, playlist)
pid = cur.lastrowid
cur.close()
p_tuple = (pid, *playlist.values())
return tuple_to_playlist(p_tuple)
@ -43,6 +44,7 @@ class SQLitePlaylistMethods:
cur.execute(sql, (name,))
data = cur.fetchone()
cur.close()
if data is not None:
return tuple_to_playlist(data)
@ -57,6 +59,7 @@ class SQLitePlaylistMethods:
cur.execute(sql, (name,))
data = cur.fetchone()
cur.close()
return int(data[0])
@ -65,6 +68,7 @@ class SQLitePlaylistMethods:
with SQLiteManager(userdata_db=True) as cur:
cur.execute("SELECT * FROM playlists")
playlists = cur.fetchall()
cur.close()
if playlists is not None:
return tuples_to_playlists(playlists)
@ -79,6 +83,7 @@ class SQLitePlaylistMethods:
cur.execute(sql, (playlist_id,))
data = cur.fetchone()
cur.close()
if data is not None:
return tuple_to_playlist(data)

View File

@ -18,6 +18,7 @@ class SettingsSQLMethods:
with SQLiteManager(userdata_db=True) as cur:
cur.execute(sql)
dirs = cur.fetchall()
cur.close()
dirs = [_dir[0] for _dir in dirs]
return [win_replace_slash(d) for d in dirs]

View File

@ -32,7 +32,7 @@ def get_folders(paths: list[str]):
for track in TrackStore.tracks:
for path in paths:
if track.filepath.startswith(path):
if track.folder.startswith(path):
count_dict[path] += 1
folders = [{"path": path, "count": count_dict[path]} for path in paths]

View File

@ -131,6 +131,11 @@ def add_track(filepath: str) -> None:
Then creates the folder, album and artist objects for the added track and adds them to the store.
"""
# remove the track if it already exists
TrackStore.remove_track_by_filepath(filepath)
db.remove_track_by_filepath(filepath)
# add the track to the database and store.
tags = get_tags(filepath)
if tags is None:
@ -253,7 +258,11 @@ class Handler(PatternMatchingEventHandler):
if os.path.getsize(event.src_path) > 0:
path = self.get_abs_path(event.src_path)
add_track(path)
except FileNotFoundError:
# file was closed and deleted.
pass
except ValueError:
# file was removed from the list by another event handler.
pass
def on_modified(self, event):

View File

@ -42,7 +42,7 @@ class Track:
self.og_album = self.album
if self.artist is not None:
artists = split_artists(self.artist)
artists = split_artists(self.artist, with_and=True)
new_title = self.title
if get_flag(ParserFlags.EXTRACT_FEAT):
@ -71,7 +71,7 @@ class Track:
self.artist_hashes = "-".join(create_hash(a, decode=True) for a in artists)
self.artist = [ArtistMinimal(a) for a in artists]
albumartists = split_artists(self.albumartist)
albumartists = split_artists(self.albumartist, with_and=True)
self.albumartist = [ArtistMinimal(a) for a in albumartists]
self.filetype = self.filepath.rsplit(".", maxsplit=1)[-1]

View File

@ -5,6 +5,8 @@ args = ALLARGS
HELP_MESSAGE = f"""
Usage: swingmusic [options]
Swing Music is a beautiful, self-hosted music player for your local audio files. Like a cooler Spotify ... but bring your own music.
Options:
{', '.join(args.help.value)}: Show this help message
{', '.join(args.version.value)}: Show the app version

View File

@ -1,4 +1,4 @@
from app.models import Track, Album, Artist
from app.models import Album, Artist, Track
def recent_fav_track_serializer(track: Track) -> dict:
@ -21,8 +21,9 @@ def recent_fav_album_serializer(album: Album) -> dict:
"""
return {
"image": album.image,
"title": album.title,
"title": album.og_title,
"albumhash": album.albumhash,
"artist": album.albumartists[0].name,
"colors": album.colors,
}

View File

@ -8,7 +8,7 @@ join = os.path.join
class Release:
APP_VERSION = "v1.2.1"
APP_VERSION = "1.3.0.beta"
class Paths:

View File

@ -6,7 +6,7 @@ def split_artists(src: str, with_and: bool = False):
"""
Splits a string of artists into a list of artists.
"""
exp = r"\s*(?: and |&|,|;)\s*" if with_and else r"\s*[,;]\s*"
exp = r"\s*(?: and |&|,|;|/)\s*" if with_and else r"\s*[,;]\s*"
artists = re.split(exp, src)
return [a.strip() for a in artists]
@ -245,3 +245,21 @@ def clean_title(title: str) -> str:
#
# if "-" in title:
# return remove_hyphen_remasters(title)
# Traceback (most recent call last):
# File "/usr/lib/python3.10/threading.py", line 1016, in _bootstrap_inner
# self.run()
# File "/usr/lib/python3.10/threading.py", line 953, in run
# self._target(*self._args, **self._kwargs)
# File "/home/cwilvx/code/swingmusic/app/periodic_scan.py", line 29, in run_periodic_scans
# Populate(key=get_random_str())
# File "/home/cwilvx/code/swingmusic/app/lib/populate.py", line 74, in __init__
# self.tag_untagged(untagged, key)
# File "/home/cwilvx/code/swingmusic/app/lib/populate.py", line 123, in tag_untagged
# insert_many_tracks(tagged_tracks)
# File "/home/cwilvx/code/swingmusic/app/db/sqlite/tracks.py", line 54, in insert_many_tracks
# cls.insert_one_track(track, cur)
# File "/home/cwilvx/code/swingmusic/app/db/sqlite/tracks.py", line 45, in insert_one_track
# cur.execute(sql, track)
# sqlite3.IntegrityError: UNIQUE constraint failed: tracks.filepath