diff options
-rw-r--r-- | src/feed.rs | 7 | ||||
-rw-r--r-- | src/lib.rs | 17 | ||||
-rw-r--r-- | src/main.rs | 23 | ||||
-rw-r--r-- | src/manager.rs | 25 |
4 files changed, 41 insertions, 31 deletions
diff --git a/src/feed.rs b/src/feed.rs index f9a7893..77f1a45 100644 --- a/src/feed.rs +++ b/src/feed.rs | |||
@@ -104,6 +104,7 @@ impl Feed { | |||
104 | 104 | ||
105 | // update entries | 105 | // update entries |
106 | self.entries = entries.into_iter().map(Result::unwrap).collect(); | 106 | self.entries = entries.into_iter().map(Result::unwrap).collect(); |
107 | self.entries.sort_by(|a, b| b.published.cmp(&a.published)); | ||
107 | 108 | ||
108 | Ok(pull_status) | 109 | Ok(pull_status) |
109 | } | 110 | } |
@@ -166,16 +167,16 @@ impl fmt::Display for Entry { | |||
166 | f, | 167 | f, |
167 | "{} {} {}", | 168 | "{} {} {}", |
168 | self.published.format(crate::DATE_FMT), | 169 | self.published.format(crate::DATE_FMT), |
170 | Style::new().dimmed().paint(self.title.to_ascii_lowercase()), | ||
169 | Style::new().fg(Color::Cyan).paint( | 171 | Style::new().fg(Color::Cyan).paint( |
170 | self.link | 172 | self.link |
171 | .as_str() | 173 | .as_str() |
172 | .trim_end_matches('/') | 174 | .trim_end_matches('/') |
173 | .trim_start_matches("http://") | ||
174 | .trim_start_matches("https://") | ||
175 | .trim_start_matches("http://www.") | 175 | .trim_start_matches("http://www.") |
176 | .trim_start_matches("https://www.") | 176 | .trim_start_matches("https://www.") |
177 | .trim_start_matches("https://") | ||
178 | .trim_start_matches("http://") | ||
177 | ), | 179 | ), |
178 | Style::new().dimmed().paint(self.title.to_ascii_lowercase()), | ||
179 | ) | 180 | ) |
180 | } | 181 | } |
181 | } | 182 | } |
@@ -5,20 +5,3 @@ pub mod manager; | |||
5 | pub mod status; | 5 | pub mod status; |
6 | 6 | ||
7 | pub(crate) static DATE_FMT: &str = "%e %b %y"; | 7 | pub(crate) static DATE_FMT: &str = "%e %b %y"; |
8 | |||
9 | pub trait PrintResult { | ||
10 | fn print(&self); | ||
11 | } | ||
12 | |||
13 | impl<T, E> PrintResult for Result<T, E> | ||
14 | where | ||
15 | T: std::fmt::Display, | ||
16 | E: std::fmt::Display, | ||
17 | { | ||
18 | fn print(&self) { | ||
19 | match self { | ||
20 | Ok(ok) => println!("{ok}"), | ||
21 | Err(err) => eprintln!("{err}"), | ||
22 | } | ||
23 | } | ||
24 | } | ||
diff --git a/src/main.rs b/src/main.rs index 8c94843..b36e08f 100644 --- a/src/main.rs +++ b/src/main.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use chrono::{naive::Days, prelude::*}; | 1 | use chrono::{naive::Days, prelude::*}; |
2 | use clap::{Args, Parser, Subcommand, ValueEnum}; | 2 | use clap::{Args, Parser, Subcommand, ValueEnum}; |
3 | use syn::{manager::Manager, PrintResult}; | 3 | use syn::manager::Manager; |
4 | 4 | ||
5 | #[derive(Parser)] | 5 | #[derive(Parser)] |
6 | #[command(author, version, about, long_about = None)] | 6 | #[command(author, version, about, long_about = None)] |
@@ -29,7 +29,7 @@ impl Default for Command { | |||
29 | 29 | ||
30 | #[derive(Args)] | 30 | #[derive(Args)] |
31 | struct AddCommand { | 31 | struct AddCommand { |
32 | url: String, | 32 | urls: Vec<String>, |
33 | } | 33 | } |
34 | 34 | ||
35 | #[derive(Args)] | 35 | #[derive(Args)] |
@@ -49,11 +49,28 @@ struct PullCommand { | |||
49 | target: Option<String>, | 49 | target: Option<String>, |
50 | } | 50 | } |
51 | 51 | ||
52 | pub trait PrintResult { | ||
53 | fn print(&self); | ||
54 | } | ||
55 | |||
56 | impl<T, E> PrintResult for Result<T, E> | ||
57 | where | ||
58 | T: std::fmt::Display, | ||
59 | E: std::fmt::Display, | ||
60 | { | ||
61 | fn print(&self) { | ||
62 | match self { | ||
63 | Ok(ok) => println!("{ok}"), | ||
64 | Err(err) => eprintln!("{err}"), | ||
65 | } | ||
66 | } | ||
67 | } | ||
68 | |||
52 | #[tokio::main(flavor = "current_thread")] | 69 | #[tokio::main(flavor = "current_thread")] |
53 | async fn main() { | 70 | async fn main() { |
54 | let opts = Cli::parse(); | 71 | let opts = Cli::parse(); |
55 | match &opts.command.unwrap_or_default() { | 72 | match &opts.command.unwrap_or_default() { |
56 | Command::Add(AddCommand { url }) => { | 73 | Command::Add(AddCommand { urls }) => { |
57 | let mut manager = Manager::load().unwrap_or_else(|e| { | 74 | let mut manager = Manager::load().unwrap_or_else(|e| { |
58 | eprintln!("{e}"); | 75 | eprintln!("{e}"); |
59 | Manager::default() | 76 | Manager::default() |
diff --git a/src/manager.rs b/src/manager.rs index 34e19be..5330d80 100644 --- a/src/manager.rs +++ b/src/manager.rs | |||
@@ -13,7 +13,7 @@ pub struct Manager { | |||
13 | } | 13 | } |
14 | 14 | ||
15 | impl Manager { | 15 | impl Manager { |
16 | pub async fn add_feed(&mut self, url: &str) -> Result<PullStatus, Error> { | 16 | fn add_feed(&mut self, url: &str) -> Result<&mut Feed, Error> { |
17 | let link = Url::parse(&url).map_err(|e| AddError::InvalidUrl(e.to_string()))?; | 17 | let link = Url::parse(&url).map_err(|e| AddError::InvalidUrl(e.to_string()))?; |
18 | 18 | ||
19 | // check if this feed is already present | 19 | // check if this feed is already present |
@@ -22,17 +22,24 @@ impl Manager { | |||
22 | } | 22 | } |
23 | 23 | ||
24 | // construct a new feed | 24 | // construct a new feed |
25 | let mut feed = Feed::new(link.clone()); | 25 | let feed = Feed::new(link.clone()); |
26 | |||
27 | let status = feed | ||
28 | .pull() | ||
29 | .await | ||
30 | .map_err(|pull_err| Error::Pull(link, pull_err))?; | ||
31 | 26 | ||
32 | // add new feed | 27 | // add new feed |
33 | self.feeds.push(feed); | 28 | self.feeds.push(feed); |
34 | 29 | ||
35 | Ok(status) | 30 | Ok(self.feeds.last_mut().unwrap()) |
31 | } | ||
32 | |||
33 | pub async fn add_feed_and_pull(&mut self, url: &str) -> Result<PullStatus, Error> { | ||
34 | let feed = self.add_feed(url)?; | ||
35 | feed.pull() | ||
36 | .await | ||
37 | .map_err(|pull_err| Error::Pull(feed.link.clone(), pull_err)) | ||
38 | } | ||
39 | |||
40 | pub async fn add_feeds_and_pull(&mut self, urls: &[&str]) -> Vec<Result<PullStatus, Error>> { | ||
41 | let add_results = urls.into_iter().map(|url| self.add_feed(&url)); | ||
42 | self.pull() | ||
36 | } | 43 | } |
37 | 44 | ||
38 | pub async fn pull(&mut self) -> Vec<Result<PullStatus, PullError>> { | 45 | pub async fn pull(&mut self) -> Vec<Result<PullStatus, PullError>> { |
@@ -71,6 +78,8 @@ impl Manager { | |||
71 | } | 78 | } |
72 | } | 79 | } |
73 | 80 | ||
81 | // an iterator over a combined list of feeds (assumes each feed is already a sorted list of | ||
82 | // entries) | ||
74 | struct EntryIterator<'e> { | 83 | struct EntryIterator<'e> { |
75 | all_entries: Vec<&'e [Entry]>, | 84 | all_entries: Vec<&'e [Entry]>, |
76 | } | 85 | } |