mirror of
https://github.com/denizsafak/abogen.git
synced 2026-07-18 05:40:26 +02:00
Reformat using black
This commit is contained in:
@@ -377,9 +377,10 @@ class HandlerDialog(QDialog):
|
|||||||
|
|
||||||
# Include replace_single_newlines in cache key since it affects text cleaning
|
# Include replace_single_newlines in cache key since it affects text cleaning
|
||||||
from abogen.utils import load_config
|
from abogen.utils import load_config
|
||||||
|
|
||||||
cfg = load_config()
|
cfg = load_config()
|
||||||
replace_single_newlines = cfg.get("replace_single_newlines", False)
|
replace_single_newlines = cfg.get("replace_single_newlines", False)
|
||||||
|
|
||||||
cache_key = (self.book_path, mod_time, self.file_type, replace_single_newlines)
|
cache_key = (self.book_path, mod_time, self.file_type, replace_single_newlines)
|
||||||
|
|
||||||
# Check if content is already cached
|
# Check if content is already cached
|
||||||
@@ -2240,6 +2241,7 @@ class HandlerDialog(QDialog):
|
|||||||
if metadata.get("cover_image"):
|
if metadata.get("cover_image"):
|
||||||
try:
|
try:
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
cache_dir = get_user_cache_path()
|
cache_dir = get_user_cache_path()
|
||||||
cover_path = os.path.join(cache_dir, f"cover_{uuid.uuid4()}.jpg")
|
cover_path = os.path.join(cache_dir, f"cover_{uuid.uuid4()}.jpg")
|
||||||
cover_path = os.path.normpath(cover_path)
|
cover_path = os.path.normpath(cover_path)
|
||||||
|
|||||||
+1
-3
@@ -2,9 +2,7 @@ from abogen.utils import get_version
|
|||||||
|
|
||||||
# Program Information
|
# Program Information
|
||||||
PROGRAM_NAME = "abogen"
|
PROGRAM_NAME = "abogen"
|
||||||
PROGRAM_DESCRIPTION = (
|
PROGRAM_DESCRIPTION = "Generate audiobooks from EPUBs, PDFs, text and subtitles with synchronized captions."
|
||||||
"Generate audiobooks from EPUBs, PDFs, text and subtitles with synchronized captions."
|
|
||||||
)
|
|
||||||
GITHUB_URL = "https://github.com/denizsafak/abogen"
|
GITHUB_URL = "https://github.com/denizsafak/abogen"
|
||||||
VERSION = get_version()
|
VERSION = get_version()
|
||||||
|
|
||||||
|
|||||||
+494
-264
File diff suppressed because it is too large
Load Diff
+46
-31
@@ -337,12 +337,12 @@ class InputBox(QLabel):
|
|||||||
|
|
||||||
self.edit_btn.setVisible(should_show_edit)
|
self.edit_btn.setVisible(should_show_edit)
|
||||||
self.go_to_folder_btn.show()
|
self.go_to_folder_btn.show()
|
||||||
|
|
||||||
# Disable subtitle generation for subtitle input files
|
# Disable subtitle generation for subtitle input files
|
||||||
is_subtitle_input = file_path.lower().endswith((".srt", ".ass", ".vtt"))
|
is_subtitle_input = file_path.lower().endswith((".srt", ".ass", ".vtt"))
|
||||||
if hasattr(window, "subtitle_combo"):
|
if hasattr(window, "subtitle_combo"):
|
||||||
window.subtitle_combo.setEnabled(not is_subtitle_input)
|
window.subtitle_combo.setEnabled(not is_subtitle_input)
|
||||||
|
|
||||||
# Enable add to queue button only when file is accepted (input box is green)
|
# Enable add to queue button only when file is accepted (input box is green)
|
||||||
self.resizeEvent(None)
|
self.resizeEvent(None)
|
||||||
if hasattr(window, "btn_add_to_queue"):
|
if hasattr(window, "btn_add_to_queue"):
|
||||||
@@ -385,16 +385,18 @@ class InputBox(QLabel):
|
|||||||
self.textbox_btn.show()
|
self.textbox_btn.show()
|
||||||
self.edit_btn.hide()
|
self.edit_btn.hide()
|
||||||
self.go_to_folder_btn.hide()
|
self.go_to_folder_btn.hide()
|
||||||
|
|
||||||
# Re-enable subtitle and replace newlines controls when cleared
|
# Re-enable subtitle and replace newlines controls when cleared
|
||||||
window = self.window()
|
window = self.window()
|
||||||
if hasattr(window, "subtitle_combo"):
|
if hasattr(window, "subtitle_combo"):
|
||||||
# Only enable if language supports it
|
# Only enable if language supports it
|
||||||
current_lang = getattr(window, "lang_code", "a")
|
current_lang = getattr(window, "lang_code", "a")
|
||||||
window.subtitle_combo.setEnabled(current_lang in SUPPORTED_LANGUAGES_FOR_SUBTITLE_GENERATION)
|
window.subtitle_combo.setEnabled(
|
||||||
|
current_lang in SUPPORTED_LANGUAGES_FOR_SUBTITLE_GENERATION
|
||||||
|
)
|
||||||
if hasattr(window, "replace_newlines_combo"):
|
if hasattr(window, "replace_newlines_combo"):
|
||||||
window.replace_newlines_combo.setEnabled(True)
|
window.replace_newlines_combo.setEnabled(True)
|
||||||
|
|
||||||
# Disable add to queue button when input is cleared
|
# Disable add to queue button when input is cleared
|
||||||
if hasattr(window, "btn_add_to_queue"):
|
if hasattr(window, "btn_add_to_queue"):
|
||||||
window.btn_add_to_queue.setEnabled(False)
|
window.btn_add_to_queue.setEnabled(False)
|
||||||
@@ -502,7 +504,9 @@ class InputBox(QLabel):
|
|||||||
)
|
)
|
||||||
event.acceptProposedAction()
|
event.acceptProposedAction()
|
||||||
else:
|
else:
|
||||||
self.set_error("Please drop a .txt, .epub, .pdf, .md, .srt, .ass, or .vtt file.")
|
self.set_error(
|
||||||
|
"Please drop a .txt, .epub, .pdf, .md, .srt, .ass, or .vtt file."
|
||||||
|
)
|
||||||
event.ignore()
|
event.ignore()
|
||||||
else:
|
else:
|
||||||
event.ignore()
|
event.ignore()
|
||||||
@@ -1318,7 +1322,10 @@ class abogen(QWidget):
|
|||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
file_path, _ = QFileDialog.getOpenFileName(
|
file_path, _ = QFileDialog.getOpenFileName(
|
||||||
self, "Select File", "", "Supported Files (*.txt *.epub *.pdf *.md *.srt *.ass *.vtt)"
|
self,
|
||||||
|
"Select File",
|
||||||
|
"",
|
||||||
|
"Supported Files (*.txt *.epub *.pdf *.md *.srt *.ass *.vtt)",
|
||||||
)
|
)
|
||||||
if not file_path:
|
if not file_path:
|
||||||
return
|
return
|
||||||
@@ -1934,9 +1941,7 @@ class abogen(QWidget):
|
|||||||
self.replace_single_newlines = getattr(
|
self.replace_single_newlines = getattr(
|
||||||
queued_item, "replace_single_newlines", False
|
queued_item, "replace_single_newlines", False
|
||||||
)
|
)
|
||||||
self.use_silent_gaps = getattr(
|
self.use_silent_gaps = getattr(queued_item, "use_silent_gaps", False)
|
||||||
queued_item, "use_silent_gaps", False
|
|
||||||
)
|
|
||||||
# Restore the original file path for save location
|
# Restore the original file path for save location
|
||||||
self.displayed_file_path = (
|
self.displayed_file_path = (
|
||||||
queued_item.save_base_path or queued_item.file_name
|
queued_item.save_base_path or queued_item.file_name
|
||||||
@@ -2083,9 +2088,7 @@ class abogen(QWidget):
|
|||||||
self.replace_single_newlines
|
self.replace_single_newlines
|
||||||
)
|
)
|
||||||
# Pass use_silent_gaps setting
|
# Pass use_silent_gaps setting
|
||||||
self.conversion_thread.use_silent_gaps = (
|
self.conversion_thread.use_silent_gaps = self.use_silent_gaps
|
||||||
self.use_silent_gaps
|
|
||||||
)
|
|
||||||
# Pass subtitle_speed_method setting
|
# Pass subtitle_speed_method setting
|
||||||
self.conversion_thread.subtitle_speed_method = self.subtitle_speed_method
|
self.conversion_thread.subtitle_speed_method = self.subtitle_speed_method
|
||||||
# Pass separate_chapters_format setting
|
# Pass separate_chapters_format setting
|
||||||
@@ -2813,17 +2816,20 @@ class abogen(QWidget):
|
|||||||
# Check if this is a timestamp detection (-1) or chapter detection
|
# Check if this is a timestamp detection (-1) or chapter detection
|
||||||
if chapter_count == -1:
|
if chapter_count == -1:
|
||||||
from abogen.conversion import TimestampDetectionDialog
|
from abogen.conversion import TimestampDetectionDialog
|
||||||
|
|
||||||
dialog = TimestampDetectionDialog(parent=self)
|
dialog = TimestampDetectionDialog(parent=self)
|
||||||
dialog.setWindowModality(Qt.WindowModality.ApplicationModal)
|
dialog.setWindowModality(Qt.WindowModality.ApplicationModal)
|
||||||
|
|
||||||
# Dialog always accepts (Yes or No), never cancels the conversion
|
# Dialog always accepts (Yes or No), never cancels the conversion
|
||||||
dialog.exec()
|
dialog.exec()
|
||||||
treat_as_subtitle = dialog.use_timestamps()
|
treat_as_subtitle = dialog.use_timestamps()
|
||||||
if hasattr(self, "conversion_thread") and self.conversion_thread.isRunning():
|
if (
|
||||||
|
hasattr(self, "conversion_thread")
|
||||||
|
and self.conversion_thread.isRunning()
|
||||||
|
):
|
||||||
self.conversion_thread.set_timestamp_response(treat_as_subtitle)
|
self.conversion_thread.set_timestamp_response(treat_as_subtitle)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Normal chapter detection
|
# Normal chapter detection
|
||||||
from abogen.conversion import ChapterOptionsDialog
|
from abogen.conversion import ChapterOptionsDialog
|
||||||
|
|
||||||
@@ -2832,7 +2838,10 @@ class abogen(QWidget):
|
|||||||
|
|
||||||
if dialog.exec() == QDialog.DialogCode.Accepted:
|
if dialog.exec() == QDialog.DialogCode.Accepted:
|
||||||
options = dialog.get_options()
|
options = dialog.get_options()
|
||||||
if hasattr(self, "conversion_thread") and self.conversion_thread.isRunning():
|
if (
|
||||||
|
hasattr(self, "conversion_thread")
|
||||||
|
and self.conversion_thread.isRunning()
|
||||||
|
):
|
||||||
self.conversion_thread.set_chapter_options(options)
|
self.conversion_thread.set_chapter_options(options)
|
||||||
else:
|
else:
|
||||||
self.cancel_conversion()
|
self.cancel_conversion()
|
||||||
@@ -3109,19 +3118,23 @@ class abogen(QWidget):
|
|||||||
"TTS Regeneration: Better quality\n"
|
"TTS Regeneration: Better quality\n"
|
||||||
"FFmpeg Time-stretch: Faster processing"
|
"FFmpeg Time-stretch: Faster processing"
|
||||||
)
|
)
|
||||||
|
|
||||||
speed_method_group = QActionGroup(self)
|
speed_method_group = QActionGroup(self)
|
||||||
speed_method_group.setExclusive(True)
|
speed_method_group.setExclusive(True)
|
||||||
|
|
||||||
for method, label in [("tts", "TTS Regeneration (better quality)"),
|
for method, label in [
|
||||||
("ffmpeg", "FFmpeg Time-stretch (better speed)")]:
|
("tts", "TTS Regeneration (better quality)"),
|
||||||
|
("ffmpeg", "FFmpeg Time-stretch (better speed)"),
|
||||||
|
]:
|
||||||
action = QAction(label, speed_method_menu)
|
action = QAction(label, speed_method_menu)
|
||||||
action.setCheckable(True)
|
action.setCheckable(True)
|
||||||
action.setChecked(self.subtitle_speed_method == method)
|
action.setChecked(self.subtitle_speed_method == method)
|
||||||
action.triggered.connect(lambda checked, m=method: self.toggle_subtitle_speed_method(m))
|
action.triggered.connect(
|
||||||
|
lambda checked, m=method: self.toggle_subtitle_speed_method(m)
|
||||||
|
)
|
||||||
speed_method_group.addAction(action)
|
speed_method_group.addAction(action)
|
||||||
speed_method_menu.addAction(action)
|
speed_method_menu.addAction(action)
|
||||||
|
|
||||||
self.speed_method_group = speed_method_group
|
self.speed_method_group = speed_method_group
|
||||||
|
|
||||||
# Add separator
|
# Add separator
|
||||||
@@ -3165,17 +3178,19 @@ class abogen(QWidget):
|
|||||||
def toggle_use_silent_gaps(self, enabled):
|
def toggle_use_silent_gaps(self, enabled):
|
||||||
# Show confirmation dialog with explanation
|
# Show confirmation dialog with explanation
|
||||||
action = "enable" if enabled else "disable"
|
action = "enable" if enabled else "disable"
|
||||||
message = ("When enabled, allows speech to continue naturally into the silent periods between subtitles, "
|
message = (
|
||||||
"preventing unnecessary audio speed-up based on subtitle end timestamps.\n\nWhen disabled, ensures strict subtitle timing where "
|
"When enabled, allows speech to continue naturally into the silent periods between subtitles, "
|
||||||
f"audio ends exactly when the subtitle ends.\n\nDo you want to {action} this option?")
|
"preventing unnecessary audio speed-up based on subtitle end timestamps.\n\nWhen disabled, ensures strict subtitle timing where "
|
||||||
|
f"audio ends exactly when the subtitle ends.\n\nDo you want to {action} this option?"
|
||||||
|
)
|
||||||
|
|
||||||
reply = QMessageBox.question(
|
reply = QMessageBox.question(
|
||||||
self,
|
self,
|
||||||
"Use Silent Gaps Between Subtitles",
|
"Use Silent Gaps Between Subtitles",
|
||||||
message,
|
message,
|
||||||
QMessageBox.StandardButton.Ok | QMessageBox.StandardButton.Cancel
|
QMessageBox.StandardButton.Ok | QMessageBox.StandardButton.Cancel,
|
||||||
)
|
)
|
||||||
|
|
||||||
if reply == QMessageBox.StandardButton.Ok:
|
if reply == QMessageBox.StandardButton.Ok:
|
||||||
self.use_silent_gaps = enabled
|
self.use_silent_gaps = enabled
|
||||||
self.config["use_silent_gaps"] = enabled
|
self.config["use_silent_gaps"] = enabled
|
||||||
@@ -3183,7 +3198,7 @@ class abogen(QWidget):
|
|||||||
else:
|
else:
|
||||||
# Revert the checkbox state if cancelled
|
# Revert the checkbox state if cancelled
|
||||||
self.silent_gaps_action.setChecked(not enabled)
|
self.silent_gaps_action.setChecked(not enabled)
|
||||||
|
|
||||||
def toggle_subtitle_speed_method(self, method):
|
def toggle_subtitle_speed_method(self, method):
|
||||||
self.subtitle_speed_method = method
|
self.subtitle_speed_method = method
|
||||||
self.config["subtitle_speed_method"] = method
|
self.config["subtitle_speed_method"] = method
|
||||||
|
|||||||
+7
-2
@@ -8,9 +8,14 @@ import signal
|
|||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
import ctypes
|
import ctypes
|
||||||
from importlib.util import find_spec
|
from importlib.util import find_spec
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if (spec := find_spec("torch")) and spec.origin and os.path.exists(
|
if (
|
||||||
dll_path := os.path.join(os.path.dirname(spec.origin), "lib", "c10.dll")
|
(spec := find_spec("torch"))
|
||||||
|
and spec.origin
|
||||||
|
and os.path.exists(
|
||||||
|
dll_path := os.path.join(os.path.dirname(spec.origin), "lib", "c10.dll")
|
||||||
|
)
|
||||||
):
|
):
|
||||||
ctypes.CDLL(os.path.normpath(dll_path))
|
ctypes.CDLL(os.path.normpath(dll_path))
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|||||||
@@ -88,7 +88,10 @@ class DroppableQueueListWidget(QListWidget):
|
|||||||
if event.mimeData().hasUrls():
|
if event.mimeData().hasUrls():
|
||||||
for url in event.mimeData().urls():
|
for url in event.mimeData().urls():
|
||||||
file_path = url.toLocalFile().lower()
|
file_path = url.toLocalFile().lower()
|
||||||
if url.isLocalFile() and (file_path.endswith(".txt") or file_path.endswith((".srt", ".ass", ".vtt"))):
|
if url.isLocalFile() and (
|
||||||
|
file_path.endswith(".txt")
|
||||||
|
or file_path.endswith((".srt", ".ass", ".vtt"))
|
||||||
|
):
|
||||||
self.drag_overlay.resize(self.size())
|
self.drag_overlay.resize(self.size())
|
||||||
self.drag_overlay.setVisible(True)
|
self.drag_overlay.setVisible(True)
|
||||||
event.acceptProposedAction()
|
event.acceptProposedAction()
|
||||||
@@ -100,7 +103,10 @@ class DroppableQueueListWidget(QListWidget):
|
|||||||
if event.mimeData().hasUrls():
|
if event.mimeData().hasUrls():
|
||||||
for url in event.mimeData().urls():
|
for url in event.mimeData().urls():
|
||||||
file_path = url.toLocalFile().lower()
|
file_path = url.toLocalFile().lower()
|
||||||
if url.isLocalFile() and (file_path.endswith(".txt") or file_path.endswith((".srt", ".ass", ".vtt"))):
|
if url.isLocalFile() and (
|
||||||
|
file_path.endswith(".txt")
|
||||||
|
or file_path.endswith((".srt", ".ass", ".vtt"))
|
||||||
|
):
|
||||||
event.acceptProposedAction()
|
event.acceptProposedAction()
|
||||||
return
|
return
|
||||||
event.ignore()
|
event.ignore()
|
||||||
@@ -115,7 +121,11 @@ class DroppableQueueListWidget(QListWidget):
|
|||||||
file_paths = [
|
file_paths = [
|
||||||
url.toLocalFile()
|
url.toLocalFile()
|
||||||
for url in event.mimeData().urls()
|
for url in event.mimeData().urls()
|
||||||
if url.isLocalFile() and (url.toLocalFile().lower().endswith(".txt") or url.toLocalFile().lower().endswith((".srt", ".ass", ".vtt")))
|
if url.isLocalFile()
|
||||||
|
and (
|
||||||
|
url.toLocalFile().lower().endswith(".txt")
|
||||||
|
or url.toLocalFile().lower().endswith((".srt", ".ass", ".vtt"))
|
||||||
|
)
|
||||||
]
|
]
|
||||||
if file_paths:
|
if file_paths:
|
||||||
self.parent_dialog.add_files_from_paths(file_paths)
|
self.parent_dialog.add_files_from_paths(file_paths)
|
||||||
@@ -408,9 +418,7 @@ class QueueManager(QDialog):
|
|||||||
parent, "replace_single_newlines", False
|
parent, "replace_single_newlines", False
|
||||||
)
|
)
|
||||||
# use_silent_gaps
|
# use_silent_gaps
|
||||||
attrs["use_silent_gaps"] = getattr(
|
attrs["use_silent_gaps"] = getattr(parent, "use_silent_gaps", False)
|
||||||
parent, "use_silent_gaps", False
|
|
||||||
)
|
|
||||||
# subtitle_speed_method
|
# subtitle_speed_method
|
||||||
attrs["subtitle_speed_method"] = getattr(
|
attrs["subtitle_speed_method"] = getattr(
|
||||||
parent, "subtitle_speed_method", "tts"
|
parent, "subtitle_speed_method", "tts"
|
||||||
@@ -527,7 +535,10 @@ class QueueManager(QDialog):
|
|||||||
|
|
||||||
# Allow .txt, .srt, .ass, and .vtt files
|
# Allow .txt, .srt, .ass, and .vtt files
|
||||||
files, _ = QFileDialog.getOpenFileNames(
|
files, _ = QFileDialog.getOpenFileNames(
|
||||||
self, "Select text or subtitle files", "", "Supported Files (*.txt *.srt *.ass *.vtt)"
|
self,
|
||||||
|
"Select text or subtitle files",
|
||||||
|
"",
|
||||||
|
"Supported Files (*.txt *.srt *.ass *.vtt)",
|
||||||
)
|
)
|
||||||
if not files:
|
if not files:
|
||||||
return
|
return
|
||||||
|
|||||||
+1
-1
@@ -259,7 +259,7 @@ def calculate_text_length(text):
|
|||||||
def get_gpu_acceleration(enabled):
|
def get_gpu_acceleration(enabled):
|
||||||
"""
|
"""
|
||||||
Check GPU acceleration availability.
|
Check GPU acceleration availability.
|
||||||
|
|
||||||
Note: On Windows, torch DLLs must be pre-loaded in main.py before PyQt6
|
Note: On Windows, torch DLLs must be pre-loaded in main.py before PyQt6
|
||||||
to avoid DLL initialization errors.
|
to avoid DLL initialization errors.
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -278,7 +278,7 @@ class VoiceMixer(QWidget):
|
|||||||
# Apply slider styling once when widget is shown and has access to parent
|
# Apply slider styling once when widget is shown and has access to parent
|
||||||
if not self._slider_style_applied:
|
if not self._slider_style_applied:
|
||||||
self._slider_style_applied = True
|
self._slider_style_applied = True
|
||||||
|
|
||||||
# Fix slider in Windows
|
# Fix slider in Windows
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
appstyle = QApplication.instance().style().objectName().lower()
|
appstyle = QApplication.instance().style().objectName().lower()
|
||||||
@@ -303,7 +303,7 @@ class VoiceMixer(QWidget):
|
|||||||
theme = parent_window.config.get("theme", "system")
|
theme = parent_window.config.get("theme", "system")
|
||||||
break
|
break
|
||||||
parent_window = parent_window.parent()
|
parent_window = parent_window.parent()
|
||||||
|
|
||||||
if theme == "light":
|
if theme == "light":
|
||||||
self.slider.setStyleSheet(
|
self.slider.setStyleSheet(
|
||||||
f"""
|
f"""
|
||||||
|
|||||||
Reference in New Issue
Block a user