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_type: str = "contains"
|
||||||
path: Optional[str] = None
|
path: Optional[str] = None
|
||||||
last_played_number: Optional[int] = None
|
last_played_number: Optional[int] = None
|
||||||
last_played_type: str = "before"
|
last_played_comparator: str = "before"
|
||||||
last_played_unit: str = "years"
|
last_played_unit: str = "years"
|
||||||
duration_type: str = "longer than"
|
duration_type: str = "longer than"
|
||||||
duration_number: int = 0
|
duration_number: int = 0
|
||||||
|
|||||||
@ -39,6 +39,7 @@ class Config(object):
|
|||||||
DISPLAY_SQL = False
|
DISPLAY_SQL = False
|
||||||
DO_NOT_IMPORT = "Do not import"
|
DO_NOT_IMPORT = "Do not import"
|
||||||
ENGINE_OPTIONS = dict(pool_pre_ping=True)
|
ENGINE_OPTIONS = dict(pool_pre_ping=True)
|
||||||
|
# ENGINE_OPTIONS = dict(pool_pre_ping=True, echo=True)
|
||||||
EPOCH = dt.datetime(1970, 1, 1)
|
EPOCH = dt.datetime(1970, 1, 1)
|
||||||
ERRORS_FROM = ["noreply@midnighthax.com"]
|
ERRORS_FROM = ["noreply@midnighthax.com"]
|
||||||
ERRORS_TO = ["kae@midnighthax.com"]
|
ERRORS_TO = ["kae@midnighthax.com"]
|
||||||
@ -55,10 +56,11 @@ class Config(object):
|
|||||||
FILTER_DURATION_SHORTER = "shorter than"
|
FILTER_DURATION_SHORTER = "shorter than"
|
||||||
FILTER_PATH_CONTAINS = "contains"
|
FILTER_PATH_CONTAINS = "contains"
|
||||||
FILTER_PATH_EXCLUDING = "excluding"
|
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_DAYS = "days"
|
||||||
FILTER_PLAYED_MONTHS = "months"
|
FILTER_PLAYED_MONTHS = "months"
|
||||||
FILTER_PLAYED_NEVER = "never"
|
|
||||||
FILTER_PLAYED_WEEKS = "weeks"
|
FILTER_PLAYED_WEEKS = "weeks"
|
||||||
FILTER_PLAYED_YEARS = "years"
|
FILTER_PLAYED_YEARS = "years"
|
||||||
FUZZYMATCH_MINIMUM_LIST = 60.0
|
FUZZYMATCH_MINIMUM_LIST = 60.0
|
||||||
|
|||||||
@ -599,7 +599,11 @@ class PlaylistRows(dbtables.PlaylistRowsTable):
|
|||||||
|
|
||||||
class Queries(dbtables.QueriesTable):
|
class Queries(dbtables.QueriesTable):
|
||||||
def __init__(
|
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:
|
) -> None:
|
||||||
"""Create new query"""
|
"""Create new query"""
|
||||||
|
|
||||||
@ -620,9 +624,7 @@ class Queries(dbtables.QueriesTable):
|
|||||||
"""Returns a list of favourite queries ordered by name"""
|
"""Returns a list of favourite queries ordered by name"""
|
||||||
|
|
||||||
return session.scalars(
|
return session.scalars(
|
||||||
select(cls)
|
select(cls).where(cls.favourite.is_(True)).order_by(cls.name)
|
||||||
.where(cls.favourite.is_(True))
|
|
||||||
.order_by(cls.name)
|
|
||||||
).all()
|
).all()
|
||||||
|
|
||||||
|
|
||||||
@ -711,12 +713,16 @@ class Tracks(dbtables.TracksTable):
|
|||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@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
|
Return tracks matching filter
|
||||||
"""
|
"""
|
||||||
|
|
||||||
query = select(cls)
|
query = select(cls)
|
||||||
|
|
||||||
|
# Path specification
|
||||||
if filter.path:
|
if filter.path:
|
||||||
if filter.path_type == "contains":
|
if filter.path_type == "contains":
|
||||||
query = query.where(cls.path.ilike(f"%{filter.path}%"))
|
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}%"))
|
query = query.where(cls.path.notilike(f"%{filter.path}%"))
|
||||||
else:
|
else:
|
||||||
raise ApplicationError(f"Can't process filter path ({filter=})")
|
raise ApplicationError(f"Can't process filter path ({filter=})")
|
||||||
# TODO
|
|
||||||
# if last_played_number:
|
# Duration specification
|
||||||
# need group_by track_id and having max/min lastplayed gt/lt, etc
|
|
||||||
seconds_duration = filter.duration_number
|
seconds_duration = filter.duration_number
|
||||||
if filter.duration_unit == Config.FILTER_DURATION_MINUTES:
|
if filter.duration_unit == Config.FILTER_DURATION_MINUTES:
|
||||||
seconds_duration *= 60
|
seconds_duration *= 60
|
||||||
elif filter.duration_unit != Config.FILTER_DURATION_SECONDS:
|
elif filter.duration_unit != Config.FILTER_DURATION_SECONDS:
|
||||||
raise ApplicationError(f"Can't process filter duration ({filter=})")
|
raise ApplicationError(f"Can't process filter duration ({filter=})")
|
||||||
|
|
||||||
if filter.duration_type == Config.FILTER_DURATION_LONGER:
|
if filter.duration_type == Config.FILTER_DURATION_LONGER:
|
||||||
query = query.where(cls.duration >= seconds_duration)
|
query = query.where(cls.duration >= seconds_duration)
|
||||||
elif filter.duration_unit == Config.FILTER_DURATION_SHORTER:
|
elif filter.duration_unit == Config.FILTER_DURATION_SHORTER:
|
||||||
@ -739,8 +745,41 @@ class Tracks(dbtables.TracksTable):
|
|||||||
else:
|
else:
|
||||||
raise ApplicationError(f"Can't process filter duration type ({filter=})")
|
raise ApplicationError(f"Can't process filter duration type ({filter=})")
|
||||||
|
|
||||||
records = session.scalars(
|
# Last played specification
|
||||||
query).unique().all()
|
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
|
return records
|
||||||
|
|
||||||
|
|||||||
@ -48,7 +48,6 @@ from PyQt6.QtWidgets import (
|
|||||||
QMenu,
|
QMenu,
|
||||||
QMessageBox,
|
QMessageBox,
|
||||||
QPushButton,
|
QPushButton,
|
||||||
QSizePolicy,
|
|
||||||
QSpinBox,
|
QSpinBox,
|
||||||
QTableView,
|
QTableView,
|
||||||
QTableWidget,
|
QTableWidget,
|
||||||
@ -215,10 +214,14 @@ class FilterDialog(QDialog):
|
|||||||
last_played_label = QLabel("Last played")
|
last_played_label = QLabel("Last played")
|
||||||
self.last_played_combo = QComboBox()
|
self.last_played_combo = QComboBox()
|
||||||
self.last_played_combo.addItems(
|
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()):
|
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)
|
self.last_played_combo.setCurrentIndex(idx)
|
||||||
break
|
break
|
||||||
|
|
||||||
@ -316,7 +319,7 @@ class FilterDialog(QDialog):
|
|||||||
self.filter.path_type = self.path_combo.currentText()
|
self.filter.path_type = self.path_combo.currentText()
|
||||||
self.filter.path = self.path_text.text()
|
self.filter.path = self.path_text.text()
|
||||||
self.filter.last_played_number = self.last_played_spinbox.value()
|
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.last_played_unit = self.last_played_unit.currentText()
|
||||||
self.filter.duration_type = self.duration_combo.currentText()
|
self.filter.duration_type = self.duration_combo.currentText()
|
||||||
self.filter.duration_number = self.duration_spinbox.value()
|
self.filter.duration_number = self.duration_spinbox.value()
|
||||||
|
|||||||
@ -230,8 +230,9 @@ class QuerylistModel(QAbstractTableModel):
|
|||||||
try:
|
try:
|
||||||
results = Tracks.get_filtered_tracks(self.session, self.filter)
|
results = Tracks.get_filtered_tracks(self.session, self.filter)
|
||||||
for result in results:
|
for result in results:
|
||||||
if hasattr(result, "lastplayed"):
|
if hasattr(result, "playdates"):
|
||||||
lastplayed = result["lastplayed"]
|
pds = result.playdates
|
||||||
|
lastplayed = max([a.lastplayed for a in pds])
|
||||||
else:
|
else:
|
||||||
lastplayed = None
|
lastplayed = None
|
||||||
queryrow = QueryRow(
|
queryrow = QueryRow(
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user