Wobuzz/wobuzz/player/playlist.py

167 lines
5.1 KiB
Python

#!/usr/bin/python3
import os
from PyQt6.QtCore import Qt
from .track import Track
class Playlist:
def __init__(self, app, title: str):
self.app = app
self.title = title # playlist title
# add to unique names so if the playlist is loaded from disk,
# no other playlist can be created using the same name
self.app.utils.unique_names.append(self.title)
self.sorting: list[Qt.SortOrder] | None = None # Custom sort order if None
self.tracks: list[Track] = []
self.current_track_index = 0
self.current_track: Track | None = None
self.view = None
def clear(self):
self.sorting: list[Qt.SortOrder] | None = None
self.tracks = []
self.current_track_index = 0
self.current_track = None
def load_from_paths(self, paths):
i = 0
while i < len(paths):
path = paths[i]
if os.path.isfile(path):
self.tracks.append(Track(self.app, path, 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]
def load_from_m3u(self, path):
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
i = 0
num_lines = len(lines)
while i < num_lines:
line = lines[i]
if line.startswith("#") or line.startswith("http"): # filter out comments, extended m3u and urls
i += 1
continue
self.tracks.append(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]
#self.app.player.history.append_track(self.current_track)
def load_from_wbz(self, path):
pass
def has_tracks(self):
return len(self.tracks) > 0
def on_first_track(self):
return self.current_track_index == 0
def on_last_track(self): # if the current track is the last
return self.current_track_index == len(self.tracks) - 1
def next_track(self):
self.current_track_index += 1
self.current_track = self.tracks[self.current_track_index]
if not self.current_track.cached: # make sure the track is cached because else the player can't play it
self.current_track.cache()
return self.current_track.sound, self.current_track.duration
def previous_track(self):
if self.on_first_track():
return self.current_track, self.current_track.duration
self.current_track_index -= 1
self.current_track = self.tracks[self.current_track_index]
if not self.current_track.cached: # make sure the track is cached because else the player can't play it
self.current_track.cache()
return self.current_track.sound, self.current_track.duration
def set_track(self, track_index):
self.current_track_index = track_index
self.current_track = self.tracks[self.current_track_index]
if not self.current_track.cached:
self.current_track.cache()
return self.current_track.sound, self.current_track.duration
def save(self):
wbz_data = ""
for track in self.tracks:
wbz_data += f"{track.path}\n"
wbz = open(
os.path.expanduser(
f"{self.app.settings.library_path}/playlists/{self.title.replace(" ", "_")}.wbz.m3u"
),
"w"
)
wbz.write(wbz_data)
wbz.close()
def rename(self, title: str):
# remove from unique names so a new playlist can have the old name and delete old playlist.
path = f"{self.app.settings.library_path}/playlists/{self.title.replace(" ", "_")}.wbz.m3u"
path = os.path.expanduser(path)
if os.path.exists(path):
os.remove(os.path.expanduser(path))
old_title = self.title
self.title = self.app.utils.unique_name(title, ignore=old_title)
if not old_title == self.title: # remove only when the playlist actually has a different name
self.app.utils.unique_names.remove(old_title)
def delete(self):
path = f"{self.app.settings.library_path}/playlists/{self.title.replace(" ", "_")}.wbz.m3u"
path = os.path.expanduser(path)
if os.path.exists(path):
os.remove(os.path.expanduser(path))
self.app.utils.unique_names.remove(self.title)
self.app.library.playlists.remove(self)
def append_track(self, track):
self.tracks.append(track)
if self.view:
self.view.append_track(track)
def h_last_track(self):
# get last track in history (only gets used in player.history)
if len(self.tracks) > 1:
return self.tracks[-2]