Implent subtotal times and unplayed time

This commit is contained in:
Keith Edmunds 2023-10-13 19:01:22 +01:00
parent 8cebf7829b
commit a8c5a56c1a
2 changed files with 54 additions and 14 deletions

View File

@ -456,7 +456,7 @@ class PlaylistRows(Base):
session.commit() session.commit()
@classmethod @classmethod
def get_from_id_list( def plrids_to_plrs(
cls, session: scoped_session, playlist_id: int, plr_ids: List[int] cls, session: scoped_session, playlist_id: int, plr_ids: List[int]
) -> List["PlaylistRows"]: ) -> List["PlaylistRows"]:
""" """

View File

@ -8,7 +8,7 @@ import obsws_python as obs # type: ignore
from collections import namedtuple from collections import namedtuple
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import Any, Callable, cast, List, Optional, TYPE_CHECKING, Union from typing import Any, Callable, cast, List, Optional, Tuple, TYPE_CHECKING, Union
from PyQt6.QtCore import ( from PyQt6.QtCore import (
QEvent, QEvent,
@ -1425,14 +1425,21 @@ class PlaylistTab(QTableWidget):
return userdata_item.data(role) return userdata_item.data(role)
def _get_section_timing_string(self, ms: int, no_end: bool = False) -> str: def _get_section_timing_string(
self, total_time: int, unplayed_time: int, no_end: bool = False
) -> str:
"""Return string describing section duration""" """Return string describing section duration"""
duration = ms_to_mmss(ms) total_duration = ms_to_mmss(total_time)
if unplayed_time:
unplayed_duration = ms_to_mmss(unplayed_time)
else:
unplayed_duration = "[No unplayed tracks]"
caveat = "" caveat = ""
if no_end: if no_end:
caveat = " (to end of playlist)" caveat = " (to end of playlist)"
return " [" + duration + caveat + "]"
return f" {unplayed_duration} ({total_duration}){caveat}"
def _get_selected_row(self) -> Optional[int]: def _get_selected_row(self) -> Optional[int]:
""" """
@ -2351,10 +2358,10 @@ class PlaylistTab(QTableWidget):
def _track_time_between_rows( def _track_time_between_rows(
self, session: scoped_session, from_plr: PlaylistRows, to_plr: PlaylistRows self, session: scoped_session, from_plr: PlaylistRows, to_plr: PlaylistRows
) -> int: ) -> Tuple[int, int]:
""" """
Returns the total duration of all tracks in rows between Returns the (total duration of all tracks in rows between
from_row and to_row inclusive from_row and to_row inclusive, total unplayed time in those rows)
""" """
plr_tracks = PlaylistRows.get_rows_with_tracks( plr_tracks = PlaylistRows.get_rows_with_tracks(
@ -2363,8 +2370,12 @@ class PlaylistTab(QTableWidget):
total_time = 0 total_time = 0
total_time = sum([a.track.duration for a in plr_tracks if a.track.duration]) total_time = sum([a.track.duration for a in plr_tracks if a.track.duration])
unplayed_time = 0
unplayed_time = sum(
[a.track.duration for a in plr_tracks if a.track.duration and not a.played]
)
return total_time return (total_time, unplayed_time)
def _update_row_track_info( def _update_row_track_info(
self, session: scoped_session, row: int, track: Tracks self, session: scoped_session, row: int, track: Tracks
@ -2395,25 +2406,31 @@ class PlaylistTab(QTableWidget):
""" """
section_start_rows: List[PlaylistRows] = [] section_start_rows: List[PlaylistRows] = []
subtotal_from: Optional[PlaylistRows] = None
header_rows = [ header_rows = [
self._get_row_plr_id(row_number) self._get_row_plr_id(row_number)
for row_number in range(self.rowCount()) for row_number in range(self.rowCount())
if self._get_row_track_id(row_number) == 0 if self._get_row_track_id(row_number) == 0
] ]
plrs = PlaylistRows.get_from_id_list(session, self.playlist_id, header_rows) plrs = PlaylistRows.plrids_to_plrs(session, self.playlist_id, header_rows)
for plr in plrs: for plr in plrs:
# Start of timed section
if plr.note.endswith("+"): if plr.note.endswith("+"):
section_start_rows.append(plr) section_start_rows.append(plr)
subtotal_from = plr
continue continue
# End of timed section
elif plr.note.endswith("-"): elif plr.note.endswith("-"):
try: try:
from_plr = section_start_rows.pop() from_plr = section_start_rows.pop()
to_plr = plr to_plr = plr
total_time = self._track_time_between_rows( total_time, unplayed_time = self._track_time_between_rows(
session, from_plr, to_plr session, from_plr, to_plr
) )
time_str = self._get_section_timing_string(total_time) time_str = self._get_section_timing_string(
total_time, unplayed_time
)
self._set_row_header_text( self._set_row_header_text(
session, from_plr.plr_rownum, from_plr.note + time_str session, from_plr.plr_rownum, from_plr.note + time_str
) )
@ -2430,11 +2447,30 @@ class PlaylistTab(QTableWidget):
+ "]" + "]"
) )
self._set_row_header_text(session, to_plr.plr_rownum, new_text) self._set_row_header_text(session, to_plr.plr_rownum, new_text)
subtotal_from = None
except IndexError: except IndexError:
# This ending row may have a time left from before a # This ending row may have a time left from before a
# starting row above was deleted, so replace content # starting row above was deleted, so replace content
self._set_row_header_text(session, plr.plr_rownum, plr.note) self._set_row_header_text(session, plr.plr_rownum, plr.note)
continue continue
# Subtotal
elif plr.note.endswith("="):
if not subtotal_from:
return
from_plr = subtotal_from
to_plr = plr
total_time, unplayed_time = self._track_time_between_rows(
session, subtotal_from, to_plr
)
time_str = self._get_section_timing_string(total_time, unplayed_time)
if to_plr.note.strip() == "=":
leader_text = "Subtotal: "
else:
leader_text = to_plr.note[:-1] + " "
new_text = leader_text + time_str
self._set_row_header_text(session, to_plr.plr_rownum, new_text)
subtotal_from = to_plr
# If we still have plrs in section_start_rows, there isn't an end # If we still have plrs in section_start_rows, there isn't an end
# section row for them # section row for them
@ -2442,8 +2478,12 @@ class PlaylistTab(QTableWidget):
if possible_plr: if possible_plr:
to_plr = possible_plr to_plr = possible_plr
for from_plr in section_start_rows: for from_plr in section_start_rows:
total_time = self._track_time_between_rows(session, from_plr, to_plr) total_time, unplayed_time = self._track_time_between_rows(
time_str = self._get_section_timing_string(total_time, no_end=True) session, from_plr, to_plr
)
time_str = self._get_section_timing_string(
total_time, unplayed_time, no_end=True
)
self._set_row_header_text( self._set_row_header_text(
session, from_plr.plr_rownum, from_plr.note + time_str session, from_plr.plr_rownum, from_plr.note + time_str
) )