mirror of
https://github.com/Yuvi9587/Kemono-Downloader.git
synced 2025-12-17 15:36:51 +00:00
Commit
This commit is contained in:
parent
ec94417569
commit
a9b210b2ba
@ -60,7 +60,6 @@ RESOLUTION_KEY = "window_resolution"
|
||||
UI_SCALE_KEY = "ui_scale_factor"
|
||||
SAVE_CREATOR_JSON_KEY = "saveCreatorJsonProfile"
|
||||
FETCH_FIRST_KEY = "fetchAllPostsFirst"
|
||||
# --- FIX: Add the missing key for the Discord token ---
|
||||
DISCORD_TOKEN_KEY = "discord/token"
|
||||
|
||||
POST_DOWNLOAD_ACTION_KEY = "postDownloadAction"
|
||||
|
||||
@ -43,9 +43,7 @@ def fetch_channel_messages(channel_id, logger=print, cancellation_event=None, pa
|
||||
}
|
||||
|
||||
offset = 0
|
||||
# --- FIX: Corrected the page size for Discord API pagination ---
|
||||
page_size = 150
|
||||
# --- END FIX ---
|
||||
|
||||
while True:
|
||||
if cancellation_event and cancellation_event.is_set():
|
||||
|
||||
@ -875,25 +875,22 @@ class PostProcessorWorker:
|
||||
def process(self):
|
||||
|
||||
if self.service == 'discord':
|
||||
# For Discord, self.post is a MESSAGE object from the API.
|
||||
post_title = self.post.get('content', '') or f"Message {self.post.get('id', 'N/A')}"
|
||||
post_id = self.post.get('id', 'unknown_id')
|
||||
post_main_file_info = {} # Discord messages don't have a single main file
|
||||
post_main_file_info = {}
|
||||
post_attachments = self.post.get('attachments', [])
|
||||
post_content_html = self.post.get('content', '')
|
||||
post_data = self.post # Keep a reference to the original message object
|
||||
post_data = self.post
|
||||
log_prefix = "Message"
|
||||
else:
|
||||
# Existing logic for standard creator posts
|
||||
post_title = self.post.get('title', '') or 'untitled_post'
|
||||
post_id = self.post.get('id', 'unknown_id')
|
||||
post_main_file_info = self.post.get('file')
|
||||
post_attachments = self.post.get('attachments', [])
|
||||
post_content_html = self.post.get('content', '')
|
||||
post_data = self.post # Reference to the post object
|
||||
post_data = self.post
|
||||
log_prefix = "Post"
|
||||
|
||||
# --- FIX: FETCH FULL POST DATA IF CONTENT IS MISSING BUT NEEDED ---
|
||||
content_is_needed = (
|
||||
self.show_external_links or
|
||||
self.extract_links_only or
|
||||
|
||||
@ -42,17 +42,12 @@ class ErrorFilesDialog(QDialog):
|
||||
if app_icon and not app_icon.isNull():
|
||||
self.setWindowIcon(app_icon)
|
||||
|
||||
# --- START OF FIX ---
|
||||
# Get the user-defined scale factor from the parent application.
|
||||
scale_factor = getattr(self.parent_app, 'scale_factor', 1.0)
|
||||
|
||||
# Define base dimensions and apply the correct scale factor.
|
||||
base_width, base_height = 550, 400
|
||||
self.setMinimumSize(int(base_width * scale_factor), int(base_height * scale_factor))
|
||||
self.resize(int(base_width * scale_factor * 1.1), int(base_height * scale_factor * 1.1))
|
||||
# --- END OF FIX ---
|
||||
|
||||
# --- Initialize UI and Apply Theming ---
|
||||
self._init_ui()
|
||||
self._retranslate_ui()
|
||||
self._apply_theme()
|
||||
|
||||
@ -260,6 +260,8 @@ class DownloaderApp (QWidget ):
|
||||
self.is_fetching_only = False
|
||||
self.fetched_posts_for_download = []
|
||||
self.is_ready_to_download_fetched = False
|
||||
self.last_logged_filter_mode = None
|
||||
self.last_logged_external_link_status = None
|
||||
|
||||
|
||||
print(f"ℹ️ Known.txt will be loaded/saved at: {self.config_file}")
|
||||
@ -406,7 +408,6 @@ class DownloaderApp (QWidget ):
|
||||
|
||||
try:
|
||||
queue_logger(f" Downloading ({download_count+1}/{total_attachments}): '{filename_to_use}'...")
|
||||
# --- FIX: Stream the download in chunks for responsive controls ---
|
||||
response = requests.get(file_url, stream=True, timeout=60)
|
||||
response.raise_for_status()
|
||||
|
||||
@ -2340,22 +2341,30 @@ class DownloaderApp (QWidget ):
|
||||
self.log_signal.emit(f" ⚠️ Could not delete temp file '{filepath}': {e}")
|
||||
self.session_temp_files = []
|
||||
|
||||
def update_external_links_setting (self ,checked ):
|
||||
def update_external_links_setting(self, checked, log_change=True):
|
||||
is_only_links_mode = self.radio_only_links and self.radio_only_links.isChecked()
|
||||
is_only_archives_mode = self.radio_only_archives and self.radio_only_archives.isChecked()
|
||||
is_only_audio_mode = hasattr(self, 'radio_only_audio') and self.radio_only_audio.isChecked()
|
||||
|
||||
if is_only_links_mode or is_only_archives_mode :
|
||||
if is_only_links_mode or is_only_archives_mode or is_only_audio_mode:
|
||||
if self.external_log_output: self.external_log_output.hide()
|
||||
if self.log_splitter: self.log_splitter.setSizes([self.height(), 0])
|
||||
return
|
||||
|
||||
self.show_external_links = checked
|
||||
|
||||
if log_change and self.last_logged_external_link_status != checked:
|
||||
if checked:
|
||||
self.log_signal.emit("ℹ️ External Links Log Enabled")
|
||||
else:
|
||||
self.log_signal.emit("ℹ️ External Links Log Disabled")
|
||||
self.last_logged_external_link_status = checked
|
||||
|
||||
if checked:
|
||||
if self.external_log_output: self.external_log_output.show()
|
||||
if self.log_splitter: self.log_splitter.setSizes([self.height() // 2, self.height() // 2])
|
||||
if self.main_log_output: self.main_log_output.setMinimumHeight(50)
|
||||
if self.external_log_output: self.external_log_output.setMinimumHeight(50)
|
||||
self.log_signal.emit("ℹ️ External Links Log Enabled")
|
||||
if self.external_log_output:
|
||||
self.external_log_output.clear()
|
||||
self.external_log_output.append("🔗 External Links Found:")
|
||||
@ -2366,23 +2375,26 @@ class DownloaderApp (QWidget ):
|
||||
if self.main_log_output: self.main_log_output.setMinimumHeight(0)
|
||||
if self.external_log_output: self.external_log_output.setMinimumHeight(0)
|
||||
if self.external_log_output: self.external_log_output.clear()
|
||||
self.log_signal.emit("ℹ️ External Links Log Disabled")
|
||||
|
||||
def _handle_filter_mode_change(self, button, checked):
|
||||
if not button or not checked:
|
||||
return
|
||||
|
||||
new_mode_text = button.text()
|
||||
if self.last_logged_filter_mode != new_mode_text:
|
||||
self.log_signal.emit(f"ℹ️ Filter mode changed to: {new_mode_text}")
|
||||
self.last_logged_filter_mode = new_mode_text
|
||||
|
||||
is_only_links = (button == self.radio_only_links)
|
||||
|
||||
if hasattr(self, 'use_multithreading_checkbox') and hasattr(self, 'thread_count_input'):
|
||||
if is_only_links:
|
||||
# When "Only Links" is selected, enable multithreading, set threads to 20, and lock the input.
|
||||
self.use_multithreading_checkbox.setChecked(True)
|
||||
self.thread_count_input.setText("20")
|
||||
self.thread_count_input.setEnabled(False)
|
||||
self.thread_count_label.setEnabled(False)
|
||||
self.update_multithreading_label("20")
|
||||
else:
|
||||
# When another mode is selected, re-enable the input for user control.
|
||||
is_multithreading_checked = self.use_multithreading_checkbox.isChecked()
|
||||
self.thread_count_input.setEnabled(is_multithreading_checked)
|
||||
self.thread_count_label.setEnabled(is_multithreading_checked)
|
||||
@ -2448,37 +2460,10 @@ class DownloaderApp (QWidget ):
|
||||
|
||||
if is_only_links:
|
||||
self.progress_log_label.setText("📜 Extracted Links Log:")
|
||||
if self.external_log_output: self.external_log_output.hide()
|
||||
if self.log_splitter: self.log_splitter.setSizes([self.height(), 0])
|
||||
|
||||
do_clear_log_in_filter_change = True
|
||||
if self.mega_download_log_preserved_once and self.only_links_log_display_mode == LOG_DISPLAY_DOWNLOAD_PROGRESS:
|
||||
do_clear_log_in_filter_change = False
|
||||
|
||||
if self.main_log_output and do_clear_log_in_filter_change:
|
||||
self.log_signal.emit("INTERNAL: _handle_filter_mode_change - About to clear log.")
|
||||
self.main_log_output.clear()
|
||||
self.log_signal.emit("INTERNAL: _handle_filter_mode_change - Log cleared by _handle_filter_mode_change.")
|
||||
|
||||
if self.main_log_output: self.main_log_output.setMinimumHeight(0)
|
||||
self.log_signal.emit(f"ℹ️ Filter mode changed to: {button.text()}")
|
||||
self._try_process_next_external_link()
|
||||
elif is_only_archives:
|
||||
self.progress_log_label.setText("📜 Progress Log (Archives Only):")
|
||||
if self.external_log_output: self.external_log_output.hide()
|
||||
if self.log_splitter: self.log_splitter.setSizes([self.height(), 0])
|
||||
if self.main_log_output: self.main_log_output.clear()
|
||||
self.log_signal.emit(f"ℹ️ Filter mode changed to: {button.text()}")
|
||||
elif is_only_audio:
|
||||
self.progress_log_label.setText(self._tr("progress_log_label_text", "📜 Progress Log:") + f" ({self._tr('filter_audio_radio', '🎧 Only Audio')})")
|
||||
if self.external_log_output: self.external_log_output.hide()
|
||||
if self.log_splitter: self.log_splitter.setSizes([self.height(), 0])
|
||||
if self.main_log_output: self.main_log_output.clear()
|
||||
self.log_signal.emit(f"ℹ️ Filter mode changed to: {button.text()}")
|
||||
else:
|
||||
self.progress_log_label.setText(self._tr("progress_log_label_text", "📜 Progress Log:"))
|
||||
|
||||
self.update_external_links_setting(self.external_links_checkbox.isChecked() if self.external_links_checkbox else False)
|
||||
self.log_signal.emit(f"ℹ️ Filter mode changed to: {button.text()}")
|
||||
|
||||
if is_only_links:
|
||||
self._filter_links_log()
|
||||
@ -2509,13 +2494,11 @@ class DownloaderApp (QWidget ):
|
||||
self.update_custom_folder_visibility()
|
||||
self.update_ui_for_manga_mode(self.manga_mode_checkbox.isChecked() if self.manga_mode_checkbox else False)
|
||||
|
||||
|
||||
def _filter_links_log (self ):
|
||||
if not (self .radio_only_links and self .radio_only_links .isChecked ()):return
|
||||
|
||||
search_term =self .link_search_input .text ().lower ().strip ()if self .link_search_input else ""
|
||||
|
||||
# This block handles the "Download Progress" view for Mega/Drive links and should be kept
|
||||
if self .mega_download_log_preserved_once and self .only_links_log_display_mode ==LOG_DISPLAY_DOWNLOAD_PROGRESS :
|
||||
self .log_signal .emit ("INTERNAL: _filter_links_log - Preserving Mega log.")
|
||||
return
|
||||
@ -3294,7 +3277,6 @@ class DownloaderApp (QWidget ):
|
||||
self.manga_rename_toggle_button, self.manga_date_prefix_input,
|
||||
self.multipart_toggle_button, self.custom_folder_input, self.custom_folder_label,
|
||||
self.discord_scope_toggle_button
|
||||
# --- FIX: REMOVED self.save_discord_as_pdf_btn from this list ---
|
||||
]
|
||||
|
||||
enable_state = not is_specialized
|
||||
@ -3335,14 +3317,10 @@ class DownloaderApp (QWidget ):
|
||||
url_text = self.link_input.text().strip()
|
||||
service, _, _ = extract_post_info(url_text)
|
||||
|
||||
# --- FIX: Use two separate flags for better control ---
|
||||
# This is true for BOTH kemono.cr/discord and discord.com
|
||||
is_any_discord_url = (service == 'discord')
|
||||
# This is ONLY true for official discord.com
|
||||
is_official_discord_url = 'discord.com' in url_text and is_any_discord_url
|
||||
|
||||
if is_official_discord_url:
|
||||
# Show the token input only for the official site
|
||||
self.remove_from_filename_label_widget.setText("🔑 Discord Token:")
|
||||
self.remove_from_filename_input.setPlaceholderText("Enter your Discord Authorization Token here")
|
||||
self.remove_from_filename_input.setEchoMode(QLineEdit.Password)
|
||||
@ -3355,16 +3333,13 @@ class DownloaderApp (QWidget ):
|
||||
self.remove_from_filename_input.setPlaceholderText(self._tr("remove_from_filename_input_placeholder_text", "e.g., patreon, HD"))
|
||||
self.remove_from_filename_input.setEchoMode(QLineEdit.Normal)
|
||||
|
||||
# Handle other specialized downloaders (Bunkr, nhentai, etc.)
|
||||
is_saint2 = 'saint2.su' in url_text or 'saint2.pk' in url_text
|
||||
is_erome = 'erome.com' in url_text
|
||||
is_specialized = service in ['bunkr', 'nhentai', 'hentai2read'] or is_saint2 or is_erome
|
||||
self._set_ui_for_specialized_downloader(is_specialized)
|
||||
|
||||
# --- FIX: Show the Scope button for ANY Discord URL (Kemono or official) ---
|
||||
self.discord_scope_toggle_button.setVisible(is_any_discord_url)
|
||||
if hasattr(self, 'discord_message_limit_input'):
|
||||
# Only show the message limit for the official site, as it's an API feature
|
||||
self.discord_message_limit_input.setVisible(is_official_discord_url)
|
||||
|
||||
if is_any_discord_url:
|
||||
@ -3705,16 +3680,12 @@ class DownloaderApp (QWidget ):
|
||||
server_id=server_id, channel_id=channel_id, url=api_url, limit=message_limit, parent=self
|
||||
)
|
||||
|
||||
# 2. Connect its signals to the main window's functions
|
||||
self.download_thread.progress_signal.connect(self.handle_main_log)
|
||||
self.download_thread.progress_label_signal.connect(self.progress_label.setText)
|
||||
self.download_thread.finished_signal.connect(self.download_finished)
|
||||
|
||||
# --- FIX: Start the thread BEFORE updating the UI ---
|
||||
# 3. Start the download process in the background
|
||||
self.download_thread.start()
|
||||
|
||||
# 4. NOW, update the UI. The app knows a download is active.
|
||||
self.set_ui_enabled(False)
|
||||
self._update_button_states_and_connections()
|
||||
|
||||
@ -5185,14 +5156,11 @@ class DownloaderApp (QWidget ):
|
||||
self ._handle_favorite_mode_toggle (is_fav_mode_active )
|
||||
|
||||
def _handle_pause_resume_action(self):
|
||||
# --- FIX: Simplified and corrected the pause/resume logic ---
|
||||
if not self._is_download_active():
|
||||
return
|
||||
|
||||
# Toggle the main app's pause state tracker
|
||||
self.is_paused = not self.is_paused
|
||||
|
||||
# Call the correct method on the thread based on the new state
|
||||
if isinstance(self.download_thread, DiscordDownloadThread):
|
||||
if self.is_paused:
|
||||
self.download_thread.pause()
|
||||
@ -5518,7 +5486,6 @@ class DownloaderApp (QWidget ):
|
||||
self.log_signal.emit("✅ Download complete! Notification sound played.")
|
||||
return
|
||||
|
||||
# --- FIX: Ensure confirm_title is defined before it is used ---
|
||||
confirm_title = self._tr("action_confirmation_title", "Action After Download")
|
||||
confirm_text = ""
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user