diff --git a/.github/renovate.json b/.github/renovate.json new file mode 100644 index 0000000000..53fac39112 --- /dev/null +++ b/.github/renovate.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": ["config:base"], + "separateMultipleMajor": true, + "packageRules": [ + { + "extends": ["monorepo:yarn"], + "groupName": "NodeJS dependencies", + "schedule": ["every 2 weeks on Monday before 5am"], + "packagePatterns": ["*"] + }, + { + "managers": ["cargo"], + "groupName": "Rust dependencies", + "schedule": ["every 2 weeks on Monday before 5am"], + "packagePatterns": ["*"] + }, + { + "managers": ["poetry"], + "groupName": "Python dependencies", + "schedule": ["every 2 weeks on Monday before 5am"], + "packagePatterns": ["*"] + } + ] +} diff --git a/Cargo.lock b/Cargo.lock index 68775f6ef9..a01137553a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -159,19 +159,15 @@ checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" [[package]] name = "apalis" -version = "0.5.5" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3da210662fee6932c2d8b291c4b33a573b5eafe09e23c6bf01295285a7d86e03" +checksum = "299684539ebbd8689f2e273b3be49226c84bd1d33435a6b43c09ae1fe3b0575d" dependencies = [ "apalis-core", - "apalis-cron", - "apalis-redis", - "apalis-sql", "futures", "pin-project-lite", "serde", - "thiserror 1.0.69", - "tokio", + "thiserror 2.0.3", "tower", "tracing", "tracing-futures", @@ -179,26 +175,24 @@ dependencies = [ [[package]] name = "apalis-core" -version = "0.5.5" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91befa475b114da630f0781fc48a577932a54790adf0a47edac00d4f058282d9" +checksum = "d0e822826152ef9f344bc61833036f3603d3a4d1d9556e4220505b18e24dc5c2" dependencies = [ - "async-oneshot", "futures", "futures-timer", "pin-project-lite", "serde", - "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.3", "tower", "ulid", ] [[package]] name = "apalis-cron" -version = "0.5.5" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "344799ff16579e1ae362143682d7bc29527adfbb9f421913ec8d8629276f7386" +checksum = "ee4b2ae57b5d300312097be6d5b50eba2eaa2c0ba5f5eceec62c61748ce8b514" dependencies = [ "apalis-core", "async-stream", @@ -208,40 +202,6 @@ dependencies = [ "tower", ] -[[package]] -name = "apalis-redis" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a77c9038106f6fa16e66fac08bc0a04edaf50b48d5a4328a98806d3f2f52c06d" -dependencies = [ - "apalis-core", - "async-stream", - "async-trait", - "chrono", - "futures", - "log", - "redis", - "serde", - "tokio", -] - -[[package]] -name = "apalis-sql" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77f5a576d1d6df3de40ab8bf66bd33912718fc9c51d98f63cfb71f60996410bc" -dependencies = [ - "apalis-core", - "async-stream", - "futures", - "futures-lite", - "log", - "serde", - "serde_json", - "sqlx", - "tokio", -] - [[package]] name = "application-utils" version = "0.1.0" @@ -260,12 +220,6 @@ dependencies = [ "sea-orm", ] -[[package]] -name = "arc-swap" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" - [[package]] name = "argon2" version = "0.6.0-pre.1" @@ -452,15 +406,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "async-oneshot" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae47de2a02d543205f3f5457a90b6ecbc9494db70557bd29590ec8f1ddff5463" -dependencies = [ - "futures-micro", -] - [[package]] name = "async-stream" version = "0.3.6" @@ -859,6 +804,7 @@ version = "0.1.0" dependencies = [ "anyhow", "apalis", + "apalis-cron", "application-utils", "async-graphql", "async-graphql-axum", @@ -1374,20 +1320,6 @@ dependencies = [ "unreachable", ] -[[package]] -name = "combine" -version = "4.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" -dependencies = [ - "bytes", - "futures-core", - "memchr", - "pin-project-lite", - "tokio", - "tokio-util", -] - [[package]] name = "common-models" version = "0.1.0" @@ -1557,9 +1489,9 @@ dependencies = [ [[package]] name = "cron" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f8c3e73077b4b4a6ab1ea5047c37c57aee77657bc8ecd6f29b0af082d0b0c07" +checksum = "eee8b2b4516038bc0f1d3c9934bcb4a13dd316e04abbc63c96757a6d75978532" dependencies = [ "chrono", "nom", @@ -2591,19 +2523,6 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" -[[package]] -name = "futures-lite" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cef40d21ae2c515b51041df9ed313ed21e572df340ea58a922a0aefe7e8891a1" -dependencies = [ - "fastrand", - "futures-core", - "futures-io", - "parking", - "pin-project-lite", -] - [[package]] name = "futures-macro" version = "0.3.31" @@ -2615,15 +2534,6 @@ dependencies = [ "syn 2.0.90", ] -[[package]] -name = "futures-micro" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b460264b3593d68b16a7bc35f7bc226ddfebdf9a1c8db1ed95d5cc6b7168c826" -dependencies = [ - "pin-project-lite", -] - [[package]] name = "futures-sink" version = "0.3.31" @@ -2754,7 +2664,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2ebc8013b4426d5b81a4364c419a95ed0b404af2b82e2457de52d9348f0e474" dependencies = [ - "combine 3.8.1", + "combine", "thiserror 1.0.69", ] @@ -3422,6 +3332,7 @@ dependencies = [ "indexmap 2.7.0", "itertools 0.13.0", "media-models", + "nest_struct", "providers", "reqwest 0.12.9", "rust_decimal", @@ -3989,6 +3900,18 @@ dependencies = [ "tempfile", ] +[[package]] +name = "nest_struct" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee4a24a522d42071ff79dfbef2e0d78b05cf383d2e94a7020eefc5f58274e9d" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "new_debug_unreachable" version = "1.0.6" @@ -4841,29 +4764,6 @@ dependencies = [ "zerocopy 0.8.11", ] -[[package]] -name = "redis" -version = "0.25.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0d7a6955c7511f60f3ba9e86c6d02b3c3f144f8c24b288d1f4e18074ab8bbec" -dependencies = [ - "arc-swap", - "async-trait", - "bytes", - "combine 4.6.7", - "futures", - "futures-util", - "itoa", - "percent-encoding", - "pin-project-lite", - "ryu", - "sha1_smol", - "tokio", - "tokio-retry", - "tokio-util", - "url", -] - [[package]] name = "redox_syscall" version = "0.5.7" @@ -4984,7 +4884,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots 0.25.4", + "webpki-roots", "winreg", ] @@ -5231,7 +5131,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1" dependencies = [ "once_cell", - "ring", "rustls-pki-types", "rustls-webpki 0.102.8", "subtle", @@ -5856,12 +5755,6 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "sha1_smol" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" - [[package]] name = "sha2" version = "0.10.8" @@ -6075,8 +5968,6 @@ dependencies = [ "paste", "percent-encoding", "rust_decimal", - "rustls 0.23.19", - "rustls-pemfile 2.2.0", "serde", "serde_json", "sha2", @@ -6088,7 +5979,6 @@ dependencies = [ "tracing", "url", "uuid", - "webpki-roots 0.26.7", ] [[package]] @@ -6710,17 +6600,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-retry" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f57eb36ecbe0fc510036adff84824dd3c24bb781e21bfa67b69d556aa85214f" -dependencies = [ - "pin-project", - "rand 0.8.5", - "tokio", -] - [[package]] name = "tokio-rustls" version = "0.24.1" @@ -7375,15 +7254,6 @@ version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" -[[package]] -name = "webpki-roots" -version = "0.26.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e" -dependencies = [ - "rustls-pki-types", -] - [[package]] name = "whoami" version = "1.5.2" diff --git a/Cargo.toml b/Cargo.toml index 1d1f086bb4..6a3c6ec945 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,7 +49,8 @@ resolver = "2" [workspace.dependencies] askama = "0.12.1" anyhow = "=1.0.93" -apalis = { version = "=0.5.5", features = ["cron", "limit"] } +apalis = { version = "=0.6.2", features = ["limit"] } +apalis-cron = "=0.6.2" argon2 = "=0.6.0-pre.1" async-graphql = { version = "=7.0.11", features = [ "chrono", @@ -98,6 +99,7 @@ logs-wheel = "=0.3.1" markdown = "=1.0.0-alpha.21" mime_guess = "=2.0.5" nanoid = "=0.4.0" +nest_struct = "=0.5.2" openidconnect = "=3.5.0" paginate = "=1.1.11" radarr-api-rs = "=3.0.1" @@ -146,7 +148,7 @@ struson = { version = "=0.6.0", features = ["serde"] } reqwest = { version = "=0.12.9", features = ["json", "stream"] } tokio = { version = "=1.41.1", features = ["full"] } tokio-util = { version = "=0.7.12", features = ["codec"] } -tower = { version = "=0.5.1", features = ["buffer"] } +tower = "=0.5.1" tower-http = { version = "=0.6.2", features = ["catch-panic", "cors", "trace"] } tracing = { version = "=0.1.41", features = ["attributes"] } tracing-subscriber = "=0.3.19" diff --git a/apps/backend/Cargo.toml b/apps/backend/Cargo.toml index e83be9b007..c7b0d42357 100644 --- a/apps/backend/Cargo.toml +++ b/apps/backend/Cargo.toml @@ -8,6 +8,7 @@ license = "GPL-3.0" [dependencies] anyhow = { workspace = true } apalis = { workspace = true } +apalis-cron = { workspace = true } application-utils = { path = "../../crates/utils/application" } async-graphql = { workspace = true } async-graphql-axum = { workspace = true } diff --git a/apps/backend/src/main.rs b/apps/backend/src/main.rs index 2802d2c735..dc86f45729 100644 --- a/apps/backend/src/main.rs +++ b/apps/backend/src/main.rs @@ -9,13 +9,10 @@ use std::{ use anyhow::{bail, Result}; use apalis::{ - cron::{CronStream, Schedule}, - layers::{ - limit::RateLimitLayer as ApalisRateLimitLayer, tracing::TraceLayer as ApalisTraceLayer, - }, + layers::{limit::RateLimitLayer as ApalisRateLimitLayer, WorkerBuilderExt}, prelude::{MemoryStorage, MessageQueue, Monitor, WorkerBuilder, WorkerFactoryFn}, - utils::TokioExecutor, }; +use apalis_cron::{CronStream, Schedule}; use aws_sdk_s3::config::Region; use background::ApplicationJob; use common_utils::{ryot_log, PROJECT_NAME, TEMP_DIR}; @@ -30,7 +27,6 @@ use tokio::{ net::TcpListener, time::{sleep, Duration as TokioDuration}, }; -use tower::buffer::BufferLayer; use tracing_subscriber::{fmt, layer::SubscriberExt}; use crate::{ @@ -119,13 +115,14 @@ async fn main() -> Result<()> { .unwrap_or_else(|_| chrono_tz::Etc::GMT); ryot_log!(info, "Timezone: {}", tz); - join_all( - [ - ApplicationJob::SyncIntegrationsData, - ApplicationJob::UpdateExerciseLibrary, - ] - .map(|j| perform_application_job_storage.enqueue(j)), - ) + join_all([ + perform_application_job_storage + .clone() + .enqueue(ApplicationJob::SyncIntegrationsData), + perform_application_job_storage + .clone() + .enqueue(ApplicationJob::UpdateExerciseLibrary), + ]) .await; let app_services = create_app_services( @@ -190,63 +187,51 @@ async fn main() -> Result<()> { let miscellaneous_service_2 = app_services.miscellaneous_service.clone(); let miscellaneous_service_3 = app_services.miscellaneous_service.clone(); - let monitor = Monitor::::new() - .register_with_count( - 1, + let monitor = Monitor::new() + .register( WorkerBuilder::new("daily_background_jobs") - .stream( + .enable_tracing() + .data(miscellaneous_service_1.clone()) + .backend( // every day - CronStream::new_with_timezone(Schedule::from_str("0 0 0 * * *").unwrap(), tz) - .into_stream(), + CronStream::new_with_timezone(Schedule::from_str("0 0 0 * * *").unwrap(), tz), ) - .layer(ApalisTraceLayer::new()) - .data(miscellaneous_service_1.clone()) .build_fn(run_background_jobs), ) - .register_with_count( - 1, + .register( WorkerBuilder::new("frequent_jobs") - .stream( - CronStream::new_with_timezone( - Schedule::from_str(&format!("0 */{} * * * *", sync_every_minutes)).unwrap(), - tz, - ) - .into_stream(), - ) - .layer(ApalisTraceLayer::new()) + .enable_tracing() .data(integration_service_1.clone()) .data(fitness_service_2.clone()) + .backend(CronStream::new_with_timezone( + Schedule::from_str(&format!("0 */{} * * * *", sync_every_minutes)).unwrap(), + tz, + )) .build_fn(run_frequent_jobs), ) // application jobs - .register_with_count( - 1, + .register( WorkerBuilder::new("perform_core_application_job") - .layer(ApalisTraceLayer::new()) + .enable_tracing() .data(integration_service_2.clone()) .data(miscellaneous_service_3.clone()) - .source(perform_core_application_job_storage) + .backend(perform_core_application_job_storage) .build_fn(perform_core_application_job), ) - .register_with_count( - 3, + .register( WorkerBuilder::new("perform_application_job") + .enable_tracing() .data(fitness_service_1.clone()) .data(exporter_service_1.clone()) .data(importer_service_1.clone()) .data(statistics_service_1.clone()) .data(integration_service_3.clone()) .data(miscellaneous_service_2.clone()) - .source(perform_application_job_storage) - // DEV: Had to do this fuckery because of https://github.com/geofmureithi/apalis/issues/297 - .chain(|s| { - s.layer(BufferLayer::new(1024)) - .layer(ApalisRateLimitLayer::new( - rate_limit_count, - Duration::new(5, 0), - )) - .layer(ApalisTraceLayer::new()) - }) + .layer(ApalisRateLimitLayer::new( + rate_limit_count, + Duration::new(5, 0), + )) + .backend(perform_application_job_storage) .build_fn(perform_application_job), ) .run(); diff --git a/apps/frontend/app/lib/state/fitness.ts b/apps/frontend/app/lib/state/fitness.ts index 54b7f91889..ca41587805 100644 --- a/apps/frontend/app/lib/state/fitness.ts +++ b/apps/frontend/app/lib/state/fitness.ts @@ -108,15 +108,15 @@ export const useGetSetAtIndex = (exerciseIdx: number, setIdx: number) => { export const getDefaultWorkout = ( fitnessEntity: FitnessAction, ): InProgressWorkout => { - const date = new Date(); + const date = dayjsLib().add(7, "second"); return { images: [], videos: [], supersets: [], exercises: [], - currentActionOrCompleted: fitnessEntity, startTime: date.toISOString(), - name: `${getTimeOfDay(date.getHours())} Workout`, + currentActionOrCompleted: fitnessEntity, + name: `${getTimeOfDay(date.hour())} Workout`, }; }; diff --git a/apps/frontend/app/routes/_dashboard.settings.imports-and-exports._index.tsx b/apps/frontend/app/routes/_dashboard.settings.imports-and-exports._index.tsx index 712b6c6ac8..a007c8740c 100644 --- a/apps/frontend/app/routes/_dashboard.settings.imports-and-exports._index.tsx +++ b/apps/frontend/app/routes/_dashboard.settings.imports-and-exports._index.tsx @@ -110,7 +110,7 @@ export const action = async ({ request }: ActionFunctionArgs) => { .with(ImportSource.Myanimelist, async () => ({ mal: processSubmission(formData, malImportFormSchema), })) - .with(ImportSource.GenericJson, async () => ({ + .with(ImportSource.GenericJson, ImportSource.Anilist, async () => ({ genericJson: processSubmission(formData, jsonImportFormSchema), })) .with(ImportSource.Jellyfin, async () => ({ @@ -376,16 +376,20 @@ export default function Page() { /> )) - .with(ImportSource.GenericJson, () => ( - <> - - - )) + .with( + ImportSource.Anilist, + ImportSource.GenericJson, + () => ( + <> + + + ), + ) .exhaustive()}