able to retrieve feeds, make sure UI displays and can add/remove feeds. (State has to load from DB)
This commit is contained in:
parent
942c7d89aa
commit
f2e00c7034
3 changed files with 118 additions and 64 deletions
99
src/db.rs
99
src/db.rs
|
@ -1,21 +1,21 @@
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use rusqlite::{params, Connection, Result};
|
|
||||||
use crate::files;
|
use crate::files;
|
||||||
|
use rusqlite::{params, Connection, Result};
|
||||||
|
|
||||||
use super::net::{*};
|
use super::files::*;
|
||||||
use super::files::{*};
|
use super::net::*;
|
||||||
|
use chrono::Utc; //Maybe use a different time?
|
||||||
|
|
||||||
/*
|
/*
|
||||||
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 {
|
struct Item {
|
||||||
title: String,
|
title: String,
|
||||||
content: Option<String>
|
content: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
const DB_LOCATION: &str = "rsscar.db";
|
const DB_LOCATION: &str = "rsscar.db";
|
||||||
|
@ -53,66 +53,115 @@ const items_table_create: &str = "CREATE TABLE IF NOT EXISTS 'items' (
|
||||||
const items_index_create: &str = "CREATE INDEX IF NOT EXISTS 'items_idx' on 'items'('itemID' ASC);";
|
const items_index_create: &str = "CREATE INDEX IF NOT EXISTS 'items_idx' on 'items'('itemID' ASC);";
|
||||||
|
|
||||||
pub fn initialize() {
|
pub fn initialize() {
|
||||||
|
let path = get_db_path();
|
||||||
let conn = Connection::open(get_db_path()).unwrap();
|
println!("Database at {} initialized", path.as_os_str().display());
|
||||||
|
let conn = Connection::open(path).unwrap();
|
||||||
conn.execute(feeds_table_create, []).unwrap();
|
conn.execute(feeds_table_create, []).unwrap();
|
||||||
conn.execute(feeds_index_create, []).unwrap();
|
conn.execute(feeds_index_create, []).unwrap();
|
||||||
conn.execute(items_table_create, []).unwrap();
|
conn.execute(items_table_create, []).unwrap();
|
||||||
conn.execute(items_index_create, []).unwrap();
|
conn.execute(items_index_create, []).unwrap();
|
||||||
conn.close();
|
conn.close();
|
||||||
println!("Database Initialized.")
|
println!("Database Initialized.")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_feed(url: &str) {
|
pub fn add_feed(url: &str) {
|
||||||
let conn = Connection::open(get_db_path()).unwrap();
|
let conn = Connection::open(get_db_path()).unwrap();
|
||||||
let feed = load_rss(url).unwrap();
|
let feed = load_rss(url).unwrap();
|
||||||
let new_feed = feed.clone();
|
let new_feed = feed.clone();
|
||||||
conn.execute("insert into feeds(title,url,description) values(?1,?2,?3)",
|
let time = Utc::now().to_rfc2822();
|
||||||
[feed.title,url.to_owned(),feed.description]).unwrap();
|
conn.execute(
|
||||||
|
"insert into feeds(title,url,description,last_updated) values(?1,?2,?3,?4)",
|
||||||
|
[feed.title, url.to_owned(), feed.description, time],
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
conn.close();
|
conn.close();
|
||||||
store_items(new_feed);
|
store_items(new_feed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn store_items(feed: rss::Channel) {
|
pub fn store_items(feed: rss::Channel) {
|
||||||
let conn = Connection::open(get_db_path()).unwrap();
|
let conn = Connection::open(get_db_path()).unwrap();
|
||||||
feed.items.iter().for_each(|i: &rss::Item| {
|
feed.items.iter().for_each(|i: &rss::Item| {
|
||||||
conn.execute("insert into items(url,title,description,content) values(?1,?2,?3,?4)",[
|
conn.execute(
|
||||||
|
"insert into items(url,title,description,content) values(?1,?2,?3,?4)",
|
||||||
|
[
|
||||||
i.link.clone(),
|
i.link.clone(),
|
||||||
i.title.clone(),
|
i.title.clone(),
|
||||||
i.description.clone(),
|
i.description.clone(),
|
||||||
i.content.clone()]
|
i.content.clone(),
|
||||||
).unwrap();
|
],
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
});
|
});
|
||||||
conn.close();
|
conn.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn return_item() -> String {
|
pub fn return_item() -> String {
|
||||||
let conn = Connection::open(get_db_path()).unwrap();
|
let conn = Connection::open(get_db_path()).unwrap();
|
||||||
let item = conn.query_row("select title,content from items where rowid=?1",[488],|row|{
|
let item = conn
|
||||||
Ok(
|
.query_row(
|
||||||
Item { title: row.get(0).unwrap(), content: row.get(1).unwrap() }
|
"select title,content from items where rowid=?1",
|
||||||
|
[],
|
||||||
|
|row| {
|
||||||
|
Ok(Item {
|
||||||
|
title: row.get(0).unwrap(),
|
||||||
|
content: row.get(1).unwrap(),
|
||||||
|
})
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}).unwrap();
|
.unwrap();
|
||||||
match item.content {
|
match item.content {
|
||||||
Some(content) => content,
|
Some(content) => content,
|
||||||
None => panic!()
|
None => panic!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Feed {
|
||||||
|
feedID: u8,
|
||||||
|
title: String,
|
||||||
|
description: Option<String>,
|
||||||
|
icon: Option<String>,
|
||||||
|
url: String,
|
||||||
|
subscribed: Option<String>, //needs to be bool
|
||||||
|
last_updated: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_feeds() -> Vec<Feed> {
|
||||||
|
let conn = Connection::open(get_db_path()).unwrap();
|
||||||
|
let mut stmt = conn.prepare("select feedID,title,description,icon,url,subscribed,last_updated from feeds").unwrap();
|
||||||
|
let rows: Result<Vec<Feed>> = stmt
|
||||||
|
.query_map([], |row| {
|
||||||
|
Ok(Feed {
|
||||||
|
feedID: row.get(0).unwrap(),
|
||||||
|
title: row.get(1).unwrap(),
|
||||||
|
description: row.get(2).unwrap(),
|
||||||
|
icon: row.get(3).unwrap(),
|
||||||
|
url: row.get(4).unwrap(),
|
||||||
|
subscribed: row.get(5).unwrap(),
|
||||||
|
last_updated: row.get(6).unwrap(),
|
||||||
|
})
|
||||||
|
}).unwrap().collect();
|
||||||
|
match rows {
|
||||||
|
Ok(r) => {
|
||||||
|
println!("Feed found\n{}",r[0].title);
|
||||||
|
r
|
||||||
|
}
|
||||||
|
Err(e) => {panic!()}
|
||||||
|
}
|
||||||
|
}
|
||||||
struct ReturnedFeedURLs {
|
struct ReturnedFeedURLs {
|
||||||
url: String
|
url: String,
|
||||||
}
|
}
|
||||||
pub fn update_feeds() {
|
pub fn update_feeds() {
|
||||||
//get feeds
|
//get feeds
|
||||||
let conn = Connection::open(get_db_path()).unwrap();
|
let conn = Connection::open(get_db_path()).unwrap();
|
||||||
let mut stmt = conn.prepare("select url from feeds").unwrap();
|
let mut stmt = conn.prepare("select url from feeds").unwrap();
|
||||||
let rows = stmt.query_map([],|row| {
|
let rows = stmt
|
||||||
|
.query_map([], |row| {
|
||||||
Ok(ReturnedFeedURLs {
|
Ok(ReturnedFeedURLs {
|
||||||
url:row.get(0).unwrap()
|
url: row.get(0).unwrap(),
|
||||||
})
|
})
|
||||||
}).unwrap();
|
})
|
||||||
|
.unwrap();
|
||||||
let mut urls: Vec<String> = Vec::new();
|
let mut urls: Vec<String> = Vec::new();
|
||||||
for feed in rows {
|
for feed in rows {
|
||||||
let url = feed.unwrap().url.clone();
|
let url = feed.unwrap().url.clone();
|
||||||
|
@ -125,8 +174,6 @@ pub fn update_feeds() {
|
||||||
store_items(load_rss(&u).unwrap());
|
store_items(load_rss(&u).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//for each feed
|
//for each feed
|
||||||
// insert items into database
|
// insert items into database
|
||||||
|
|
||||||
|
|
22
src/main.rs
22
src/main.rs
|
@ -1,30 +1,16 @@
|
||||||
mod net;
|
mod net;
|
||||||
use db::initialize;
|
use db::initialize;
|
||||||
use iced::{application, widget::{self, button, column, markdown, row, text}, Settings, Theme};
|
|
||||||
use net::load_rss;
|
use net::load_rss;
|
||||||
use rss::Channel;
|
|
||||||
mod ui;
|
mod ui;
|
||||||
mod html;
|
mod html;
|
||||||
mod db;
|
mod db;
|
||||||
|
use db::Feed;
|
||||||
mod files;
|
mod files;
|
||||||
|
|
||||||
|
pub fn main() -> iced::Result {
|
||||||
|
|
||||||
//build CLI first, then create GUI
|
|
||||||
|
|
||||||
/*
|
|
||||||
TO DO:
|
|
||||||
1) Create basic CLI interactions
|
|
||||||
2) Create comprehensive Schema
|
|
||||||
3) Add/remove subscriptions
|
|
||||||
4)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
pub fn main() {
|
|
||||||
db::initialize();
|
db::initialize();
|
||||||
db::add_feed("https://gabe.rocks/rss");
|
db::get_feeds();
|
||||||
|
ui::user_interface()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
21
src/ui.rs
21
src/ui.rs
|
@ -0,0 +1,21 @@
|
||||||
|
use iced::{Element, Result};
|
||||||
|
pub fn user_interface() -> iced::Result {
|
||||||
|
|
||||||
|
iced::run(update, view)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct State{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug,Clone)]
|
||||||
|
enum Message {}
|
||||||
|
|
||||||
|
fn update(state: &mut State,message: Message) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn view(state: &State) -> Element<'_, Message> {
|
||||||
|
iced::widget::text("Ayy lmao").into()
|
||||||
|
}
|
Loading…
Reference in a new issue