mirror of
https://codeberg.org/icewind/rss-webhook-trigger.git
synced 2026-06-03 09:54:18 +02:00
deal with not-modified responses
This commit is contained in:
parent
f8b59df362
commit
c325eaba62
4 changed files with 33 additions and 15 deletions
|
|
@ -4,6 +4,7 @@ version = "0.2.0"
|
|||
authors = ["Robin Appelman <robin@icewind.nl>"]
|
||||
edition = "2018"
|
||||
rust-version = "1.71.1"
|
||||
repository = "https://github.com/icewind1991/rss-webhook-trigger"
|
||||
license = "MIT"
|
||||
|
||||
[dependencies]
|
||||
|
|
|
|||
|
|
@ -84,8 +84,8 @@ pub struct FetchPlan {
|
|||
}
|
||||
|
||||
impl FetchPlan {
|
||||
pub fn elapsed(&self) -> bool {
|
||||
Instant::now() > self.time
|
||||
pub fn is_elapsed(&self) -> bool {
|
||||
Instant::now() >= self.time
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use crate::error::HubError;
|
||||
use crate::fetcher::{CacheHeaders, FetchResponse};
|
||||
use reqwest::Client;
|
||||
use reqwest::{Client, StatusCode};
|
||||
use reqwest::header::{HeaderValue, USER_AGENT};
|
||||
use serde::Deserialize;
|
||||
use time::OffsetDateTime;
|
||||
|
|
@ -15,10 +15,10 @@ pub async fn tags(
|
|||
cache_headers: &CacheHeaders,
|
||||
) -> FetchResponse<Vec<HubTag>, HubError> {
|
||||
let result = client
|
||||
.get(format!(
|
||||
.get(dbg!(format!(
|
||||
"https://hub.docker.com/v2/repositories/{}/{}/tags",
|
||||
user, repo
|
||||
))
|
||||
)))
|
||||
.headers(cache_headers.headers())
|
||||
.header(USER_AGENT, HeaderValue::from_static(FETCHER_USER_AGENT))
|
||||
.send()
|
||||
|
|
@ -28,6 +28,9 @@ pub async fn tags(
|
|||
.map_err(HubError::Network)
|
||||
.check_status_code(HubError::ClientError, HubError::ServerError)
|
||||
.map(|response| async {
|
||||
if response.status() == StatusCode::NOT_MODIFIED {
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
response
|
||||
.text()
|
||||
.await
|
||||
|
|
|
|||
32
src/main.rs
32
src/main.rs
|
|
@ -7,7 +7,7 @@ use crate::config::{Config, FeedConfig};
|
|||
use crate::error::{FetchError, FetchFeedError, HubError, ParseFeedError};
|
||||
use crate::fetcher::{next_fetch, CacheHeaders, FetchPlan, FetchResponse};
|
||||
use main_error::MainResult;
|
||||
use reqwest::{Client, Response};
|
||||
use reqwest::{Client, Response, StatusCode};
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::collections::HashMap;
|
||||
use std::future::ready;
|
||||
|
|
@ -106,7 +106,10 @@ impl FeedFetcher {
|
|||
}
|
||||
|
||||
pub fn should_update(&self, feed: &str) -> bool {
|
||||
self.fetch_plans.get(feed).filter(|plan| FetchPlan::elapsed(plan)).is_some()
|
||||
match self.fetch_plans.get(feed) {
|
||||
Some(plan) => plan.is_elapsed(),
|
||||
None => true,
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
|
|
@ -130,7 +133,7 @@ impl FeedFetcher {
|
|||
};
|
||||
|
||||
Ok(match (self.cache.get_mut(feed), new_key) {
|
||||
(Some(cached), Some(new_key)) => {
|
||||
(Some(cached), Some(Some(new_key))) => {
|
||||
debug!(cached, new_key, "checked existing feed");
|
||||
if new_key != *cached {
|
||||
*cached = new_key;
|
||||
|
|
@ -139,13 +142,17 @@ impl FeedFetcher {
|
|||
false
|
||||
}
|
||||
}
|
||||
(None, Some(new_key)) => {
|
||||
(None, Some(Some(new_key))) => {
|
||||
debug!(feed, "new feed");
|
||||
self.cache.insert(feed.into(), new_key);
|
||||
|
||||
// don't trigger the actions on start
|
||||
false
|
||||
}
|
||||
(_, Some(None)) => {
|
||||
debug!("not modified response");
|
||||
false
|
||||
}
|
||||
(_, None) => {
|
||||
warn!("rate limited by server");
|
||||
false
|
||||
|
|
@ -158,18 +165,21 @@ impl FeedFetcher {
|
|||
&self,
|
||||
feed: &str,
|
||||
cache_headers: &CacheHeaders,
|
||||
) -> FetchResponse<u64, FetchError> {
|
||||
) -> FetchResponse<Option<u64>, FetchError> {
|
||||
if let Some(hub) = feed.strip_prefix("docker-hub://") {
|
||||
if let Some((user, repo)) = hub.split_once('/') {
|
||||
hub::tags(&self.client, user, repo, cache_headers)
|
||||
.await
|
||||
.map(|tags| {
|
||||
if tags.is_empty() {
|
||||
return ready(None);
|
||||
}
|
||||
let mut hasher = DefaultHasher::new();
|
||||
for tag in tags {
|
||||
tag.id.hash(&mut hasher);
|
||||
tag.last_updated.hash(&mut hasher);
|
||||
}
|
||||
ready(hasher.finish())
|
||||
ready(Some(hasher.finish()))
|
||||
}).await
|
||||
.map_err(FetchError::Hub)
|
||||
} else {
|
||||
|
|
@ -190,7 +200,7 @@ impl FeedFetcher {
|
|||
&self,
|
||||
feed: &str,
|
||||
cache_headers: &CacheHeaders,
|
||||
) -> FetchResponse<u64, FetchFeedError> {
|
||||
) -> FetchResponse<Option<u64>, FetchFeedError> {
|
||||
let response = self
|
||||
.client
|
||||
.get(feed)
|
||||
|
|
@ -209,7 +219,11 @@ impl FeedFetcher {
|
|||
}
|
||||
}
|
||||
|
||||
async fn parse_rss_response(response: Response) -> Result<u64, FetchFeedError> {
|
||||
async fn parse_rss_response(response: Response) -> Result<Option<u64>, FetchFeedError> {
|
||||
if response.status() == StatusCode::NOT_MODIFIED {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let content = response.text().await?;
|
||||
let channel = Feed::from_str(&content).map_err(ParseFeedError::Parse)?;
|
||||
|
||||
|
|
@ -235,5 +249,5 @@ async fn parse_rss_response(response: Response) -> Result<u64, FetchFeedError> {
|
|||
}
|
||||
}
|
||||
|
||||
Ok(hasher.finish())
|
||||
Ok(Some(hasher.finish()))
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue