playlist adding working. delete song from db needs fix
This commit is contained in:
parent
58df3d8c9b
commit
68590deea2
@ -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()
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
3
main.py
3
main.py
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
23
utils/delete_song_id_from_database.py
Normal file
23
utils/delete_song_id_from_database.py
Normal 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
|
||||||
Loading…
x
Reference in New Issue
Block a user