Date parsing works now!

This commit is contained in:
Gabriel 2025-12-05 12:45:45 -05:00
parent b37c73cf14
commit 60fd547a6d
3 changed files with 152 additions and 117 deletions

View file

@ -169,6 +169,13 @@ pub fn remove_feed(feed_id: usize) {
}
}
fn modify_date(s: &str) -> Option<String> {
match DateTime::parse_from_rfc2822(s){
Ok(t) => {Some(t.to_rfc3339())}
Err(_) => None
}
}
pub fn store_items(feed: rss::Channel, feed_id: usize) {
let conn = Connection::open(get_db_path()).unwrap();
feed.items.into_iter().for_each(|i: rss::Item| {
@ -185,11 +192,23 @@ pub fn store_items(feed: rss::Channel, feed_id: usize) {
values(?1,?2,?3,?4,?5,?6,?7,?8)",
[
i.link,
i.title,
i.description,
i.content,
match i.title {
Some(t) => Some(t.clone()),
None => None
},
match i.description {
Some(d) => Some(d.clone()),
None => None
},
match i.content {
Some(c) => {Some(c.clone())},
None => {None}
},
Some(feed_id.to_string()),
i.pub_date.clone(),
match i.pub_date {
Some(s) => {modify_date(&s)},
None => {None}
},
{
match t.enclosure() {
Some(e) => Some(e.url().to_owned()),
@ -237,7 +256,7 @@ fn row2feed_item(row: &Row) -> FeedItem{
pub fn get_all_items() -> Vec<FeedItem> {
let conn = get_db();
let mut stmt = conn.prepare("select itemID,title,url,date,media,description,content from items").unwrap();
let mut stmt = conn.prepare("select itemID,title,url,date,media,description,content from items order by date desc limit 50 ").unwrap();
let items: Result<Vec<FeedItem>> = stmt.query_map([],|row| {
Ok(row2feed_item(row))
}).unwrap().collect();

View file

@ -33,6 +33,7 @@ pub fn user_interface() -> iced::Result {
#[derive(Clone, Debug,PartialEq)]
pub enum Page {
Home,
Feeds,
FeedView,
AllItems,
ItemView,
@ -151,6 +152,7 @@ fn update(state: &mut State, mes: Message) -> Task<Message> {
fn view(state: &State) -> Element<'_, Message> {
match state.page {
Page::Home => home(&state),
Page::Feeds => feeds(&state),
Page::FeedView => feed_layout(&state),
Page::AllItems => item_list(&state),
Page::ItemView => item_view(&state),
@ -162,10 +164,7 @@ fn view(state: &State) -> Element<'_, Message> {
fn home(state: &State) -> Element<'_, Message> {
container(column!(
widgets::navbar(state),
scrollable(widgets::list_feeds())
.width(iced::Fill)
.height(iced::Fill),
button("Go to test!").on_press(Message::ChangePage(Page::Testing))
text("RSSCar: RSS Crawler-aided reader.")
))
.padding(0)
.height(Fill)
@ -173,6 +172,18 @@ fn home(state: &State) -> Element<'_, Message> {
.into()
}
fn feeds(state: &State) -> Element<'_,Message> {
container(
column!(
navbar(state),
scrollable(widgets::list_feeds())
.width(iced::Fill)
.height(iced::Fill)
)
).width(iced::Fill)
.height(iced::Fill).into()
}
fn feed_layout(state: &State) -> Element<'_, Message> {
container(column!(
widgets::navbar(state),
@ -209,10 +220,9 @@ fn item_list(state: &State) -> Element<'_, Message> {
db::get_all_items().iter().map(|i|{
widgets::list_item(i.item_id, i.title.clone(), i.description.clone().unwrap_or("".to_owned()))
}).map(iced::Element::from)
).align_x(iced::Alignment::Center)).width(Fill).spacing(5)
).align_x(iced::Alignment::Center).width(Fill)).width(Fill).spacing(5)
),
).width(Fill).height(Fill).into()
).width(Fill).height(Fill).align_x(iced::Alignment::Center).into()
}
fn category_view(state: &State) -> Element<'_,Message> {

View file

@ -3,19 +3,19 @@ use crate::ui::Page;
use super::db;
use super::ui;
use iced::widget::Text;
use iced::widget::markdown;
use iced::widget::row;
use iced::widget::scrollable;
use iced::widget::Column;
use iced::widget::Text;
use iced::Theme;
use rss_content::Content;
use ui::Message;
use rss_content;
use iced::{
widget::{button, column, container, text},
Element,
};
use rss_content;
use rss_content::Content;
use ui::Message;
pub fn list_feeds() -> iced::widget::Column<'static, Message> {
let feeds = db::get_feeds();
@ -25,13 +25,14 @@ pub fn list_feeds() -> iced::widget::Column<'static, Message> {
.map(|f| {
let n = net::url_network(&f.url);
let prefix = match n {
net::Network::Clearnet => {""}
net::Network::Tor => {"Tor: "}
net::Network::I2P => {"I2P: "}
_ => {""}
net::Network::Clearnet => "",
net::Network::Tor => "Tor: ",
net::Network::I2P => "I2P: ",
_ => "",
};
row!(
button(text(prefix.to_owned() + &f.title)).on_press(Message::LoadFeed(f.feed_id)),
button(text(prefix.to_owned() + &f.title))
.on_press(Message::LoadFeed(f.feed_id)),
button(text("Remove feed")).on_press(Message::RemoveFeed(f.feed_id))
)
})
@ -42,14 +43,13 @@ pub fn list_feeds() -> iced::widget::Column<'static, Message> {
.padding(15)
}
pub fn list_items(feed_id: usize) -> iced::widget::Column<'static,Message> {
pub fn list_items(feed_id: usize) -> iced::widget::Column<'static, Message> {
let items: Vec<db::FeedItem> = db::get_feed_items(feed_id);
column(
items.iter()
.map(|i| {
button(text(i.title.clone())).on_press(Message::LoadItem(i.item_id))
})
.map(Element::from),
items
.iter()
.map(|i| button(text(i.title.clone())).on_press(Message::LoadItem(i.item_id)))
.map(Element::from),
)
.align_x(iced::Alignment::Start)
.spacing(5)
@ -59,115 +59,121 @@ pub fn list_items(feed_id: usize) -> iced::widget::Column<'static,Message> {
pub fn content_area(content: &'_ Vec<Content>) -> iced::widget::Container<'_, Message> {
let mut children: Vec<Element<Message>> = Vec::new();
for c in content {
match c {
Content::MarkdownParsed(p) => {
children.push(
markdown(p, Theme::Dark).map(Message::LinkClicked)
);
}
Content::Image(_) => {children.push(text("<Image goes here>")
.size(32)
.into());},
Content::Audio(_) => {children.push(text("<Audio widget here>")
.size(32)
.into());},
Content::Video(_) => {children.push(text("<Video goes here>")
.size(32)
.into());},
_ => {}
}
match c {
Content::MarkdownParsed(p) => {
children.push(markdown(p, Theme::Dark).map(Message::LinkClicked));
}
container(
Column::with_children(children).spacing(5)
)
Content::Image(_) => {
children.push(text("<Image goes here>").size(32).into());
}
Content::Audio(_) => {
children.push(text("<Audio widget here>").size(32).into());
}
Content::Video(_) => {
children.push(text("<Video goes here>").size(32).into());
}
_ => {}
}
}
container(Column::with_children(children).spacing(5))
}
pub fn media_view(state: &'_ ui::State) -> Element<'_, Message> {
match state.current_item.clone().unwrap().media {
Some(m) => {
if m.len() > 0{
text(format!("<Media is available:{}>",m)).into()
}
else {
if m.len() > 0 {
text(format!("<Media is available:{}>", m)).into()
} else {
text("".to_owned()).into()
}
}
None => {
text("".to_owned()).into()
}
None => text("".to_owned()).into(),
}
}
pub fn navbar (state: &ui::State) -> Element<Message>{
pub fn navbar(state: &ui::State) -> Element<Message> {
match state.page {
Page::Home => {
row::Row::new().push(
button("All Items").on_press(Message::ChangePage(Page::AllItems))
).push(button("Categories").on_press(Message::ChangePage(Page::CategoryView)))
Page::Home => row::Row::new()
.push(button("Feeds").on_press(Message::ChangePage(Page::Feeds)))
.push(button("All Items").on_press(Message::ChangePage(Page::AllItems)))
.push(button("Categories").on_press(Message::ChangePage(Page::CategoryView)))
.push(button("Dev Panel").on_press(Message::ChangePage(Page::Testing)))
.spacing(5).padding(5)
},
Page::FeedView => {
row::Row::new().push(button("Home").on_press(Message::ChangePage(Page::Home)))
.push(
button("All Items").on_press(Message::ChangePage(Page::AllItems))
)
.spacing(5).padding(5)
},
Page::AllItems => {
row::Row::new().push(button("Home").on_press(Message::ChangePage(Page::Home)))
.spacing(5)
.padding(5),
Page::Feeds => row::Row::new()
.push(button("Home").on_press(Message::ChangePage(Page::Home)))
.push(button("All Items").on_press(Message::ChangePage(Page::AllItems)))
.push(button("Categories").on_press(Message::ChangePage(Page::CategoryView)))
.push(button("Dev Panel").on_press(Message::ChangePage(Page::Testing)))
.spacing(5).padding(5)}
Page::CategoryView => {
row::Row::new().push(button("Home").on_press(Message::ChangePage(Page::Home)))
.push(
button("All Items").on_press(Message::ChangePage(Page::AllItems))
)
.spacing(5).padding(5)}
Page::Testing => {
row::Row::new().push(button("Home").on_press(Message::ChangePage(Page::Home)))
.push(
button("All Items").on_press(Message::ChangePage(Page::AllItems))
)
.spacing(5).padding(5)}
Page::ItemView => {
row::Row::new().push(button("Home").on_press(Message::ChangePage(Page::Home)))
.push(
button("All Items").on_press(Message::ChangePage(Page::AllItems))
)
.spacing(5).padding(5)}
}.into()
.spacing(5)
.padding(5),
Page::FeedView => row::Row::new()
.push(button("Home").on_press(Message::ChangePage(Page::Home)))
.push(button("All Items").on_press(Message::ChangePage(Page::AllItems)))
.push(button("Categories").on_press(Message::ChangePage(Page::CategoryView)))
.push(button("Dev Panel").on_press(Message::ChangePage(Page::Testing)))
.spacing(5)
.padding(5),
Page::AllItems => row::Row::new()
.push(button("Home").on_press(Message::ChangePage(Page::Home)))
.push(button("Feeds").on_press(Message::ChangePage(Page::Feeds)))
.push(button("Categories").on_press(Message::ChangePage(Page::CategoryView)))
.push(button("Dev Panel").on_press(Message::ChangePage(Page::Testing)))
.spacing(5)
.padding(5),
Page::CategoryView => row::Row::new()
.push(button("Home").on_press(Message::ChangePage(Page::Home)))
.push(button("Feeds").on_press(Message::ChangePage(Page::Feeds)))
.push(button("All Items").on_press(Message::ChangePage(Page::AllItems)))
.push(button("Dev Panel").on_press(Message::ChangePage(Page::Testing)))
.spacing(5)
.padding(5),
Page::Testing => row::Row::new()
.push(button("Home").on_press(Message::ChangePage(Page::Home)))
.push(button("Feeds").on_press(Message::ChangePage(Page::Feeds)))
.push(button("Categories").on_press(Message::ChangePage(Page::CategoryView)))
.push(button("All Items").on_press(Message::ChangePage(Page::AllItems)))
.spacing(5)
.padding(5),
Page::ItemView => row::Row::new()
.push(button("Home").on_press(Message::ChangePage(Page::Home)))
.push(button("Feeds").on_press(Message::ChangePage(Page::Feeds)))
.push(button("Categories").on_press(Message::ChangePage(Page::CategoryView)))
.push(button("All Items").on_press(Message::ChangePage(Page::AllItems)))
.spacing(5)
.padding(5),
}
.into()
}
pub fn list_item(id: usize,title: String, description: String) -> Column<'static,Message>{
pub fn list_item(id: usize, title: String, description: String) -> Column<'static, Message> {
Column::new()
.push(button(Text::new(title)).on_press(Message::LoadItem(id)))
.push(text(description))
.align_x(iced::Alignment::Center)
.spacing(5)
.push(button(Text::new(title)).on_press(Message::LoadItem(id)))
.push(text(description))
.align_x(iced::Alignment::Center)
.spacing(5)
}
pub fn content_view(state: &'_ ui::State) -> iced::widget::Scrollable<'_, Message> {
let item = state.current_item.clone().unwrap();
scrollable(
column!(
match item.description {
Some(_d) => {
content_area(&state.item_description)
},
None => {container(text("No description found"))}
},
match item.content {
Some(_c) => {
content_area(&state.item_content)
}
None => {container(text("No content found"))}
scrollable(column!(
match item.description {
Some(_d) => {
content_area(&state.item_description)
}
)
).width(iced::Fill)
None => {
container(text("No description found"))
}
},
match item.content {
Some(_c) => {
content_area(&state.item_content)
}
None => {
container(text("No content found"))
}
}
))
.width(iced::Fill)
}