diff --git a/Cargo.lock b/Cargo.lock index 461eb30..e33d460 100755 --- a/Cargo.lock +++ b/Cargo.lock @@ -248,6 +248,21 @@ dependencies = [ "alloc-no-stdlib", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "atom_syndication" version = "0.12.2" @@ -414,11 +429,17 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.28" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ed24df0632f708f5f6d8082675bef2596f7084dee3dd55f632290bf35bfe0f" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", "num-traits", + "serde", + "wasm-bindgen", + "windows-targets", ] [[package]] @@ -556,9 +577,12 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" +checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +dependencies = [ + "powerfmt", +] [[package]] name = "derive_builder" @@ -612,6 +636,7 @@ checksum = "d98235fdc2f355d330a8244184ab6b4b33c28679c0b4158f63138e51d6cf7e88" dependencies = [ "bitflags 2.4.0", "byteorder", + "chrono", "diesel_derives", "itoa 1.0.9", "pq-sys", @@ -1069,6 +1094,29 @@ dependencies = [ "tokio-native-tls", ] +[[package]] +name = "iana-time-zone" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -1531,6 +1579,12 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1763,6 +1817,7 @@ dependencies = [ "actix-service", "actix-web", "bcrypt", + "chrono", "diesel", "dotenv", "env_logger", @@ -2127,12 +2182,13 @@ checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" [[package]] name = "time" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" +checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" dependencies = [ "deranged", "itoa 1.0.9", + "powerfmt", "serde", "time-core", "time-macros", @@ -2140,15 +2196,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572" +checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" dependencies = [ "time-core", ] @@ -2455,6 +2511,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-core" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.48.0" diff --git a/Cargo.toml b/Cargo.toml index 36a2633..0454a4c 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ futures = "0.3.24" serde = { version = "1.0.144", features = ["alloc", "derive", "serde_derive"] } serde_derive = "1.0.145" actix-service = "2.0.2" -diesel = { version = "2.0.2", features = ["postgres"]} +diesel = { version = "2.0.2", features = ["postgres", "chrono"] } dotenv = "0.15.0" bcrypt = "0.13.0" uuid = {version = "1.2.1", features=["serde", "v4"]} @@ -26,6 +26,7 @@ log = "0.4.17" env_logger = "0.9.3" scraper = "0.14.0" actix-cors = "0.6.4" +chrono = { version = "0.4.31", features = ["serde"] } [dependencies.serde_json] version = "1.0.86" diff --git a/migrations/2023-10-22-115359_update_feed_item_date/down.sql b/migrations/2023-10-22-115359_update_feed_item_date/down.sql new file mode 100644 index 0000000..259d710 --- /dev/null +++ b/migrations/2023-10-22-115359_update_feed_item_date/down.sql @@ -0,0 +1,3 @@ +-- This file should undo anything in `up.sql` +ALTER TABLE feed_item +DROP COLUMN created_ts; diff --git a/migrations/2023-10-22-115359_update_feed_item_date/up.sql b/migrations/2023-10-22-115359_update_feed_item_date/up.sql new file mode 100644 index 0000000..64b92a0 --- /dev/null +++ b/migrations/2023-10-22-115359_update_feed_item_date/up.sql @@ -0,0 +1,6 @@ +-- Your SQL goes here +ALTER TABLE feed_item +ADD COLUMN created_ts TIMESTAMP; + +ALTER TABLE feed_item +ALTER COLUMN created_ts SET DEFAULT now(); diff --git a/src/models/feed_item/new_feed_item.rs b/src/models/feed_item/new_feed_item.rs index 35667e7..24e6a32 100755 --- a/src/models/feed_item/new_feed_item.rs +++ b/src/models/feed_item/new_feed_item.rs @@ -1,8 +1,5 @@ -// extern crate bcrypt; - -// use bcrypt::{hash, DEFAULT_COST}; +use chrono::NaiveDateTime; use diesel::Insertable; -// use uuid::Uuid; use crate::schema::feed_item; @@ -13,15 +10,23 @@ pub struct NewFeedItem { pub content: String, pub title: String, pub url: String, + pub created_ts: Option, } impl NewFeedItem { - pub fn new(feed_id: i32, content: String, title: String, url: String) -> Self { + pub fn new( + feed_id: i32, + content: String, + title: String, + url: String, + created_ts: Option, + ) -> Self { Self { feed_id, content, title, url, + created_ts, } } } diff --git a/src/models/feed_item/rss_feed_item.rs b/src/models/feed_item/rss_feed_item.rs index 3168c6a..b30a72a 100755 --- a/src/models/feed_item/rss_feed_item.rs +++ b/src/models/feed_item/rss_feed_item.rs @@ -1,8 +1,8 @@ use crate::models::feed::rss_feed::Feed; -use diesel::{Associations, Identifiable, Queryable}; - use crate::schema::feed_item; -#[derive(Clone, Queryable, Identifiable, Associations)] +use chrono::NaiveDateTime; +use diesel::{Associations, Identifiable, Queryable}; +#[derive(Clone, Identifiable, Queryable, Associations)] #[diesel(belongs_to(Feed))] #[diesel(table_name=feed_item)] pub struct FeedItem { @@ -12,6 +12,7 @@ pub struct FeedItem { pub read: bool, pub title: String, pub url: String, + pub created_ts: Option, } impl FeedItem { @@ -22,6 +23,7 @@ impl FeedItem { url: String, content: String, read: bool, + created_ts: Option, ) -> Self { Self { id, @@ -30,6 +32,7 @@ impl FeedItem { url, content, read, + created_ts, } } } diff --git a/src/reader/get.rs b/src/reader/get.rs index beaa87b..78bd659 100755 --- a/src/reader/get.rs +++ b/src/reader/get.rs @@ -10,6 +10,7 @@ use crate::{ schema::feed_item, }; use actix_web::{web, HttpRequest, Responder}; +use chrono::Local; use diesel::prelude::*; use super::structs::article::Article; @@ -41,10 +42,17 @@ pub async fn get(path: web::Path, req: HttpRequest) -> impl Responder let article_list: Vec
= existing_item .into_iter() - .map(|feed_item: FeedItem| Article { - title: feed_item.title, - content: feed_item.content, - url: feed_item.url, + .map(|feed_item: FeedItem| { + let time: String = match feed_item.created_ts { + Some(r) => r.to_string(), + None => Local::now().naive_local().to_string(), + }; + Article { + title: feed_item.title, + content: feed_item.content, + url: feed_item.url, + timestamp: time, + } }) .collect(); diff --git a/src/reader/structs/article.rs b/src/reader/structs/article.rs index 3591e7d..56e7040 100644 --- a/src/reader/structs/article.rs +++ b/src/reader/structs/article.rs @@ -5,6 +5,7 @@ pub struct Article { pub title: String, pub content: String, pub url: String, + pub timestamp: String, } // impl Article { diff --git a/src/reader/sync.rs b/src/reader/sync.rs index 0324072..cd99bd0 100644 --- a/src/reader/sync.rs +++ b/src/reader/sync.rs @@ -12,13 +12,14 @@ use crate::{ }, }; use actix_web::{web, HttpRequest, HttpResponse, Responder}; +use chrono::{Local, NaiveDateTime}; use diesel::prelude::*; use rss::Item; use scraper::{Html, Selector}; fn create_feed_item(item: Item, feed: &Feed, connection: &mut PgConnection) { - let item_title = item.title.unwrap(); - let frag = Html::parse_fragment(&item.content.unwrap()); + let item_title = item.title.clone().unwrap(); + let frag = Html::parse_fragment(&item.content.clone().unwrap()); let mut content = "".to_string(); let frag_clone = frag.clone(); frag.tree.into_iter().for_each(|node| { @@ -40,13 +41,20 @@ fn create_feed_item(item: Item, feed: &Feed, connection: &mut PgConnection) { .filter(title.eq(&item_title)) .load(connection) .unwrap(); - + // todo; if existing_item.is_empty() { + log::info!("{:?}", item.pub_date()); + let mut time: NaiveDateTime = Local::now().naive_local(); + if item.pub_date().is_some() { + let format_string = "%a, %d %b %Y %H:%M:%S %z"; + time = NaiveDateTime::parse_from_str(item.pub_date().unwrap(), format_string).unwrap(); + } let new_feed_item = NewFeedItem::new( feed.id, content.clone(), item_title.clone(), item.link.unwrap(), + Some(time), ); let insert_result = diesel::insert_into(feed_item::table) .values(&new_feed_item) diff --git a/src/schema.rs b/src/schema.rs index 7ca84c8..3e0e206 100755 --- a/src/schema.rs +++ b/src/schema.rs @@ -17,6 +17,7 @@ diesel::table! { read -> Bool, title -> Varchar, url -> Varchar, + created_ts -> Nullable, } } diff --git a/vue/src/components/RssFeeds.vue b/vue/src/components/RssFeeds.vue index 6242924..fbdf732 100644 --- a/vue/src/components/RssFeeds.vue +++ b/vue/src/components/RssFeeds.vue @@ -81,6 +81,7 @@ async function sync() { if (response.status == 200) { showMessageForXSeconds('Sync successful.', 5) } + fetchData(); } catch (error) { console.error('Error sync', error) showMessageForXSeconds(error, 5)