978 add youtube title (#1321)

This commit is contained in:
Raivis Dejus 2025-12-21 20:02:39 +02:00 committed by GitHub
commit 734bd99d17
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 63 additions and 12 deletions

View file

@ -250,6 +250,22 @@ class TranscriptionDAO(DAO[Transcription]):
if not query.exec():
raise Exception(query.lastError().text())
def update_transcription_file_and_name(self, id: UUID, file_path: str, name: str | None = None):
query = self._create_query()
query.prepare(
"""
UPDATE transcription
SET file = :file, name = COALESCE(:name, name)
WHERE id = :id
"""
)
query.bindValue(":id", str(id))
query.bindValue(":file", file_path)
query.bindValue(":name", name)
if not query.exec():
raise Exception(query.lastError().text())
def update_transcription_name(self, id: UUID, name: str):
query = self._create_query()
query.prepare(

View file

@ -47,6 +47,9 @@ class TranscriptionService:
)
)
def update_transcription_file_and_name(self, id: UUID, file_path: str, name: str | None = None):
self.transcription_dao.update_transcription_file_and_name(id, file_path, name)
def update_transcription_name(self, id: UUID, name: str):
self.transcription_dao.update_transcription_name(id, name)

View file

@ -38,12 +38,35 @@ class FileTranscriber(QObject):
@pyqtSlot()
def run(self):
if self.transcription_task.source == FileTranscriptionTask.Source.URL_IMPORT:
temp_output_path = tempfile.mktemp()
cookiefile = os.getenv("BUZZ_DOWNLOAD_COOKIEFILE")
# First extract info to get the video title
extract_options = {
"logger": logging.getLogger(),
}
if cookiefile:
extract_options["cookiefile"] = cookiefile
try:
with YoutubeDL(extract_options) as ydl_info:
info = ydl_info.extract_info(self.transcription_task.url, download=False)
video_title = info.get("title", "audio")
except Exception as exc:
logging.debug(f"Error extracting video info: {exc}")
video_title = "audio"
# Sanitize title for use as filename
video_title = YoutubeDL.sanitize_info({"title": video_title})["title"]
# Remove characters that are problematic in filenames
for char in ['/', '\\', ':', '*', '?', '"', '<', '>', '|']:
video_title = video_title.replace(char, '_')
# Create temp directory and use video title as filename
temp_dir = tempfile.mkdtemp()
temp_output_path = os.path.join(temp_dir, video_title)
wav_file = temp_output_path + ".wav"
wav_file = str(Path(wav_file).resolve())
cookiefile = os.getenv("BUZZ_DOWNLOAD_COOKIEFILE")
options = {
"format": "bestaudio/best",
"progress_hooks": [self.on_download_progress],

View file

@ -385,6 +385,15 @@ class MainWindow(QMainWindow):
pass
def on_task_completed(self, task: FileTranscriptionTask, segments: List[Segment]):
# Update file path in database (important for URL imports where file is downloaded)
if task.file_path:
logging.debug(f"Updating transcription file path: {task.file_path}")
# For URL imports, use the file basename (video title) as the display name
name = None
if task.source == FileTranscriptionTask.Source.URL_IMPORT:
basename = os.path.basename(task.file_path)
name = os.path.splitext(basename)[0] # Remove .wav extension
self.transcription_service.update_transcription_file_and_name(task.uid, task.file_path, name)
self.transcription_service.update_transcription_as_completed(task.uid, segments)
self.table_widget.refresh_row(task.uid)

View file

@ -95,8 +95,8 @@ column_definitions = [
width=400,
delegate=RecordDelegate(
text_getter=lambda record: record.value("name") or (
record.value("url") if record.value("url") != ""
else os.path.basename(record.value("file"))
os.path.basename(record.value("file")) if record.value("file")
else record.value("url") or ""
)
),
hidden_toggleable=False,

View file

@ -286,16 +286,16 @@ class TestTranscriptionTasksTableWidget:
text = file_column_def.delegate.callback(record_with_name)
assert text == "Custom Name"
# Test fallback to URL when no name
record_url_fallback = mock_record({"name": None, "url": "http://example.com/audio.mp3", "file": "/path/file.mp3"})
# Test fallback to file basename when no name (file takes priority over URL)
record_file_fallback = mock_record({"name": None, "url": "http://example.com/audio.mp3", "file": "/path/file.mp3"})
text = file_column_def.delegate.callback(record_file_fallback)
assert text == "file.mp3"
# Test fallback to URL when no name and no file
record_url_fallback = mock_record({"name": None, "url": "http://example.com/audio.mp3", "file": ""})
text = file_column_def.delegate.callback(record_url_fallback)
assert text == "http://example.com/audio.mp3"
# Test fallback to filename when no name or URL
record_file_fallback = mock_record({"name": None, "url": "", "file": "/path/to/audio.mp3"})
text = file_column_def.delegate.callback(record_file_fallback)
assert text == "audio.mp3"
def test_notes_column_text_getter(self, widget):
"""Test that notes column displays notes or empty string"""
notes_column_def = next((col for col in column_definitions if col.column == Column.NOTES), None)