Compare commits

..

No commits in common. "8e48d63ebb5d56f00609db49c6ee680d79e78c26" and "b4f5d92f5dde358a85fa9669e256a7dbd002aef7" have entirely different histories.

9 changed files with 257 additions and 669 deletions

View File

@ -80,7 +80,6 @@ class FileErrors(NamedTuple):
@dataclass @dataclass
class Filter: class Filter:
version: int = 1
path_type: str = "contains" path_type: str = "contains"
path: Optional[str] = None path: Optional[str] = None
last_played_number: Optional[int] = None last_played_number: Optional[int] = None

View File

@ -49,18 +49,6 @@ class Config(object):
FADEOUT_DB = -10 FADEOUT_DB = -10
FADEOUT_SECONDS = 5 FADEOUT_SECONDS = 5
FADEOUT_STEPS_PER_SECOND = 5 FADEOUT_STEPS_PER_SECOND = 5
FILTER_DURATION_LONGER = "longer than"
FILTER_DURATION_MINUTES = "minutes"
FILTER_DURATION_SECONDS = "seconds"
FILTER_DURATION_SHORTER = "shorter than"
FILTER_PATH_CONTAINS = "contains"
FILTER_PATH_EXCLUDING = "excluding"
FILTER_PLAYED_BEFORE = "before"
FILTER_PLAYED_DAYS = "days"
FILTER_PLAYED_MONTHS = "months"
FILTER_PLAYED_NEVER = "never"
FILTER_PLAYED_WEEKS = "weeks"
FILTER_PLAYED_YEARS = "years"
FUZZYMATCH_MINIMUM_LIST = 60.0 FUZZYMATCH_MINIMUM_LIST = 60.0
FUZZYMATCH_MINIMUM_SELECT_ARTIST = 80.0 FUZZYMATCH_MINIMUM_SELECT_ARTIST = 80.0
FUZZYMATCH_MINIMUM_SELECT_TITLE = 80.0 FUZZYMATCH_MINIMUM_SELECT_TITLE = 80.0

View File

@ -154,7 +154,7 @@ class QueriesTable(Model):
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
name: Mapped[str] = mapped_column(String(128), nullable=False) name: Mapped[str] = mapped_column(String(128), nullable=False)
_filter_data: Mapped[dict | None] = mapped_column("filter_data", JSONEncodedDict, nullable=False) _filter_data: Mapped[dict | None] = mapped_column("filter_data", JSONEncodedDict, nullable=True)
favourite: Mapped[bool] = mapped_column(Boolean, nullable=False, index=False, default=False) favourite: Mapped[bool] = mapped_column(Boolean, nullable=False, index=False, default=False)
def _get_filter(self) -> Filter: def _get_filter(self) -> Filter:

View File

@ -10,7 +10,7 @@ import ssl
import tempfile import tempfile
# PyQt imports # PyQt imports
from PyQt6.QtWidgets import QInputDialog, QMainWindow, QMessageBox, QWidget from PyQt6.QtWidgets import QMainWindow, QMessageBox, QWidget
# Third party imports # Third party imports
from mutagen.flac import FLAC # type: ignore from mutagen.flac import FLAC # type: ignore
@ -150,23 +150,6 @@ def get_audio_metadata(filepath: str) -> AudioMetadata:
) )
def get_name(prompt: str, default: str = "") -> str | None:
"""Get a name from the user"""
dlg = QInputDialog()
dlg.setInputMode(QInputDialog.InputMode.TextInput)
dlg.setLabelText(prompt)
while True:
if default:
dlg.setTextValue(default)
dlg.resize(500, 100)
ok = dlg.exec()
if ok:
return dlg.textValue()
return None
def get_relative_date( def get_relative_date(
past_date: Optional[dt.datetime], reference_date: Optional[dt.datetime] = None past_date: Optional[dt.datetime], reference_date: Optional[dt.datetime] = None
) -> str: ) -> str:

View File

@ -4,10 +4,10 @@ menus:
- text: "Save as Template" - text: "Save as Template"
handler: "save_as_template" handler: "save_as_template"
- text: "Manage Templates" - text: "Manage Templates"
handler: "manage_templates_wrapper" handler: "manage_templates"
- separator: true - separator: true
- text: "Manage Queries" - text: "Manage Queries"
handler: "manage_queries_wrapper" handler: "manage_queries"
- separator: true - separator: true
- text: "Exit" - text: "Exit"
handler: "close" handler: "close"

View File

@ -25,7 +25,7 @@ from sqlalchemy.orm.session import Session
from sqlalchemy.engine.row import RowMapping from sqlalchemy.engine.row import RowMapping
# App imports # App imports
from classes import ApplicationError, Filter from classes import ApplicationError
from config import Config from config import Config
from dbmanager import DatabaseManager from dbmanager import DatabaseManager
import dbtables import dbtables
@ -610,21 +610,11 @@ class Queries(dbtables.QueriesTable):
session.commit() session.commit()
@classmethod @classmethod
def get_all(cls, session: Session) -> Sequence["Queries"]: def get_all_queries(cls, session: Session) -> Sequence["Queries"]:
"""Returns a list of all queries ordered by name""" """Returns a list of all queries ordered by name"""
return session.scalars(select(cls).order_by(cls.name)).all() return session.scalars(select(cls).order_by(cls.name)).all()
@classmethod
def get_favourites(cls, session: Session) -> Sequence["Queries"]:
"""Returns a list of favourite queries ordered by name"""
return session.scalars(
select(cls)
.where(cls.favourite.is_(True))
.order_by(cls.name)
).all()
class Settings(dbtables.SettingsTable): class Settings(dbtables.SettingsTable):
def __init__(self, session: Session, name: str) -> None: def __init__(self, session: Session, name: str) -> None:
@ -710,40 +700,6 @@ class Tracks(dbtables.TracksTable):
.all() .all()
) )
@classmethod
def get_filtered_tracks(cls, session: Session, filter: Filter) -> Sequence["Tracks"]:
"""
Return tracks matching filter
"""
query = select(cls)
if filter.path:
if filter.path_type == "contains":
query = query.where(cls.path.ilike(f"%{filter.path}%"))
elif filter.path_type == "excluding":
query = query.where(cls.path.notilike(f"%{filter.path}%"))
else:
raise ApplicationError(f"Can't process filter path ({filter=})")
# TODO
# if last_played_number:
# need group_by track_id and having max/min lastplayed gt/lt, etc
seconds_duration = filter.duration_number
if filter.duration_unit == Config.FILTER_DURATION_MINUTES:
seconds_duration *= 60
elif filter.duration_unit != Config.FILTER_DURATION_SECONDS:
raise ApplicationError(f"Can't process filter duration ({filter=})")
if filter.duration_type == Config.FILTER_DURATION_LONGER:
query = query.where(cls.duration >= seconds_duration)
elif filter.duration_unit == Config.FILTER_DURATION_SHORTER:
query = query.where(cls.duration <= seconds_duration)
else:
raise ApplicationError(f"Can't process filter duration type ({filter=})")
records = session.scalars(
query).unique().all()
return records
@classmethod @classmethod
def get_by_path(cls, session: Session, path: str) -> Optional["Tracks"]: def get_by_path(cls, session: Session, path: str) -> Optional["Tracks"]:
""" """

File diff suppressed because it is too large Load Diff

View File

@ -38,7 +38,7 @@ from helpers import (
show_warning, show_warning,
) )
from log import log from log import log
from models import db, Playdates, Tracks from models import db, Playdates
from music_manager import RowAndTrack from music_manager import RowAndTrack
@ -228,20 +228,20 @@ class QuerylistModel(QAbstractTableModel):
row = 0 row = 0
try: try:
results = Tracks.get_filtered_tracks(self.session, self.filter) results = Tracks.get_filtered(self.session, self.filter)
for result in results: for result in results:
if hasattr(result, "lastplayed"): if hasattr(result, "lastplayed"):
lastplayed = result["lastplayed"] lastplayed = result["lastplayed"]
else: else:
lastplayed = None lastplayed = None
queryrow = QueryRow( queryrow = QueryRow(
artist=result.artist, artist=result["artist"],
bitrate=result.bitrate or 0, bitrate=result["bitrate"],
duration=result.duration, duration=result["duration"],
lastplayed=lastplayed, lastplayed=lastplayed,
path=result.path, path=result["path"],
title=result.title, title=result["title"],
track_id=result.id, track_id=result["id"],
) )
self.querylist_rows[row] = queryrow self.querylist_rows[row] = queryrow

View File

@ -33,7 +33,7 @@ def upgrade_() -> None:
op.create_table('queries', op.create_table('queries',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False), sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('name', sa.String(length=128), nullable=False), sa.Column('name', sa.String(length=128), nullable=False),
sa.Column('filter_data', dbtables.JSONEncodedDict(), nullable=False), sa.Column('filter_data', dbtables.JSONEncodedDict(), nullable=True),
sa.Column('favourite', sa.Boolean(), nullable=False), sa.Column('favourite', sa.Boolean(), nullable=False),
sa.PrimaryKeyConstraint('id') sa.PrimaryKeyConstraint('id')
) )