save track logs to logged in user

+ rewrite migration collection
+ prevent logging invalid track logs
+ add jsoni
This commit is contained in:
cwilvx
2024-05-18 17:16:07 +03:00
parent f8f07c2116
commit 30768dd5d6
10 changed files with 160 additions and 42 deletions
+3 -1
View File
@@ -68,7 +68,9 @@ def create_api():
app.config["JWT_TOKEN_LOCATION"] = ["cookies"]
app.config["JWT_COOKIE_CSRF_PROTECT"] = False
app.config["JWT_SESSION_COOKIE"] = False
app.config["JWT_ACCESS_TOKEN_EXPIRES"] = int(datetime.timedelta(days=30).total_seconds())
jwt_expiry = int(datetime.timedelta(days=30).total_seconds())
app.config["JWT_ACCESS_TOKEN_EXPIRES"] = jwt_expiry
# CORS
CORS(app, origins="*", supports_credentials=True)
+10 -2
View File
@@ -1,3 +1,4 @@
from flask_jwt_extended import current_user
from flask_openapi3 import Tag
from flask_openapi3 import APIBlueprint
from pydantic import Field
@@ -31,8 +32,15 @@ def log_track(body: LogTrackBody):
duration = body.duration
source = body.source
if not timestamp or duration < 5:
return {"msg": "Invalid entry."}, 400
last_row = db.insert_track(
trackhash=trackhash, timestamp=timestamp, duration=duration, source=source
trackhash=trackhash,
timestamp=timestamp,
duration=duration,
source=source,
userid=current_user["id"],
)
return {"last_row": last_row}
return {"total entries": last_row}
+2 -2
View File
@@ -3,7 +3,7 @@ from app.db.sqlite.utils import SQLiteManager
class SQLiteTrackLogger:
@classmethod
def insert_track(cls, trackhash: str, duration: int, source: str, timestamp: int):
def insert_track(cls, trackhash: str, duration: int, source: str, timestamp: int, userid: int):
"""
Inserts a track into the database
"""
@@ -18,7 +18,7 @@ class SQLiteTrackLogger:
) VALUES(?,?,?,?,?)
"""
cur.execute(sql, (trackhash, duration, timestamp, source, 0))
cur.execute(sql, (trackhash, duration, timestamp, source, userid))
lastrowid = cur.lastrowid
return lastrowid
+19 -13
View File
@@ -4,24 +4,28 @@ Migrations module.
Reads and applies the latest database migrations.
"""
import inspect
from types import ModuleType
from app.db.sqlite.migrations import MigrationManager
from app.logger import log
from app.migrations import v1_3_0, v1_4_9
from app.migrations.base import Migration
migrations: list[list[Migration]] = [
[
# v1.3.0
v1_3_0.RemoveSmallThumbnailFolder,
v1_3_0.RemovePlaylistArtistHashes,
v1_3_0.AddSettingsToPlaylistTable,
v1_3_0.AddLastUpdatedToTrackTable,
v1_3_0.MovePlaylistsAndFavoritesTo10BitHashes,
v1_3_0.RemoveAllTracks,
v1_3_0.UpdateAppSettingsTable,
],
[v1_4_9.AddTimestampToFavoritesTable, v1_4_9.DeleteOriginalThumbnails],
]
def get_all_migrations(module: ModuleType) -> list[Migration]:
"""
Extracts all migration classes from a module.
"""
predicate = (
lambda obj: inspect.isclass(obj)
and issubclass(obj, Migration)
and obj.enabled
and obj.__module__ == module.__name__
)
# INFO: I couldn't find how to sort the classes in order of appearance
# so I just renamed them to be sortable by name
return [obj for name, obj in inspect.getmembers(module, predicate)]
def apply_migrations():
@@ -34,6 +38,8 @@ def apply_migrations():
migrations past that index are applied and the new length
is stored as the new migration index.
"""
modules = [v1_3_0, v1_4_9]
migrations = [get_all_migrations(m) for m in modules]
index = MigrationManager.get_index()
all_migrations = [migration for sublist in migrations for migration in sublist]
+1
View File
@@ -2,6 +2,7 @@ class Migration:
"""
Base migration class.
"""
enabled: bool = True
@staticmethod
def migrate():
+7 -7
View File
@@ -23,7 +23,7 @@ from app.utils.hashing import create_hash
# 6: trackhashes
class RemoveSmallThumbnailFolder(Migration):
class m1_RemoveSmallThumbnailFolder(Migration):
"""
Removes the small thumbnail folder.
@@ -45,7 +45,7 @@ class RemoveSmallThumbnailFolder(Migration):
os.makedirs(path, exist_ok=True)
class RemovePlaylistArtistHashes(Migration):
class m2_RemovePlaylistArtistHashes(Migration):
"""
removes the artisthashes column from the playlists table.
"""
@@ -64,7 +64,7 @@ class RemovePlaylistArtistHashes(Migration):
cur.close()
class AddSettingsToPlaylistTable(Migration):
class m3_AddSettingsToPlaylistTable(Migration):
"""
adds the settings column and removes the banner_pos and has_gif columns
to the playlists table.
@@ -141,7 +141,7 @@ class AddSettingsToPlaylistTable(Migration):
cur.close()
class AddLastUpdatedToTrackTable(Migration):
class m4_AddLastUpdatedToTrackTable(Migration):
"""
adds the last modified column to the tracks table.
"""
@@ -161,7 +161,7 @@ class AddLastUpdatedToTrackTable(Migration):
cur.close()
class MovePlaylistsAndFavoritesTo10BitHashes(Migration):
class m5_MovePlaylistsAndFavoritesTo10BitHashes(Migration):
"""
moves the playlists and favorites to 10 bit hashes.
"""
@@ -268,7 +268,7 @@ class MovePlaylistsAndFavoritesTo10BitHashes(Migration):
cur.close()
class RemoveAllTracks(Migration):
class m6_RemoveAllTracks(Migration):
"""
removes all tracks from the tracks table.
"""
@@ -282,7 +282,7 @@ class RemoveAllTracks(Migration):
cur.close()
class UpdateAppSettingsTable(Migration):
class m7_UpdateAppSettingsTable(Migration):
@staticmethod
def migrate():
drop_table_sql = "DROP TABLE settings"
+13 -14
View File
@@ -5,7 +5,7 @@ from app.migrations.base import Migration
from app.settings import Paths
class AddTimestampToFavoritesTable(Migration):
class _1AddTimestampToFavoritesTable(Migration):
"""
Adds a timestamp column to the favorites table.
"""
@@ -30,7 +30,7 @@ class AddTimestampToFavoritesTable(Migration):
cur.close()
class MoveHashesToSha1(Migration):
class _4MoveHashesToSha1(Migration):
"""
Moves the 10 bit item hashes from sha256 to sha1 which is
faster and more lenient on less powerful devices.
@@ -38,13 +38,15 @@ class MoveHashesToSha1(Migration):
Thanks to [@tcsenpai](https:github.com/tcsenpai) for the contribution.
"""
enabled: bool = False
pass
# INFO: Apparentlly, every single table is affected by this migration.
# NOTE: Use generators to avoid memory issues.
class DeleteOriginalThumbnails(Migration):
class _2DeleteOriginalThumbnails(Migration):
"""
Original thumbnails are too large and are not needed.
"""
@@ -59,18 +61,15 @@ class DeleteOriginalThumbnails(Migration):
if os.path.exists(og_imgpath):
shutil.rmtree(og_imgpath)
class DeleteOriginalThumbnailsa(Migration):
"""
Original thumbnails are too large and are not needed.
"""
# TODO: Implement this migration
class _3MoveScrobbleToUserId1(Migration):
"""
Updates all track logs from user id = 0 to user id = 1
"""
@staticmethod
def migrate():
imgpath = Paths.get_thumbs_path()
og_imgpath = os.path.join(imgpath, "original")
if os.path.exists(og_imgpath):
shutil.rmtree(og_imgpath)
# INFO: Move the scrobble table to the user id 1
with SQLiteManager(userdata_db=True) as cur:
cur.execute("UPDATE track_logger SET userid = 1 WHERE userid = 0")
cur.close()