Fix showing tracks from queries

This commit is contained in:
Keith Edmunds 2025-04-11 17:13:03 +01:00
parent f9c8541b17
commit 199abc9c0c
7 changed files with 284 additions and 328 deletions

View File

@ -80,12 +80,13 @@ class TrackDTO:
@dataclass @dataclass
class PlaylistRowDTO(TrackDTO): class PlaylistRowDTO:
note: str note: str
played: bool played: bool
playlist_id: int playlist_id: int
playlistrow_id: int playlistrow_id: int
row_number: int row_number: int
track: TrackDTO | None
@dataclass @dataclass

View File

@ -738,6 +738,9 @@ class Tracks(dbtables.TracksTable):
Return tracks matching filter Return tracks matching filter
""" """
# Now implemented in repostory.py
return []
query = select(cls) query = select(cls)
# Path specification # Path specification

View File

@ -1297,7 +1297,7 @@ class Window(QMainWindow):
if handler: if handler:
# Use a lambda to pass arguments to the function # Use a lambda to pass arguments to the function
action.triggered.connect(lambda _, h=handler, a=args: h(*a)) action.triggered.connect(lambda _, h=handler, a=args: h(a))
submenu.addAction(action) submenu.addAction(action)
break break
@ -1318,7 +1318,7 @@ class Window(QMainWindow):
{ {
"text": "Show all", "text": "Show all",
"handler": "create_playlist_from_template", "handler": "create_playlist_from_template",
"args": (0), "args": 0,
}, },
{ {
"separator": True, "separator": True,
@ -1829,15 +1829,16 @@ class Window(QMainWindow):
# Required directive on first line # Required directive on first line
f.write("#EXTM3U\n") f.write("#EXTM3U\n")
for playlistrow in repository.get_playlist_rows(playlist_id): for playlistrow in repository.get_playlist_rows(playlist_id):
f.write( if playlistrow.track:
"#EXTINF:" f.write(
f"{int(playlistrow.duration / 1000)}," "#EXTINF:"
f"{playlistrow.title} - " f"{int(playlistrow.track.duration / 1000)},"
f"{playlistrow.artist}" f"{playlistrow.track.title} - "
"\n" f"{playlistrow.track.artist}"
f"{playlistrow.path}" "\n"
"\n" f"{playlistrow.track.path}"
) "\n"
)
def fade(self, checked: bool = False) -> None: def fade(self, checked: bool = False) -> None:
"""Fade currently playing track""" """Fade currently playing track"""

View File

@ -52,17 +52,23 @@ class PlaylistRow:
self.start_time: dt.datetime | None = None self.start_time: dt.datetime | None = None
def __repr__(self) -> str: def __repr__(self) -> str:
track_id = None
if self.dto.track:
track_id = self.dto.track.track_id
return ( return (
f"<PlaylistRow(playlist_id={self.dto.playlist_id}, " f"<PlaylistRow(playlist_id={self.dto.playlist_id}, "
f"row_number={self.dto.row_number}, " f"row_number={self.dto.row_number}, "
f"playlistrow_id={self.dto.playlistrow_id}, " f"playlistrow_id={self.dto.playlistrow_id}, "
f"note={self.dto.note}, track_id={self.dto.track_id}>" f"note={self.dto.note}, track_id={track_id}>"
) )
# Expose TrackDTO fields as properties # Expose TrackDTO fields as properties
@property @property
def artist(self): def artist(self):
return self.dto.artist if self.dto.track:
return self.dto.track.artist
else:
return ""
@artist.setter @artist.setter
def artist(self, value: str) -> None: def artist(self, value: str) -> None:
@ -70,19 +76,31 @@ class PlaylistRow:
@property @property
def bitrate(self): def bitrate(self):
return self.dto.bitrate if self.dto.track:
return self.dto.track.bitrate
else:
return 0
@property @property
def duration(self): def duration(self):
return self.dto.duration if self.dto.track:
return self.dto.track.duration
else:
return 0
@property @property
def fade_at(self): def fade_at(self):
return self.dto.fade_at if self.dto.track:
return self.dto.track.fade_at
else:
return 0
@property @property
def intro(self): def intro(self):
return self.dto.intro if self.dto.track:
return self.dto.track.intro
else:
return 0
@intro.setter @intro.setter
def intro(self, value: int) -> None: def intro(self, value: int) -> None:
@ -90,23 +108,38 @@ class PlaylistRow:
@property @property
def lastplayed(self): def lastplayed(self):
return self.dto.lastplayed if self.dto.track:
return self.dto.track.lastplayed
else:
return None
@property @property
def path(self): def path(self):
return self.dto.path if self.dto.track:
return self.dto.track.path
else:
return ""
@property @property
def silence_at(self): def silence_at(self):
return self.dto.silence_at if self.dto.track:
return self.dto.track.silence_at
else:
return 0
@property @property
def start_gap(self): def start_gap(self):
return self.dto.start_gap if self.dto.track:
return self.dto.track.start_gap
else:
return 0
@property @property
def title(self): def title(self):
return self.dto.title if self.dto.track:
return self.dto.track.title
else:
return ""
@title.setter @title.setter
def title(self, value: str) -> None: def title(self, value: str) -> None:
@ -114,10 +147,13 @@ class PlaylistRow:
@property @property
def track_id(self): def track_id(self):
return self.dto.track_id if self.dto.track:
return self.dto.track.track_id
else:
return 0
@track_id.setter @track_id.setter
def track_id(self, value: int) -> None: def track_id(self, track_id: int) -> None:
""" """
Adding a track_id should only happen to a header row. Adding a track_id should only happen to a header row.
""" """
@ -125,6 +161,14 @@ class PlaylistRow:
if self.track_id > 0: if self.track_id > 0:
raise ApplicationError("Attempting to add track to row with existing track ({self=}") raise ApplicationError("Attempting to add track to row with existing track ({self=}")
repository.add_track_to_header(track_id)
# Need to update with track information
track = repository.track_by_id(track_id)
if track:
for attr, value in track.__dataclass_fields__.items():
setattr(self, attr, value)
# TODO: set up write access to track_id. Should only update if # TODO: set up write access to track_id. Should only update if
# track_id == 0. Need to update all other track fields at the # track_id == 0. Need to update all other track fields at the
# same time. # same time.

View File

@ -231,16 +231,11 @@ class QuerylistModel(QAbstractTableModel):
try: try:
results = repository.get_filtered_tracks(self.filter) results = repository.get_filtered_tracks(self.filter)
for result in results: for result in results:
lastplayed = None
if hasattr(result, "playdates"):
pds = result.playdates
if pds:
lastplayed = max([a.lastplayed for a in pds])
queryrow = QueryRow( queryrow = QueryRow(
artist=result.artist, artist=result.artist,
bitrate=result.bitrate or 0, bitrate=result.bitrate or 0,
duration=result.duration, duration=result.duration,
lastplayed=lastplayed, lastplayed=result.lastplayed,
path=result.path, path=result.path,
title=result.title, title=result.title,
track_id=result.track_id, track_id=result.track_id,

View File

@ -129,12 +129,10 @@ def remove_colour_substring(text: str) -> str:
# Track functions # Track functions
@log_call @log_call
def _tracks_where( def _tracks_where(query: BinaryExpression | ColumnElement[bool],) -> list[TrackDTO]:
query: BinaryExpression | ColumnElement[bool], """
filter_by_last_played: bool = False, filter_by_last_played: bool = False,
last_played_before: dt.datetime | None = None, last_played_before: dt.datetime | None = None,
) -> list[TrackDTO]:
"""
Return tracks selected by query Return tracks selected by query
""" """
@ -150,36 +148,23 @@ def _tracks_where(
.group_by(LatestPlaydate.track_id) .group_by(LatestPlaydate.track_id)
.subquery() .subquery()
) )
if not filter_by_last_played: stmt = (
query = query.outerjoin( select(
latest_playdate_subq, Tracks.id == latest_playdate_subq.c.track_id Tracks.id.label("track_id"),
Tracks.artist,
Tracks.bitrate,
Tracks.duration,
Tracks.fade_at,
Tracks.intro,
Tracks.path,
Tracks.silence_at,
Tracks.start_gap,
Tracks.title,
latest_playdate_subq.c.lastplayed,
) )
else: .outerjoin(latest_playdate_subq, Tracks.id == latest_playdate_subq.c.track_id)
# We are filtering by last played. If last_played_before is None, .where(query)
# we want tracks that have never been played )
if last_played_before is None:
query = query.outerjoin(Playdates, Tracks.id == Playdates.track_id).where(
Playdates.id.is_(None)
)
else:
query = query.join(
latest_playdate_subq, Tracks.id == latest_playdate_subq.c.track_id
).where(latest_playdate_subq.c.max_last_played < last_played_before)
pass
stmt = select(
Tracks.id.label("track_id"),
Tracks.artist,
Tracks.bitrate,
Tracks.duration,
Tracks.fade_at,
Tracks.intro,
Tracks.path,
Tracks.silence_at,
Tracks.start_gap,
Tracks.title,
latest_playdate_subq.c.lastplayed,
).where(query)
results: list[TrackDTO] = [] results: list[TrackDTO] = []
@ -252,6 +237,97 @@ def get_all_tracks() -> list[TrackDTO]:
return _tracks_where(Tracks.id > 0) return _tracks_where(Tracks.id > 0)
def get_filtered_tracks(filter: Filter) -> list[TrackDTO]:
"""
Return tracks matching filter
"""
query = select(Tracks)
# Path specification
if filter.path:
if filter.path_type == "contains":
query = query.where(Tracks.path.ilike(f"%{filter.path}%"))
elif filter.path_type == "excluding":
query = query.where(Tracks.path.notilike(f"%{filter.path}%"))
else:
raise ApplicationError(f"Can't process filter path ({filter=})")
# 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(Tracks.duration >= seconds_duration)
elif filter.duration_unit == Config.FILTER_DURATION_SHORTER:
query = query.where(Tracks.duration <= seconds_duration)
else:
raise ApplicationError(f"Can't process filter duration type ({filter=})")
# Process comparator
if filter.last_played_comparator == Config.FILTER_PLAYED_COMPARATOR_NEVER:
# Select tracks that have never been played
query = query.outerjoin(Playdates, Tracks.id == Playdates.track_id).where(
Playdates.id.is_(None)
)
else:
# Last played specification
now = dt.datetime.now()
# Set sensible default, and correct for Config.FILTER_PLAYED_COMPARATOR_ANYTIME
before = now
# If not ANYTIME, set 'before' appropriates
if filter.last_played_comparator != Config.FILTER_PLAYED_COMPARATOR_ANYTIME:
if filter.last_played_unit == Config.FILTER_PLAYED_DAYS:
before = now - dt.timedelta(days=filter.last_played_number)
elif filter.last_played_unit == Config.FILTER_PLAYED_WEEKS:
before = now - dt.timedelta(days=7 * filter.last_played_number)
elif filter.last_played_unit == Config.FILTER_PLAYED_MONTHS:
before = now - dt.timedelta(days=30 * filter.last_played_number)
elif filter.last_played_unit == Config.FILTER_PLAYED_YEARS:
before = now - dt.timedelta(days=365 * filter.last_played_number)
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 < before
)
results: list[TrackDTO] = []
with db.Session() as session:
records = session.scalars(query).unique().all()
for record in records:
if record.playdates:
last_played = record.playdates[0].lastplayed
else:
last_played = None
last_played
dto = TrackDTO(
artist=record.artist,
bitrate=record.bitrate,
duration=record.duration,
fade_at=record.fade_at,
intro=record.intro,
lastplayed=last_played,
path=record.path,
silence_at=record.silence_at,
start_gap=record.start_gap,
title=record.title,
track_id=record.id,
)
results.append(dto)
return results
@log_call @log_call
def add_track_to_header(playlistrow_id: int, track_id: int) -> None: def add_track_to_header(playlistrow_id: int, track_id: int) -> None:
""" """
@ -329,66 +405,6 @@ def update_track(
return updated_track return updated_track
@log_call
def get_filtered_tracks(filter: Filter) -> list[TrackDTO]:
"""
Return tracks matching filter
"""
# Create a base query
query = Tracks.id > 0
# Path specification
if filter.path:
if filter.path_type == "contains":
query = query.where(Tracks.path.ilike(f"%{filter.path}%"))
elif filter.path_type == "excluding":
query = query.where(Tracks.path.notilike(f"%{filter.path}%"))
else:
raise ApplicationError(f"Can't process filter path ({filter=})")
# 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(Tracks.duration >= seconds_duration)
elif filter.duration_unit == Config.FILTER_DURATION_SHORTER:
query = query.where(Tracks.duration <= seconds_duration)
else:
raise ApplicationError(f"Can't process filter duration type ({filter=})")
# Process comparator
if filter.last_played_comparator == Config.FILTER_PLAYED_COMPARATOR_ANYTIME:
return _tracks_where(query, filter_by_last_played=False)
elif filter.last_played_comparator == Config.FILTER_PLAYED_COMPARATOR_NEVER:
return _tracks_where(query, filter_by_last_played=True, last_played_before=None)
else:
# Last played specification
now = dt.datetime.now()
# Set sensible default, and correct for Config.FILTER_PLAYED_COMPARATOR_ANYTIME
before = now
# If not ANYTIME, set 'before' appropriates
if filter.last_played_unit == Config.FILTER_PLAYED_DAYS:
before = now - dt.timedelta(days=filter.last_played_number)
elif filter.last_played_unit == Config.FILTER_PLAYED_WEEKS:
before = now - dt.timedelta(days=7 * filter.last_played_number)
elif filter.last_played_unit == Config.FILTER_PLAYED_MONTHS:
before = now - dt.timedelta(days=30 * filter.last_played_number)
elif filter.last_played_unit == Config.FILTER_PLAYED_YEARS:
before = now - dt.timedelta(days=365 * filter.last_played_number)
else:
raise ApplicationError("Can't determine last played criteria")
return _tracks_where(
query, filter_by_last_played=True, last_played_before=before
)
def set_track_intro(track_id: int, intro: int) -> None: def set_track_intro(track_id: int, intro: int) -> None:
""" """
Set track intro time Set track intro time
@ -730,196 +746,6 @@ def create_playlist(name: str, template_id: int, as_template: bool = False) -> P
return new_playlist return new_playlist
@log_call
def get_playlist_row(playlistrow_id: int) -> PlaylistRowDTO | None:
"""
Return specific row DTO
"""
# Alias PlaydatesTable for subquery
LatestPlaydate = aliased(Playdates)
# Subquery: latest playdate for each track
latest_playdate_subq = (
select(
LatestPlaydate.track_id,
func.max(LatestPlaydate.lastplayed).label("lastplayed"),
)
.group_by(LatestPlaydate.track_id)
.subquery()
)
stmt = (
select(
PlaylistRows.id.label("playlistrow_id"),
PlaylistRows.row_number,
PlaylistRows.note,
PlaylistRows.played,
PlaylistRows.playlist_id,
Tracks.id.label("track_id"),
Tracks.artist,
Tracks.bitrate,
Tracks.duration,
Tracks.fade_at,
Tracks.intro,
Tracks.path,
Tracks.silence_at,
Tracks.start_gap,
Tracks.title,
latest_playdate_subq.c.lastplayed,
)
.outerjoin(Tracks, PlaylistRows.track_id == Tracks.id)
.outerjoin(latest_playdate_subq, Tracks.id == latest_playdate_subq.c.track_id)
.where(PlaylistRows.id == playlistrow_id)
.order_by(PlaylistRows.row_number)
)
with db.Session() as session:
record = session.execute(stmt).one_or_none()
if not record:
return None
# Handle cases where track_id is None (no track associated)
if record.track_id is None:
dto = PlaylistRowDTO(
artist="",
bitrate=0,
duration=0,
fade_at=0,
intro=None,
lastplayed=None,
note=record.note,
path="",
played=record.played,
playlist_id=record.playlist_id,
playlistrow_id=record.playlistrow_id,
row_number=record.row_number,
silence_at=0,
start_gap=0,
title="",
track_id=-1,
)
else:
dto = PlaylistRowDTO(
artist=record.artist,
bitrate=record.bitrate,
duration=record.duration,
fade_at=record.fade_at,
intro=record.intro,
lastplayed=record.lastplayed,
note=record.note,
path=record.path,
played=record.played,
playlist_id=record.playlist_id,
playlistrow_id=record.playlistrow_id,
row_number=record.row_number,
silence_at=record.silence_at,
start_gap=record.start_gap,
title=record.title,
track_id=record.track_id,
)
return dto
def get_playlist_rows(
playlist_id: int, check_playlist_itegrity: bool = True
) -> list[PlaylistRowDTO]:
# Alias PlaydatesTable for subquery
LatestPlaydate = aliased(Playdates)
# Subquery: latest playdate for each track
latest_playdate_subq = (
select(
LatestPlaydate.track_id,
func.max(LatestPlaydate.lastplayed).label("lastplayed"),
)
.group_by(LatestPlaydate.track_id)
.subquery()
)
stmt = (
select(
PlaylistRows.id.label("playlistrow_id"),
PlaylistRows.row_number,
PlaylistRows.note,
PlaylistRows.played,
PlaylistRows.playlist_id,
Tracks.id.label("track_id"),
Tracks.artist,
Tracks.bitrate,
Tracks.duration,
Tracks.fade_at,
Tracks.intro,
Tracks.path,
Tracks.silence_at,
Tracks.start_gap,
Tracks.title,
latest_playdate_subq.c.lastplayed,
)
.outerjoin(Tracks, PlaylistRows.track_id == Tracks.id)
.outerjoin(latest_playdate_subq, Tracks.id == latest_playdate_subq.c.track_id)
.where(PlaylistRows.playlist_id == playlist_id)
.order_by(PlaylistRows.row_number)
)
with db.Session() as session:
results = session.execute(stmt).all()
# Sanity check
# TODO: would be good to be confident at removing this
if check_playlist_itegrity:
_check_playlist_integrity(
session=session, playlist_id=playlist_id, fix=False
)
dto_list = []
for row in results:
# Handle cases where track_id is None (no track associated)
if row.track_id is None:
dto = PlaylistRowDTO(
artist="",
bitrate=0,
duration=0,
fade_at=0,
intro=None,
lastplayed=None,
note=row.note,
path="",
played=row.played,
playlist_id=row.playlist_id,
playlistrow_id=row.playlistrow_id,
row_number=row.row_number,
silence_at=0,
start_gap=0,
title="",
track_id=-1,
# Additional fields like row_fg, row_bg, etc., use default None values
)
else:
dto = PlaylistRowDTO(
artist=row.artist,
bitrate=row.bitrate,
duration=row.duration,
fade_at=row.fade_at,
intro=row.intro,
lastplayed=row.lastplayed,
note=row.note,
path=row.path,
played=row.played,
playlist_id=row.playlist_id,
playlistrow_id=row.playlistrow_id,
row_number=row.row_number,
silence_at=row.silence_at,
start_gap=row.start_gap,
title=row.title,
track_id=row.track_id,
# Additional fields like row_fg, row_bg, etc., use default None values
)
dto_list.append(dto)
return dto_list
def copy_playlist(src_id: int, dst_id: int) -> None: def copy_playlist(src_id: int, dst_id: int) -> None:
"""Copy playlist entries""" """Copy playlist entries"""
@ -1068,6 +894,78 @@ def playlist_save_tabs(playlist_id_to_tab: dict[int, int]) -> None:
session.commit() session.commit()
# Playlist Rows
@log_call
def get_playlist_row(playlistrow_id: int) -> PlaylistRowDTO | None:
"""
Return specific row DTO
"""
with db.Session() as session:
record = (
session.execute(select(PlaylistRows).where(PlaylistRows.id == playlistrow_id))
.scalars()
.one_or_none()
)
if not record:
return None
track = None
if record.track_id:
track = track_by_id(record.track_id)
dto = PlaylistRowDTO(
note=record.note,
played=record.played,
playlist_id=record.playlist_id,
playlistrow_id=record.id,
row_number=record.row_number,
track=track,
)
return dto
def get_playlist_rows(
playlist_id: int, check_playlist_itegrity: bool = True
) -> list[PlaylistRowDTO]:
with db.Session() as session:
# TODO: would be good to be confident at removing this
if check_playlist_itegrity:
_check_playlist_integrity(
session=session, playlist_id=playlist_id, fix=False
)
records = session.scalars(
select(PlaylistRows)
.where(PlaylistRows.playlist_id == playlist_id)
.order_by(PlaylistRows.row_number)
).all()
dto_list = []
for record in records:
track = None
if record.track_id:
track = track_by_id(record.track_id)
dto = PlaylistRowDTO(
note=record.note,
played=record.played,
playlist_id=record.playlist_id,
playlistrow_id=record.id,
row_number=record.row_number,
track=track,
)
dto_list.append(dto)
return dto_list
# Playdates # Playdates
@log_call @log_call
def get_last_played_dates(track_id: int, limit: int = 5) -> str: def get_last_played_dates(track_id: int, limit: int = 5) -> str:
@ -1154,20 +1052,19 @@ def _queries_where(
Return queries selected by query Return queries selected by query
""" """
stmt = select(
Queries.id.label("query_id"), Queries.name, Queries.favourite, Queries.filter
).where(query)
results: list[QueryDTO] = [] results: list[QueryDTO] = []
with db.Session() as session: with db.Session() as session:
records = session.execute(stmt).one_or_none() records = session.scalars(
select(Queries)
.where(query)
).all()
for record in records: for record in records:
dto = QueryDTO( dto = QueryDTO(
favourite=record.favourite, favourite=record.favourite,
filter=record.filter, filter=record.filter,
name=record.name, name=record.name,
query_id=record.query_id, query_id=record.id,
) )
results.append(dto) results.append(dto)

View File

@ -49,7 +49,7 @@ class MyTestCase(unittest.TestCase):
return (playlist, model) return (playlist, model)
def create_playlist_model_tracks(self, playlist_name: str): def create_playlist_model_tracks(self, playlist_name: str):
(playlist, model) = self.create_playlist_and_model("my playlist") (playlist, model) = self.create_playlist_and_model(playlist_name)
# Create tracks # Create tracks
metadata1 = get_all_track_metadata(self.isa_path) metadata1 = get_all_track_metadata(self.isa_path)
self.track1 = repository.create_track(self.isa_path, metadata1) self.track1 = repository.create_track(self.isa_path, metadata1)
@ -99,7 +99,7 @@ class MyTestCase(unittest.TestCase):
self.create_playlist_model_tracks("my playlist") self.create_playlist_model_tracks("my playlist")
repository.add_track_to_header(self.row1.playlistrow_id, self.track2.track_id) repository.add_track_to_header(self.row1.playlistrow_id, self.track2.track_id)
result = repository.get_playlist_row(self.row1.playlistrow_id) result = repository.get_playlist_row(self.row1.playlistrow_id)
assert result.track_id == self.track2.track_id assert result.track.track_id == self.track2.track_id
def test_create_track(self): def test_create_track(self):
metadata = get_all_track_metadata(self.isa_path) metadata = get_all_track_metadata(self.isa_path)
@ -119,18 +119,18 @@ class MyTestCase(unittest.TestCase):
_ = repository.create_track(self.isa_path, metadata) _ = repository.create_track(self.isa_path, metadata)
metadata = get_all_track_metadata(self.mom_path) metadata = get_all_track_metadata(self.mom_path)
_ = repository.create_track(self.mom_path, metadata) _ = repository.create_track(self.mom_path, metadata)
result_isa = repository.tracks_like_artist(self.isa_artist) result_isa = repository.tracks_by_artist(self.isa_artist)
assert len(result_isa) == 1 assert len(result_isa) == 1
assert result_isa[0].artist == self.isa_artist assert result_isa[0].artist == self.isa_artist
result_mom = repository.tracks_like_artist(self.mom_artist) result_mom = repository.tracks_by_artist(self.mom_artist)
assert len(result_mom) == 1 assert len(result_mom) == 1
assert result_mom[0].artist == self.mom_artist assert result_mom[0].artist == self.mom_artist
def test_get_track_by_title(self): def test_get_track_by_title(self):
metadata = get_all_track_metadata(self.isa_path) metadata_isa = get_all_track_metadata(self.isa_path)
_ = repository.create_track(self.isa_path, metadata) _ = repository.create_track(self.isa_path, metadata_isa)
metadata = get_all_track_metadata(self.mom_path) metadata_mom = get_all_track_metadata(self.mom_path)
_ = repository.create_track(self.mom_path, metadata) _ = repository.create_track(self.mom_path, metadata_mom)
result_isa = repository.tracks_by_title(self.isa_title) result_isa = repository.tracks_by_title(self.isa_title)
assert len(result_isa) == 1 assert len(result_isa) == 1
assert result_isa[0].title == self.isa_title assert result_isa[0].title == self.isa_title
@ -138,6 +138,21 @@ class MyTestCase(unittest.TestCase):
assert len(result_mom) == 1 assert len(result_mom) == 1
assert result_mom[0].title == self.mom_title assert result_mom[0].title == self.mom_title
def test_tracks_get_all_tracks(self):
self.create_playlist_model_tracks(playlist_name="test_track_get_all_tracks")
all_tracks = repository.get_all_tracks()
assert len(all_tracks) == 2
def test_tracks_by_path(self):
metadata_isa = get_all_track_metadata(self.isa_path)
_ = repository.create_track(self.isa_path, metadata_isa)
metadata_mom = get_all_track_metadata(self.mom_path)
_ = repository.create_track(self.mom_path, metadata_mom)
result_isa = repository.track_by_path(self.isa_path)
assert result_isa.title == self.isa_title
result_mom = repository.track_by_path(self.mom_path)
assert result_mom.title == self.mom_title
def test_move_rows_test1(self): def test_move_rows_test1(self):
# move row 3 to row 5 # move row 3 to row 5