diff --git a/Cargo.lock b/Cargo.lock index fb536ea..50ed176 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -83,66 +83,6 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" -[[package]] -name = "darling" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn", -] - -[[package]] -name = "darling_macro" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" -dependencies = [ - "darling_core", - "quote", - "syn", -] - -[[package]] -name = "derive_builder" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2658621297f2cf68762a6f7dc0bb7e1ff2cfd6583daef8ee0fed6f7ec468ec0" -dependencies = [ - "darling", - "derive_builder_core", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "derive_builder_core" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2791ea3e372c8495c0bc2033991d76b512cd799d07491fbd6890124db9458bef" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "encoding_rs" version = "0.8.24" @@ -329,12 +269,6 @@ dependencies = [ "tokio-native-tls", ] -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - [[package]] name = "idna" version = "0.2.0" @@ -605,11 +539,10 @@ dependencies = [ [[package]] name = "quick-xml" -version = "0.17.2" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe1e430bdcf30c9fdc25053b9c459bb1a4672af4617b6c783d7d91dc17c6bbb0" +checksum = "26aab6b48e2590e4a64d1ed808749ba06257882b461d01ca71baeb747074a6dd" dependencies = [ - "encoding_rs", "memchr", ] @@ -712,23 +645,13 @@ dependencies = [ "winreg", ] -[[package]] -name = "rss" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99979205510c60f80a119dedbabd0b8426517384edf205322f8bcd51796bcef9" -dependencies = [ - "derive_builder", - "quick-xml", -] - [[package]] name = "rss-anime-notifier-rs" -version = "0.2.2" +version = "0.2.3" dependencies = [ "chrono", + "quick-xml", "reqwest", - "rss", "serde", "serde_json", "tokio", @@ -833,12 +756,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "strsim" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" - [[package]] name = "syn" version = "1.0.46" diff --git a/Cargo.toml b/Cargo.toml index 85ec9f0..74c11f8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rss-anime-notifier-rs" -version = "0.2.2" +version = "0.2.3" authors = ["blank X "] edition = "2018" @@ -10,7 +10,7 @@ edition = "2018" lto = true [dependencies] -rss = "1.9.0" +quick-xml = "0.20.0" chrono = "0.4.19" serde_json = "1.0" reqwest = "0.11" diff --git a/src/main.rs b/src/main.rs index e729a11..01d2bb4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,3 @@ -extern crate rss; extern crate serde; extern crate tokio; extern crate chrono; @@ -6,12 +5,14 @@ extern crate reqwest; extern crate serde_json; use std::env; use std::path::Path; +use std::io::Cursor; use std::process::exit; use reqwest::Client; use serde_json::json; +use quick_xml::Writer; use serde::Deserialize; use chrono::{Utc, DateTime, NaiveDateTime}; -use rss::{Item, ItemBuilder, ChannelBuilder, GuidBuilder}; +use quick_xml::events::{Event, BytesStart, BytesText, BytesEnd}; const QUERY: &str = r#"query ($id: Int) { Media (id: $id) { @@ -107,7 +108,7 @@ fn main() { let mut last_build_date = pub_date.clone(); let resp = &resp.data.media; let title = resp.title.english.as_ref().unwrap_or(&resp.title.romaji); - let mut items: Vec = Vec::with_capacity(resp.airing_schedule.nodes.len()); + let mut items: Vec<(i32, String, String)> = Vec::with_capacity(resp.airing_schedule.nodes.len()); for i in &resp.airing_schedule.nodes { let i_date = DateTime::::from_utc(NaiveDateTime::from_timestamp(i.airing_at, 0), Utc).to_rfc2822(); pub_date = i_date.clone(); @@ -119,24 +120,114 @@ fn main() { if Some(i.episode) == resp.episodes { title.push_str(" END"); } - items.push(ItemBuilder::default() - .title(title) - .link(resp.site_url.clone()) - .pub_date(i_date) - .guid(GuidBuilder::default().permalink(false).value(format!("ran-{}-{}", anime_id, i.id)).build().unwrap()) - .build() - .unwrap() - ); + items.push((i.id, i_date, title)); } items.reverse(); - let channel = ChannelBuilder::default() - .title(title) - .link(resp.site_url.clone()) - .description(format!("Aired episodes of {}", title)) - .pub_date(pub_date) - .last_build_date(last_build_date) - .items(items) - .build() - .unwrap(); - println!("{}", channel.to_string()); + let mut writer = Writer::new(Cursor::new(Vec::new())); + + { + let mut elem = BytesStart::owned(b"rss".to_vec(), 3); + elem.push_attribute(("version", "2.0")); + writer.write_event(Event::Start(elem)).unwrap(); + + let elem = BytesStart::owned(b"channel".to_vec(), 7); + writer.write_event(Event::Start(elem)).unwrap(); + + let elem = BytesStart::owned(b"title".to_vec(), 5); + writer.write_event(Event::Start(elem)).unwrap(); + + let elem = BytesText::from_plain_str(&title).into_owned(); + writer.write_event(Event::Text(elem)).unwrap(); + + let elem = BytesEnd::owned(b"title".to_vec()); + writer.write_event(Event::End(elem)).unwrap(); + + let elem = BytesStart::owned(b"link".to_vec(), 4); + writer.write_event(Event::Start(elem)).unwrap(); + + let elem = BytesText::from_plain_str(&resp.site_url).into_owned(); + writer.write_event(Event::Text(elem)).unwrap(); + + let elem = BytesEnd::owned(b"link".to_vec()); + writer.write_event(Event::End(elem)).unwrap(); + + let elem = BytesStart::owned(b"description".to_vec(), 11); + writer.write_event(Event::Start(elem)).unwrap(); + + let elem = BytesText::from_plain_str(&format!("Aired episodes of {}", &title)).into_owned(); + writer.write_event(Event::Text(elem)).unwrap(); + + let elem = BytesEnd::owned(b"description".to_vec()); + writer.write_event(Event::End(elem)).unwrap(); + + let elem = BytesStart::owned(b"pubDate".to_vec(), 7); + writer.write_event(Event::Start(elem)).unwrap(); + + let elem = BytesText::from_plain_str(&pub_date).into_owned(); + writer.write_event(Event::Text(elem)).unwrap(); + + let elem = BytesEnd::owned(b"pubDate".to_vec()); + writer.write_event(Event::End(elem)).unwrap(); + + let elem = BytesStart::owned(b"lastBuildDate".to_vec(), 13); + writer.write_event(Event::Start(elem)).unwrap(); + + let elem = BytesText::from_plain_str(&last_build_date).into_owned(); + writer.write_event(Event::Text(elem)).unwrap(); + + let elem = BytesEnd::owned(b"lastBuildDate".to_vec()); + writer.write_event(Event::End(elem)).unwrap(); + } + + for (id, date, title) in items { + let elem = BytesStart::owned(b"item".to_vec(), 4); + writer.write_event(Event::Start(elem)).unwrap(); + + let elem = BytesStart::owned(b"title".to_vec(), 5); + writer.write_event(Event::Start(elem)).unwrap(); + + let elem = BytesText::from_plain_str(&title).into_owned(); + writer.write_event(Event::Text(elem)).unwrap(); + + let elem = BytesEnd::owned(b"title".to_vec()); + writer.write_event(Event::End(elem)).unwrap(); + + let elem = BytesStart::owned(b"link".to_vec(), 4); + writer.write_event(Event::Start(elem)).unwrap(); + + let elem = BytesText::from_plain_str(&resp.site_url).into_owned(); + writer.write_event(Event::Text(elem)).unwrap(); + + let elem = BytesEnd::owned(b"link".to_vec()); + writer.write_event(Event::End(elem)).unwrap(); + + let elem = BytesStart::owned(b"guid".to_vec(), 4); + writer.write_event(Event::Start(elem)).unwrap(); + + let elem = BytesText::from_plain_str(&format!("ran-{}-{}", &anime_id, id)).into_owned(); + writer.write_event(Event::Text(elem)).unwrap(); + + let elem = BytesEnd::owned(b"guid".to_vec()); + writer.write_event(Event::End(elem)).unwrap(); + + let elem = BytesStart::owned(b"pubDate".to_vec(), 7); + writer.write_event(Event::Start(elem)).unwrap(); + + let elem = BytesText::from_plain_str(&date).into_owned(); + writer.write_event(Event::Text(elem)).unwrap(); + + let elem = BytesEnd::owned(b"pubDate".to_vec()); + writer.write_event(Event::End(elem)).unwrap(); + + let elem = BytesEnd::owned(b"item".to_vec()); + writer.write_event(Event::End(elem)).unwrap(); + } + + let elem = BytesEnd::owned(b"channel".to_vec()); + writer.write_event(Event::End(elem)).unwrap(); + + let elem = BytesEnd::owned(b"rss".to_vec()); + writer.write_event(Event::End(elem)).unwrap(); + + println!("{}", String::from_utf8(writer.into_inner().into_inner()).unwrap()); }