commit - b5eca9ca3490fd1dd3df30c8a31913bc80c36b94
commit + 46f44a2336309e746db316fa3a6d8abb3bb27def
blob - 5fce90c85a729c4f1ec763052fe0571160e8346a
blob + c8ac3cd8601f38e70158d4179be3b92664d9ca54
--- Cargo.lock
+++ Cargo.lock
]
[[package]]
+name = "atty"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
+dependencies = [
+ "hermit-abi",
+ "libc",
+ "winapi",
+]
+
+[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
dependencies = [
+ "libc",
"num-integer",
"num-traits",
+ "time",
+ "winapi",
]
[[package]]
+name = "clap"
+version = "3.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5177fac1ab67102d8989464efd043c6ff44191b1557ec1ddd489b4f7e1447e77"
+dependencies = [
+ "atty",
+ "bitflags",
+ "indexmap",
+ "os_str_bytes",
+ "strsim",
+ "termcolor",
+ "textwrap",
+]
+
+[[package]]
name = "core-foundation"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
]
[[package]]
+name = "os_str_bytes"
+version = "6.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
name = "percent-encoding"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
]
[[package]]
-name = "rss-mail"
+name = "rss-email"
version = "0.1.0"
dependencies = [
"anyhow",
+ "chrono",
+ "clap",
"diesel",
"dotenv",
"reqwest",
]
[[package]]
+name = "termcolor"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "textwrap"
+version = "0.14.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80"
+
+[[package]]
+name = "time"
+version = "0.1.44"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
+dependencies = [
+ "libc",
+ "wasi",
+ "winapi",
+]
+
+[[package]]
name = "tinyvec"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
]
[[package]]
+name = "wasi"
+version = "0.10.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
+
+[[package]]
name = "wasm-bindgen"
version = "0.2.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
+name = "winapi-util"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
blob - 73b5f8baab3fcb9ebafd8e24c7cab83a9e51feb7
blob + 2f8d72c87940a2bef0ba4e74760e846b48b2cfef
--- Cargo.toml
+++ Cargo.toml
[package]
-name = "rss-mail"
+name = "rss-email"
version = "0.1.0"
+authors = ["witcher <witcher@wiredspace.de>"]
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
rss = "2.0"
anyhow = "1.0"
reqwest = { version = "0.11", features = ["blocking"] }
+clap = "3"
+chrono = "0.4"
blob - 97fd07066e280a7b36184cd5bf5ac87930dd9b6b
blob + 87c7854151cf92a4ad352f7928fdd0ee37909e7b
--- migrations/2022-02-22-214045_create_posts/up.sql
+++ migrations/2022-02-22-214045_create_posts/up.sql
author TEXT,
url TEXT,
feedurl TEXT,
- pub_date TEXT,
+ pub_date BIGINT,
content TEXT,
sent BOOLEAN NOT NULL DEFAULT 0
)
blob - e791b274d0d884818031b67854c71c4a44036760
blob + 4c94182ff2167e7ae6de0ab51f0807c2f2823e0e
--- src/db.rs
+++ src/db.rs
use dotenv::dotenv;
use rss::Item;
use std::env;
+use chrono::DateTime;
use crate::models::NewPost;
use crate::schema::posts;
// inserts a new post or updates an old one with the same guid
pub fn insert_post(conn: &SqliteConnection, item: &Item) -> anyhow::Result<usize> {
+ let time = item.pub_date().map(|date| DateTime::parse_from_rfc2822(date).unwrap().timestamp());
+
let new_post = NewPost {
guid: item.guid().ok_or(anyhow!("No guid found"))?.value(),
title: item.title(),
author: item.author(),
url: item.link(),
feedurl: item.source().map(|s| s.url()),
- pub_date: item.pub_date(),
+ pub_date: time,
content: item.content(),
};
blob - /dev/null
blob + fcda3636a99e5ee3ee6c5684c9d791eda3294123 (mode 644)
--- /dev/null
+++ src/clap.rs
+use clap::{Arg, Command};
+
+pub fn build_app<'a>() -> Command<'a> {
+ let urls_path = Arg::new("urls_path")
+ .help("Path to the urls.")
+ .required(true)
+ .validator(|p| {
+ if std::path::Path::new(p).exists() {
+ Ok(())
+ } else {
+ Err(format!("config file does not exist: {}", p))
+ }
+ });
+
+ Command::new("rss-email").arg(urls_path)
+}
blob - 788d431e23f514e3e86b694117cca11daf02a7c5
blob + c6500ad8074f891d843a81b230fd47d60596650f
--- src/main.rs
+++ src/main.rs
pub mod models;
pub mod rss;
pub mod schema;
+pub mod clap;
+use std::fs::File;
+use std::io::BufReader;
+use std::io::BufRead;
+
fn main() -> anyhow::Result<()> {
use self::diesel::prelude::*;
use schema::posts::dsl::*;
+ let app = clap::build_app();
+ let matches = app.get_matches();
+
+ // positional argument "urls_path" is required to be present
+ let urls_path = matches.value_of("urls_path").unwrap();
+ // urls_path is required to be a present file by clap
+ let urls = BufReader::new(File::open(urls_path).unwrap()).lines().map(|l| l.unwrap());
+
let conn = db::establish_connection()?;
- let new = rss::fetch_new("https://wiredspace.de/index.xml")?;
- let _ = db::insert_post(&conn, new.items().first().unwrap());
+ for u in urls {
+ let new = rss::fetch_new(u)?;
+ for i in new.items() {
+ let _ = db::insert_post(&conn, i)?;
+ }
+ }
let results = posts
.filter(sent.eq(false))
.limit(5)
+ .order(pub_date.desc())
.load::<models::Post>(&conn)?;
dbg!(results);
blob - 2f40a58698e68b0fd2d3f16fb97aaed66b9ea4a9
blob + 903f08c6a1557affb789da7f92d7d48750ff8df0
--- src/models.rs
+++ src/models.rs
pub author: Option<String>,
pub url: Option<String>,
pub feedurl: Option<String>,
- pub pub_date: Option<String>,
+ pub pub_date: Option<i64>,
pub content: Option<String>,
pub sent: bool,
}
pub author: Option<&'a str>,
pub url: Option<&'a str>,
pub feedurl: Option<&'a str>,
- pub pub_date: Option<&'a str>,
+ pub pub_date: Option<i64>,
pub content: Option<&'a str>,
}
blob - a353a599e1ea3bfee7074fe42a3a02b3adc802de
blob + f30fc90dc34796b218720eae7dde22c7fde207f9
--- src/schema.rs
+++ src/schema.rs
author -> Nullable<Text>,
url -> Nullable<Text>,
feedurl -> Nullable<Text>,
- pub_date -> Nullable<Text>,
+ pub_date -> Nullable<BigInt>,
content -> Nullable<Text>,
sent -> Bool,
}
blob - /dev/null
blob + b96abe1f85a068a3271dc3cf83ff7d2f1193703a (mode 644)
--- /dev/null
+++ urls
+https://wiredspace.de/index.xml
+https://drewdevault.com/blog/index.xml