Filter options
All checks were successful
Android Build Final Fixed / build-android (push) Successful in 12m29s
All checks were successful
Android Build Final Fixed / build-android (push) Successful in 12m29s
This commit is contained in:
Submodule src-tauri/easy-nostr updated: 1becf76264...9845dd025d
@@ -6,7 +6,13 @@ use tauri::{AppHandle, Manager, State};
|
||||
|
||||
#[derive(Serialize, Deserialize, Default, Clone)]
|
||||
pub struct RssConfig {
|
||||
pub urls: Vec<String>,
|
||||
pub feeds: Vec<RssFeed>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct RssFeed {
|
||||
pub url: String,
|
||||
pub category: String,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
@@ -22,6 +28,7 @@ pub struct NewsArticle {
|
||||
pub content: String,
|
||||
pub author: String,
|
||||
pub created_at: String,
|
||||
pub category: String,
|
||||
}
|
||||
|
||||
fn get_config_path(app: &AppHandle) -> PathBuf {
|
||||
@@ -31,6 +38,81 @@ fn get_config_path(app: &AppHandle) -> PathBuf {
|
||||
.join("rss.ron")
|
||||
}
|
||||
|
||||
fn default_feeds() -> Vec<RssFeed> {
|
||||
vec![
|
||||
// 💻 Technik
|
||||
RssFeed {
|
||||
url: "https://www.heise.de/rss/heise-atom.xml".into(),
|
||||
category: "Technik".into(),
|
||||
},
|
||||
RssFeed {
|
||||
url: "https://www.golem.de/rss.php?feed=ATOM1.0".into(),
|
||||
category: "Technik".into(),
|
||||
},
|
||||
RssFeed {
|
||||
url: "https://www.theverge.com/rss/index.xml".into(),
|
||||
category: "Technik".into(),
|
||||
},
|
||||
RssFeed {
|
||||
url: "https://arstechnica.com/feed/".into(),
|
||||
category: "Technik".into(),
|
||||
},
|
||||
RssFeed {
|
||||
url: "https://www.phoronix.com/rss.php".into(),
|
||||
category: "Technik".into(),
|
||||
},
|
||||
// 📰 Nachrichten
|
||||
RssFeed {
|
||||
url: "https://www.tagesschau.de/xml/rss2".into(),
|
||||
category: "Nachrichten".into(),
|
||||
},
|
||||
RssFeed {
|
||||
url: "https://www.spiegel.de/schlagzeilen/index.rss".into(),
|
||||
category: "Nachrichten".into(),
|
||||
},
|
||||
RssFeed {
|
||||
url: "https://feeds.bbci.co.uk/news/technology/rss.xml".into(),
|
||||
category: "Nachrichten".into(),
|
||||
},
|
||||
RssFeed {
|
||||
url: "https://feeds.reuters.com/reuters/technologyNews".into(),
|
||||
category: "Nachrichten".into(),
|
||||
},
|
||||
// 🔭 Wissenschaft
|
||||
RssFeed {
|
||||
url: "https://www.nasa.gov/news-release/feed/".into(),
|
||||
category: "Wissenschaft".into(),
|
||||
},
|
||||
RssFeed {
|
||||
url: "https://www.sciencedaily.com/rss/computers_math/artificial_intelligence.xml"
|
||||
.into(),
|
||||
category: "Wissenschaft".into(),
|
||||
},
|
||||
RssFeed {
|
||||
url: "https://deepmind.google/blog/rss.xml".into(),
|
||||
category: "Wissenschaft".into(),
|
||||
},
|
||||
// 🤖 KI
|
||||
RssFeed {
|
||||
url: "https://openai.com/blog/rss.xml".into(),
|
||||
category: "KI".into(),
|
||||
},
|
||||
RssFeed {
|
||||
url: "https://venturebeat.com/feed/".into(),
|
||||
category: "KI".into(),
|
||||
},
|
||||
// 🐧 Open Source
|
||||
RssFeed {
|
||||
url: "https://lwn.net/headlines/rss".into(),
|
||||
category: "Open Source".into(),
|
||||
},
|
||||
RssFeed {
|
||||
url: "https://github.blog/feed/".into(),
|
||||
category: "Open Source".into(),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
#[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")?;
|
||||
@@ -49,39 +131,45 @@ pub async fn save_groq_key(key: String, state: State<'_, NewsState>) -> Result<(
|
||||
pub async fn load_rss_config(
|
||||
app: AppHandle,
|
||||
state: State<'_, NewsState>,
|
||||
) -> Result<Vec<String>, String> {
|
||||
) -> Result<Vec<RssFeed>, String> {
|
||||
let path = get_config_path(&app);
|
||||
if !path.exists() {
|
||||
let default_urls = vec![
|
||||
"https://www.nasa.gov/news-release/feed/".to_string(),
|
||||
"https://www.heise.de/rss/heise-atom.xml".to_string(),
|
||||
];
|
||||
let config = RssConfig {
|
||||
urls: default_urls.clone(),
|
||||
};
|
||||
if let Some(parent) = path.parent() {
|
||||
fs::create_dir_all(parent).map_err(|e| e.to_string())?;
|
||||
let defaults = default_feeds();
|
||||
|
||||
let existing_config: Option<RssConfig> = if path.exists() {
|
||||
let content = fs::read_to_string(&path).map_err(|e| e.to_string())?;
|
||||
ron::from_str(&content).ok()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// Datei fehlt ODER hat weniger als 3 Einträge → defaults schreiben
|
||||
let feeds = match existing_config {
|
||||
Some(config) if config.feeds.len() >= 3 => config.feeds,
|
||||
_ => {
|
||||
let config = RssConfig {
|
||||
feeds: defaults.clone(),
|
||||
};
|
||||
if let Some(parent) = path.parent() {
|
||||
fs::create_dir_all(parent).map_err(|e| e.to_string())?;
|
||||
}
|
||||
let ron_str = ron::to_string(&config).map_err(|e| e.to_string())?;
|
||||
fs::write(&path, ron_str).map_err(|e| e.to_string())?;
|
||||
defaults
|
||||
}
|
||||
let ron_str = ron::to_string(&config).map_err(|e| e.to_string())?;
|
||||
fs::write(&path, ron_str).map_err(|e| e.to_string())?;
|
||||
let mut lock = state.rss_config.lock().unwrap();
|
||||
lock.urls = default_urls.clone();
|
||||
return Ok(default_urls);
|
||||
}
|
||||
let content = fs::read_to_string(path).map_err(|e| e.to_string())?;
|
||||
let config: RssConfig = ron::from_str(&content).map_err(|e| e.to_string())?;
|
||||
};
|
||||
|
||||
let mut lock = state.rss_config.lock().unwrap();
|
||||
*lock = config.clone();
|
||||
Ok(config.urls)
|
||||
lock.feeds = feeds.clone();
|
||||
Ok(feeds)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn save_rss_urls(
|
||||
urls: Vec<String>,
|
||||
feeds: Vec<RssFeed>,
|
||||
app: AppHandle,
|
||||
state: State<'_, NewsState>,
|
||||
) -> Result<(), String> {
|
||||
let config = RssConfig { urls };
|
||||
let config = RssConfig { feeds };
|
||||
let path = get_config_path(&app);
|
||||
if let Some(parent) = path.parent() {
|
||||
fs::create_dir_all(parent).map_err(|e| e.to_string())?;
|
||||
@@ -152,17 +240,18 @@ pub async fn fetch_ai_news(
|
||||
content,
|
||||
author: author.into(),
|
||||
created_at: "Gerade eben".into(),
|
||||
category: "KI".into(),
|
||||
}])
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn fetch_rss_news(state: State<'_, NewsState>) -> Result<Vec<NewsArticle>, String> {
|
||||
let urls = state.rss_config.lock().unwrap().urls.clone();
|
||||
let feeds = state.rss_config.lock().unwrap().feeds.clone();
|
||||
let mut all_articles = Vec::new();
|
||||
let client = reqwest::Client::new();
|
||||
|
||||
for url in urls {
|
||||
if let Ok(res) = client.get(&url).send().await {
|
||||
for feed_cfg in feeds {
|
||||
if let Ok(res) = client.get(&feed_cfg.url).send().await {
|
||||
if let Ok(bytes) = res.bytes().await {
|
||||
if let Ok(feed) = feed_rs::parser::parse(&bytes[..]) {
|
||||
let source = feed
|
||||
@@ -184,6 +273,7 @@ pub async fn fetch_rss_news(state: State<'_, NewsState>) -> Result<Vec<NewsArtic
|
||||
),
|
||||
author: source.clone(),
|
||||
created_at: date,
|
||||
category: feed_cfg.category.clone(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user