Implemented saving of the sortorder to the .wbz.m3u

This commit is contained in:
The Wobbler 2025-02-23 18:05:28 +01:00
parent 894b3d213a
commit 78b60dba02
3 changed files with 68 additions and 4 deletions

View file

@ -134,7 +134,63 @@ class Playlist:
self.app.gui.on_background_job_stop(process_title) self.app.gui.on_background_job_stop(process_title)
def load_from_wbz(self, path): def load_from_wbz(self, path):
self.load_from_m3u(path) # placeholder file = open(path, "r")
m3u = file.read()
file.close()
lines = m3u.split("\n") # m3u entries are separated by newlines
lines = lines[:-1] # remove last entry because it is just an empty string
num_lines = len(lines)
i = 0
process_title = f'Loading Playlist "{self.title}"'
self.app.gui.on_background_job_start(
process_title,
f'Loading the tracks of "{self.title}".',
num_lines,
lambda: i
)
while i < num_lines:
line = lines[i]
if line.startswith("#"): # comments and EXTM3U/WOBUZZM3U
if line.startswith("#SORT: "): # sort
sort_line = line[6:] # delete "#SORT: " from the line
sorting = sort_line.split(", ") # split into the sort column specifier and the sort order
# e.g. ["0", "True"]
del self.sorting[0] # delete first sort so the length stays at 6
# convert these from strings back to int and bool and append them to the sorting
self.sorting.append((int(sorting[0]), sorting[1] == "True"))
i += 1
continue
elif line.startswith("http"): # filter out urls
i += 1
continue
self.append_track(Track(self.app, line, cache=i == 0)) # first track is cached
i += 1
# set current track to the first track if there is no currently playing track
if self.current_track is None and self.has_tracks():
self.current_track = self.tracks[0]
list(self.views.values())[0].sort() # execute sort() on the first view
self.loaded = True
self.app.gui.on_background_job_stop(process_title)
def sync(self, view, user_sort: bool=False): def sync(self, view, user_sort: bool=False):
num_tracks = view.topLevelItemCount() num_tracks = view.topLevelItemCount()
@ -206,7 +262,10 @@ class Playlist:
first_view.sortItems(4, Qt.SortOrder.AscendingOrder) first_view.sortItems(4, Qt.SortOrder.AscendingOrder)
self.sync(first_view) self.sync(first_view)
wbz_data = "#WOBUZZM3U\n" wbz_data = "#WOBUZZM3U\n" # header
for sort_column, order in self.sorting:
wbz_data += f"#SORT: {sort_column}, {order}\n"
for track in self.tracks: for track in self.tracks:
wbz_data += f"{track.path}\n" wbz_data += f"{track.path}\n"

View file

@ -67,7 +67,7 @@ class Track:
self.duration = len(self.audio) # track duration in milliseconds self.duration = len(self.audio) # track duration in milliseconds
self.tags = TinyTag.get(self.path, ignore_errors=True, duration=False, image=True) # metadata with images self.tags = TinyTag.get(self.path, ignore_errors=True, duration=False, image=True) # metadata with images
self.cached = True self.cached = True

View file

@ -9,6 +9,7 @@ from .track import TrackItem
class PlaylistView(QTreeWidget): class PlaylistView(QTreeWidget):
itemDropped = pyqtSignal(QTreeWidget, list) itemDropped = pyqtSignal(QTreeWidget, list)
sort_signal = pyqtSignal(int, Qt.SortOrder)
playing_mark = QIcon.fromTheme(QIcon.ThemeIcon.MediaPlaybackStart) playing_mark = QIcon.fromTheme(QIcon.ThemeIcon.MediaPlaybackStart)
@ -42,6 +43,7 @@ class PlaylistView(QTreeWidget):
self.itemActivated.connect(self.on_track_activation) self.itemActivated.connect(self.on_track_activation)
self.header.sectionClicked.connect(self.on_header_click) self.header.sectionClicked.connect(self.on_header_click)
self.sort_signal.connect(self.sortItems)
def on_header_click(self, section_index: int): def on_header_click(self, section_index: int):
if section_index == 0: # this would just invert the current sorting if section_index == 0: # this would just invert the current sorting
@ -73,7 +75,10 @@ class PlaylistView(QTreeWidget):
# convert True/False to Qt.SortOrder.AscendingOrder/Qt.SortOrder.DescendingOrder # convert True/False to Qt.SortOrder.AscendingOrder/Qt.SortOrder.DescendingOrder
qorder = Qt.SortOrder.AscendingOrder if order else Qt.SortOrder.DescendingOrder qorder = Qt.SortOrder.AscendingOrder if order else Qt.SortOrder.DescendingOrder
self.sortItems(index, qorder) # somehow, QTreeWidget.sortItems() cant be called from a thread, so we have to use a signal to execute it
# in the main thread
self.sort_signal.emit(index, qorder)
# self.sortItems(index, qorder)
self.on_sort() self.on_sort()