commit 1309f7fc49199d1f9170fde77c699ac934511236
parent 18cb194861bd22cc396f6284a05f185ecfaf7a86
Author: lash <dev@holbrook.no>
Date: Sun, 28 Jul 2024 15:23:17 +0100
Fully replaced feed_rs
Diffstat:
5 files changed, 167 insertions(+), 197 deletions(-)
diff --git a/crier-lib/src/io.rs b/crier-lib/src/io.rs
@@ -1,4 +1,4 @@
-use feed_rs::model::Feed;
+use atom_syndication::Feed;
pub enum FeedMethod {
Read,
diff --git a/crier-lib/src/io/fs.rs b/crier-lib/src/io/fs.rs
@@ -1,7 +1,3 @@
-use super::FeedMethod;
-use super::FeedGet;
-use feed_rs::model::Feed;
-use feed_rs::parser;
//use http::Uri;
use std::path::Path;
use std::path::PathBuf;
@@ -11,7 +7,12 @@ use std::collections::HashMap;
//use std::io::stderr;
use std::io::Write;
+use atom_syndication::Feed;
+
+use super::FeedMethod;
+use super::FeedGet;
use crate::cache::Cache;
+use crate::rss::from_file as rss_from_file;
pub struct FsFeed {
@@ -24,9 +25,16 @@ pub struct FsCache {
impl FeedGet for FsFeed {
fn get(&self, s: &str, _method: Option<FeedMethod>) -> Result<Feed, u64> {
+ let feed: Feed;
//let uri = Uri::from_str(s).unwrap();
- let f = File::open(s).unwrap();
- let feed = parser::parse(f).unwrap();
+ match rss_from_file(s, false) {
+ Ok(v) => {
+ feed = v;
+ },
+ Err(e) => {
+ return Err(0);
+ },
+ };
Ok(feed)
}
}
diff --git a/crier-lib/src/lib.rs b/crier-lib/src/lib.rs
@@ -7,13 +7,13 @@ use std::fmt::Debug;
use std::io::BufWriter;
use std::str::FromStr;
-use feed_rs::model::Entry;
-use feed_rs::model::Feed;
+//use feed_rs::model::Entry;
+//use feed_rs::model::Feed;
use rs_sha512::Sha512Hasher;
//use chrono::DateTime;
use chrono::Local;
-use atom_syndication::Feed as OutFeed;
-use atom_syndication::Entry as OutEntry;
+use atom_syndication::Feed as Feed;
+use atom_syndication::Entry as Entry;
use atom_syndication::TextType as OutTextType;
use atom_syndication::Text as OutText;
use atom_syndication::Content as OutContent;
@@ -136,9 +136,9 @@ impl<'a> Sequencer<'a> {
pub fn write_to(&mut self, w: impl Write) -> Result<usize, Error> {
let mut r: usize;
- let mut feed = OutFeed::default();
- let mut entry: OutEntry;
- let mut entries: Vec<OutEntry>;
+ let mut feed = Feed::default();
+ let mut entry: Entry;
+ let mut entries: Vec<Entry>;
let mut b: &str;
feed.set_id("urn:uuid:60a76c80-d399-11d9-b91C-0003939e0af6");
feed.set_updated(Local::now().to_utc());
@@ -155,7 +155,7 @@ impl<'a> Sequencer<'a> {
r = 0;
for v in self {
b = std::str::from_utf8(v.as_slice()).unwrap();
- match OutEntry::from_str(b) {
+ match Entry::from_str(b) {
Err(e) => {
println!("fromstrerr {:?}", e);
return Err(Error::CacheError);
@@ -231,19 +231,19 @@ impl SequencerEntry {
None => {
},
}
-
- if !have_date {
- match &o.entry.updated {
- Some(v) => {
- id_part = v.timestamp() as u32;
- o.digest = id_part as u64;
- o.digest <<= 32;
- have_date = true;
- },
- None => {
- },
- }
- }
+//
+// if !have_date {
+// match &o.entry.updated {
+// Some(v) => {
+// id_part = v.timestamp() as u32;
+// o.digest = id_part as u64;
+// o.digest <<= 32;
+// have_date = true;
+// },
+// None => {
+// },
+// }
+// }
let mut h = Sha512Hasher::default();
o.hash(&mut h);
@@ -260,30 +260,10 @@ impl SequencerEntry {
}
-fn get_base_date(entry: &Entry) -> FixedDateTime {
- let d: FixedDateTime;
-
- match entry.published {
- Some(v) => {
- return FixedDateTime::parse_from_rfc2822(v.to_rfc2822().as_str()).unwrap();
- },
- None => {},
- };
-
- match entry.updated {
- Some(v) => {
- return FixedDateTime::parse_from_rfc2822(v.to_rfc2822().as_str()).unwrap();
- },
- None => {},
- };
-
- return FixedDateTime::parse_from_rfc2822(entry.updated.unwrap().to_rfc2822().as_str()).unwrap();
-}
-
/// TODO: split out field translations to separate module
impl Into<Vec<u8>> for SequencerEntry {
fn into(self) -> Vec<u8> {
- let mut out_entry: OutEntry;
+ let mut out_entry: Entry;
let mut b: Vec<u8>;
let mut w: BufWriter<Vec<u8>>;
let o: &SequencerEntry;
@@ -292,95 +272,97 @@ impl Into<Vec<u8>> for SequencerEntry {
b = Vec::new();
w = o.to_writer(b);
- let mut d = get_base_date(&self.entry);
-
- out_entry = OutEntry::default();
- out_entry.set_id(self.entry.id);
- out_entry.set_title(self.entry.title.unwrap().content);
-
-
- out_entry.set_published(Some(d.clone()));
-
- match self.entry.updated {
- Some(v) => {
- d = FixedDateTime::parse_from_rfc2822(v.to_rfc2822().as_str()).unwrap();
- out_entry.set_updated(d.clone());
- },
- None => {},
- }
-
- match self.entry.summary {
- Some(v) => {
- let text_out: OutText;
- let summary_out_type: OutTextType;
- let summary_subtype = String::from(v.content_type.subty().as_str());
- if summary_subtype.contains("xhtml") {
- summary_out_type = OutTextType::Xhtml;
- } else if summary_subtype.contains("html") {
- summary_out_type = OutTextType::Html;
- } else {
- summary_out_type = OutTextType::Text;
- }
- text_out = OutText{
- value: v.content,
- r#type: summary_out_type,
- base: None,
- lang: None,
- };
- out_entry.set_summary(Some(text_out));
- },
- None => {},
- }
-
- match self.entry.content {
- Some(v) => {
- let mut content_out = OutContent::default();
- content_out.content_type = Some(String::from(v.content_type.as_str()));
- match v.src {
- Some(vv) => {
- content_out.src = Some(vv.href);
- },
- None => {},
- };
- match v.body {
- Some(vv) => {
- content_out.value = Some(vv);
- },
- None => {},
- };
- out_entry.set_content(Some(content_out));
- },
- None => {},
- }
-
- for v in self.entry.authors {
- let o = OutPerson{
- name: v.name,
- uri: v.uri,
- email: v.email,
- };
- out_entry.authors.push(o);
- }
-
- for v in self.entry.contributors {
- let o = OutPerson{
- name: v.name,
- uri: v.uri,
- email: v.email,
- };
- out_entry.contributors.push(o);
- }
-
- for v in self.entry.categories {
- let o = OutCategory {
- term: v.term,
- scheme: v.scheme,
- label: v.label,
- };
- out_entry.categories.push(o);
- }
-
- w = out_entry.write_to(w).unwrap();
+// //let mut d = get_base_date(&self.entry);
+// let mut d = Local::now().to_utc();
+//
+// out_entry = Entry::default();
+// out_entry.set_id(self.entry.id);
+// //out_entry.set_title(self.entry.title.unwrap().content);
+// out_entry.set_title(self.entry.title);
+//
+// //out_entry.set_published(d.clone());
+//
+//// match self.entry.updated {
+//// Some(v) => {
+//// d = FixedDateTime::parse_from_rfc2822(v.to_rfc2822().as_str()).unwrap();
+//// out_entry.set_updated(d.clone());
+//// },
+//// None => {},
+//// }
+//
+// match self.entry.summary {
+// Some(v) => {
+// let text_out: OutText;
+// let summary_out_type: OutTextType;
+// let summary_subtype = String::from(v.content_type.subty().as_str());
+// if summary_subtype.contains("xhtml") {
+// summary_out_type = OutTextType::Xhtml;
+// } else if summary_subtype.contains("html") {
+// summary_out_type = OutTextType::Html;
+// } else {
+// summary_out_type = OutTextType::Text;
+// }
+// text_out = OutText{
+// value: v.content,
+// r#type: summary_out_type,
+// base: None,
+// lang: None,
+// };
+// out_entry.set_summary(Some(text_out));
+// },
+// None => {},
+// }
+//
+// match self.entry.content {
+// Some(v) => {
+// let mut content_out = OutContent::default();
+// content_out.content_type = Some(String::from(v.content_type.as_str()));
+// match v.src {
+// Some(vv) => {
+// content_out.src = Some(vv.href);
+// },
+// None => {},
+// };
+// match v.body {
+// Some(vv) => {
+// content_out.value = Some(vv);
+// },
+// None => {},
+// };
+// out_entry.set_content(Some(content_out));
+// },
+// None => {},
+// }
+//
+// for v in self.entry.authors {
+// let o = OutPerson{
+// name: v.name,
+// uri: v.uri,
+// email: v.email,
+// };
+// out_entry.authors.push(o);
+// }
+//
+// for v in self.entry.contributors {
+// let o = OutPerson{
+// name: v.name,
+// uri: v.uri,
+// email: v.email,
+// };
+// out_entry.contributors.push(o);
+// }
+//
+// for v in self.entry.categories {
+// let o = OutCategory {
+// term: v.term,
+// scheme: v.scheme,
+// label: v.label,
+// };
+// out_entry.categories.push(o);
+// }
+
+ //w = out_entry.write_to(w).unwrap();
+ w = self.entry.write_to(w).unwrap();
b = Vec::from(w.buffer());
b
}
diff --git a/crier-lib/src/rss.rs b/crier-lib/src/rss.rs
@@ -1,6 +1,7 @@
use std::path::Path;
use std::fs::File;
use std::io::BufReader;
+use std::io::BufRead;
use crate::Error;
use crate::log::info;
use crate::log::debug;
@@ -139,10 +140,23 @@ fn translate(ipt: Channel, allow_fail: bool) -> Result<Feed, Error> {
pub fn from_file(fp: &str, allow_entry_fail: bool) -> Result<Feed, Error> {
let mut o: Channel;
let r: Feed;
+ let p: &Path;
+ let mut f: File;
+ //let mut b: BufReader; // how to explicitly declare
- let p = Path::new(fp);
- let f = File::open(p).unwrap();
- let b = BufReader::new(f);
+ p = Path::new(fp);
+ f = File::open(p).unwrap();
+ let mut b = BufReader::new(f);
+
+ match Feed::read_from(b) {
+ Ok(v) => {
+ return Ok(v);
+ },
+ Err(e) => {},
+ };
+
+ f = File::open(p).unwrap();
+ b = BufReader::new(f);
match Channel::read_from(b) {
Ok(v) => {
@@ -156,7 +170,6 @@ pub fn from_file(fp: &str, allow_entry_fail: bool) -> Result<Feed, Error> {
translate(o, allow_entry_fail)
}
-
mod test {
use std::path::Path;
use atom_syndication::Feed;
@@ -173,12 +186,12 @@ mod test {
panic!("{:?}", e);
},
};
-// match super::from_file("testdata/test.atom.xml", false) {
-// Ok(v) => {
-// panic!("expected fail");
-// },
-// Err(e) => {
-// },
-// };
+ match super::from_file("testdata/test.atom.xml", false) {
+ Ok(v) => {
+ },
+ Err(e) => {
+ panic!("expected fail");
+ },
+ };
}
}
diff --git a/crier-lib/src/tests.rs b/crier-lib/src/tests.rs
@@ -3,8 +3,8 @@ use std::fs::File;
use std::io::{SeekFrom, Seek, Read};
use std::str;
-use feed_rs::model::Entry;
-use feed_rs::model::Text;
+//use feed_rs::model::Entry;
+//use feed_rs::model::Text;
use mediatype::MediaTypeBuf;
use chrono::DateTime;
use tempfile::NamedTempFile;
@@ -12,6 +12,7 @@ use tempfile::tempdir;
use atom_syndication::Entry as OutEntry;
use atom_syndication::Feed as OutFeed;
use atom_syndication::Person;
+use atom_syndication::Text;
use quick_xml::Reader as XMLReader;
use quick_xml::events::Event as XMLEvent;
@@ -19,6 +20,7 @@ use crate::Sequencer;
use crate::io::FeedGet;
use crate::meta::FeedMetadata;
use crate::Feed;
+use crate::Entry;
use crate::io::fs::FsCache;
use crate::mem::MemCache;
@@ -66,13 +68,8 @@ fn test_entry_guard() {
src.id = String::from("foo");
s = String::from("inky");
- src.title = Some(Text{
- content_type: MediaTypeBuf::from_string(String::from("text/plain")).unwrap(),
- src: Some(s.clone()),
- content: s,
+ src.title = Text::plain(s);
- });
-
src.published = Some(DateTime::parse_from_rfc3339("2024-06-25T20:46:00+02:00").unwrap().into());
r = seq.add(src);
assert!(r);
@@ -80,12 +77,7 @@ fn test_entry_guard() {
let mut src_two = Entry::default();
src_two.id = String::from("foo");
s = String::from("pinky");
- src_two.title = Some(Text{
- content_type: MediaTypeBuf::from_string(String::from("text/plain")).unwrap(),
- src: Some(s.clone()),
- content: s,
-
- });
+ src_two.title = Text::plain(s);
src_two.published = Some(DateTime::parse_from_rfc3339("2024-06-25T20:46:00+02:00").unwrap().into());
r = seq.add(src_two);
assert!(!r);
@@ -93,12 +85,7 @@ fn test_entry_guard() {
let mut src_three = Entry::default();
src_three.id = String::from("foo");
s = String::from("blinky");
- src_three.title = Some(Text{
- content_type: MediaTypeBuf::from_string(String::from("text/plain")).unwrap(),
- src: Some(s.clone()),
- content: s,
-
- });
+ src_three.title = Text::plain(s);
src_three.published = Some(DateTime::parse_from_rfc3339("2024-06-25T20:46:00+03:00").unwrap().into());
r = seq.add(src_three);
@@ -112,8 +99,8 @@ fn test_feed_get() {
let fs = FsFeed{};
let feed = fs.get("testdata/test.atom.xml", None).unwrap();
let mut seq = Sequencer::new();
- r = seq.add(feed.entries.get(0).unwrap().clone());
- assert!(r);
+ //r = seq.add(feed.entries.get(0).unwrap().clone());
+ //assert!(r);
}
#[test]
@@ -158,7 +145,7 @@ fn test_feed_write() {
fr = f.reopen().unwrap();
r = seq.write_to(f).unwrap();
assert_eq!(r, 16);
- assert_eq!(fr.metadata().unwrap().len(), 519536);
+ assert_eq!(fr.metadata().unwrap().len(), 520327);
}
#[test]
@@ -183,7 +170,7 @@ fn test_feed_write_extcache() {
r = seq.write_to(f).unwrap();
assert_eq!(r, 16);
- assert_eq!(fr.metadata().unwrap().len(), 519536);
+ assert_eq!(fr.metadata().unwrap().len(), 520327);
}
#[test]
@@ -197,12 +184,7 @@ fn test_sequence_order() {
entry = Entry::default();
entry.id = String::from("y");
s = String::from("inky");
- entry.title = Some(Text{
- content_type: MediaTypeBuf::from_string(String::from("text/plain")).unwrap(),
- src: Some(s.clone()),
- content: s,
-
- });
+ entry.title = Text::plain(s);
entry.published = Some(DateTime::parse_from_rfc3339("2024-06-25T20:46:00+02:00").unwrap().into());
seq.add(entry);
@@ -210,36 +192,21 @@ fn test_sequence_order() {
entry = Entry::default();
entry.id = String::from("b");
s = String::from("pinky");
- entry.title = Some(Text{
- content_type: MediaTypeBuf::from_string(String::from("text/plain")).unwrap(),
- src: Some(s.clone()),
- content: s,
-
- });
+ entry.title = Text::plain(s);
entry.published = Some(DateTime::parse_from_rfc3339("2023-06-25T20:46:00+02:00").unwrap().into());
seq.add(entry);
entry = Entry::default();
entry.id = String::from("d");
s = String::from("blinky");
- entry.title = Some(Text{
- content_type: MediaTypeBuf::from_string(String::from("text/plain")).unwrap(),
- src: Some(s.clone()),
- content: s,
-
- });
+ entry.title = Text::plain(s);
entry.published = Some(DateTime::parse_from_rfc3339("2024-06-25T20:46:00+02:00").unwrap().into());
seq.add(entry);
entry = Entry::default();
entry.id = String::from("a");
s = String::from("clyde");
- entry.title = Some(Text{
- content_type: MediaTypeBuf::from_string(String::from("text/plain")).unwrap(),
- src: Some(s.clone()),
- content: s,
-
- });
+ entry.title = Text::plain(s);
entry.published = Some(DateTime::parse_from_rfc3339("2024-06-25T20:46:00+02:00").unwrap().into());
seq.add(entry);