Skip to content

Commit 12b391b

Browse files
authored
feat(targets): add -rrs to refresh items + rewrite support (#174)
1 parent 19e82b9 commit 12b391b

File tree

30 files changed

+492
-139
lines changed

30 files changed

+492
-139
lines changed

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@
1313
"editor.codeActionsOnSave": {
1414
"source.fixAll.ts": "explicit",
1515
"source.organizeImports": "explicit",
16-
}
16+
},
17+
"rust-analyzer.check.command": "clippy"
1718
}

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,7 @@ futures-util = "0.3.31"
101101
# [dev-dependencies]
102102
# # Standardize logging output
103103
# tracing-test = "0.2.5"
104+
105+
[profile.dev]
106+
opt-level = 1
107+
incremental = true

README.md

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ We use the following terminology:
5151
- Jellyfin
5252
- Emby
5353
- Command
54+
- Sonarr
55+
- Radarr
5456
- Tdarr
5557
- FileFlows
5658
- Another autopulse instance
@@ -167,17 +169,11 @@ triggers:
167169
from: "/downloads"
168170
to: "/movies"
169171
170-
my_lidarr:
171-
type: "lidarr"
172-
rewrite:
173-
from: "/downloads"
174-
to: "/music"
175-
176-
my_readarr:
177-
type: "readarr"
172+
my_manual:
173+
type: "manual"
178174
rewrite:
179175
from: "/downloads"
180-
to: "/books"
176+
to: "/"
181177
182178
my_notify:
183179
type: "notify"
@@ -198,6 +194,14 @@ targets:
198194
url: "http://plex:32400"
199195
token: "<your_token>"
200196
197+
my_different_plex:
198+
type: "plex"
199+
url: "http://plex:32401"
200+
token: "<your_token>"
201+
rewrite:
202+
from: "/media"
203+
to: "/plex"
204+
201205
my_jellyfin:
202206
type: "jellyfin"
203207
url: "http://jellyfin:8096"

src/build.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ fn main() {
44
let postgres_enabled = env::var("CARGO_FEATURE_POSTGRES").is_ok();
55
let sqlite_enabled = env::var("CARGO_FEATURE_SQLITE").is_ok();
66

7-
if !postgres_enabled && !sqlite_enabled {
8-
panic!("You must enable at least one of the `postgres` or `sqlite` features.");
9-
}
7+
assert!(
8+
!(!postgres_enabled && !sqlite_enabled),
9+
"You must enable at least one of the `postgres` or `sqlite` features."
10+
)
1011
}

src/db/conn.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ const POSTGRES_MIGRATIONS: EmbeddedMigrations = embed_migrations!("migrations/po
1818
#[cfg(feature = "sqlite")]
1919
const SQLITE_MIGRATIONS: EmbeddedMigrations = embed_migrations!("migrations/sqlite");
2020

21-
/// Represents a connection to either a PostgreSQL or SQLite database.
21+
/// Represents a connection to either a `PostgreSQL` or `SQLite` database.
2222
#[derive(diesel::MultiConnection)]
2323
pub enum AnyConnection {
24-
/// A connection to a PostgreSQL database.
24+
/// A connection to a `PostgreSQL` database.
2525
///
26-
/// This is used when the `database_url` is a PostgreSQL URL.
26+
/// This is used when the `database_url` is a `PostgreSQL` URL.
2727
///
2828
/// # Example
2929
///
@@ -33,9 +33,9 @@ pub enum AnyConnection {
3333
#[cfg(feature = "postgres")]
3434
Postgresql(diesel::PgConnection),
3535
// Mysql(diesel::MysqlConnection),
36-
/// A connection to a SQLite database.
36+
/// A connection to a `SQLite` database.
3737
///
38-
/// This is used when the `database_url` is a SQLite URL.
38+
/// This is used when the `database_url` is a `SQLite` URL.
3939
///
4040
/// Note: The directory where the database is stored will also be populated with a WAL file and a journal file.
4141
///

src/db/models.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1+
use crate::{settings::rewrite::Rewrite, utils::generate_uuid::generate_uuid};
12
use chrono::NaiveDateTime;
23
use diesel::prelude::*;
34
use serde::Serialize;
45
use std::fmt::Display;
56

6-
use crate::utils::generate_uuid::generate_uuid;
7-
87
/// The status of a scan event being proccessed by [Targets](crate::service::targets).
98
#[derive(Serialize)]
109
pub enum ProcessStatus {
@@ -16,7 +15,7 @@ pub enum ProcessStatus {
1615

1716
/// Whether a file was found or not.
1817
///
19-
/// Note: only used if [opts.check_path](crate::settings::opts::Opts::check_path) is set.
18+
/// Note: only used if [`opts.check_path`](crate::settings::opts::Opts::check_path) is set.
2019
#[derive(Serialize)]
2120
pub enum FoundStatus {
2221
Found,
@@ -79,7 +78,7 @@ pub struct ScanEvent {
7978
/// The status of the file being found.
8079
pub found_status: String,
8180

82-
/// The number of times the scan event has failed. Used for retries and is limited to [opts.max_retries](crate::settings::opts::Opts::max_retries).
81+
/// The number of times the scan event has failed. Used for retries and is limited to [`opts.max_retries`](crate::settings::opts::Opts::max_retries).
8382
pub failed_times: i32,
8483
/// The time the scan event will be retried.
8584
pub next_retry_at: Option<chrono::NaiveDateTime>,
@@ -117,6 +116,13 @@ impl ScanEvent {
117116
targets.dedup();
118117
self.targets_hit = targets.join(",");
119118
}
119+
120+
pub fn get_path(&self, rewrite: &Option<Rewrite>) -> String {
121+
rewrite.as_ref().map_or_else(
122+
|| self.file_path.clone(),
123+
|rewrite| rewrite.rewrite_path(self.file_path.clone()),
124+
)
125+
}
120126
}
121127

122128
#[derive(Insertable)]

src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//!
1111
//! ## About
1212
#![doc = include_str!("../README.md")]
13+
#![cfg_attr(debug_assertions, warn(clippy::nursery))]
1314

1415
use actix_web::{middleware::Logger, web::Data, App, HttpServer};
1516
use actix_web_httpauth::extractors::basic;

src/routes/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ pub mod status;
3636
///
3737
/// # Responses
3838
///
39-
/// - **200 OK**: Returns a [StatsResponse](stats::StatsResponse) object containing the service statistics and response time.
39+
/// - **200 OK**: Returns a [`StatsResponse`](stats::StatsResponse) object containing the service statistics and response time.
4040
pub mod stats;
4141

4242
/// GET `/list?status={status}&page={page}&limit={limit}&sort={sort}`
@@ -50,11 +50,11 @@ pub mod stats;
5050
/// - `limit`: The number of items to retrieve per page.
5151
/// - `sort`: The field to sort the results by. Can be one of `id`, `file_path`, `process_status`, `event_source`, `created_at`, or `updated_at`.
5252
///
53-
/// See [list::ListQuery] for more information.
53+
/// See [`list::ListQuery`] for more information.
5454
///
5555
/// # Responses
5656
///
57-
/// - **200 OK**: Returns a list of [ScanEvent](crate::db::models::ScanEvent) objects.
57+
/// - **200 OK**: Returns a list of [`ScanEvent`](crate::db::models::ScanEvent) objects.
5858
/// - **401 Unauthorized**: Returned if the request is not authenticated.
5959
pub mod list;
6060

@@ -78,7 +78,7 @@ pub mod login;
7878
///
7979
/// # Responses
8080
///
81-
/// - **200 OK**: Returns a [ScanEvent](crate::db::models::ScanEvent) object containing the scan event.
81+
/// - **200 OK**: Returns a [`ScanEvent`](crate::db::models::ScanEvent) object containing the scan event.
8282
/// - **401 Unauthorized**: Returned if the request is not authenticated.
8383
/// - **404 Not Found**: Returned if the trigger does not exist.
8484
/// - **400 Bad Request**: Returned if the request is invalid.

src/service/manager.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ impl PulseManager {
133133
if let Some(mut sort) = sort {
134134
let mut direction = "desc";
135135

136-
if sort.starts_with("-") {
136+
if sort.starts_with('-') {
137137
direction = "asc";
138138
sort = sort[1..].to_string();
139139
}
@@ -168,12 +168,12 @@ impl PulseManager {
168168
}
169169

170170
if let Some(search) = search {
171-
query = query.filter(file_path.like(format!("%{}%", search)));
171+
query = query.filter(file_path.like(format!("%{search}%")));
172172
}
173173

174174
query
175175
.limit(limit.into())
176-
.offset(((page - 1) * (limit as u64)) as i64)
176+
.offset(((page - 1) * u64::from(limit)) as i64)
177177
.load::<ScanEvent>(&mut get_conn(&self.pool)?)
178178
.map_err(Into::into)
179179
}
@@ -238,7 +238,7 @@ impl PulseManager {
238238
service
239239
.watcher(tx)
240240
.await
241-
.context(format!("failed to start notify service '{}'", cloned_name))
241+
.context(format!("failed to start notify service '{cloned_name}'"))
242242
})
243243
.await;
244244

src/service/runner.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ impl PulseRunner {
168168

169169
let trigger_settings = &self.settings.triggers;
170170

171-
for (name, target) in self.settings.targets.iter() {
171+
for (name, target) in &self.settings.targets {
172172
let evs = evs
173173
.iter_mut()
174174
.filter(|x| !x.get_targets_hit().contains(name))
@@ -242,7 +242,7 @@ impl PulseRunner {
242242
Ok((succeeded, retrying, failed))
243243
}
244244

245-
async fn cleanup(&self) -> anyhow::Result<()> {
245+
fn cleanup(&self) -> anyhow::Result<()> {
246246
let time_before_cleanup = chrono::Utc::now().naive_utc()
247247
- chrono::Duration::days(self.settings.opts.cleanup_days as i64);
248248

@@ -290,7 +290,7 @@ impl PulseRunner {
290290

291291
self.update_found_status().await?;
292292
self.update_process_status().await?;
293-
self.cleanup().await?;
293+
self.cleanup()?;
294294

295295
Ok(())
296296
}

0 commit comments

Comments
 (0)