playlist adding working. delete song from db needs fix

This commit is contained in:
billypom on debian 2024-08-03 12:44:11 -04:00
parent 58df3d8c9b
commit 68590deea2
6 changed files with 127 additions and 25 deletions

View File

@ -7,25 +7,34 @@ from PyQt5.QtWidgets import (
QLabel, QLabel,
QLineEdit, QLineEdit,
QPushButton, QPushButton,
QListWidgetItem,
) )
from PyQt5.QtGui import QFont from PyQt5.QtGui import QFont
import DBA
import logging
class AddToPlaylistWindow(QDialog): class AddToPlaylistWindow(QDialog):
def __init__(self, list_options: dict): def __init__(self, list_options: dict, song_db_ids: list):
super(AddToPlaylistWindow, self).__init__() super(AddToPlaylistWindow, self).__init__()
self.setWindowTitle("Choose") self.song_db_ids = song_db_ids
self.setWindowTitle("Add songs to playlist:")
self.setMinimumSize(400, 400) self.setMinimumSize(400, 400)
layout = QVBoxLayout() layout = QVBoxLayout()
listWidget = QListWidget(self)
for k, v in list_options: self.item_dict = {}
listWidget.addItem(f"{k} | {v}") self.listWidget = QListWidget(self)
for i, (k, v) in enumerate(list_options.items()):
item_text = f"{i} | {v}"
item = QListWidgetItem(item_text)
self.listWidget.addItem(item)
self.item_dict[item_text] = k
# add ui elements to window # add ui elements to window
label = QLabel("Playlists") label = QLabel("Playlists")
label.setFont(QFont("Sans", weight=QFont.Bold)) label.setFont(QFont("Sans", weight=QFont.Bold))
layout.addWidget(label) layout.addWidget(label)
layout.addWidget(listWidget) layout.addWidget(self.listWidget)
# Save button # Save button
save_button = QPushButton("Add") save_button = QPushButton("Add")
@ -35,5 +44,19 @@ class AddToPlaylistWindow(QDialog):
self.show() self.show()
def save(self): def save(self):
print(self.listWidget.selectedItems()) selected_items = [item.text() for item in self.listWidget.selectedItems()]
selected_db_ids = [self.item_dict[item] for item in selected_items]
for song in self.song_db_ids:
for playlist in selected_db_ids:
try:
with DBA.DBAccess() as db:
db.execute(
"INSERT INTO song_playlist (playlist_id, song_id) VALUES (?, ?);",
(playlist, song),
)
except Exception as e:
logging.error(
"AddToPlaylistWindow.py save() | could not insert song into playlist: {e}"
)
self.close() self.close()

View File

@ -1,19 +1,45 @@
from PyQt5.QtWidgets import QInputDialog import logging
from PyQt5.QtWidgets import QDialog, QHBoxLayout, QLineEdit, QPushButton, QVBoxLayout
import DBA
class CreatePlaylistWindow(QInputDialog): class CreatePlaylistWindow(QDialog):
def __init__(self, list_options: dict): def __init__(self):
super(CreatePlaylistWindow, self).__init__() super(CreatePlaylistWindow, self).__init__()
self.setWindowTitle("Choose") self.setWindowTitle("Create new playlist")
self.setLabelText("Enter playlist name:") layout = QVBoxLayout()
self.exec() button_layout = QHBoxLayout()
def done(self, result: int) -> None: self.input = QLineEdit()
value = self.textValue() layout.addWidget(self.input)
if result:
print(value) ok_button = QPushButton("OK")
ok_button.clicked.connect(self.save)
button_layout.addWidget(ok_button)
cancel_button = QPushButton("Cancel")
cancel_button.clicked.connect(self.cancel)
button_layout.addWidget(cancel_button)
layout.addLayout(button_layout)
self.setLayout(layout)
def save(self) -> None:
"""Creates a playlist in the database with a specific name"""
value = self.input.text()
if value == "" or value is None:
self.close()
return
else: else:
print("NOPE") try:
# FIXME: dialog box doesn't close on OK or Cancel buttons pressed... with DBA.DBAccess() as db:
# do i have to manually implement the accept and reject when i override the done() func? db.execute("INSERT INTO playlist (name) VALUES (?);", (value,))
except Exception as e:
logging.error(
f"CreatePlaylistWindow.py save() | Could not create playlist: {e}"
)
self.close()
def cancel(self) -> None:
self.close() self.close()
return

View File

@ -19,6 +19,7 @@ from PyQt5.QtWidgets import (
from PyQt5.QtCore import QAbstractItemModel, QModelIndex, Qt, pyqtSignal, QTimer from PyQt5.QtCore import QAbstractItemModel, QModelIndex, Qt, pyqtSignal, QTimer
from components.LyricsWindow import LyricsWindow from components.LyricsWindow import LyricsWindow
from components.AddToPlaylistWindow import AddToPlaylistWindow from components.AddToPlaylistWindow import AddToPlaylistWindow
from utils import delete_song_id_from_database
from utils import add_files_to_library from utils import add_files_to_library
from utils import update_song_in_library from utils import update_song_in_library
from utils import get_id3_tags from utils import get_id3_tags
@ -66,6 +67,8 @@ class MusicTable(QTableView):
"TDRC", "TDRC",
None, None,
] ]
# hide the id column
self.hideColumn(0)
# db names of headers # db names of headers
self.database_columns = str(self.config["table"]["columns"]).split(",") self.database_columns = str(self.config["table"]["columns"]).split(",")
self.vertical_scroll_position = 0 self.vertical_scroll_position = 0
@ -124,13 +127,18 @@ class MusicTable(QTableView):
selected_indices = self.get_selected_rows() selected_indices = self.get_selected_rows()
for file in selected_filepaths: for file in selected_filepaths:
with DBA.DBAccess() as db: with DBA.DBAccess() as db:
db.execute("DELETE FROM song WHERE filepath = ?", (file,)) song_id = db.query(
"SELECT id FROM song WHERE filepath = ?", (file,)
)[0][0]
delete_song_id_from_database(song_id)
self.model.dataChanged.disconnect(self.on_cell_data_changed)
for index in selected_indices: for index in selected_indices:
try: try:
model.removeRow(index) model.removeRow(index)
except Exception as e: except Exception as e:
logging.info(f"MusicTable.py delete_songs() failed | {e}") logging.info(f"MusicTable.py delete_songs() failed | {e}")
self.fetch_library() self.fetch_library()
self.model.dataChanged.connect(self.on_cell_data_changed)
def open_directory(self): def open_directory(self):
"""Opens the currently selected song in the system file manager""" """Opens the currently selected song in the system file manager"""
@ -157,11 +165,14 @@ class MusicTable(QTableView):
def add_selected_files_to_playlist(self): def add_selected_files_to_playlist(self):
"""Opens a playlist choice menu and adds the currently selected files to the chosen playlist""" """Opens a playlist choice menu and adds the currently selected files to the chosen playlist"""
playlist_dict = {} playlist_dict = {}
print(type(playlist_dict))
with DBA.DBAccess() as db: with DBA.DBAccess() as db:
data = db.query("SELECT id, name from playlist", ()) data = db.query("SELECT id, name from playlist;", ())
for row in data: for row in data:
playlist_dict[row[0][0]] = row[0][1] playlist_dict[row[0]] = row[1]
playlist_choice_window = AddToPlaylistWindow(playlist_dict) playlist_choice_window = AddToPlaylistWindow(
playlist_dict, self.get_selected_songs_db_ids()
)
playlist_choice_window.exec_() playlist_choice_window.exec_()
def show_lyrics_menu(self): def show_lyrics_menu(self):
@ -387,6 +398,23 @@ class MusicTable(QTableView):
"""Returns the selected song's ID3 tags""" """Returns the selected song's ID3 tags"""
return get_id3_tags(self.selected_song_filepath) return get_id3_tags(self.selected_song_filepath)
def get_selected_songs_db_ids(self) -> list:
"""Returns a list of id's for the selected songs"""
indexes = self.selectedIndexes()
if not indexes:
return []
selected_rows = set(index.row() for index in indexes)
id_list = [
self.model.data(self.model.index(row, 0), Qt.UserRole)
for row in selected_rows
]
# selected_ids = []
# for index in indexes:
# model_item = self.model.item(index.row())
# id_data = model_item.data(Qt.UserRole)
# selected_ids.append(id_data)
return id_list
def get_current_song_filepath(self) -> str: def get_current_song_filepath(self) -> str:
"""Returns the currently playing song filepath""" """Returns the currently playing song filepath"""
return self.current_song_filepath return self.current_song_filepath

View File

@ -573,7 +573,7 @@ class MainWindow(QMainWindow):
def create_playlist(self) -> None: def create_playlist(self) -> None:
"""Creates a database record for a playlist, given a name""" """Creates a database record for a playlist, given a name"""
create_playlist_window = CreatePlaylistWindow(self) create_playlist_window = CreatePlaylistWindow()
create_playlist_window.exec_() create_playlist_window.exec_()
def open_preferences(self) -> None: def open_preferences(self) -> None:
@ -651,6 +651,7 @@ if __name__ == "__main__":
for statement in lines.split(";"): for statement in lines.split(";"):
print(f"executing [{statement}]") print(f"executing [{statement}]")
db.execute(statement, ()) db.execute(statement, ())
# logging setup # logging setup
logging.basicConfig(filename="musicpom.log", encoding="utf-8", level=logging.DEBUG) logging.basicConfig(filename="musicpom.log", encoding="utf-8", level=logging.DEBUG)
# Allow for dynamic imports of my custom classes and utilities # Allow for dynamic imports of my custom classes and utilities

View File

@ -5,6 +5,7 @@ from .safe_get import safe_get
from .get_album_art import get_album_art from .get_album_art import get_album_art
from .get_id3_tags import get_id3_tags from .get_id3_tags import get_id3_tags
from .set_id3_tag import set_id3_tag from .set_id3_tag import set_id3_tag
from .delete_song_id_from_database import delete_song_id_from_database
from .delete_and_create_library_database import delete_and_create_library_database from .delete_and_create_library_database import delete_and_create_library_database
from .update_song_in_library import update_song_in_library from .update_song_in_library import update_song_in_library
from .scan_for_music import scan_for_music from .scan_for_music import scan_for_music

View File

@ -0,0 +1,23 @@
import DBA
from components.ErrorDialog import ErrorDialog
def delete_song_id_from_database(song_id: int):
"""
Handles deleting a song from the database by ID
Accounts for playlists and other dependencies
Returns True on success
False on failure/error
"""
try:
with DBA.DBAccess() as db:
db.execute("DELETE FROM song_playlist WHERE song_id = ?", (song_id,))
db.execute("DELETE FROM song WHERE id = ?", (song_id,))
except Exception as e:
dialog = ErrorDialog(
f"delete_song_id_from_database.py | could not delete song id {song_id} from database: {e}"
)
dialog.exec_()
return False
return True