This commit is contained in:
afkarxyz
2025-08-06 20:21:52 +07:00
parent dbcd49225d
commit 303b76d1ec
+45 -46
View File
@@ -58,9 +58,10 @@ class MetadataFetchWorker(QThread):
class DownloadWorker(QThread): class DownloadWorker(QThread):
finished = pyqtSignal(bool, str, list) finished = pyqtSignal(bool, str, list)
progress = pyqtSignal(str, int) progress = pyqtSignal(str, int)
def __init__(self, tracks, outpath, is_single_track=False, is_album=False, is_playlist=False, def __init__(self, tracks, outpath, is_single_track=False, is_album=False, is_playlist=False,
album_or_playlist_name='', filename_format='title_artist', use_track_numbers=True, album_or_playlist_name='', filename_format='title_artist', use_track_numbers=True,
use_album_subfolders=False, service="tidal", qobuz_region="us"): use_artist_subfolders=False, use_album_subfolders=False, service="tidal", qobuz_region="us"):
super().__init__() super().__init__()
self.tracks = tracks self.tracks = tracks
self.outpath = outpath self.outpath = outpath
@@ -70,6 +71,7 @@ class DownloadWorker(QThread):
self.album_or_playlist_name = album_or_playlist_name self.album_or_playlist_name = album_or_playlist_name
self.filename_format = filename_format self.filename_format = filename_format
self.use_track_numbers = use_track_numbers self.use_track_numbers = use_track_numbers
self.use_artist_subfolders = use_artist_subfolders
self.use_album_subfolders = use_album_subfolders self.use_album_subfolders = use_album_subfolders
self.service = service self.service = service
self.qobuz_region = qobuz_region self.qobuz_region = qobuz_region
@@ -96,11 +98,9 @@ class DownloadWorker(QThread):
downloader = DeezerDownloader() downloader = DeezerDownloader()
else: else:
downloader = TidalDownloader() downloader = TidalDownloader()
def progress_update(current, total): def progress_update(current, total):
if total > 0: if total <= 0:
percent = (current / total) * 100
self.progress.emit("", int(percent))
else:
self.progress.emit("Processing metadata...", 0) self.progress.emit("Processing metadata...", 0)
downloader.set_progress_callback(progress_update) downloader.set_progress_callback(progress_update)
@@ -119,14 +119,23 @@ class DownloadWorker(QThread):
int((i) / total_tracks * 100)) int((i) / total_tracks * 100))
try: try:
if self.is_playlist and self.use_album_subfolders: if self.is_playlist:
album_folder = re.sub(r'[<>:"/\\|?*]', '_', track.album) track_outpath = self.outpath
track_outpath = os.path.join(self.outpath, album_folder)
if self.use_artist_subfolders:
artist_name = track.artists.split(', ')[0] if ', ' in track.artists else track.artists
artist_folder = re.sub(r'[<>:"/\\|?*]', lambda m: "'" if m.group() == '"' else '_', artist_name)
track_outpath = os.path.join(track_outpath, artist_folder)
if self.use_album_subfolders:
album_folder = re.sub(r'[<>:"/\\|?*]', lambda m: "'" if m.group() == '"' else '_', track.album)
track_outpath = os.path.join(track_outpath, album_folder)
os.makedirs(track_outpath, exist_ok=True) os.makedirs(track_outpath, exist_ok=True)
else: else:
track_outpath = self.outpath track_outpath = self.outpath
if (self.is_album or (self.is_playlist and self.use_album_subfolders)) and self.use_track_numbers: if (self.is_album or self.is_playlist) and self.use_track_numbers:
new_filename = f"{track.track_number:02d} - {self.get_formatted_filename(track)}" new_filename = f"{track.track_number:02d} - {self.get_formatted_filename(track)}"
else: else:
new_filename = self.get_formatted_filename(track) new_filename = self.get_formatted_filename(track)
@@ -564,7 +573,7 @@ class QobuzRegionComboBox(QComboBox):
class SpotiFLACGUI(QWidget): class SpotiFLACGUI(QWidget):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.current_version = "4.2" self.current_version = "4.3"
self.tracks = [] self.tracks = []
self.all_tracks = [] self.all_tracks = []
self.reset_state() self.reset_state()
@@ -575,6 +584,7 @@ class SpotiFLACGUI(QWidget):
self.filename_format = self.settings.value('filename_format', 'title_artist') self.filename_format = self.settings.value('filename_format', 'title_artist')
self.use_track_numbers = self.settings.value('use_track_numbers', False, type=bool) self.use_track_numbers = self.settings.value('use_track_numbers', False, type=bool)
self.use_artist_subfolders = self.settings.value('use_artist_subfolders', False, type=bool)
self.use_album_subfolders = self.settings.value('use_album_subfolders', False, type=bool) self.use_album_subfolders = self.settings.value('use_album_subfolders', False, type=bool)
self.service = self.settings.value('service', 'tidal') self.service = self.settings.value('service', 'tidal')
self.qobuz_region = self.settings.value('qobuz_region', 'us') self.qobuz_region = self.settings.value('qobuz_region', 'us')
@@ -798,7 +808,6 @@ class SpotiFLACGUI(QWidget):
self.search_input.textChanged.connect(self.filter_tracks) self.search_input.textChanged.connect(self.filter_tracks)
self.search_input.setFixedWidth(250) self.search_input.setFixedWidth(250)
search_input_layout.addWidget(self.search_input) search_input_layout.addWidget(self.search_input)
search_layout.addLayout(search_input_layout) search_layout.addLayout(search_input_layout)
@@ -971,18 +980,24 @@ class SpotiFLACGUI(QWidget):
checkbox_layout = QHBoxLayout() checkbox_layout = QHBoxLayout()
self.track_number_checkbox = QCheckBox('Add Track Numbers to Album Files') self.artist_subfolder_checkbox = QCheckBox('Artist Subfolder (Playlist)')
self.track_number_checkbox.setCursor(Qt.CursorShape.PointingHandCursor) self.artist_subfolder_checkbox.setCursor(Qt.CursorShape.PointingHandCursor)
self.track_number_checkbox.setChecked(self.use_track_numbers) self.artist_subfolder_checkbox.setChecked(self.use_artist_subfolders)
self.track_number_checkbox.toggled.connect(self.save_track_numbering) self.artist_subfolder_checkbox.toggled.connect(self.save_artist_subfolder_setting)
checkbox_layout.addWidget(self.track_number_checkbox) checkbox_layout.addWidget(self.artist_subfolder_checkbox)
self.album_subfolder_checkbox = QCheckBox('Create Album Subfolders for Playlist Downloads') self.album_subfolder_checkbox = QCheckBox('Album Subfolder (Playlist)')
self.album_subfolder_checkbox.setCursor(Qt.CursorShape.PointingHandCursor) self.album_subfolder_checkbox.setCursor(Qt.CursorShape.PointingHandCursor)
self.album_subfolder_checkbox.setChecked(self.use_album_subfolders) self.album_subfolder_checkbox.setChecked(self.use_album_subfolders)
self.album_subfolder_checkbox.toggled.connect(self.save_album_subfolder_setting) self.album_subfolder_checkbox.toggled.connect(self.save_album_subfolder_setting)
checkbox_layout.addWidget(self.album_subfolder_checkbox) checkbox_layout.addWidget(self.album_subfolder_checkbox)
self.track_number_checkbox = QCheckBox('Track Number for Album')
self.track_number_checkbox.setCursor(Qt.CursorShape.PointingHandCursor)
self.track_number_checkbox.setChecked(self.use_track_numbers)
self.track_number_checkbox.toggled.connect(self.save_track_numbering)
checkbox_layout.addWidget(self.track_number_checkbox)
checkbox_layout.addStretch() checkbox_layout.addStretch()
file_layout.addLayout(checkbox_layout) file_layout.addLayout(checkbox_layout)
@@ -1016,8 +1031,6 @@ class SpotiFLACGUI(QWidget):
region_label.hide() region_label.hide()
self.qobuz_region_dropdown.hide() self.qobuz_region_dropdown.hide()
service_fallback_layout.addStretch() service_fallback_layout.addStretch()
auth_layout.addLayout(service_fallback_layout) auth_layout.addLayout(service_fallback_layout)
@@ -1028,8 +1041,6 @@ class SpotiFLACGUI(QWidget):
self.set_combobox_value(self.service_dropdown, self.service) self.set_combobox_value(self.service_dropdown, self.service)
self.set_combobox_value(self.qobuz_region_dropdown, self.qobuz_region) self.set_combobox_value(self.qobuz_region_dropdown, self.qobuz_region)
self.update_service_ui() self.update_service_ui()
self.qobuz_region_dropdown.status_updated.connect( self.qobuz_region_dropdown.status_updated.connect(
@@ -1237,7 +1248,7 @@ class SpotiFLACGUI(QWidget):
about_layout.addWidget(section_widget) about_layout.addWidget(section_widget)
footer_label = QLabel(f"v{self.current_version} | July 2025") footer_label = QLabel(f"v{self.current_version} | August 2025")
footer_label.setStyleSheet("font-size: 12px; margin-top: 20px;") footer_label.setStyleSheet("font-size: 12px; margin-top: 20px;")
about_layout.addWidget(footer_label, alignment=Qt.AlignmentFlag.AlignCenter) about_layout.addWidget(footer_label, alignment=Qt.AlignmentFlag.AlignCenter)
@@ -1293,6 +1304,12 @@ class SpotiFLACGUI(QWidget):
self.use_track_numbers = self.track_number_checkbox.isChecked() self.use_track_numbers = self.track_number_checkbox.isChecked()
self.settings.setValue('use_track_numbers', self.use_track_numbers) self.settings.setValue('use_track_numbers', self.use_track_numbers)
self.settings.sync() self.settings.sync()
def save_artist_subfolder_setting(self):
self.use_artist_subfolders = self.artist_subfolder_checkbox.isChecked()
self.settings.setValue('use_artist_subfolders', self.use_artist_subfolders)
self.settings.sync()
def save_album_subfolder_setting(self): def save_album_subfolder_setting(self):
self.use_album_subfolders = self.album_subfolder_checkbox.isChecked() self.use_album_subfolders = self.album_subfolder_checkbox.isChecked()
self.settings.setValue('use_album_subfolders', self.use_album_subfolders) self.settings.setValue('use_album_subfolders', self.use_album_subfolders)
@@ -1305,8 +1322,6 @@ class SpotiFLACGUI(QWidget):
self.settings.sync() self.settings.sync()
self.log_output.append(f"Qobuz region setting saved: {self.qobuz_region_dropdown.currentText()}") self.log_output.append(f"Qobuz region setting saved: {self.qobuz_region_dropdown.currentText()}")
def save_settings(self): def save_settings(self):
self.settings.setValue('output_path', self.output_dir.text().strip()) self.settings.setValue('output_path', self.output_dir.text().strip())
self.settings.sync() self.settings.sync()
@@ -1429,7 +1444,7 @@ class SpotiFLACGUI(QWidget):
title=track["name"], title=track["name"],
artists=track["artists"], artists=track["artists"],
album=track["album_name"], album=track["album_name"],
track_number=len(self.tracks) + 1, track_number=track.get("track_number", len(self.tracks) + 1),
duration_ms=track.get("duration_ms", 0), duration_ms=track.get("duration_ms", 0),
id=track_id, id=track_id,
isrc=track.get("isrc", "") isrc=track.get("isrc", "")
@@ -1601,6 +1616,7 @@ class SpotiFLACGUI(QWidget):
self.start_download_worker(tracks_to_download, outpath) self.start_download_worker(tracks_to_download, outpath)
except Exception as e: except Exception as e:
self.log_output.append(f"Error: An error occurred while starting the download: {str(e)}") self.log_output.append(f"Error: An error occurred while starting the download: {str(e)}")
def start_download_worker(self, tracks_to_download, outpath): def start_download_worker(self, tracks_to_download, outpath):
service = self.service_dropdown.currentData() service = self.service_dropdown.currentData()
qobuz_region = self.qobuz_region_dropdown.currentData() if service == "qobuz" else "us" qobuz_region = self.qobuz_region_dropdown.currentData() if service == "qobuz" else "us"
@@ -1614,6 +1630,7 @@ class SpotiFLACGUI(QWidget):
self.album_or_playlist_name, self.album_or_playlist_name,
self.filename_format, self.filename_format,
self.use_track_numbers, self.use_track_numbers,
self.use_artist_subfolders,
self.use_album_subfolders, self.use_album_subfolders,
service, service,
qobuz_region qobuz_region
@@ -1641,27 +1658,9 @@ class SpotiFLACGUI(QWidget):
self.tab_widget.setCurrentWidget(self.process_tab) self.tab_widget.setCurrentWidget(self.process_tab)
def update_progress(self, message, percentage): def update_progress(self, message, percentage):
if "Download progress:" in message or "Processing metadata..." in message: self.log_output.append(message)
current_text = self.log_output.toPlainText() self.log_output.moveCursor(QTextCursor.MoveOperation.End)
if percentage > 0:
if current_text:
lines = current_text.split('\n')
if "Download progress:" in lines[-1] or "Processing metadata..." in lines[-1]:
lines[-1] = message
new_text = '\n'.join(lines)
self.log_output.setPlainText(new_text)
self.log_output.moveCursor(QTextCursor.MoveOperation.End)
else:
self.log_output.append(message)
else:
self.log_output.append(message)
else:
self.log_output.append(message)
if percentage > 0 and not "Download progress:" in message:
self.progress_bar.setValue(percentage) self.progress_bar.setValue(percentage)
def stop_download(self): def stop_download(self):