diff options
| author | exislow <exislow@users.noreply.github.com> | 2024-12-15 23:35:31 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-12-15 23:35:31 +0100 |
| commit | c4b5ae1cb92f305eca6e111f2816629977cbf3ad (patch) | |
| tree | cb5ec1765386c3e08bf90fa82103341c1c8bb1d3 | |
| parent | 62c32f19a4bbf708e6330f3c89813de1c1883ad1 (diff) | |
| parent | 5768edacc57fd29bf2ef182cb9db312d4aebb468 (diff) | |
| download | tidal-dl-ng-c4b5ae1cb92f305eca6e111f2816629977cbf3ad.tar.gz | |
Merge pull request #281 from exislow/180-feature-multi-threaded-downloads-download-album-covers
✨ Multithreaded downloads implemented (for Playlists, Albums etc.). F…
| -rw-r--r-- | tidal_dl_ng/dialog.py | 2 | ||||
| -rw-r--r-- | tidal_dl_ng/download.py | 36 | ||||
| -rw-r--r-- | tidal_dl_ng/model/cfg.py | 6 | ||||
| -rw-r--r-- | tidal_dl_ng/ui/dialog_settings.py | 25 | ||||
| -rw-r--r-- | tidal_dl_ng/ui/dialog_settings.ui | 30 |
5 files changed, 80 insertions, 19 deletions
diff --git a/tidal_dl_ng/dialog.py b/tidal_dl_ng/dialog.py index 073e016..4e36d8a 100644 --- a/tidal_dl_ng/dialog.py +++ b/tidal_dl_ng/dialog.py @@ -162,7 +162,7 @@ class DialogPreferences(QtWidgets.QDialog): ] def _init_spin_box(self): - self.parameters_spin_box = ["album_track_num_pad_min"] + self.parameters_spin_box = ["album_track_num_pad_min", "downloads_concurrent_max"] def _init_comboboxes(self): self.parameters_combo = [ diff --git a/tidal_dl_ng/download.py b/tidal_dl_ng/download.py index 83d8743..af00497 100644 --- a/tidal_dl_ng/download.py +++ b/tidal_dl_ng/download.py @@ -621,22 +621,30 @@ class Download: # Iterate through list items while not self.progress.finished: - for item_media in items: - # Download the item. - status, result_path_file = self.item( - media=item_media, - file_template=file_name_relative, - quality_audio=quality_audio, - quality_video=quality_video, - download_delay=download_delay, - is_parent_album=is_album, - ) + with futures.ThreadPoolExecutor(max_workers=self.settings.data.downloads_concurrent_max) as executor: + # Dispatch all download tasks to worker threads + l_futures: [any] = [ + executor.submit( + self.item, + media=item_media, + file_template=file_name_relative, + quality_audio=quality_audio, + quality_video=quality_video, + download_delay=download_delay, + is_parent_album=is_album, + ) + for item_media in items + ] + # Report results as they become available + for future in futures.as_completed(l_futures): + # Retrieve result + status, result_path_file = future.result() - # Advance progress bar. - self.progress.advance(p_task1) + # Advance progress bar. + self.progress.advance(p_task1) - if not progress_stdout: - self.progress_gui.list_item.emit(self.progress.tasks[p_task1].percentage) + if not progress_stdout: + self.progress_gui.list_item.emit(self.progress.tasks[p_task1].percentage) self.fn_logger.info(f"Finished list '{list_media_name}'.") diff --git a/tidal_dl_ng/model/cfg.py b/tidal_dl_ng/model/cfg.py index bf01814..88636f1 100644 --- a/tidal_dl_ng/model/cfg.py +++ b/tidal_dl_ng/model/cfg.py @@ -40,7 +40,8 @@ class Settings: downloads_simultaneous_per_track_max: int = 20 download_delay_sec_min: float = 3.0 download_delay_sec_max: float = 5.0 - album_track_num_pad_min: int = 0 + album_track_num_pad_min: int = 1 + downloads_concurrent_max: int = 3 @dataclass_json @@ -86,8 +87,9 @@ class HelpSettings: download_delay_sec_min: str = "Lower boundary for the calculation of the download delay in seconds." download_delay_sec_max: str = "Upper boundary for the calculation of the download delay in seconds." album_track_num_pad_min: str = ( - "Minimum length of the album track count, will be padded with zeroes (0). To disable " "padding set this to 0." + "Minimum length of the album track count, will be padded with zeroes (0). To disable padding set this to 1." ) + downloads_concurrent_max: str = "Maximum concurrent number of downloads (threads)." @dataclass_json diff --git a/tidal_dl_ng/ui/dialog_settings.py b/tidal_dl_ng/ui/dialog_settings.py index d3d2401..945af92 100644 --- a/tidal_dl_ng/ui/dialog_settings.py +++ b/tidal_dl_ng/ui/dialog_settings.py @@ -27,7 +27,7 @@ class Ui_DialogSettings: def setupUi(self, DialogSettings): if not DialogSettings.objectName(): DialogSettings.setObjectName("DialogSettings") - DialogSettings.resize(640, 705) + DialogSettings.resize(640, 767) sizePolicy = QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) sizePolicy.setHorizontalStretch(100) sizePolicy.setVerticalStretch(100) @@ -293,6 +293,27 @@ class Ui_DialogSettings: self.verticalLayout_8.addLayout(self.horizontalLayout_9) + self.horizontalLayout_11 = QHBoxLayout() + self.horizontalLayout_11.setObjectName("horizontalLayout_11") + self.l_downloads_concurrent_max = QLabel(self.gb_numbers) + self.l_downloads_concurrent_max.setObjectName("l_downloads_concurrent_max") + + self.horizontalLayout_11.addWidget(self.l_downloads_concurrent_max) + + self.l_icon_downloads_concurrent_max = QLabel(self.gb_numbers) + self.l_icon_downloads_concurrent_max.setObjectName("l_icon_downloads_concurrent_max") + + self.horizontalLayout_11.addWidget(self.l_icon_downloads_concurrent_max) + + self.sb_downloads_concurrent_max = QSpinBox(self.gb_numbers) + self.sb_downloads_concurrent_max.setObjectName("sb_downloads_concurrent_max") + self.sb_downloads_concurrent_max.setMinimum(1) + self.sb_downloads_concurrent_max.setMaximum(5) + + self.horizontalLayout_11.addWidget(self.sb_downloads_concurrent_max) + + self.verticalLayout_8.addLayout(self.horizontalLayout_11) + self.lv_main.addWidget(self.gb_numbers) self.gb_path = QGroupBox(DialogSettings) @@ -563,6 +584,8 @@ class Ui_DialogSettings: self.gb_numbers.setTitle(QCoreApplication.translate("DialogSettings", "Numbers", None)) self.l_album_track_num_pad_min.setText(QCoreApplication.translate("DialogSettings", "TextLabel", None)) self.l_icon_album_track_num_pad_min.setText(QCoreApplication.translate("DialogSettings", "TextLabel", None)) + self.l_downloads_concurrent_max.setText(QCoreApplication.translate("DialogSettings", "TextLabel", None)) + self.l_icon_downloads_concurrent_max.setText(QCoreApplication.translate("DialogSettings", "TextLabel", None)) self.gb_path.setTitle(QCoreApplication.translate("DialogSettings", "Path", None)) self.l_icon_download_base_path.setText(QCoreApplication.translate("DialogSettings", "TextLabel", None)) self.l_download_base_path.setText(QCoreApplication.translate("DialogSettings", "TextLabel", None)) diff --git a/tidal_dl_ng/ui/dialog_settings.ui b/tidal_dl_ng/ui/dialog_settings.ui index bff04c7..d81701a 100644 --- a/tidal_dl_ng/ui/dialog_settings.ui +++ b/tidal_dl_ng/ui/dialog_settings.ui @@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>640</width> - <height>705</height> + <height>767</height> </rect> </property> <property name="sizePolicy"> @@ -386,6 +386,34 @@ </item> </layout> </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_11"> + <item> + <widget class="QLabel" name="l_downloads_concurrent_max"> + <property name="text"> + <string>TextLabel</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="l_icon_downloads_concurrent_max"> + <property name="text"> + <string>TextLabel</string> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="sb_downloads_concurrent_max"> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>5</number> + </property> + </widget> + </item> + </layout> + </item> </layout> </widget> </item> |
