This commit is contained in:
2026-01-22 13:37:48 +01:00
parent ba72e8118f
commit 6d201280ed
6 changed files with 312 additions and 67 deletions

View File

@@ -11,6 +11,8 @@ pub fn run() {
home::fetch_nostr_posts,
news::save_openrouter_key,
news::fetch_ai_news,
news::fetch_rss_news,
news::save_rss_url,
])
.run(tauri::generate_context!())
.expect("error while running tauri application");

View File

@@ -5,6 +5,7 @@ use tauri::State;
#[derive(Default)]
pub struct NewsState {
pub openrouter_key: Mutex<String>,
pub rss_url: Mutex<String>, // Neu: Speicher für die RSS-URL
}
#[derive(Serialize, Deserialize, Clone)]
@@ -15,26 +16,29 @@ pub struct NewsArticle {
pub created_at: u64,
}
// Bestehender Command für den API Key
#[tauri::command]
pub async fn save_openrouter_key(key: String, state: State<'_, NewsState>) -> Result<(), String> {
let mut lock = state
.openrouter_key
.lock()
.map_err(|_| "Lock failed".to_string())?;
let mut lock = state.openrouter_key.lock().map_err(|_| "Lock failed")?;
*lock = key.trim().to_string();
Ok(())
}
// NEU: Command zum Speichern der RSS URL
#[tauri::command]
pub async fn save_rss_url(url: String, state: State<'_, NewsState>) -> Result<(), String> {
let mut lock = state.rss_url.lock().map_err(|_| "Lock failed")?;
*lock = url.trim().to_string();
Ok(())
}
#[tauri::command]
pub async fn fetch_ai_news(state: State<'_, NewsState>) -> Result<Vec<NewsArticle>, String> {
let key = {
let lock = state
.openrouter_key
.lock()
.map_err(|_| "Lock failed".to_string())?;
lock.clone()
};
let key = state
.openrouter_key
.lock()
.map_err(|_| "Lock failed")?
.clone();
if key.is_empty() {
return Err("API Key fehlt.".to_string());
}
@@ -51,21 +55,15 @@ pub async fn fetch_ai_news(state: State<'_, NewsState>) -> Result<Vec<NewsArticl
let response = client
.post("https://openrouter.ai/api/v1/chat/completions")
.header("Authorization", format!("Bearer {}", key))
.header("HTTP-Referer", "http://localhost:1420")
.json(&body)
.send()
.await
.map_err(|e| e.to_string())?;
if !response.status().is_success() {
return Err(format!("API Fehler: {}", response.status()));
}
let json_res: serde_json::Value = response.json().await.map_err(|e| e.to_string())?;
let content = json_res["choices"][0]["message"]["content"]
.as_str()
.ok_or_else(|| "Kein Content im JSON".to_string())?
.unwrap_or("Fehler")
.to_string();
Ok(vec![NewsArticle {
@@ -74,3 +72,46 @@ pub async fn fetch_ai_news(state: State<'_, NewsState>) -> Result<Vec<NewsArticl
created_at: 0,
}])
}
// VERBESSERT: Lädt nun den echten Feed von der gespeicherten URL
#[tauri::command]
pub async fn fetch_rss_news(state: State<'_, NewsState>) -> Result<Vec<NewsArticle>, String> {
let url = state.rss_url.lock().map_err(|_| "Lock failed")?.clone();
if url.is_empty() {
return Err("RSS URL fehlt. Bitte in den Einstellungen eintragen.".to_string());
}
let response = reqwest::get(&url)
.await
.map_err(|e| e.to_string())?
.bytes()
.await
.map_err(|e| e.to_string())?;
let feed = feed_rs::parser::parse(&response[..]).map_err(|e| e.to_string())?;
let articles = feed
.entries
.into_iter()
.take(5)
.map(|entry| NewsArticle {
content: format!(
"### {}\n\n{}",
entry.title.map(|t| t.content).unwrap_or_default(),
entry
.summary
.map(|s| s.content)
.unwrap_or_else(|| "Kein Inhalt".to_string())
),
author: feed
.title
.as_ref()
.map(|t| t.content.clone())
.unwrap_or_else(|| "RSS".into()),
created_at: entry.updated.map(|d| d.timestamp() as u64).unwrap_or(0),
})
.collect();
Ok(articles)
}