Lazy implementation of .opml import. Needs cleanup and better streamlining of events.
This commit is contained in:
parent
60fd547a6d
commit
8dbda35b18
5 changed files with 81 additions and 7 deletions
|
|
@ -13,6 +13,7 @@ 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"
|
||||
#rfd = "0.15.4" (for importing files)
|
||||
[profile.dev]
|
||||
debug=true
|
||||
|
|
|
|||
13
src/db.rs
13
src/db.rs
|
|
@ -2,6 +2,7 @@ use super::files::*;
|
|||
use super::net::*;
|
||||
use chrono::DateTime;
|
||||
use chrono::Utc;
|
||||
use rss::Channel;
|
||||
use rusqlite::Row;
|
||||
//Maybe use a different time?
|
||||
use rusqlite::{Connection, Result};
|
||||
|
|
@ -100,7 +101,17 @@ pub fn get_feed_id_by_url(url: &str) -> Option<usize> {
|
|||
}
|
||||
}
|
||||
pub fn add_feed(url: &str) -> Option<usize> {
|
||||
let feed = load_rss(url).unwrap();
|
||||
let mut feed: Channel;
|
||||
match load_rss(url) {
|
||||
Some(f) => {
|
||||
feed = f;
|
||||
}
|
||||
None => {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
let time = Utc::now().to_rfc2822();
|
||||
let image = if let Some(i) = feed.image() {
|
||||
i.url().to_owned()
|
||||
|
|
|
|||
40
src/net.rs
40
src/net.rs
|
|
@ -29,7 +29,9 @@ pub fn url_network(url: &str) -> Network {
|
|||
return Network::Clearnet;
|
||||
}
|
||||
}
|
||||
None => {return Network::Unknown;}
|
||||
None => {
|
||||
return Network::Unknown;
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
return Network::Clearnet;
|
||||
|
|
@ -39,7 +41,7 @@ pub fn url_network(url: &str) -> Network {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn network_testing(){
|
||||
fn network_testing() {
|
||||
assert!(url_network("http://gabe.onion/rss") == Network::Tor);
|
||||
assert!(url_network("http://gabe.i2p/rss") == Network::I2P);
|
||||
assert!(url_network("https://gabe.rocks/rss") == Network::Clearnet);
|
||||
|
|
@ -96,6 +98,36 @@ fn get_content(url: &str) -> Option<String> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn retrieve_opml(url: &str) -> Vec<Url> {
|
||||
match get_content(url) {
|
||||
Some(c) => match opml::OPML::from_str(&c) {
|
||||
Ok(list) => {
|
||||
let mut links = Vec::new();
|
||||
for link in list.body.outlines {
|
||||
match link.html_url {
|
||||
Some(l) => match Url::parse(&l) {
|
||||
Ok(u) => {
|
||||
links.push(u);
|
||||
}
|
||||
Err(_) => {}
|
||||
},
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
return links;
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to parse OPML: {}\n{}", c, e);
|
||||
return Vec::new();
|
||||
}
|
||||
},
|
||||
None => {
|
||||
return Vec::new();
|
||||
}
|
||||
}
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_onion_content() {
|
||||
get_content("http://gabriel262me3lgv3w7xohtesg3laoojmtye644pwirhdm73qmedmsqd.onion/rss");
|
||||
|
|
@ -147,7 +179,8 @@ pub fn load_rss(url: &str) -> Option<Channel> {
|
|||
}
|
||||
},
|
||||
Err(err) => {
|
||||
panic!("Error loading feed.:{}", err)
|
||||
println!("Error loading feed.:{}", err);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -202,7 +235,6 @@ fn is_media(link: &str) -> bool {
|
|||
false
|
||||
}
|
||||
|
||||
|
||||
pub fn parse_links(content: &str) -> Vec<String> {
|
||||
let mut result = Vec::new();
|
||||
let frag = Html::parse_fragment(content);
|
||||
|
|
|
|||
30
src/ui.rs
30
src/ui.rs
|
|
@ -1,4 +1,5 @@
|
|||
use crate::db::FeedItem;
|
||||
use crate::net;
|
||||
use crate::widgets::content_view;
|
||||
use crate::widgets::media_view;
|
||||
use crate::widgets::navbar;
|
||||
|
|
@ -16,6 +17,7 @@ use iced::{
|
|||
};
|
||||
use rss_content::parse_content;
|
||||
use rss_content::Content;
|
||||
use url::Url;
|
||||
const ICON: &[u8] = include_bytes!("../assets/icon_placeholder.png");
|
||||
|
||||
pub fn user_interface() -> iced::Result {
|
||||
|
|
@ -69,6 +71,7 @@ pub enum Message {
|
|||
AddFeed(String),
|
||||
RemoveFeed(usize),
|
||||
LoadItem(usize),
|
||||
ProcessOPML(String),
|
||||
FieldUpdated(AppField, String),
|
||||
LinkClicked(String),
|
||||
Done(String),
|
||||
|
|
@ -78,6 +81,18 @@ pub enum Message {
|
|||
#[derive(Debug, Clone)]
|
||||
pub enum AppField {
|
||||
FeedInput,
|
||||
OPMLInput,
|
||||
}
|
||||
|
||||
|
||||
async fn add_multiple_feeds_background(url:String) -> String {
|
||||
println!("Adding feeds.");
|
||||
let links = net::retrieve_opml(&url);
|
||||
for link in links {
|
||||
add_feed_background(link.to_string()).await;
|
||||
}
|
||||
"Done adding feeds.".to_string()
|
||||
|
||||
}
|
||||
|
||||
async fn add_feed_background(url: String) -> String {
|
||||
|
|
@ -103,6 +118,11 @@ fn update(state: &mut State, mes: Message) -> Task<Message> {
|
|||
Task::none()
|
||||
}
|
||||
|
||||
Message::ProcessOPML(url) => {
|
||||
state.feed_input = "".to_string();
|
||||
Task::perform(add_multiple_feeds_background(url), Message::Done)
|
||||
}
|
||||
|
||||
Message::AddFeed(f) => {
|
||||
state.feed_input = "".to_string();
|
||||
Task::perform(add_feed_background(f.to_string()), Message::Done)
|
||||
|
|
@ -138,6 +158,9 @@ fn update(state: &mut State, mes: Message) -> Task<Message> {
|
|||
match field {
|
||||
AppField::FeedInput => {
|
||||
state.feed_input = value;
|
||||
},
|
||||
AppField::OPMLInput => {
|
||||
state.feed_input = value;
|
||||
}
|
||||
}
|
||||
Task::none()
|
||||
|
|
@ -203,6 +226,7 @@ fn item_view(state: &State) -> Element<'_, Message> {
|
|||
};
|
||||
container(column!(
|
||||
widgets::navbar(state),
|
||||
text(title).size(34),
|
||||
media_view(state),
|
||||
content_view(state),
|
||||
))
|
||||
|
|
@ -249,6 +273,12 @@ fn testing(state: &State) -> Element<'_, Message> {
|
|||
)
|
||||
.spacing(5)
|
||||
.padding(10),
|
||||
row!(
|
||||
text_input("OPML Url",&state.feed_input)
|
||||
.on_input(|val| Message::FieldUpdated(AppField::OPMLInput,val))
|
||||
.width(300),
|
||||
button("Add feeds from .OPML").on_press(Message::ProcessOPML(state.feed_input.clone()))
|
||||
),
|
||||
button("Wipe DB").on_press(Message::ResetDB),
|
||||
button("go back!").on_press(Message::ChangePage(Page::Home))
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue