diff --git a/app/models.py b/app/models.py index a538d37..2c037e3 100644 --- a/app/models.py +++ b/app/models.py @@ -462,6 +462,28 @@ class PlaylistRows(Base): # Ensure new row numbers are available to the caller session.commit() + @classmethod + def get_section_header_rows(cls, session: scoped_session, + playlist_id: int) -> List["PlaylistRows"]: + """ + Return a list of PlaylistRows that are section headers for this + playlist + """ + + plrs = session.execute( + select(cls) + .where( + cls.playlist_id == playlist_id, + cls.track_id.is_(None), + ( + cls.note.endswith("-") | + cls.note.endswith("+") + ) + ) + .order_by(cls.row_number)).scalars().all() + + return plrs + @staticmethod def get_track_plr(session: scoped_session, track_id: int, playlist_id: int) -> Optional["PlaylistRows"]: @@ -506,21 +528,25 @@ class PlaylistRows(Base): return plrs @classmethod - def get_rows_with_tracks(cls, session: scoped_session, - playlist_id: int) -> List["PlaylistRows"]: + def get_rows_with_tracks( + cls, session: scoped_session, playlist_id: int, + from_row: Optional[int] = None, + to_row: Optional[int] = None) -> List["PlaylistRows"]: """ For passed playlist, return a list of rows that contain tracks """ - plrs = session.execute( - select(cls) - .where( - cls.playlist_id == playlist_id, - cls.track_id.is_not(None) - ) - .order_by(cls.row_number) - ).scalars().all() + query = select(cls).where( + cls.playlist_id == playlist_id, + cls.track_id.is_not(None) + ) + if from_row is not None: + query = query.where(cls.row_number >= from_row) + if to_row is not None: + query = query.where(cls.row_number <= to_row) + + plrs = session.execute((query).order_by(cls.row_number)).scalars().all() return plrs diff --git a/app/playlists.py b/app/playlists.py index 22e47b1..031345e 100644 --- a/app/playlists.py +++ b/app/playlists.py @@ -1580,28 +1580,6 @@ class PlaylistTab(QTableWidget): return userdata_item.data(role) - def _get_section_start_time(self, session: scoped_session, - row: int) -> Optional[datetime]: - """ - Parse section header for a start time. - Return None if: - - it's not a section header row or - - we can't parse a time from it - Otherwise return datetime from header. - """ - - # If we have a track_id, we're not a section header - if self._get_row_track_id(row): - return None - - # Check for start time in note. Extract note text from database - # to ignore section timings. - plr = session.get(PlaylistRows, self._get_playlistrow_id(row)) - if plr and plr.note: - return self._get_note_text_time(plr.note) - else: - return None - def _get_selected_row(self) -> Optional[int]: """Return row number of first selected row, or None if none selected""" @@ -2220,29 +2198,6 @@ class PlaylistTab(QTableWidget): self.musicmuster.tabInfolist.open_in_songfacts(title) - def _update_note_text(self, session: scoped_session, - playlist_row: PlaylistRows, - additional_text: str) -> None: - """Append additional_text to row display""" - - if not playlist_row.row_number: - return - - # Column to update is either HEADER_NOTES_COLUMN for a section - # header or the appropriate row_notes column for a track row - if playlist_row.track_id: - column = ROW_NOTES - else: - column = HEADER_NOTES_COLUMN - - # Update text - if playlist_row.note: - new_text = playlist_row.note + additional_text - else: - new_text = additional_text - - _ = self._set_row_note(session, playlist_row.row_number, new_text) - def _update_row(self, session, row: int, track: Tracks) -> None: """ Update the passed row with info from the passed track. @@ -2256,10 +2211,42 @@ class PlaylistTab(QTableWidget): self.update_display(session) + def _update_section_headers(self, session: scoped_session) -> None: + """ + Update section headers with run time of section + """ + + header_rows = [] + + # Get section header PlaylistRows + plrs = PlaylistRows.get_section_header_rows(session, self.playlist_id) + for plr in plrs: + if plr.note.endswith("+"): + header_rows.append(plr) + else: + try: + from_plr = header_rows.pop() + except IndexError: + pass + # section runs from from_plr to plr + from_row = from_plr.row_number + plr_tracks = PlaylistRows.get_rows_with_tracks( + session, self.playlist_id, from_row, plr.row_number) + + total_time = 0 + total_time = sum([a.track.duration for a in plr_tracks]) + import ipdb; ipdb.set_trace() + time_str = self._get_section_timing_string(total_time) + + new_text = self._get_row_note(from_row) + time_str + _ = self._set_row_note(session, from_row, new_text) + + def _update_start_end_times(self) -> None: """ Update track start and end times """ with Session() as session: + section_start_rows = [] current_track_end_time = self._get_current_track_end_time() current_track_row = self._get_current_track_row_number() current_track_start_time = self._get_current_track_start_time() @@ -2276,7 +2263,8 @@ class PlaylistTab(QTableWidget): # Get any timing from header row (that's all we need) if self._get_row_track_id(row) == 0: - note_time = self._get_section_start_time(session, row) + note_time = self._get_note_text_time( + self._get_row_note(row)) if note_time: next_start_time = note_time continue @@ -2321,6 +2309,8 @@ class PlaylistTab(QTableWidget): next_start_time = self._set_row_times( row, next_start_time, self._get_row_duration(row)) + self._update_section_headers(session) + def _wikipedia(self, row_number: int) -> None: """Look up passed row title in Wikipedia and display info tab"""