mirror of
https://github.com/Dvorinka/swingmusic-extended.git
synced 2026-06-04 20:43:04 +00:00
move to xxh3 hashing algorithm
+ port: search
This commit is contained in:
+50
-20
@@ -14,7 +14,7 @@ from app.models import Album as AlbumModel
|
||||
from app.utils.remove_duplicates import remove_duplicates
|
||||
from app.db import engine
|
||||
|
||||
from sqlalchemy import JSON, Boolean, Integer, String, and_, delete, select, update
|
||||
from sqlalchemy import JSON, Boolean, Integer, String, delete, select, update
|
||||
from sqlalchemy.orm import Mapped, mapped_column, DeclarativeBase
|
||||
|
||||
|
||||
@@ -32,16 +32,26 @@ class Base(MasterBase, DeclarativeBase):
|
||||
@classmethod
|
||||
def get_all_hashes(cls, create_date: int | None = None):
|
||||
with DbManager() as conn:
|
||||
if cls.__tablename__ == "track":
|
||||
stmt = select(TrackTable.trackhash).where(cls.last_mod < create_date)
|
||||
elif cls.__tablename__ == "album":
|
||||
stmt = select(AlbumTable.albumhash).where(
|
||||
cls.created_date < create_date
|
||||
)
|
||||
elif cls.__tablename__ == "artist":
|
||||
stmt = select(ArtistTable.artisthash).where(
|
||||
cls.created_date < create_date
|
||||
)
|
||||
if create_date:
|
||||
if cls.__tablename__ == "track":
|
||||
stmt = select(TrackTable.trackhash).where(
|
||||
cls.last_mod < create_date
|
||||
)
|
||||
elif cls.__tablename__ == "album":
|
||||
stmt = select(AlbumTable.albumhash).where(
|
||||
cls.created_date < create_date
|
||||
)
|
||||
elif cls.__tablename__ == "artist":
|
||||
stmt = select(ArtistTable.artisthash).where(
|
||||
cls.created_date < create_date
|
||||
)
|
||||
else:
|
||||
if cls.__tablename__ == "track":
|
||||
stmt = select(TrackTable.trackhash)
|
||||
elif cls.__tablename__ == "album":
|
||||
stmt = select(AlbumTable.albumhash)
|
||||
elif cls.__tablename__ == "artist":
|
||||
stmt = select(ArtistTable.artisthash)
|
||||
|
||||
result = conn.execute(stmt)
|
||||
return {row[0] for row in result.fetchall()}
|
||||
@@ -135,7 +145,9 @@ class TrackTable(Base):
|
||||
def get_tracks_by_filepaths(cls, filepaths: list[str]):
|
||||
with DbManager() as conn:
|
||||
result = conn.execute(
|
||||
select(TrackTable).where(TrackTable.filepath.in_(filepaths))
|
||||
select(TrackTable)
|
||||
.where(TrackTable.filepath.in_(filepaths))
|
||||
.order_by(TrackTable.last_mod)
|
||||
)
|
||||
return tracks_to_dataclasses(result.fetchall())
|
||||
|
||||
@@ -155,10 +167,8 @@ class TrackTable(Base):
|
||||
result = conn.execute(
|
||||
select(TrackTable)
|
||||
.where(
|
||||
and_(
|
||||
TrackTable.trackhash == hash,
|
||||
TrackTable.filepath == filepath,
|
||||
)
|
||||
(TrackTable.trackhash == hash)
|
||||
& (TrackTable.filepath == filepath),
|
||||
)
|
||||
.order_by(TrackTable.bitrate.desc())
|
||||
)
|
||||
@@ -194,9 +204,18 @@ class TrackTable(Base):
|
||||
def get_tracks_by_trackhashes(cls, hashes: Iterable[str], limit: int | None = None):
|
||||
with DbManager() as conn:
|
||||
result = conn.execute(
|
||||
select(TrackTable).where(TrackTable.trackhash.in_(hashes)).limit(limit)
|
||||
select(TrackTable)
|
||||
.where(TrackTable.trackhash.in_(hashes))
|
||||
.group_by(TrackTable.trackhash)
|
||||
.limit(limit)
|
||||
)
|
||||
return tracks_to_dataclasses(result.fetchall())
|
||||
tracks = tracks_to_dataclasses(result.fetchall())
|
||||
|
||||
# order the tracks in the same order as the hashes
|
||||
if type(hashes) == list:
|
||||
return sorted(tracks, key=lambda x: hashes.index(x.trackhash))
|
||||
|
||||
return tracks
|
||||
|
||||
@classmethod
|
||||
def get_recently_added(cls, start: int, limit: int):
|
||||
@@ -212,7 +231,12 @@ class TrackTable(Base):
|
||||
|
||||
@classmethod
|
||||
def get_recently_played(cls, limit: int):
|
||||
result = cls.execute(select(cls).order_by(cls.lastplayed.desc()).limit(limit))
|
||||
result = cls.execute(
|
||||
select(cls)
|
||||
.group_by(cls.trackhash)
|
||||
.order_by(cls.lastplayed.desc())
|
||||
.limit(limit)
|
||||
)
|
||||
return tracks_to_dataclasses(result.fetchall())
|
||||
|
||||
@classmethod
|
||||
@@ -276,7 +300,13 @@ class AlbumTable(Base):
|
||||
result = conn.execute(
|
||||
select(AlbumTable).where(AlbumTable.albumhash.in_(hashes)).limit(limit)
|
||||
)
|
||||
return albums_to_dataclasses(result.fetchall())
|
||||
albums = albums_to_dataclasses(result.fetchall())
|
||||
|
||||
# order the albums in the same order as the hashes
|
||||
if type(hashes) == list:
|
||||
return sorted(albums, key=lambda x: hashes.index(x.albumhash))
|
||||
|
||||
return albums
|
||||
|
||||
@classmethod
|
||||
def get_albums_by_artisthashes(cls, artisthashes: list[str]):
|
||||
|
||||
+50
-14
@@ -1,7 +1,7 @@
|
||||
import datetime
|
||||
import enum
|
||||
from shlex import join
|
||||
from typing import Any
|
||||
from flask_jwt_extended import current_user
|
||||
from sqlalchemy import (
|
||||
JSON,
|
||||
Boolean,
|
||||
@@ -313,36 +313,41 @@ class PlaylistTable(Base):
|
||||
|
||||
@classmethod
|
||||
def append_to_playlist(cls, id: int, trackhashes: list[str]):
|
||||
print("type(trackhashes):", type(trackhashes))
|
||||
dbtrackhashes = cls.get_trackhashes(id)
|
||||
if not dbtrackhashes:
|
||||
dbtrackhashes = []
|
||||
|
||||
return cls.execute(
|
||||
update(cls)
|
||||
.where((cls.id == id) & (cls.userid == get_current_userid()))
|
||||
.values(trackhashes=cls.trackhashes + trackhashes),
|
||||
.values(trackhashes=dbtrackhashes + trackhashes),
|
||||
commit=True,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def remove_from_playlist(cls, id: int, trackhashes: list[dict[str, Any]]):
|
||||
# CHECKPOINT: Properly remove tracks from a playlist
|
||||
# Without messing up the order in case of duplicates
|
||||
tracks = cls.execute(
|
||||
def get_trackhashes(cls, id: int) -> list[str]:
|
||||
result = cls.execute(
|
||||
select(cls.trackhashes).where(
|
||||
(cls.id == id) & (cls.userid == get_current_userid())
|
||||
)
|
||||
)
|
||||
result = result.fetchone()
|
||||
if result:
|
||||
return result[0]
|
||||
|
||||
results = tracks.fetchone()
|
||||
if results:
|
||||
dbhashes: list[str] = results[0]
|
||||
|
||||
@classmethod
|
||||
def remove_from_playlist(cls, id: int, trackhashes: list[dict[str, Any]]):
|
||||
# INFO: Get db trackhashes
|
||||
dbtrackhashes = cls.get_trackhashes(id)
|
||||
if dbtrackhashes:
|
||||
for item in trackhashes:
|
||||
if dbhashes.index(item["trackhash"]) == item["index"]:
|
||||
dbhashes.remove(item["trackhash"])
|
||||
if dbtrackhashes.index(item["trackhash"]) == item["index"]:
|
||||
dbtrackhashes.remove(item["trackhash"])
|
||||
|
||||
return cls.execute(
|
||||
update(cls)
|
||||
.where((cls.id == id) & (cls.userid == get_current_userid()))
|
||||
.values(trackhashes=dbhashes),
|
||||
.values(trackhashes=dbtrackhashes),
|
||||
commit=True,
|
||||
)
|
||||
|
||||
@@ -381,3 +386,34 @@ class PlaylistTable(Base):
|
||||
.values(image=None),
|
||||
commit=True,
|
||||
)
|
||||
|
||||
|
||||
# class PlaylistTrackTable(Base):
|
||||
# __tablename__ = "playlisttrack"
|
||||
|
||||
# id: Mapped[int] = mapped_column(primary_key=True)
|
||||
# trackhash: Mapped[str] = mapped_column(String(), index=True)
|
||||
# playlistid: Mapped[int] = mapped_column(
|
||||
# Integer(), ForeignKey("playlist.id", ondelete="cascade")
|
||||
# )
|
||||
# index: Mapped[int] = mapped_column(Integer())
|
||||
# userid: Mapped[int] = mapped_column(
|
||||
# Integer(), ForeignKey("user.id", ondelete="cascade")
|
||||
# )
|
||||
|
||||
# @classmethod
|
||||
# def count_by_playlist()
|
||||
|
||||
# @classmethod
|
||||
# def insert_many(cls, playlistid: int, trackhashes: list[str]):
|
||||
# userid = get_current_userid()
|
||||
# items = [
|
||||
# {
|
||||
# "index": index,
|
||||
# "userid": userid,
|
||||
# "trackhash": trackhash,
|
||||
# "playlistid": playlistid,
|
||||
# }
|
||||
# for index, trackhash in enumerate(trackhashes)
|
||||
# ]
|
||||
# return cls.execute(insert(cls).values(items), commit=True)
|
||||
|
||||
Reference in New Issue
Block a user