rss parsing works now
This commit is contained in:
parent
824af0449b
commit
fbe201c4db
6 changed files with 85 additions and 29 deletions
|
@ -15,6 +15,8 @@ regex = "1"
|
||||||
directories = "6.0.0"
|
directories = "6.0.0"
|
||||||
chrono = "0.4.41"
|
chrono = "0.4.41"
|
||||||
rss_content = { git = "https://code.gabe.rocks/gabriel/rss_content", version = "0.1.1" }
|
rss_content = { git = "https://code.gabe.rocks/gabriel/rss_content", version = "0.1.1" }
|
||||||
|
bytes = "1.10.1"
|
||||||
|
scraper = "0.23.1"
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
debug=true
|
debug=true
|
||||||
|
|
26
src/db.rs
26
src/db.rs
|
@ -5,16 +5,11 @@ use super::files::*;
|
||||||
use super::net::*;
|
use super::net::*;
|
||||||
use chrono::Utc; //Maybe use a different time?
|
use chrono::Utc; //Maybe use a different time?
|
||||||
use chrono::DateTime;
|
use chrono::DateTime;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Cache is the in-memory database
|
Cache is the in-memory database
|
||||||
Any changes/updates are written to file database
|
Any changes/updates are written to file database
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct Item {
|
|
||||||
title: String,
|
|
||||||
content: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
const DB_LOCATION: &str = "rsscar.db";
|
const DB_LOCATION: &str = "rsscar.db";
|
||||||
|
|
||||||
|
@ -127,25 +122,6 @@ pub fn store_items(feed: rss::Channel,feed_id: usize) {
|
||||||
conn.close().unwrap();
|
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 struct FeedItem {
|
||||||
pub item_id: usize,
|
pub item_id: usize,
|
||||||
|
@ -230,7 +206,7 @@ pub fn get_feeds() -> Vec<Feed> {
|
||||||
Ok(r) => {
|
Ok(r) => {
|
||||||
r
|
r
|
||||||
}
|
}
|
||||||
Err(e) => {panic!("No idea what causes this")}
|
Err(_) => {panic!("No idea what causes this")}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
struct ReturnedFeedURLs {
|
struct ReturnedFeedURLs {
|
||||||
|
|
|
@ -5,9 +5,13 @@ pub mod db;
|
||||||
pub mod files;
|
pub mod files;
|
||||||
pub mod widgets;
|
pub mod widgets;
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub fn main() -> iced::Result {
|
pub fn main() -> iced::Result {
|
||||||
db::initialize();
|
db::initialize();
|
||||||
ui::user_interface()
|
ui::user_interface()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests;
|
||||||
|
|
||||||
|
|
62
src/net.rs
62
src/net.rs
|
@ -1,9 +1,65 @@
|
||||||
use core::panic;
|
use core::panic;
|
||||||
use iced::widget::image::Handle;
|
use iced::widget::image::Handle;
|
||||||
use rss::{Channel};
|
use rss::{Channel};
|
||||||
|
use bytes::Bytes;
|
||||||
use reqwest::{self, blocking::Client, header::USER_AGENT};
|
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>{
|
pub fn load_rss(url: &str) -> Option<Channel>{
|
||||||
let client = Client::new();
|
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)}
|
Err(err) => {panic!("Error loading feed.:{}",err)}
|
||||||
|
@ -58,4 +114,4 @@ pub fn download_image(url: &str) -> Option<iced::widget::image::Handle>{
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
18
src/tests.rs
Normal file
18
src/tests.rs
Normal 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());
|
||||||
|
}
|
||||||
|
}
|
|
@ -163,7 +163,7 @@ fn item_view(state: &State) -> Element<'_, Message> {
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn item_list(state: &State) -> Element<'_,Message>{
|
fn item_list(_: &State) -> Element<'_,Message>{
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
fn testing(state: &State) -> Element<'_, Message> {
|
fn testing(state: &State) -> Element<'_, Message> {
|
||||||
|
|
Loading…
Reference in a new issue