diff --git a/Cargo.toml b/Cargo.toml index daf2bd1..56252cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,12 +11,13 @@ rusqlite = {version=">=0.34",features=['bundled']} scraper = "0.23.1" directories = "6.0.0" chrono = "0.4.41" -rss_content = { git = "https://code.gabe.rocks/gabriel/rss_content", version = "0.1.1" } url = "2.5.4" opml = "1.1.6" sha1 = "0.10.6" bytes = "1.11.1" +ego-tree = "0.10.0" #rfd = "0.15.4" (for importing files) + [profile.dev] debug=true incremental = true diff --git a/src/main.rs b/src/main.rs index 951ca1c..3d68e40 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ pub mod ui; pub mod db; pub mod files; pub mod widgets; +mod rss_content; pub fn main() -> iced::Result { db::initialize(); diff --git a/src/net.rs b/src/net.rs index 10dad05..a84e62b 100644 --- a/src/net.rs +++ b/src/net.rs @@ -89,28 +89,20 @@ fn get_client(network: Network) -> Result { } } -pub fn get_content(url: &str) -> Option { +fn fetch(url: &str) -> Option { let client = get_client(url_network(url)).unwrap(); - 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, - } + client.get(url) + .header(USER_AGENT, "RSS Reader") + .send() + .ok() +} + +pub fn get_content(url: &str) -> Option { + fetch(url)?.text().ok() } pub fn get_bytes(url: &str) -> Option { - let client = get_client(url_network(url)).unwrap(); - let res = client.get(url).header(USER_AGENT, "RSS Reader").send(); - match res { - Ok(resp) => match resp.bytes() { - Ok(body) => return Some(body), - Err(_) => return None, - }, - Err(_) => return None, - } + fetch(url)?.bytes().ok() } pub fn retrieve_opml(url: &str) -> Vec { diff --git a/src/rss_content/mod.rs b/src/rss_content/mod.rs new file mode 100644 index 0000000..cfdbe07 --- /dev/null +++ b/src/rss_content/mod.rs @@ -0,0 +1,350 @@ +use scraper::{ElementRef, Html, Node}; +use iced::widget::markdown; + +/* + The goal here is to flatten the DOM as much as possible. + paragraphs with fancy formatting are turned into markdown, same with +*/ + +//Supported content +#[derive(Debug,Clone)] +pub enum Content { + Markdown(String), + MarkdownParsed(Vec), + Image(String), + Audio(String), + Video(String), + Ignore +} + +pub fn parse_content(c: &str) -> Vec{ + process_content(&itemize_content(c)).into_iter().map(|i| { + match i { + Content::Markdown(s) => { + Content::MarkdownParsed(markdown::parse(&s).collect()) + //this is super lazy but it works.... + } + _ => {i} + } + }).collect() +} + +fn markdownify_child(item: &Item) -> String { + let mut result = "".to_owned(); + match markdown_content(&item) { + Content::Markdown(s) => { + result = result + &s; + }, + _ => {} + } + result + +} + +fn process_children(children: &Vec) -> String { + let mut result = "".to_owned(); + for c in children{ + result = result + &markdownify_child(c); + } + result +} + + +fn has_image(children: &Vec) -> bool { + for c in children { + match c { + Item::Image(_) => { + return true; + } + _ => {} + } + } + false +} + +fn has_video(children: &Vec) -> bool{ + for c in children { + match c { + Item::Video(_) => { + return true; + } + _ => {} + } + + } + false +} + +fn markdown_content(item: &Item) -> Content { + let mut markdown = String::new(); + match item { + Item::Title(n,children) => { + markdown = markdown + &"#".repeat(*n) + " " +&process_children(children); + }, + Item::BoldedText(children) => { + markdown = format!("**{}**",process_children(children)); + }, + Item::EmphasisText(children) => { + markdown = format!("*{}*",process_children(children)); + } + Item::Text(s) => { + markdown = markdown + s; + }, + Item::Link(href, children) => { + markdown = markdown + &format!("[{}]({})",process_children(children),href); + } + Item::Paragraph(children) => { + markdown = markdown + &process_children(children); + } + Item::UnorderedList(children) => { + markdown = markdown + &process_children(children); + } + Item::OrderedList(children) => { + markdown = markdown + &process_children(children); + } + Item::ListItem(children) => { + markdown = "\n- ".to_owned() + &process_children(children); + } + Item::Code(children) => { + markdown = markdown + &format!("```{}```",&process_children(children)); + } + Item::Blockquote(children) => { + markdown = markdown + "> " + &process_children(children); + } + _ => {} + } + Content::Markdown(markdown) +} + +fn get_media_source(children: &Vec) -> Option { + for c in children { + match c { + Item::Source(src) => { + return Some(src.to_owned()); + } + _ => {} + } + } + None +} + +fn media_content(item: &Item) -> Content{ + match item { + Item::Link(_,children) => { + for c in children { + match c { + Item::Video(_) => {return media_content(c);} + Item::Audio(_) => {return media_content(c);} + _ => {} + } + } + Content::Ignore + } + Item::Audio(children) => { + match get_media_source(children) { + Some(s) => { + return Content::Audio(s); + } + None => { + return Content::Markdown("