MusicTable logical organization, selected cell highlighting, add_files_to_library add_files_to_database rename for clarity
This commit is contained in:
parent
29182d5ca6
commit
257e09c241
@ -41,7 +41,7 @@ from utils.batch_delete_filepaths_from_database import (
|
|||||||
batch_delete_filepaths_from_database,
|
batch_delete_filepaths_from_database,
|
||||||
)
|
)
|
||||||
from utils.delete_song_id_from_database import delete_song_id_from_database
|
from utils.delete_song_id_from_database import delete_song_id_from_database
|
||||||
from utils.add_files_to_library import add_files_to_library
|
from utils.add_files_to_database import add_files_to_database
|
||||||
from utils.get_reorganize_vars import get_reorganize_vars
|
from utils.get_reorganize_vars import get_reorganize_vars
|
||||||
from utils.update_song_in_database import update_song_in_database
|
from utils.update_song_in_database import update_song_in_database
|
||||||
from utils.get_id3_tags import get_id3_tags
|
from utils.get_id3_tags import get_id3_tags
|
||||||
@ -190,19 +190,17 @@ class MusicTable(QTableView):
|
|||||||
super().paintEvent(e)
|
super().paintEvent(e)
|
||||||
|
|
||||||
# Check if we have a current cell
|
# Check if we have a current cell
|
||||||
if self.current_index and self.current_index.isValid():
|
current_index = self.currentIndex()
|
||||||
|
if current_index and current_index.isValid():
|
||||||
# Get the visual rect for the current cell
|
# Get the visual rect for the current cell
|
||||||
rect = self.visualRect(self.current_index)
|
rect = self.visualRect(current_index)
|
||||||
|
|
||||||
# Create a painter for custom drawing
|
# Create a painter for custom drawing
|
||||||
painter = QPainter(self.viewport())
|
with QPainter(self.viewport()) as painter:
|
||||||
|
|
||||||
# Draw a border around the current cell
|
# Draw a border around the current cell
|
||||||
pen = QPen(QColor("#4a90e2"), 2) # Blue, 2px width
|
pen = QPen(QColor("#4a90e2"), 2) # Blue, 2px width
|
||||||
|
|
||||||
painter.setPen(pen)
|
painter.setPen(pen)
|
||||||
painter.drawRect(rect.adjusted(1, 1, -1, -1))
|
painter.drawRect(rect.adjusted(1, 1, -1, -1))
|
||||||
painter.end()
|
|
||||||
|
|
||||||
def contextMenuEvent(self, a0):
|
def contextMenuEvent(self, a0):
|
||||||
"""Right-click context menu for rows in Music Table"""
|
"""Right-click context menu for rows in Music Table"""
|
||||||
@ -283,7 +281,7 @@ class MusicTable(QTableView):
|
|||||||
threadpool = self.qapp.threadpool
|
threadpool = self.qapp.threadpool
|
||||||
threadpool.start(worker)
|
threadpool.start(worker)
|
||||||
if files:
|
if files:
|
||||||
self.add_files(files)
|
self.add_files_to_library(files)
|
||||||
else:
|
else:
|
||||||
e.ignore()
|
e.ignore()
|
||||||
|
|
||||||
@ -293,44 +291,48 @@ class MusicTable(QTableView):
|
|||||||
return
|
return
|
||||||
|
|
||||||
key = e.key()
|
key = e.key()
|
||||||
if key == Qt.Key.Key_Space: # Spacebar to play/pause
|
if key == Qt.Key.Key_Space:
|
||||||
self.toggle_play_pause()
|
self.toggle_play_pause()
|
||||||
|
|
||||||
elif key == Qt.Key.Key_Right:
|
elif key == Qt.Key.Key_Right:
|
||||||
current_index = self.currentIndex()
|
index = self.currentIndex()
|
||||||
new_index = self.model2.index(
|
new_index = self.model2.index(index.row(), index.column() + 1)
|
||||||
current_index.row(), current_index.column() + 1
|
|
||||||
)
|
|
||||||
if new_index.isValid():
|
if new_index.isValid():
|
||||||
|
print(f"right -> ({new_index.row()},{new_index.column()})")
|
||||||
self.setCurrentIndex(new_index)
|
self.setCurrentIndex(new_index)
|
||||||
|
self.viewport().update() # type: ignore
|
||||||
super().keyPressEvent(e)
|
super().keyPressEvent(e)
|
||||||
|
return
|
||||||
|
|
||||||
elif key == Qt.Key.Key_Left:
|
elif key == Qt.Key.Key_Left:
|
||||||
current_index = self.currentIndex()
|
index = self.currentIndex()
|
||||||
new_index = self.model2.index(
|
new_index = self.model2.index(index.row(), index.column() - 1)
|
||||||
current_index.row(), current_index.column() - 1
|
|
||||||
)
|
|
||||||
if new_index.isValid():
|
if new_index.isValid():
|
||||||
|
print(f"left -> ({new_index.row()},{new_index.column()})")
|
||||||
self.setCurrentIndex(new_index)
|
self.setCurrentIndex(new_index)
|
||||||
|
self.viewport().update() # type: ignore
|
||||||
super().keyPressEvent(e)
|
super().keyPressEvent(e)
|
||||||
|
return
|
||||||
|
|
||||||
elif key == Qt.Key.Key_Up:
|
elif key == Qt.Key.Key_Up:
|
||||||
current_index = self.currentIndex()
|
index = self.currentIndex()
|
||||||
new_index = self.model2.index(
|
new_index = self.model2.index(index.row() - 1, index.column())
|
||||||
current_index.row() - 1, current_index.column()
|
|
||||||
)
|
|
||||||
if new_index.isValid():
|
if new_index.isValid():
|
||||||
|
print(f"up -> ({new_index.row()},{new_index.column()})")
|
||||||
self.setCurrentIndex(new_index)
|
self.setCurrentIndex(new_index)
|
||||||
|
self.viewport().update() # type: ignore
|
||||||
super().keyPressEvent(e)
|
super().keyPressEvent(e)
|
||||||
|
return
|
||||||
|
|
||||||
elif key == Qt.Key.Key_Down:
|
elif key == Qt.Key.Key_Down:
|
||||||
current_index = self.currentIndex()
|
index = self.currentIndex()
|
||||||
new_index = self.model2.index(
|
new_index = self.model2.index(index.row() + 1, index.column())
|
||||||
current_index.row() + 1, current_index.column()
|
|
||||||
)
|
|
||||||
if new_index.isValid():
|
if new_index.isValid():
|
||||||
|
print(f"down -> ({new_index.row()},{new_index.column()})")
|
||||||
self.setCurrentIndex(new_index)
|
self.setCurrentIndex(new_index)
|
||||||
|
self.viewport().update() # type: ignore
|
||||||
super().keyPressEvent(e)
|
super().keyPressEvent(e)
|
||||||
|
return
|
||||||
|
|
||||||
elif key in (Qt.Key.Key_Return, Qt.Key.Key_Enter):
|
elif key in (Qt.Key.Key_Return, Qt.Key.Key_Enter):
|
||||||
if self.state() != QAbstractItemView.EditingState:
|
if self.state() != QAbstractItemView.EditingState:
|
||||||
@ -351,10 +353,11 @@ class MusicTable(QTableView):
|
|||||||
"""
|
"""
|
||||||
When a cell is clicked, do some stuff :)
|
When a cell is clicked, do some stuff :)
|
||||||
"""
|
"""
|
||||||
if index == self.current_index:
|
print(f"click - ({index.row()}, {index.column()})")
|
||||||
print("nope")
|
current_index = self.currentIndex()
|
||||||
|
if index == current_index:
|
||||||
return
|
return
|
||||||
self.current_index = index
|
self.setCurrentIndex(index)
|
||||||
self.set_selected_song_filepath()
|
self.set_selected_song_filepath()
|
||||||
self.viewport().update() # type: ignore
|
self.viewport().update() # type: ignore
|
||||||
|
|
||||||
@ -408,66 +411,19 @@ class MusicTable(QTableView):
|
|||||||
def on_recursive_search_finished(self, result):
|
def on_recursive_search_finished(self, result):
|
||||||
"""file search completion handler"""
|
"""file search completion handler"""
|
||||||
if result:
|
if result:
|
||||||
self.add_files(result)
|
self.add_files_to_library(result)
|
||||||
|
|
||||||
|
def handle_progress(self, data):
|
||||||
|
"""Emits data to main"""
|
||||||
|
self.handleProgressSignal.emit(data)
|
||||||
|
|
||||||
# ____________________
|
# ____________________
|
||||||
# | |
|
# | |
|
||||||
# | |
|
# | |
|
||||||
# | Verbs |
|
# | Connection Mgmt |
|
||||||
# | |
|
# | |
|
||||||
# |____________________|
|
# |____________________|
|
||||||
|
|
||||||
def load_header_widths(self):
|
|
||||||
"""
|
|
||||||
Loads the header widths from the last application close.
|
|
||||||
"""
|
|
||||||
table_view_column_widths = str(self.config["table"]["column_widths"]).split(",")
|
|
||||||
if not isinstance(table_view_column_widths[0], int):
|
|
||||||
return
|
|
||||||
if not isinstance(table_view_column_widths, list):
|
|
||||||
for i in range(self.model2.columnCount() - 1):
|
|
||||||
self.setColumnWidth(i, int(table_view_column_widths[i]))
|
|
||||||
|
|
||||||
def sort_table_by_multiple_columns(self):
|
|
||||||
"""
|
|
||||||
Sorts the data in QTableView (self) by multiple columns
|
|
||||||
as defined in config.ini
|
|
||||||
"""
|
|
||||||
# TODO: Rewrite this function to use self.load_music_table() with dynamic SQL queries
|
|
||||||
# in order to sort the data more effectively & have more control over UI refreshes.
|
|
||||||
|
|
||||||
# Disconnect these signals to prevent unnecessary loads
|
|
||||||
debug("sort_table_by_multiple_columns()")
|
|
||||||
self.disconnect_data_changed()
|
|
||||||
self.disconnect_layout_changed()
|
|
||||||
sort_orders = []
|
|
||||||
config_sort_orders: list[int] = [
|
|
||||||
int(x) for x in self.config["table"]["sort_orders"].split(",")
|
|
||||||
]
|
|
||||||
for order in config_sort_orders:
|
|
||||||
if order == 0:
|
|
||||||
sort_orders.append(None)
|
|
||||||
elif order == 1:
|
|
||||||
sort_orders.append(Qt.SortOrder.AscendingOrder)
|
|
||||||
elif order == 2:
|
|
||||||
sort_orders.append(Qt.SortOrder.DescendingOrder)
|
|
||||||
|
|
||||||
# QTableView sorts need to happen in reverse order
|
|
||||||
# The primary sort column is the last column sorted.
|
|
||||||
for i in reversed(range(len(sort_orders))):
|
|
||||||
if sort_orders[i] is not None:
|
|
||||||
debug(f"sorting column {i} by {sort_orders[i]}")
|
|
||||||
self.sortByColumn(i, sort_orders[i])
|
|
||||||
# WARNING:
|
|
||||||
# sortByColumn calls a SELECT statement,
|
|
||||||
# and will do this for as many sorts that are needed
|
|
||||||
# maybe not a huge deal for a small music application...?
|
|
||||||
# `len(config_sort_orders)` number of SELECTs
|
|
||||||
|
|
||||||
self.connect_data_changed()
|
|
||||||
self.connect_layout_changed()
|
|
||||||
# self.model2.layoutChanged.emit()
|
|
||||||
|
|
||||||
def disconnect_data_changed(self):
|
def disconnect_data_changed(self):
|
||||||
"""Disconnects the dataChanged signal from QTableView.model"""
|
"""Disconnects the dataChanged signal from QTableView.model"""
|
||||||
try:
|
try:
|
||||||
@ -496,14 +452,32 @@ class MusicTable(QTableView):
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def show_id3_tags_debug_menu(self):
|
# ____________________
|
||||||
"""Shows ID3 tags for a specific .mp3 file"""
|
# | |
|
||||||
selected_song_filepath = self.get_selected_song_filepath()
|
# | |
|
||||||
if selected_song_filepath is None:
|
# | Verbs |
|
||||||
return
|
# | |
|
||||||
current_song = self.get_selected_song_metadata()
|
# |____________________|
|
||||||
lyrics_window = DebugWindow(selected_song_filepath, str(current_song))
|
|
||||||
lyrics_window.exec_()
|
def add_files_to_library(self, files: list[str]) -> None:
|
||||||
|
"""
|
||||||
|
Spawns a worker thread - adds a list of filepaths to the library
|
||||||
|
- Drag & Drop song(s) on tableView
|
||||||
|
- File > Open > List of song(s)
|
||||||
|
"""
|
||||||
|
worker = Worker(add_files_to_database, files)
|
||||||
|
worker.signals.signal_progress.connect(self.qapp.handle_progress)
|
||||||
|
worker.signals.signal_finished.connect(self.load_music_table)
|
||||||
|
if self.qapp:
|
||||||
|
threadpool = self.qapp.threadpool
|
||||||
|
threadpool.start(worker)
|
||||||
|
else:
|
||||||
|
error("Application window could not be found")
|
||||||
|
|
||||||
|
def add_selected_files_to_playlist(self):
|
||||||
|
"""Opens a playlist choice menu and adds the currently selected files to the chosen playlist"""
|
||||||
|
playlist_choice_window = AddToPlaylistWindow(self.get_selected_songs_db_ids())
|
||||||
|
playlist_choice_window.exec_()
|
||||||
|
|
||||||
def delete_songs(self):
|
def delete_songs(self):
|
||||||
"""Asks to delete the currently selected songs from the db and music table (not the filesystem)"""
|
"""Asks to delete the currently selected songs from the db and music table (not the filesystem)"""
|
||||||
@ -518,13 +492,13 @@ class MusicTable(QTableView):
|
|||||||
selected_filepaths = self.get_selected_songs_filepaths()
|
selected_filepaths = self.get_selected_songs_filepaths()
|
||||||
worker = Worker(batch_delete_filepaths_from_database, selected_filepaths)
|
worker = Worker(batch_delete_filepaths_from_database, selected_filepaths)
|
||||||
worker.signals.signal_progress.connect(self.qapp.handle_progress)
|
worker.signals.signal_progress.connect(self.qapp.handle_progress)
|
||||||
worker.signals.signal_finished.connect(self.remove_selected_row_indices)
|
worker.signals.signal_finished.connect(self.delete_selected_row_indices)
|
||||||
worker.signals.signal_finished.connect(self.load_music_table)
|
worker.signals.signal_finished.connect(self.load_music_table)
|
||||||
if self.qapp:
|
if self.qapp:
|
||||||
threadpool = self.qapp.threadpool
|
threadpool = self.qapp.threadpool
|
||||||
threadpool.start(worker)
|
threadpool.start(worker)
|
||||||
|
|
||||||
def remove_selected_row_indices(self):
|
def delete_selected_row_indices(self):
|
||||||
"""Removes rows from the QTableView based on a list of indices"""
|
"""Removes rows from the QTableView based on a list of indices"""
|
||||||
selected_indices = self.get_selected_rows()
|
selected_indices = self.get_selected_rows()
|
||||||
self.disconnect_data_changed()
|
self.disconnect_data_changed()
|
||||||
@ -535,6 +509,14 @@ class MusicTable(QTableView):
|
|||||||
debug(f" delete_songs() failed | {e}")
|
debug(f" delete_songs() failed | {e}")
|
||||||
self.connect_data_changed()
|
self.connect_data_changed()
|
||||||
|
|
||||||
|
def edit_selected_files_metadata(self):
|
||||||
|
"""Opens a form with metadata from the selected audio files"""
|
||||||
|
files = self.get_selected_songs_filepaths()
|
||||||
|
song_ids = self.get_selected_songs_db_ids()
|
||||||
|
window = MetadataWindow(self.refreshMusicTable, files, song_ids)
|
||||||
|
window.refreshMusicTableSignal.connect(self.load_music_table)
|
||||||
|
window.exec_() # Display the preferences window modally
|
||||||
|
|
||||||
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"""
|
||||||
if self.get_selected_song_filepath() is None:
|
if self.get_selected_song_filepath() is None:
|
||||||
@ -551,18 +533,14 @@ class MusicTable(QTableView):
|
|||||||
path = "/".join(filepath)
|
path = "/".join(filepath)
|
||||||
Popen(["xdg-open", path])
|
Popen(["xdg-open", path])
|
||||||
|
|
||||||
def edit_selected_files_metadata(self):
|
def show_id3_tags_debug_menu(self):
|
||||||
"""Opens a form with metadata from the selected audio files"""
|
"""Shows ID3 tags for a specific .mp3 file"""
|
||||||
files = self.get_selected_songs_filepaths()
|
selected_song_filepath = self.get_selected_song_filepath()
|
||||||
song_ids = self.get_selected_songs_db_ids()
|
if selected_song_filepath is None:
|
||||||
window = MetadataWindow(self.refreshMusicTable, files, song_ids)
|
return
|
||||||
window.refreshMusicTableSignal.connect(self.load_music_table)
|
current_song = self.get_selected_song_metadata()
|
||||||
window.exec_() # Display the preferences window modally
|
lyrics_window = DebugWindow(selected_song_filepath, str(current_song))
|
||||||
|
lyrics_window.exec_()
|
||||||
def add_selected_files_to_playlist(self):
|
|
||||||
"""Opens a playlist choice menu and adds the currently selected files to the chosen playlist"""
|
|
||||||
playlist_choice_window = AddToPlaylistWindow(self.get_selected_songs_db_ids())
|
|
||||||
playlist_choice_window.exec_()
|
|
||||||
|
|
||||||
def show_lyrics_menu(self):
|
def show_lyrics_menu(self):
|
||||||
"""Shows the lyrics for the currently selected song"""
|
"""Shows the lyrics for the currently selected song"""
|
||||||
@ -590,10 +568,6 @@ class MusicTable(QTableView):
|
|||||||
shortcut = QShortcut(QKeySequence("Delete"), self)
|
shortcut = QShortcut(QKeySequence("Delete"), self)
|
||||||
shortcut.activated.connect(self.delete_songs)
|
shortcut.activated.connect(self.delete_songs)
|
||||||
|
|
||||||
def handle_progress(self, data):
|
|
||||||
"""Emits data to main"""
|
|
||||||
self.handleProgressSignal.emit(data)
|
|
||||||
|
|
||||||
def confirm_reorganize_files(self) -> None:
|
def confirm_reorganize_files(self) -> None:
|
||||||
"""
|
"""
|
||||||
Ctrl+Shift+R = Reorganize
|
Ctrl+Shift+R = Reorganize
|
||||||
@ -665,21 +639,6 @@ class MusicTable(QTableView):
|
|||||||
self.set_current_song_filepath()
|
self.set_current_song_filepath()
|
||||||
self.playPauseSignal.emit()
|
self.playPauseSignal.emit()
|
||||||
|
|
||||||
def add_files(self, files: list[str]) -> None:
|
|
||||||
"""
|
|
||||||
Spawns a worker thread - adds a list of filepaths to the library
|
|
||||||
- Drag & Drop song(s) on tableView
|
|
||||||
- File > Open > List of song(s)
|
|
||||||
"""
|
|
||||||
worker = Worker(add_files_to_library, files)
|
|
||||||
worker.signals.signal_progress.connect(self.qapp.handle_progress)
|
|
||||||
worker.signals.signal_finished.connect(self.load_music_table)
|
|
||||||
if self.qapp:
|
|
||||||
threadpool = self.qapp.threadpool
|
|
||||||
threadpool.start(worker)
|
|
||||||
else:
|
|
||||||
error("Application window could not be found")
|
|
||||||
|
|
||||||
def load_music_table(self, *playlist_id):
|
def load_music_table(self, *playlist_id):
|
||||||
"""
|
"""
|
||||||
Loads data into self (QTableView)
|
Loads data into self (QTableView)
|
||||||
@ -741,6 +700,57 @@ class MusicTable(QTableView):
|
|||||||
self.connect_data_changed()
|
self.connect_data_changed()
|
||||||
self.connect_layout_changed()
|
self.connect_layout_changed()
|
||||||
|
|
||||||
|
def load_header_widths(self):
|
||||||
|
"""
|
||||||
|
Loads the header widths from the last application close.
|
||||||
|
"""
|
||||||
|
table_view_column_widths = str(self.config["table"]["column_widths"]).split(",")
|
||||||
|
if not isinstance(table_view_column_widths[0], int):
|
||||||
|
return
|
||||||
|
if not isinstance(table_view_column_widths, list):
|
||||||
|
for i in range(self.model2.columnCount() - 1):
|
||||||
|
self.setColumnWidth(i, int(table_view_column_widths[i]))
|
||||||
|
|
||||||
|
def sort_table_by_multiple_columns(self):
|
||||||
|
"""
|
||||||
|
Sorts the data in QTableView (self) by multiple columns
|
||||||
|
as defined in config.ini
|
||||||
|
"""
|
||||||
|
# TODO: Rewrite this function to use self.load_music_table() with dynamic SQL queries
|
||||||
|
# in order to sort the data more effectively & have more control over UI refreshes.
|
||||||
|
|
||||||
|
# Disconnect these signals to prevent unnecessary loads
|
||||||
|
debug("sort_table_by_multiple_columns()")
|
||||||
|
self.disconnect_data_changed()
|
||||||
|
self.disconnect_layout_changed()
|
||||||
|
sort_orders = []
|
||||||
|
config_sort_orders: list[int] = [
|
||||||
|
int(x) for x in self.config["table"]["sort_orders"].split(",")
|
||||||
|
]
|
||||||
|
for order in config_sort_orders:
|
||||||
|
if order == 0:
|
||||||
|
sort_orders.append(None)
|
||||||
|
elif order == 1:
|
||||||
|
sort_orders.append(Qt.SortOrder.AscendingOrder)
|
||||||
|
elif order == 2:
|
||||||
|
sort_orders.append(Qt.SortOrder.DescendingOrder)
|
||||||
|
|
||||||
|
# QTableView sorts need to happen in reverse order
|
||||||
|
# The primary sort column is the last column sorted.
|
||||||
|
for i in reversed(range(len(sort_orders))):
|
||||||
|
if sort_orders[i] is not None:
|
||||||
|
debug(f"sorting column {i} by {sort_orders[i]}")
|
||||||
|
self.sortByColumn(i, sort_orders[i])
|
||||||
|
# WARNING:
|
||||||
|
# sortByColumn calls a SELECT statement,
|
||||||
|
# and will do this for as many sorts that are needed
|
||||||
|
# maybe not a huge deal for a small music application...?
|
||||||
|
# `len(config_sort_orders)` number of SELECTs
|
||||||
|
|
||||||
|
self.connect_data_changed()
|
||||||
|
self.connect_layout_changed()
|
||||||
|
# self.model2.layoutChanged.emit()
|
||||||
|
|
||||||
def restore_scroll_position(self) -> None:
|
def restore_scroll_position(self) -> None:
|
||||||
"""Restores the scroll position"""
|
"""Restores the scroll position"""
|
||||||
debug("restore_scroll_position")
|
debug("restore_scroll_position")
|
||||||
|
|||||||
5
main.py
5
main.py
@ -11,7 +11,6 @@ from mutagen.id3 import ID3
|
|||||||
from mutagen.id3._frames import APIC
|
from mutagen.id3._frames import APIC
|
||||||
from configparser import ConfigParser
|
from configparser import ConfigParser
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from numpy import where as npwhere
|
|
||||||
from appdirs import user_config_dir
|
from appdirs import user_config_dir
|
||||||
from logging import debug, error, warning, basicConfig, INFO, DEBUG
|
from logging import debug, error, warning, basicConfig, INFO, DEBUG
|
||||||
from ui import Ui_MainWindow
|
from ui import Ui_MainWindow
|
||||||
@ -40,7 +39,7 @@ from PyQt5.QtGui import QClipboard, QCloseEvent, QPixmap, QResizeEvent
|
|||||||
from utils import (
|
from utils import (
|
||||||
scan_for_music,
|
scan_for_music,
|
||||||
initialize_db,
|
initialize_db,
|
||||||
add_files_to_library,
|
add_files_to_database,
|
||||||
)
|
)
|
||||||
from components import (
|
from components import (
|
||||||
PreferencesWindow,
|
PreferencesWindow,
|
||||||
@ -545,7 +544,7 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
|
|||||||
open_files_window.exec_()
|
open_files_window.exec_()
|
||||||
filenames = open_files_window.selectedFiles()
|
filenames = open_files_window.selectedFiles()
|
||||||
# Adds files to the library in a new thread
|
# Adds files to the library in a new thread
|
||||||
worker = Worker(add_files_to_library, filenames)
|
worker = Worker(add_files_to_database, filenames)
|
||||||
worker.signals.signal_finished.connect(self.tableView.load_music_table)
|
worker.signals.signal_finished.connect(self.tableView.load_music_table)
|
||||||
worker.signals.signal_progress.connect(self.handle_progress)
|
worker.signals.signal_progress.connect(self.handle_progress)
|
||||||
self.threadpool.start(worker)
|
self.threadpool.start(worker)
|
||||||
|
|||||||
@ -11,5 +11,5 @@ from .batch_delete_filepaths_from_database import batch_delete_filepaths_from_da
|
|||||||
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_database import update_song_in_database
|
from .update_song_in_database import update_song_in_database
|
||||||
from .scan_for_music import scan_for_music
|
from .scan_for_music import scan_for_music
|
||||||
from .add_files_to_library import add_files_to_library
|
from .add_files_to_database import add_files_to_database
|
||||||
from .convert_date_str_to_tyer_tdat_id3_tag import convert_date_str_to_tyer_tdat_id3_tag
|
from .convert_date_str_to_tyer_tdat_id3_tag import convert_date_str_to_tyer_tdat_id3_tag
|
||||||
|
|||||||
@ -8,9 +8,9 @@ from appdirs import user_config_dir
|
|||||||
import platform
|
import platform
|
||||||
|
|
||||||
|
|
||||||
def add_files_to_library(files, progress_callback=None):
|
def add_files_to_database(files, progress_callback=None):
|
||||||
"""
|
"""
|
||||||
Adds audio file(s) to the sqllite db
|
Adds audio file(s) to the sqllite db "song" table
|
||||||
Args:
|
Args:
|
||||||
files: list() of fully qualified paths to audio file(s)
|
files: list() of fully qualified paths to audio file(s)
|
||||||
progress_callback: emit data for user feedback
|
progress_callback: emit data for user feedback
|
||||||
@ -1,12 +1,11 @@
|
|||||||
import os
|
import os
|
||||||
from PyQt5.QtCore import pyqtSignal
|
from PyQt5.QtCore import pyqtSignal
|
||||||
from utils.add_files_to_library import add_files_to_library
|
from utils.add_files_to_database import add_files_to_database
|
||||||
from configparser import ConfigParser
|
from configparser import ConfigParser
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from appdirs import user_config_dir
|
from appdirs import user_config_dir
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def scan_for_music():
|
def scan_for_music():
|
||||||
config = ConfigParser()
|
config = ConfigParser()
|
||||||
cfg_file = (
|
cfg_file = (
|
||||||
@ -22,4 +21,4 @@ def scan_for_music():
|
|||||||
filename = os.path.join(dirpath, file)
|
filename = os.path.join(dirpath, file)
|
||||||
if any(filename.lower().endswith(ext) for ext in extensions):
|
if any(filename.lower().endswith(ext) for ext in extensions):
|
||||||
files_to_add.append(filename)
|
files_to_add.append(filename)
|
||||||
add_files_to_library(files_to_add)
|
add_files_to_database(files_to_add)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user