diff --git a/DBA.py b/DBA.py index 3ea56f5..69d6930 100644 --- a/DBA.py +++ b/DBA.py @@ -15,7 +15,7 @@ class DBAccess: ) config.read(cfg_file) if db_name is None: - db_name = config.get("db", "database") + db_name = config.get("settings", "db") self._conn: sqlite3.Connection = sqlite3.connect(db_name) self._cursor: sqlite3.Cursor = self._conn.cursor() diff --git a/README.md b/README.md index 9d2f72f..486270d 100644 --- a/README.md +++ b/README.md @@ -84,3 +84,4 @@ QMultimedia.EncodingMode / Encoding quality... - edit metadata, get metadata in another thread (freezing) - on save metadata modal, run save in another thread (freezing) - on save metadata modal, return to previous state in table (jump to current song/restore scroll position) +- on add to playlist, check if song already exists - prompt user for duplicate? diff --git a/components/ExportPlaylistWindow.py b/components/ExportPlaylistWindow.py index 7e7a306..8b12019 100644 --- a/components/ExportPlaylistWindow.py +++ b/components/ExportPlaylistWindow.py @@ -27,10 +27,9 @@ class ExportPlaylistWindow(QDialog): self.setMinimumSize(600, 400) self.load_config() self.relative_path: str = self.config.get( - "directories", "playlist_relative_path" + "settings", "playlist_content_relative_path" ) - self.current_relative_path: str = self.relative_path - self.export_path: str = self.config.get("directories", "playlist_export_path") + 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() @@ -85,8 +84,8 @@ class ExportPlaylistWindow(QDialog): layout.addWidget(label) # Playlist file save path line edit widget - self.input_m3u_path = QLineEdit(self.export_path) # not needed - layout.addWidget(self.input_m3u_path) + self.export_m3u_path = QLineEdit(self.config.get("settings", "playlist_export_path")) + layout.addWidget(self.export_m3u_path) # Save button self.save_button = QPushButton("Export") @@ -122,12 +121,14 @@ class ExportPlaylistWindow(QDialog): # Create the filename for the playlist to be exported self.selected_playlist_name = self.chosen_list_widget_item.text() + ".m3u" - # get the db id? i guess? + + # get the db id self.selected_playlist_db_id = self.item_dict[ self.chosen_list_widget_item.text() ] # 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("/") if "." in current_text[-1]: current_text = current_text[:-1] @@ -179,13 +180,13 @@ class ExportPlaylistWindow(QDialog): for song in db_paths: artist, album = get_reorganize_vars(song) write_path = os.path.join( - relative_path, artist, album, song.split("/")[-1], "\n" + relative_path, artist, album, song.split("/")[-1] + "\n" ) write_paths.append(str(write_path)) else: # Normal paths for song in db_paths: - write_paths.append(song) + write_paths.append(song + "\n") # Write playlist file TODO: add threading os.makedirs(os.path.dirname(output_filename), exist_ok=True) diff --git a/components/MusicTable.py b/components/MusicTable.py index df3d805..efdd651 100644 --- a/components/MusicTable.py +++ b/components/MusicTable.py @@ -783,8 +783,8 @@ class MusicTable(QTableView): self.current_song_qmodel_index = real_index self.model2.layoutChanged.emit() # emits a signal that the view should be updated - db_name: str = self.config.get("db", "database").split("/").pop() - db_filename = self.config.get("db", "database") + db_name: str = self.config.get("settings", "db").split("/").pop() + db_filename = self.config.get("settings", "db") self.playlistStatsSignal.emit( f"Songs: {row_count} | Total time: {total_time} | {db_name} | {db_filename}" ) diff --git a/main.py b/main.py index 0744a31..194e232 100644 --- a/main.py +++ b/main.py @@ -662,8 +662,10 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow): Scans for new files in the configured library folder then, refreshes the datagridview """ - scan_for_music() - self.tableView.load_music_table() + worker = Worker(scan_for_music) + worker.signals.signal_finished.connect(self.tableView.load_music_table) + worker.signals.signal_progress.connect(self.handle_progress) + self.threadpool.start(worker) def delete_database(self) -> None: """Deletes the entire database""" @@ -689,7 +691,7 @@ def update_database_file() -> bool: cfg_path = str(Path(user_config_dir(appname="musicpom", appauthor="billypom"))) config = ConfigParser() config.read(cfg_file) - db_filepath: str = config.get("db", "database") + db_filepath: str = config.get("settings", "db") # If the database location isnt set at the config location, move it if not db_filepath.startswith(cfg_path): @@ -702,7 +704,7 @@ def update_database_file() -> bool: with open(cfg_file, "w") as configfile: config.write(configfile) config.read(cfg_file) - db_filepath: str = config.get("db", "database") + db_filepath: str = config.get("settings", "db") db_path = db_filepath.split("/") db_path.pop() diff --git a/sample_config.ini b/sample_config.ini index d921014..2091f65 100644 --- a/sample_config.ini +++ b/sample_config.ini @@ -1,17 +1,10 @@ -[db] -# The library database file -database = db/library.db - -[directories] -# Useful paths to have stored +[settings] +db = library.db 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 - -[settings] -# Which file types are scanned extensions = mp3,wav,ogg,flac volume = 100 window_size=1152,894 diff --git a/utils/add_files_to_database.py b/utils/add_files_to_database.py index 66607cc..a675cf9 100644 --- a/utils/add_files_to_database.py +++ b/utils/add_files_to_database.py @@ -31,10 +31,8 @@ def add_files_to_database(files, progress_callback=None): failed_dict = {} insert_data = [] # To store data for batch insert for filepath in files: - try: + if progress_callback: progress_callback.emit(filepath) - except Exception: - pass filename = filepath.split("/")[-1] tags, details = get_tags(filepath) diff --git a/utils/scan_for_music.py b/utils/scan_for_music.py index a446d5d..79706f7 100644 --- a/utils/scan_for_music.py +++ b/utils/scan_for_music.py @@ -1,29 +1,33 @@ import os -from PyQt5.QtCore import pyqtSignal from utils.add_files_to_database import add_files_to_database from configparser import ConfigParser from pathlib import Path from appdirs import user_config_dir +import glob +from concurrent.futures import ThreadPoolExecutor -def scan_for_music(): + +def scan_for_music(progress_callback=None): """ - Scans the user-defined library directory (defined in config file) - Looks for audio files with specific extensions (defined in config file) - Adds found files to the database/primary library (songs table - which holds all songs :o) + Scans for audio files in user-defined paths + - Paths are defined in config file + - Accepted file extensions are defined in config file + - Adds found file to database """ + if progress_callback: + progress_callback.emit('Scanning libraries...') config = ConfigParser() - cfg_file = ( - Path(user_config_dir(appname="musicpom", appauthor="billypom")) / "config.ini" - ) - config.read(cfg_file) - root_dir = config.get("directories", "library") + config.read(Path(user_config_dir(appname="musicpom", appauthor="billypom")) / "config.ini") + libraries = [path.strip() for path in config.get("settings", "library_path").split(',')] extensions = config.get("settings", "extensions").split(",") - files_to_add = [] - # for dirpath, dirnames, filenames ... - for dirpath, _, filenames in os.walk(root_dir): - for file in filenames: - filename = os.path.join(dirpath, file) - if any(filename.lower().endswith(ext) for ext in extensions): - files_to_add.append(filename) - add_files_to_database(files_to_add) + + # Use each library as root dir, walk the dir and find files + for library in libraries: + files_to_add = [] + for dirpath, _, filenames in os.walk(library): + for file in filenames: + filename = os.path.join(dirpath, file) + if any(filename.lower().endswith(ext) for ext in extensions): + files_to_add.append(filename) + add_files_to_database(files_to_add, progress_callback)