auto export playlist works!!!

This commit is contained in:
billy 2025-09-29 22:43:26 -04:00
parent 3a9f7a27d3
commit dc4f7a4cbc
9 changed files with 188 additions and 17 deletions

View File

@ -0,0 +1,85 @@
import DBA
from PyQt5.QtWidgets import (
QDialog,
QLineEdit,
QLabel,
QPushButton,
QVBoxLayout,
)
from PyQt5.QtGui import QFont
class EditPlaylistOptionsWindow(QDialog):
def __init__(self, playlist_id):
super(EditPlaylistOptionsWindow, self).__init__()
self.setWindowTitle("Playlist options")
self.setMinimumSize(600, 400)
self.playlist_id = playlist_id
# self.playlist_path_prefix: str = self.config.get(
# "settings", "playlist_path_prefix"
# )
# self.export_path: str = self.config.get("settings", "playlist_export_path")
# self.selected_playlist_name: str = "my-playlist.m3u"
# self.chosen_list_widget_item: QListWidgetItem | None = None
layout = self.setup_ui()
self.setLayout(layout)
self.show()
def setup_ui(self):
layout = QVBoxLayout()
# Header label
label = QLabel("Options")
label.setFont(QFont("Sans", weight=QFont.Bold))
layout.addWidget(label)
# Get options from db
with DBA.DBAccess() as db:
data = db.query("SELECT auto_export_path, path_prefix from playlist WHERE id = ?;", (self.playlist_id,))
auto_export_path = data[0][0]
path_prefix = data[0][1]
# Relative export path label
label = QLabel("Auto export path (../music/playlists/my_playlist.m3u)")
label.setFont(QFont("Sans", weight=QFont.Bold)) # bold category
label.setStyleSheet("text-transform:lowercase;") # uppercase category
layout.addWidget(label)
# Relative export path line edit widget
self.auto_export_path = QLineEdit(auto_export_path)
layout.addWidget(self.auto_export_path)
# Playlist file save path label
label = QLabel("Path prefix (/prefix/song.mp3, /prefix/song2.mp3)")
label.setFont(QFont("Sans", weight=QFont.Bold))
label.setStyleSheet("text-transform:lowercase;")
layout.addWidget(label)
# Playlist file save path line edit widget
self.path_prefix = QLineEdit(path_prefix)
layout.addWidget(self.path_prefix)
# Save button
self.save_button = QPushButton("Save")
layout.addWidget(self.save_button)
# Signals
self.save_button.clicked.connect(self.save)
return layout
def save(self) -> None:
"""
Updates the options in the db
"""
with DBA.DBAccess() as db:
db.execute('''
UPDATE playlist SET auto_export_path = ?, path_prefix = ? WHERE id = ?
''', (self.auto_export_path.text(), self.path_prefix.text(), self.playlist_id)
)
self.close()
return
def cancel(self) -> None:
self.close()
return

View File

@ -4,7 +4,6 @@ import os
from PyQt5.QtWidgets import (
QCheckBox,
QDialog,
QHBoxLayout,
QLineEdit,
QLabel,
QPushButton,
@ -26,8 +25,8 @@ class ExportPlaylistWindow(QDialog):
self.setWindowTitle("Export playlist")
self.setMinimumSize(600, 400)
self.load_config()
self.relative_path: str = self.config.get(
"settings", "playlist_content_relative_path"
self.playlist_path_prefix: str = self.config.get(
"settings", "playlist_path_prefix"
)
self.export_path: str = self.config.get("settings", "playlist_export_path")
self.selected_playlist_name: str = "my-playlist.m3u"
@ -74,7 +73,7 @@ class ExportPlaylistWindow(QDialog):
layout.addWidget(label)
# Relative export path line edit widget
self.input_relative_path = QLineEdit(self.relative_path) # not needed
self.input_relative_path = QLineEdit(self.playlist_path_prefix) # not needed
layout.addWidget(self.input_relative_path)
# Playlist file save path label
@ -112,9 +111,7 @@ class ExportPlaylistWindow(QDialog):
Sets the current playlist name, then edits the playlist export path
"""
# Get the current chosen list item
self.chosen_list_widget_item: QListWidgetItem | None = (
self.playlist_listWidget.currentItem()
)
self.chosen_list_widget_item = self.playlist_listWidget.currentItem()
# We don't care if nothing is chosen
if self.chosen_list_widget_item is None:
return
@ -129,13 +126,13 @@ class ExportPlaylistWindow(QDialog):
# alter line edit text for playlist path
# Make the thing react and show the correct thing or whatever
current_text: list = self.input_m3u_path.text().split("/")
current_text: list = self.export_m3u_path.text().split("/")
if "." in current_text[-1]:
current_text = current_text[:-1]
else:
current_text = current_text
m3u_text = os.path.join("/", *current_text, self.selected_playlist_name)
self.input_m3u_path.setText(m3u_text)
self.export_m3u_path.setText(m3u_text)
def save(self) -> None:
"""
@ -145,7 +142,7 @@ class ExportPlaylistWindow(QDialog):
if self.chosen_list_widget_item is None:
return
relative_path = self.input_relative_path.text()
output_filename = self.input_m3u_path.text()
output_filename = self.export_m3u_path.text()
# If no output path is provided, just close the window...
if output_filename == "" or output_filename is None:

View File

@ -6,13 +6,12 @@ from PyQt5.QtWidgets import (
QTreeWidget,
QTreeWidgetItem,
)
from PyQt5.QtCore import QThreadPool, pyqtSignal, Qt, QPoint
from PyQt5.QtCore import pyqtSignal, Qt, QPoint
import DBA
from logging import debug
from components.ErrorDialog import ErrorDialog
from utils import Worker
from components import CreatePlaylistWindow
from components import CreatePlaylistWindow, EditPlaylistOptionsWindow
class PlaylistWidgetItem(QTreeWidgetItem):
@ -70,10 +69,13 @@ class PlaylistsPane(QTreeWidget):
# only allow delete/rename non-root nodes
rename_action = QAction("Rename", self)
delete_action = QAction("Delete", self)
options_action = QAction("Options", self)
rename_action.triggered.connect(self.rename_playlist)
delete_action.triggered.connect(self.delete_playlist)
options_action.triggered.connect(self.options)
menu.addAction(rename_action)
menu.addAction(delete_action)
menu.addAction(options_action)
create_action = QAction("New playlist", self)
create_action.triggered.connect(self.create_playlist)
menu.addAction(create_action)
@ -85,6 +87,10 @@ class PlaylistsPane(QTreeWidget):
window.playlistCreatedSignal.connect(self.reload_playlists)
window.exec_()
def options(self):
window = EditPlaylistOptionsWindow(self.playlist_db_id_choice)
window.exec_()
def rename_playlist(self, *args):
"""
Asks user for input

View File

@ -6,6 +6,7 @@ from .ErrorDialog import ErrorDialog
from .LyricsWindow import LyricsWindow
from .DebugWindow import DebugWindow
from .AddToPlaylistWindow import AddToPlaylistWindow
from .EditPlaylistOptionsWindow import EditPlaylistOptionsWindow
from .CreatePlaylistWindow import CreatePlaylistWindow
from .PlaylistsPane import PlaylistsPane
from .ExportPlaylistWindow import ExportPlaylistWindow

14
main.py
View File

@ -4,7 +4,7 @@ import logging
from PyQt5 import QtCore
import qdarktheme
import typing
# import DBA
import DBA
from subprocess import run
# from pyqtgraph import mkBrush
from mutagen.id3 import ID3
@ -60,6 +60,7 @@ from components import (
CreatePlaylistWindow,
ExportPlaylistWindow,
)
from utils.export_playlist_by_id import export_playlist_by_id
# good help with signals slots in threads
# https://stackoverflow.com/questions/52993677/how-do-i-setup-signals-and-slots-in-pyqt-with-qthreads-in-both-directions
@ -246,13 +247,22 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
self.config["settings"]["window_size"] = (
str(self.width()) + "," + str(self.height())
)
# Save the config
try:
with open(self.cfg_file, "w") as configfile:
self.config.write(configfile)
except Exception as e:
debug(f"wtf man {e}")
# auto export any playlists that want it
try:
with DBA.DBAccess() as db:
result = db.query('SELECT id FROM playlist WHERE auto_export_path IS NOT NULL;', ())
ids = [id[0] for id in result]
for id in ids:
export_playlist_by_id(id)
except Exception:
pass
if a0 is not None:
super().closeEvent(a0)

View File

@ -4,7 +4,7 @@ library = /path/to/music
reorganize_destination = /where/to/reorganize/to
playlist_auto_export_enabled = 0
playlist_export_path = /where/to/export/to
playlist_relative_path = /relative/prefix
playlist_path_prefix = /relative/prefix
extensions = mp3,wav,ogg,flac
volume = 100
window_size=1152,894

View File

@ -17,3 +17,4 @@ from .convert_date_str_to_tyer_tdat_id3_tag import convert_date_str_to_tyer_tdat
from .set_album_art import set_album_art
from .delete_album_art import delete_album_art
from .Worker import Worker
from .export_playlist_by_id import export_playlist_by_id

View File

@ -0,0 +1,69 @@
import os
from PyQt5.QtCore import QThreadPool
import DBA
import logging
from utils import get_reorganize_vars, Worker
def export_playlist_by_id(playlist_db_id: int) -> bool:
"""
Exports a playlist to its defined auto_export_path, by database ID
"""
threadpool = QThreadPool()
try:
with DBA.DBAccess() as db:
result = db.query('''
SELECT auto_export_path, path_prefix FROM playlist WHERE id = ?
''', (playlist_db_id,)
)
auto_export_path = result[0][0]
path_prefix = result[0][1]
except Exception as e:
logging.error(
f"export_playlist_by_id.py | Could not contact database: {e}"
)
return False
# If the prefix is null, then use an empty string
if not path_prefix:
path_prefix = ""
# Get filepaths for selected playlist from the database
try:
with DBA.DBAccess() as db:
data = db.query(
"""SELECT s.filepath FROM song_playlist as sp
JOIN song as s ON s.id = sp.song_id
WHERE sp.playlist_id = ?;""",
(playlist_db_id,),
)
db_paths = [path[0] for path in data]
except Exception as e:
logging.error(
f"export_playlist_by_id.py | Could not retrieve records from playlist: {e}"
)
return False
# Gather playlist song paths
write_paths = []
# Relative paths
for song in db_paths:
artist, album = get_reorganize_vars(song)
write_path = os.path.join(
path_prefix, artist, album, song.split("/")[-1] + "\n"
)
write_paths.append(str(write_path))
worker = Worker(write_to_playlist_file, write_paths, auto_export_path)
# worker.signals.signal_finished.connect(None)
# worker.signals.signal_progress.connect()
threadpool.start(worker)
return True
def write_to_playlist_file(paths: list[str], outfile: str, progress_callback=None) -> None:
"""
Writes a list of strings to a m3u file
"""
os.makedirs(os.path.dirname(outfile), exist_ok=True)
with open(outfile, "w") as f:
f.writelines(paths)

View File

@ -22,7 +22,9 @@ CREATE TABLE song(
CREATE TABLE playlist(
id integer primary key,
name varchar(64),
date_created TIMESTAMP default CURRENT_TIMESTAMP
date_created TIMESTAMP default CURRENT_TIMESTAMP,
auto_export_path varchar(512),
path_prefix varchar(255)
);
CREATE TABLE song_playlist(