loading arbitrary feeds via the UI works!

This commit is contained in:
Gabriel 2025-07-04 11:38:49 -04:00
parent 03084ac15f
commit 2604306d67
3 changed files with 44 additions and 38 deletions

View file

@ -25,12 +25,13 @@ fn get_db_path() -> PathBuf {
fn get_db() -> Connection{
Connection::open(get_db_path()).unwrap()
}
//url needs to be from the feed URL NOT the url in the channel itself!!
const FEEDS_TABLE_CREATE: &str = "CREATE TABLE IF NOT EXISTS 'feeds' (
'feedID' INTEGER NOT NULL,
'title' TEXT NOT NULL,
'description' TEXT,
'icon' BLOB,
'url' text not null unique on conflict replace,
'url' text,
'subscribed' INTEGER NOT NULL default 0,
'last_updated' TEXT ,
PRIMARY KEY('feedID')
@ -43,19 +44,21 @@ const FEEDS_INDEX_CREATE: &str = "CREATE INDEX IF NOT EXISTS 'subscribed_feeds_
/* */
const ITEMS_TABLE_CREATE: &str = "CREATE TABLE IF NOT EXISTS 'items' (
'itemID' INTEGER NOT NULL,
'feedID' INTEGER NOT NULL,
'title' TEXT NOT NULL,
'icon' BLOB,
'url' text not null unique on conflict replace,
'description' TEXT,
'content' TEXT,
'read' INTEGER DEFAULT 0,
PRIMARY KEY('itemID')
PRIMARY KEY('itemID'),
FOREIGN KEY('feedID') REFERENCES 'feeds'('feedID')
);";
const ITEMS_INDEX_CREATE: &str = "CREATE INDEX IF NOT EXISTS 'items_idx' on 'items'('itemID' ASC);";
const DB_RESET: &str = "
drop table feeds;
drop table items;
drop table feeds;
";
pub fn reset(){
@ -94,24 +97,29 @@ pub fn add_feed(url: &str) {
[feed.title, url.to_owned(), feed.description, time],
)
.unwrap();
conn.close().unwrap();
let mut stmt = conn.prepare("select feedID from feeds where url=?1").unwrap();
let id: usize = stmt.query_row([url],|row| {
row.get(0)
}).unwrap();
//need to get the feed_id from the DB and then make sure items are mapped to feed
store_items(new_feed);
store_items(new_feed,id);
}
pub fn store_items(feed: rss::Channel) {
pub fn store_items(feed: rss::Channel,feed_id: usize) {
let conn = Connection::open(get_db_path()).unwrap();
feed.items.iter().for_each(|i: &rss::Item| {
conn.execute(
"insert into items(url,title,description,content) values(?1,?2,?3,?4)",
"insert into items(url,title,description,content,feedID)
values(?1,?2,?3,?4,?5)",
[
i.link.clone(),
i.title.clone(),
i.description.clone(),
i.content.clone(),
Some(feed_id.to_string())
],
)
.unwrap();
.ok();
});
conn.close().unwrap();
}
@ -149,8 +157,8 @@ pub struct FeedItem {
pub fn get_feed_items(id: usize) -> Vec<FeedItem>{
let conn = get_db();
let mut stmt = conn.prepare("select itemID,title,url,icon,description,content from items").unwrap();
let items:Result<Vec<FeedItem>> = stmt.query_map([], |row| {
let mut stmt = conn.prepare("select itemID,title,url,icon,description,content from items where feedID = ?1").unwrap();
let items:Result<Vec<FeedItem>> = stmt.query_map([id], |row| {
Ok(FeedItem{
item_id: row.get(0).unwrap(),
title: row.get(1).unwrap(),
@ -209,30 +217,5 @@ struct ReturnedFeedURLs {
url: String,
}
pub fn update_feeds() {
//get feeds
let conn = Connection::open(get_db_path()).unwrap();
let mut stmt = conn.prepare("select url from feeds").unwrap();
let rows = stmt
.query_map([], |row| {
Ok(ReturnedFeedURLs {
url: row.get(0).unwrap(),
})
})
.unwrap();
let mut urls: Vec<String> = Vec::new();
for feed in rows {
let url = feed.unwrap().url.clone();
urls.push(url);
}
stmt.finalize().unwrap();
conn.close().unwrap();
for u in urls {
store_items(load_rss(&u).unwrap());
}
//for each feed
// insert items into database
//close out
todo!()
}

View file

@ -2,7 +2,9 @@ use crate::db::add_feed;
use super::db;
use super::widgets;
use iced::widget::row;
use iced::widget::scrollable;
use iced::widget::text_input;
use iced::{
widget::{button, column, container, text},
Element,
@ -23,13 +25,15 @@ enum Page {
struct State {
page: Page,
current_feed: usize
current_feed: usize,
feed_input: String
}
impl Default for State {
fn default() -> Self {
State {
page: Page::home,
current_feed: 0
current_feed: 0,
feed_input: String::from("")
}
}
}
@ -39,9 +43,15 @@ pub enum Message {
ChangePage(Page),
LoadFeed(usize),
AddFeed(String),
FieldUpdated(AppField,String),
ResetDB
}
#[derive(Debug,Clone)]
enum AppField {
FeedInput
}
fn update(state: &mut State, mes: Message) {
match mes {
Message::ChangePage(p) => state.page=p,
@ -53,6 +63,13 @@ fn update(state: &mut State, mes: Message) {
Message::AddFeed(f) => {
db::add_feed(&f);
},
Message::FieldUpdated(field, value) => {
match field {
AppField::FeedInput => {
state.feed_input=value;
}
}
},
Message::ResetDB => {
db::reset();
}
@ -109,6 +126,10 @@ fn testing(state: &State) -> Element<'_, Message> {
text("Dev Panel"),
button("Add gabe.rocks").on_press(Message::AddFeed(String::from("https://gabe.rocks/rss"))),
button("Add LSN").on_press(Message::AddFeed(String::from("https://libresolutions.network/rss"))),
row!(
text_input("Add a feed",&state.feed_input).on_input(|val| Message::FieldUpdated(AppField::FeedInput,val)),
button("Add feed!").on_press(Message::AddFeed(state.feed_input.clone()))
),
button("Wipe DB").on_press(Message::ResetDB),
button("go back!").on_press(Message::ChangePage(Page::home))
)

View file

@ -19,6 +19,7 @@ pub fn list_feeds() -> iced::widget::Column<'static, Message> {
)
.align_x(iced::Alignment::Start)
.spacing(5)
.padding(15)
}
pub fn list_items(feed_id: usize) -> iced::widget::Column<'static,Message> {
@ -32,4 +33,5 @@ pub fn list_items(feed_id: usize) -> iced::widget::Column<'static,Message> {
)
.align_x(iced::Alignment::Start)
.spacing(5)
.padding(15)
}