diff --git a/README.md b/README.md index b0c32aa..86ecf18 100644 --- a/README.md +++ b/README.md @@ -21,12 +21,13 @@ Given a YouTube URL, the app can: - generate an English summary with a local Ollama model - optionally translate that summary into German and Japanese - store the results locally so they can be reopened later +- optionally send individual summaries to Discord with a user-provided webhook URL ## Local-Only Behavior This repository is intentionally reset to a clean publishable state: -- no Discord webhook integration +- no bundled Discord webhook URL or production credentials - no remote PHP/MySQL sync - no bundled production data or pre-filled database - runtime data is stored in the OS app data directory, not in the repo diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 2e04a94..890a1d1 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -814,13 +814,13 @@ fn is_word_char(ch: char) -> bool { fn is_abbreviation(token: &str) -> bool { const ABBREVIATIONS: &[&str] = &[ - "mr.", "mrs.", "ms.", "dr.", "prof.", "sr.", "jr.", "st.", "vs.", "etc.", "e.g.", - "i.e.", "cf.", "al.", "a.m.", "p.m.", "jan.", "feb.", "mar.", "apr.", "jun.", "jul.", - "aug.", "sep.", "sept.", "oct.", "nov.", "dec.", "no.", "fig.", "eq.", "vol.", "rev.", - "gen.", "gov.", "sen.", "rep.", "dept.", "univ.", "inc.", "ltd.", "co.", "corp.", - "bros.", "approx.", "est.", "min.", "sec.", "hr.", "fr.", "bzw.", "z.b.", "d.h.", - "u.a.", "u.u.", "i.d.r.", "ca.", "ggf.", "vgl.", "evtl.", "sog.", "u.s.w.", "nr.", - "abs.", "art.", "s.", "ff.", "mio.", "mrd.", "sek.", "okt.", "dez.", + "mr.", "mrs.", "ms.", "dr.", "prof.", "sr.", "jr.", "st.", "vs.", "etc.", "e.g.", "i.e.", + "cf.", "al.", "a.m.", "p.m.", "jan.", "feb.", "mar.", "apr.", "jun.", "jul.", "aug.", + "sep.", "sept.", "oct.", "nov.", "dec.", "no.", "fig.", "eq.", "vol.", "rev.", "gen.", + "gov.", "sen.", "rep.", "dept.", "univ.", "inc.", "ltd.", "co.", "corp.", "bros.", + "approx.", "est.", "min.", "sec.", "hr.", "fr.", "bzw.", "z.b.", "d.h.", "u.a.", "u.u.", + "i.d.r.", "ca.", "ggf.", "vgl.", "evtl.", "sog.", "u.s.w.", "nr.", "abs.", "art.", "s.", + "ff.", "mio.", "mrd.", "sek.", "okt.", "dez.", ]; ABBREVIATIONS.contains(&token) } @@ -874,10 +874,7 @@ fn insert_sentence_line_breaks(text: &str) -> String { while j > 0 && is_word_char(chars[j - 1]) { j -= 1; } - let token = chars[j..=i] - .iter() - .collect::() - .to_ascii_lowercase(); + let token = chars[j..=i].iter().collect::().to_ascii_lowercase(); if ch == '.' && is_abbreviation(&token) { i += 1; continue; @@ -1124,7 +1121,7 @@ fn build_discord_messages( chunks.splice(0..1, first_parts); } - if chunks.len() > 1 && char_len(chunks.last().unwrap_or(&String::new())) > last_limit { + if chunks.len() > 1 && chunks.last().map(|chunk| char_len(chunk)).unwrap_or(0) > last_limit { let last_index = chunks.len() - 1; let last_parts = split_summary_into_chunks(&chunks[last_index], last_limit); chunks.splice(last_index.., last_parts); @@ -1217,12 +1214,8 @@ fn post_summary_to_discord( let channel_text_line = limit_chars(&channel_name, 300); let video_line = limit_chars(&format!("Video: {video_url}"), 700); let summary_text = format_summary_for_discord(summary); - let messages = build_discord_messages( - &title_line, - &channel_text_line, - &video_line, - &summary_text, - ); + let messages = + build_discord_messages(&title_line, &channel_text_line, &video_line, &summary_text); for (index, message) in messages.iter().enumerate() { post_discord_message(client, webhook_url, message)?; @@ -1459,6 +1452,17 @@ async fn translate_summary( .map_err(|err| format!("Translate task failed: {err}"))? } +#[tauri::command] +async fn send_summary_to_discord( + state: State<'_, AppState>, + request: SendSummaryToDiscordRequest, +) -> Result<(), String> { + let state = state.inner().clone(); + tauri::async_runtime::spawn_blocking(move || send_summary_to_discord_inner(&state, request)) + .await + .map_err(|err| format!("Discord task failed: {err}"))? +} + #[tauri::command] fn open_external(url: String) -> Result<(), String> { that(url).map_err(|err| format!("Failed to open URL: {err}")) @@ -1531,6 +1535,7 @@ fn main() { summarize_video, delete_summary, translate_summary, + send_summary_to_discord, open_external, open_file ])