scan files thread
This commit is contained in:
parent
be9f17a89d
commit
5adb760d83
2
DBA.py
2
DBA.py
@ -15,7 +15,7 @@ class DBAccess:
|
|||||||
)
|
)
|
||||||
config.read(cfg_file)
|
config.read(cfg_file)
|
||||||
if db_name is None:
|
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._conn: sqlite3.Connection = sqlite3.connect(db_name)
|
||||||
self._cursor: sqlite3.Cursor = self._conn.cursor()
|
self._cursor: sqlite3.Cursor = self._conn.cursor()
|
||||||
|
|
||||||
|
|||||||
@ -84,3 +84,4 @@ QMultimedia.EncodingMode / Encoding quality...
|
|||||||
- edit metadata, get metadata in another thread (freezing)
|
- edit metadata, get metadata in another thread (freezing)
|
||||||
- on save metadata modal, run save 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 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?
|
||||||
|
|||||||
@ -27,10 +27,9 @@ class ExportPlaylistWindow(QDialog):
|
|||||||
self.setMinimumSize(600, 400)
|
self.setMinimumSize(600, 400)
|
||||||
self.load_config()
|
self.load_config()
|
||||||
self.relative_path: str = self.config.get(
|
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("settings", "playlist_export_path")
|
||||||
self.export_path: str = self.config.get("directories", "playlist_export_path")
|
|
||||||
self.selected_playlist_name: str = "my-playlist.m3u"
|
self.selected_playlist_name: str = "my-playlist.m3u"
|
||||||
self.chosen_list_widget_item: QListWidgetItem | None = None
|
self.chosen_list_widget_item: QListWidgetItem | None = None
|
||||||
layout = self.setup_ui()
|
layout = self.setup_ui()
|
||||||
@ -85,8 +84,8 @@ class ExportPlaylistWindow(QDialog):
|
|||||||
layout.addWidget(label)
|
layout.addWidget(label)
|
||||||
|
|
||||||
# Playlist file save path line edit widget
|
# Playlist file save path line edit widget
|
||||||
self.input_m3u_path = QLineEdit(self.export_path) # not needed
|
self.export_m3u_path = QLineEdit(self.config.get("settings", "playlist_export_path"))
|
||||||
layout.addWidget(self.input_m3u_path)
|
layout.addWidget(self.export_m3u_path)
|
||||||
|
|
||||||
# Save button
|
# Save button
|
||||||
self.save_button = QPushButton("Export")
|
self.save_button = QPushButton("Export")
|
||||||
@ -122,12 +121,14 @@ class ExportPlaylistWindow(QDialog):
|
|||||||
|
|
||||||
# Create the filename for the playlist to be exported
|
# Create the filename for the playlist to be exported
|
||||||
self.selected_playlist_name = self.chosen_list_widget_item.text() + ".m3u"
|
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.selected_playlist_db_id = self.item_dict[
|
||||||
self.chosen_list_widget_item.text()
|
self.chosen_list_widget_item.text()
|
||||||
]
|
]
|
||||||
|
|
||||||
# alter line edit text for playlist path
|
# 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.input_m3u_path.text().split("/")
|
||||||
if "." in current_text[-1]:
|
if "." in current_text[-1]:
|
||||||
current_text = current_text[:-1]
|
current_text = current_text[:-1]
|
||||||
@ -179,13 +180,13 @@ class ExportPlaylistWindow(QDialog):
|
|||||||
for song in db_paths:
|
for song in db_paths:
|
||||||
artist, album = get_reorganize_vars(song)
|
artist, album = get_reorganize_vars(song)
|
||||||
write_path = os.path.join(
|
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))
|
write_paths.append(str(write_path))
|
||||||
else:
|
else:
|
||||||
# Normal paths
|
# Normal paths
|
||||||
for song in db_paths:
|
for song in db_paths:
|
||||||
write_paths.append(song)
|
write_paths.append(song + "\n")
|
||||||
|
|
||||||
# Write playlist file TODO: add threading
|
# Write playlist file TODO: add threading
|
||||||
os.makedirs(os.path.dirname(output_filename), exist_ok=True)
|
os.makedirs(os.path.dirname(output_filename), exist_ok=True)
|
||||||
|
|||||||
@ -783,8 +783,8 @@ class MusicTable(QTableView):
|
|||||||
self.current_song_qmodel_index = real_index
|
self.current_song_qmodel_index = real_index
|
||||||
self.model2.layoutChanged.emit() # emits a signal that the view should be updated
|
self.model2.layoutChanged.emit() # emits a signal that the view should be updated
|
||||||
|
|
||||||
db_name: str = self.config.get("db", "database").split("/").pop()
|
db_name: str = self.config.get("settings", "db").split("/").pop()
|
||||||
db_filename = self.config.get("db", "database")
|
db_filename = self.config.get("settings", "db")
|
||||||
self.playlistStatsSignal.emit(
|
self.playlistStatsSignal.emit(
|
||||||
f"Songs: {row_count} | Total time: {total_time} | {db_name} | {db_filename}"
|
f"Songs: {row_count} | Total time: {total_time} | {db_name} | {db_filename}"
|
||||||
)
|
)
|
||||||
|
|||||||
10
main.py
10
main.py
@ -662,8 +662,10 @@ class ApplicationWindow(QMainWindow, Ui_MainWindow):
|
|||||||
Scans for new files in the configured library folder
|
Scans for new files in the configured library folder
|
||||||
then, refreshes the datagridview
|
then, refreshes the datagridview
|
||||||
"""
|
"""
|
||||||
scan_for_music()
|
worker = Worker(scan_for_music)
|
||||||
self.tableView.load_music_table()
|
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:
|
def delete_database(self) -> None:
|
||||||
"""Deletes the entire database"""
|
"""Deletes the entire database"""
|
||||||
@ -689,7 +691,7 @@ def update_database_file() -> bool:
|
|||||||
cfg_path = str(Path(user_config_dir(appname="musicpom", appauthor="billypom")))
|
cfg_path = str(Path(user_config_dir(appname="musicpom", appauthor="billypom")))
|
||||||
config = ConfigParser()
|
config = ConfigParser()
|
||||||
config.read(cfg_file)
|
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 the database location isnt set at the config location, move it
|
||||||
if not db_filepath.startswith(cfg_path):
|
if not db_filepath.startswith(cfg_path):
|
||||||
@ -702,7 +704,7 @@ def update_database_file() -> bool:
|
|||||||
with open(cfg_file, "w") as configfile:
|
with open(cfg_file, "w") as configfile:
|
||||||
config.write(configfile)
|
config.write(configfile)
|
||||||
config.read(cfg_file)
|
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 = db_filepath.split("/")
|
||||||
db_path.pop()
|
db_path.pop()
|
||||||
|
|||||||
@ -1,17 +1,10 @@
|
|||||||
[db]
|
[settings]
|
||||||
# The library database file
|
db = library.db
|
||||||
database = db/library.db
|
|
||||||
|
|
||||||
[directories]
|
|
||||||
# Useful paths to have stored
|
|
||||||
library = /path/to/music
|
library = /path/to/music
|
||||||
reorganize_destination = /where/to/reorganize/to
|
reorganize_destination = /where/to/reorganize/to
|
||||||
playlist_auto_export_enabled = 0
|
playlist_auto_export_enabled = 0
|
||||||
playlist_export_path = /where/to/export/to
|
playlist_export_path = /where/to/export/to
|
||||||
playlist_relative_path = /relative/prefix
|
playlist_relative_path = /relative/prefix
|
||||||
|
|
||||||
[settings]
|
|
||||||
# Which file types are scanned
|
|
||||||
extensions = mp3,wav,ogg,flac
|
extensions = mp3,wav,ogg,flac
|
||||||
volume = 100
|
volume = 100
|
||||||
window_size=1152,894
|
window_size=1152,894
|
||||||
|
|||||||
@ -31,10 +31,8 @@ def add_files_to_database(files, progress_callback=None):
|
|||||||
failed_dict = {}
|
failed_dict = {}
|
||||||
insert_data = [] # To store data for batch insert
|
insert_data = [] # To store data for batch insert
|
||||||
for filepath in files:
|
for filepath in files:
|
||||||
try:
|
if progress_callback:
|
||||||
progress_callback.emit(filepath)
|
progress_callback.emit(filepath)
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
filename = filepath.split("/")[-1]
|
filename = filepath.split("/")[-1]
|
||||||
|
|
||||||
tags, details = get_tags(filepath)
|
tags, details = get_tags(filepath)
|
||||||
|
|||||||
@ -1,29 +1,33 @@
|
|||||||
import os
|
import os
|
||||||
from PyQt5.QtCore import pyqtSignal
|
|
||||||
from utils.add_files_to_database import add_files_to_database
|
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
|
||||||
|
|
||||||
|
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)
|
Scans for audio files in user-defined paths
|
||||||
Looks for audio files with specific extensions (defined in config file)
|
- Paths are defined in config file
|
||||||
Adds found files to the database/primary library (songs table - which holds all songs :o)
|
- Accepted file extensions are defined in config file
|
||||||
|
- Adds found file to database
|
||||||
"""
|
"""
|
||||||
|
if progress_callback:
|
||||||
|
progress_callback.emit('Scanning libraries...')
|
||||||
config = ConfigParser()
|
config = ConfigParser()
|
||||||
cfg_file = (
|
config.read(Path(user_config_dir(appname="musicpom", appauthor="billypom")) / "config.ini")
|
||||||
Path(user_config_dir(appname="musicpom", appauthor="billypom")) / "config.ini"
|
libraries = [path.strip() for path in config.get("settings", "library_path").split(',')]
|
||||||
)
|
|
||||||
config.read(cfg_file)
|
|
||||||
root_dir = config.get("directories", "library")
|
|
||||||
extensions = config.get("settings", "extensions").split(",")
|
extensions = config.get("settings", "extensions").split(",")
|
||||||
files_to_add = []
|
|
||||||
# for dirpath, dirnames, filenames ...
|
# Use each library as root dir, walk the dir and find files
|
||||||
for dirpath, _, filenames in os.walk(root_dir):
|
for library in libraries:
|
||||||
for file in filenames:
|
files_to_add = []
|
||||||
filename = os.path.join(dirpath, file)
|
for dirpath, _, filenames in os.walk(library):
|
||||||
if any(filename.lower().endswith(ext) for ext in extensions):
|
for file in filenames:
|
||||||
files_to_add.append(filename)
|
filename = os.path.join(dirpath, file)
|
||||||
add_files_to_database(files_to_add)
|
if any(filename.lower().endswith(ext) for ext in extensions):
|
||||||
|
files_to_add.append(filename)
|
||||||
|
add_files_to_database(files_to_add, progress_callback)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user