Select from query working (may need tidying)
This commit is contained in:
parent
8e48d63ebb
commit
67c48f5022
@ -84,7 +84,7 @@ class Filter:
|
||||
path_type: str = "contains"
|
||||
path: Optional[str] = None
|
||||
last_played_number: Optional[int] = None
|
||||
last_played_type: str = "before"
|
||||
last_played_comparator: str = "before"
|
||||
last_played_unit: str = "years"
|
||||
duration_type: str = "longer than"
|
||||
duration_number: int = 0
|
||||
|
||||
@ -39,6 +39,7 @@ class Config(object):
|
||||
DISPLAY_SQL = False
|
||||
DO_NOT_IMPORT = "Do not import"
|
||||
ENGINE_OPTIONS = dict(pool_pre_ping=True)
|
||||
# ENGINE_OPTIONS = dict(pool_pre_ping=True, echo=True)
|
||||
EPOCH = dt.datetime(1970, 1, 1)
|
||||
ERRORS_FROM = ["noreply@midnighthax.com"]
|
||||
ERRORS_TO = ["kae@midnighthax.com"]
|
||||
@ -55,10 +56,11 @@ class Config(object):
|
||||
FILTER_DURATION_SHORTER = "shorter than"
|
||||
FILTER_PATH_CONTAINS = "contains"
|
||||
FILTER_PATH_EXCLUDING = "excluding"
|
||||
FILTER_PLAYED_BEFORE = "before"
|
||||
FILTER_PLAYED_COMPARATOR_ANYTIME = "Any time"
|
||||
FILTER_PLAYED_COMPARATOR_BEFORE = "before"
|
||||
FILTER_PLAYED_COMPARATOR_NEVER = "never"
|
||||
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
|
||||
|
||||
@ -599,7 +599,11 @@ class PlaylistRows(dbtables.PlaylistRowsTable):
|
||||
|
||||
class Queries(dbtables.QueriesTable):
|
||||
def __init__(
|
||||
self, session: Session, name: str, filter: dbtables.Filter, favourite: bool = False
|
||||
self,
|
||||
session: Session,
|
||||
name: str,
|
||||
filter: dbtables.Filter,
|
||||
favourite: bool = False,
|
||||
) -> None:
|
||||
"""Create new query"""
|
||||
|
||||
@ -620,9 +624,7 @@ class Queries(dbtables.QueriesTable):
|
||||
"""Returns a list of favourite queries ordered by name"""
|
||||
|
||||
return session.scalars(
|
||||
select(cls)
|
||||
.where(cls.favourite.is_(True))
|
||||
.order_by(cls.name)
|
||||
select(cls).where(cls.favourite.is_(True)).order_by(cls.name)
|
||||
).all()
|
||||
|
||||
|
||||
@ -711,12 +713,16 @@ class Tracks(dbtables.TracksTable):
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_filtered_tracks(cls, session: Session, filter: Filter) -> Sequence["Tracks"]:
|
||||
def get_filtered_tracks(
|
||||
cls, session: Session, filter: Filter
|
||||
) -> Sequence["Tracks"]:
|
||||
"""
|
||||
Return tracks matching filter
|
||||
"""
|
||||
|
||||
query = select(cls)
|
||||
|
||||
# Path specification
|
||||
if filter.path:
|
||||
if filter.path_type == "contains":
|
||||
query = query.where(cls.path.ilike(f"%{filter.path}%"))
|
||||
@ -724,14 +730,14 @@ class Tracks(dbtables.TracksTable):
|
||||
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
|
||||
|
||||
# Duration specification
|
||||
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:
|
||||
@ -739,8 +745,41 @@ class Tracks(dbtables.TracksTable):
|
||||
else:
|
||||
raise ApplicationError(f"Can't process filter duration type ({filter=})")
|
||||
|
||||
records = session.scalars(
|
||||
query).unique().all()
|
||||
# Last played specification
|
||||
if (
|
||||
filter.last_played_number
|
||||
and filter.last_played_comparator != Config.FILTER_PLAYED_COMPARATOR_ANYTIME
|
||||
):
|
||||
now = dt.datetime.now()
|
||||
since = now - dt.timedelta(days=365 * filter.last_played_number)
|
||||
if filter.duration_unit == Config.FILTER_PLAYED_DAYS:
|
||||
since = now - dt.timedelta(days=filter.last_played_number)
|
||||
elif filter.duration_unit == Config.FILTER_PLAYED_WEEKS:
|
||||
since = now - dt.timedelta(days=7 * filter.last_played_number)
|
||||
if filter.duration_unit == Config.FILTER_PLAYED_MONTHS:
|
||||
since = now - dt.timedelta(days=30 * filter.last_played_number)
|
||||
|
||||
if filter.last_played_comparator == Config.FILTER_PLAYED_COMPARATOR_NEVER:
|
||||
# Select tracks that have never been played
|
||||
query = query.outerjoin(Playdates, cls.id == Playdates.track_id).where(
|
||||
Playdates.id.is_(None)
|
||||
)
|
||||
elif (
|
||||
filter.last_played_comparator == Config.FILTER_PLAYED_COMPARATOR_BEFORE
|
||||
):
|
||||
subquery = (
|
||||
select(
|
||||
Playdates.track_id,
|
||||
func.max(Playdates.lastplayed).label("max_last_played"),
|
||||
)
|
||||
.group_by(Playdates.track_id)
|
||||
.subquery()
|
||||
)
|
||||
query = query.join(subquery, Tracks.id == subquery.c.track_id).where(
|
||||
subquery.c.max_last_played < since
|
||||
)
|
||||
|
||||
records = session.scalars(query).unique().all()
|
||||
|
||||
return records
|
||||
|
||||
|
||||
@ -48,7 +48,6 @@ from PyQt6.QtWidgets import (
|
||||
QMenu,
|
||||
QMessageBox,
|
||||
QPushButton,
|
||||
QSizePolicy,
|
||||
QSpinBox,
|
||||
QTableView,
|
||||
QTableWidget,
|
||||
@ -215,10 +214,14 @@ class FilterDialog(QDialog):
|
||||
last_played_label = QLabel("Last played")
|
||||
self.last_played_combo = QComboBox()
|
||||
self.last_played_combo.addItems(
|
||||
[Config.FILTER_PLAYED_BEFORE, Config.FILTER_PLAYED_NEVER]
|
||||
[
|
||||
Config.FILTER_PLAYED_COMPARATOR_BEFORE,
|
||||
Config.FILTER_PLAYED_COMPARATOR_NEVER,
|
||||
Config.FILTER_PLAYED_COMPARATOR_ANYTIME,
|
||||
]
|
||||
)
|
||||
for idx in range(self.last_played_combo.count()):
|
||||
if self.last_played_combo.itemText(idx) == filter.last_played_type:
|
||||
if self.last_played_combo.itemText(idx) == filter.last_played_comparator:
|
||||
self.last_played_combo.setCurrentIndex(idx)
|
||||
break
|
||||
|
||||
@ -316,7 +319,7 @@ class FilterDialog(QDialog):
|
||||
self.filter.path_type = self.path_combo.currentText()
|
||||
self.filter.path = self.path_text.text()
|
||||
self.filter.last_played_number = self.last_played_spinbox.value()
|
||||
self.filter.last_played_type = self.last_played_combo.currentText()
|
||||
self.filter.last_played_comparator = self.last_played_combo.currentText()
|
||||
self.filter.last_played_unit = self.last_played_unit.currentText()
|
||||
self.filter.duration_type = self.duration_combo.currentText()
|
||||
self.filter.duration_number = self.duration_spinbox.value()
|
||||
|
||||
@ -230,8 +230,9 @@ class QuerylistModel(QAbstractTableModel):
|
||||
try:
|
||||
results = Tracks.get_filtered_tracks(self.session, self.filter)
|
||||
for result in results:
|
||||
if hasattr(result, "lastplayed"):
|
||||
lastplayed = result["lastplayed"]
|
||||
if hasattr(result, "playdates"):
|
||||
pds = result.playdates
|
||||
lastplayed = max([a.lastplayed for a in pds])
|
||||
else:
|
||||
lastplayed = None
|
||||
queryrow = QueryRow(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user