feat: add detailed logging for transcription and summarization processes and ensure correct content type synchronization for transcription triggering.
This commit is contained in:
@@ -750,6 +750,7 @@ pub async fn run_transcription_task(pool: PgPool, lesson_id: Uuid) -> Result<(),
|
|||||||
let file_path = format!("uploads/{}", filename);
|
let file_path = format!("uploads/{}", filename);
|
||||||
|
|
||||||
// 2. Set status to processing
|
// 2. Set status to processing
|
||||||
|
tracing::info!("Starting transcription for lesson {} (file: {})", lesson_id, file_path);
|
||||||
sqlx::query("UPDATE lessons SET transcription_status = 'processing' WHERE id = $1")
|
sqlx::query("UPDATE lessons SET transcription_status = 'processing' WHERE id = $1")
|
||||||
.bind(lesson_id)
|
.bind(lesson_id)
|
||||||
.execute(&pool)
|
.execute(&pool)
|
||||||
@@ -759,7 +760,13 @@ pub async fn run_transcription_task(pool: PgPool, lesson_id: Uuid) -> Result<(),
|
|||||||
// 3. Read file
|
// 3. Read file
|
||||||
let file_data = tokio::fs::read(&file_path)
|
let file_data = tokio::fs::read(&file_path)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| format!("File read failed ({}): {}", file_path, e))?;
|
.map_err(|e| {
|
||||||
|
let err = format!("File read failed ({}): {}", file_path, e);
|
||||||
|
tracing::error!("{}", err);
|
||||||
|
err
|
||||||
|
})?;
|
||||||
|
|
||||||
|
tracing::info!("File read successfully ({} bytes). Sending to Whisper...", file_data.len());
|
||||||
|
|
||||||
// 4. Send to Whisper
|
// 4. Send to Whisper
|
||||||
let whisper_url = env::var("LOCAL_WHISPER_URL").unwrap_or_else(|_| "http://localhost:8000".to_string());
|
let whisper_url = env::var("LOCAL_WHISPER_URL").unwrap_or_else(|_| "http://localhost:8000".to_string());
|
||||||
@@ -775,17 +782,25 @@ pub async fn run_transcription_task(pool: PgPool, lesson_id: Uuid) -> Result<(),
|
|||||||
.multipart(form)
|
.multipart(form)
|
||||||
.send()
|
.send()
|
||||||
.await
|
.await
|
||||||
.map_err(|e| format!("Whisper request failed: {}", e))?;
|
.map_err(|e| {
|
||||||
|
let err = format!("Whisper request failed: {}", e);
|
||||||
|
tracing::error!("{}", err);
|
||||||
|
err
|
||||||
|
})?;
|
||||||
|
|
||||||
if !response.status().is_success() {
|
if !response.status().is_success() {
|
||||||
let status = response.status();
|
let status = response.status();
|
||||||
let err_body = response.text().await.unwrap_or_default();
|
let err_body = response.text().await.unwrap_or_default();
|
||||||
return Err(format!("Whisper API error: {} - {}", status, err_body));
|
let err = format!("Whisper API error: {} - {}", status, err_body);
|
||||||
|
tracing::error!("{}", err);
|
||||||
|
return Err(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
let transcription_result: serde_json::Value = response.json().await
|
let transcription_result: serde_json::Value = response.json().await
|
||||||
.map_err(|e| format!("Failed to parse Whisper response: {}", e))?;
|
.map_err(|e| format!("Failed to parse Whisper response: {}", e))?;
|
||||||
|
|
||||||
|
tracing::info!("Transcription received successfully for lesson {}", lesson_id);
|
||||||
|
|
||||||
// 5. Update lesson with transcription
|
// 5. Update lesson with transcription
|
||||||
sqlx::query("UPDATE lessons SET transcription = $1, transcription_status = 'completed' WHERE id = $2")
|
sqlx::query("UPDATE lessons SET transcription = $1, transcription_status = 'completed' WHERE id = $2")
|
||||||
.bind(&transcription_result)
|
.bind(&transcription_result)
|
||||||
@@ -797,7 +812,9 @@ pub async fn run_transcription_task(pool: PgPool, lesson_id: Uuid) -> Result<(),
|
|||||||
// 6. Optional: Trigger Summarization using Ollama
|
// 6. Optional: Trigger Summarization using Ollama
|
||||||
let full_text = transcription_result["text"].as_str().unwrap_or("");
|
let full_text = transcription_result["text"].as_str().unwrap_or("");
|
||||||
if !full_text.is_empty() {
|
if !full_text.is_empty() {
|
||||||
|
tracing::info!("Triggering AI summary for lesson {}", lesson_id);
|
||||||
if let Ok(summary) = generate_summary_with_ollama(full_text).await {
|
if let Ok(summary) = generate_summary_with_ollama(full_text).await {
|
||||||
|
tracing::info!("Summary generated successfully for lesson {}", lesson_id);
|
||||||
let _ = sqlx::query("UPDATE lessons SET summary = $1 WHERE id = $2")
|
let _ = sqlx::query("UPDATE lessons SET summary = $1 WHERE id = $2")
|
||||||
.bind(summary)
|
.bind(summary)
|
||||||
.bind(lesson_id)
|
.bind(lesson_id)
|
||||||
@@ -832,7 +849,11 @@ async fn generate_summary_with_ollama(text: &str) -> Result<String, String> {
|
|||||||
}))
|
}))
|
||||||
.send()
|
.send()
|
||||||
.await
|
.await
|
||||||
.map_err(|e| format!("Ollama summary request failed: {}", e))?;
|
.map_err(|e| {
|
||||||
|
let err = format!("Ollama summary request failed: {}", e);
|
||||||
|
tracing::error!("{}", err);
|
||||||
|
err
|
||||||
|
})?;
|
||||||
|
|
||||||
if !response.status().is_success() {
|
if !response.status().is_success() {
|
||||||
return Err("Ollama summary API error".into());
|
return Err("Ollama summary API error".into());
|
||||||
|
|||||||
@@ -136,16 +136,23 @@ export default function LessonEditor({ params }: { params: { id: string; lessonI
|
|||||||
try {
|
try {
|
||||||
// Sync content_url for video/audio lessons from the first media block
|
// Sync content_url for video/audio lessons from the first media block
|
||||||
let content_url = lesson.content_url;
|
let content_url = lesson.content_url;
|
||||||
if (lesson.content_type === 'video' || lesson.content_type === 'audio') {
|
let content_type = lesson.content_type;
|
||||||
const mediaBlock = blocks.find(b => b.type === 'media');
|
|
||||||
|
const mediaBlock = blocks.find(b => b.type === 'media' || b.type === 'video_marker');
|
||||||
if (mediaBlock && mediaBlock.url) {
|
if (mediaBlock && mediaBlock.url) {
|
||||||
content_url = mediaBlock.url;
|
content_url = mediaBlock.url;
|
||||||
|
// If it's a video marker or explicitly a video/audio media block
|
||||||
|
if (mediaBlock.type === 'video_marker') {
|
||||||
|
content_type = 'video';
|
||||||
|
} else if (mediaBlock.type === 'media') {
|
||||||
|
content_type = mediaBlock.media_type || 'video';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const updated = await cmsApi.updateLesson(lesson.id, {
|
const updated = await cmsApi.updateLesson(lesson.id, {
|
||||||
metadata: { ...lesson.metadata, blocks },
|
metadata: { ...lesson.metadata, blocks },
|
||||||
content_url,
|
content_url,
|
||||||
|
content_type, // Sync type to ensure backend triggers transcription
|
||||||
summary,
|
summary,
|
||||||
is_graded: isGraded,
|
is_graded: isGraded,
|
||||||
grading_category_id: selectedCategoryId || null,
|
grading_category_id: selectedCategoryId || null,
|
||||||
|
|||||||
Reference in New Issue
Block a user