rss parsing works now

This commit is contained in:
Gabriel 2025-07-22 11:09:42 -04:00
parent 824af0449b
commit fbe201c4db
6 changed files with 85 additions and 29 deletions

View file

@ -15,6 +15,8 @@ regex = "1"
directories = "6.0.0"
chrono = "0.4.41"
rss_content = { git = "https://code.gabe.rocks/gabriel/rss_content", version = "0.1.1" }
bytes = "1.10.1"
scraper = "0.23.1"
[profile.dev]
debug=true

View file

@ -5,16 +5,11 @@ use super::files::*;
use super::net::*;
use chrono::Utc; //Maybe use a different time?
use chrono::DateTime;
/*
Cache is the in-memory database
Any changes/updates are written to file database
*/
struct Item {
title: String,
content: Option<String>,
}
const DB_LOCATION: &str = "rsscar.db";
@ -127,25 +122,6 @@ pub fn store_items(feed: rss::Channel,feed_id: usize) {
conn.close().unwrap();
}
pub fn return_item() -> String {
let conn = Connection::open(get_db_path()).unwrap();
let item = conn
.query_row(
"select title,content from items where rowid=?1",
[],
|row| {
Ok(Item {
title: row.get(0).unwrap(),
content: row.get(1).unwrap(),
})
},
)
.unwrap();
match item.content {
Some(content) => content,
None => panic!(),
}
}
pub struct FeedItem {
pub item_id: usize,
@ -230,7 +206,7 @@ pub fn get_feeds() -> Vec<Feed> {
Ok(r) => {
r
}
Err(e) => {panic!("No idea what causes this")}
Err(_) => {panic!("No idea what causes this")}
}
}
struct ReturnedFeedURLs {

View file

@ -5,9 +5,13 @@ pub mod db;
pub mod files;
pub mod widgets;
#[allow(dead_code)]
pub fn main() -> iced::Result {
db::initialize();
ui::user_interface()
}
#[cfg(test)]
mod tests;

View file

@ -1,9 +1,65 @@
use core::panic;
use iced::widget::image::Handle;
use rss::{Channel};
use bytes::Bytes;
use reqwest::{self, blocking::Client, header::USER_AGENT};
use scraper::{ElementRef, Html, Node, Selector};
// needs to support loading over various schemes (such as Tor & I2P) ideally based on the URL but DB may have to store scheme....
fn get_content(url: &str) -> Option<String> {
let client = Client::new();
let res = client.get(url)
.header(USER_AGENT,"RSS Reader")
.send();
match res {
Ok(resp) => {
match resp.text() {
Ok(body) => {return Some(body)}
Err(_) => {return None}
}
}
Err(_) => {return None}
}
None
}
pub fn get_feeds(url: &str) -> Option<Vec<Channel>>{
let page = get_content(url).unwrap();
let doc = Html::parse_document(&page);
let link_selector = Selector::parse("head link").unwrap();
let mut feeds: Vec<Channel> = Vec::new();
for e in doc.select(&link_selector) {
if let Some(rel) = e.value().attr("rel") {
if rel == "alternate" {
if let Some(href) = e.value().attr("href") {
match load_rss(href) {
Some(c) => {feeds.push(c)}
None => {}
}
}
}
}
}
return match feeds.len() {
0 => None,
_ => {Some(feeds)}
}
}
pub fn is_feed(url: &str) -> bool {
return match get_feeds(url) {
Some(_) => true,
None => false
};
false
}
pub fn load_rss(url: &str) -> Option<Channel>{
let client = Client::new();
@ -21,7 +77,7 @@ pub fn load_rss(url: &str) -> Option<Channel>{
},
Err(e) => { panic!("Empty response")}
Err(_) => { panic!("Empty response")}
}
},
Err(err) => {panic!("Error loading feed.:{}",err)}
@ -58,4 +114,4 @@ pub fn download_image(url: &str) -> Option<iced::widget::image::Handle>{
None
}
}
}
}

18
src/tests.rs Normal file
View file

@ -0,0 +1,18 @@
use super::net;
#[test]
fn get_feed_test(){
println!("Checking if gabe.rocks is an RSS feed");
assert!(net::is_feed("https://gabe.rocks"),"Error finding RSS feed");
}
#[test]
fn load_feeds() {
let url = "https://gabe.rocks";
let feeds = net::get_feeds(url).unwrap();
println!("Checking {} for feeds.\nResult:",url);
for f in feeds {
println!("Feed found:{}",f.title());
}
}

View file

@ -163,7 +163,7 @@ fn item_view(state: &State) -> Element<'_, Message> {
.into()
}
fn item_list(state: &State) -> Element<'_,Message>{
fn item_list(_: &State) -> Element<'_,Message>{
todo!()
}
fn testing(state: &State) -> Element<'_, Message> {