Skip to content

Commit

Permalink
Merge pull request #1118 from IgnisDa/issue-1113
Browse files Browse the repository at this point in the history
* feat(migrations): create new columns for daily user activities

* chore(migrations): remove newlines

* feat(backend): store data in new dua columns

* chore(backend): change data type of muscles stored in db

* chore: make start time less than end time

* chore: make start date less than end date

* chore(backend): common input struct for date range

* chore(backend): add comment to input struct

* chore(frontend): adapt to new gql schema

* chore(utils): add debug logs for user activity calculation

* feat(models): add new struct to return response for analytics

* build(models/dependent): add new deps

* build(backend): add new required deps

* feat(backend): add new query for getting fitness analytics

* feat(backend): add query fragment for fitness analytics

* build(services/statistics): add new deps to crate

* feat(services/statistics): calculate hour counts

* feat(backend): complete implementation of fitness statistics

* feat(backend): compute additional fields

* feat(migrations): add new column to store value

* feat(backend): allow saving value in application cache

* feat(backend): cache fitness analytics for 2 hours

* feat(frontend): add basic fitness analytics page

* fix(frontend): pass correct schema to parser

* feat(backend): add new preference for fitness analytics

* feat(frontend): add fitness analytics to sidebar

* feat(frontend): design basic webpage

* feat(frontend): do most calculations on the server loader

* feat(frontend): get fallback search params

* feat(frontend): allow specifying custom time ranges

* feat(frontend): fetch data for fitness analytics

* chore(services/cache): log when cache key found

* Revert "chore(services/cache): log when cache key found"

This reverts commit ca8e59d.

* feat(frontend): display basic pie chart

* refactor(frontend): extract component to display chart container

* feat(frontend): allow changing how many muscles to display

* feat(frontend): save count of muscles shown in local storage

* feat(frontend): also allow setting analytics timespan to "All Time"

* chore(docs): remove fragment from link

* feat(frontend): add bar chart for exercises done

* chore(frontend): minor enhancements to chart

* feat(frontend): handle cases when no analytics present

* feat(backend): save igdb settings in application cache

* feat(backend): save listennotes settings in application cache

* perf(backend): remove extra parameter

* refactor(backend): change function name

* perf(backend): do not make a useless clone

* feat(backend): save tmdb settings in application cache

* fix(providers): cache tmdb settings in the database

* chore(migrations): make column non nullable

* chore(backend): adapt to new database schema

* refactor(backend): change function names

* chore(frontend): minor changes to graphs

* chore(gql): fix formatting of query

* feat(frontend): use better colors for graphs

* fix(frontend): remove text align from page heading

* chore(frontend): select entire text when focusing on input

* chore(frontend): change how props are structured

* feat(frontend): function to convert utc hour to local hour

* feat(frontend): start section to display time of day

* fix(utils/database): calculate hour correctly

* feat(frontend): generate correct data for time of day chart

* fix(frontend): generate correct arrays

* feat(frontend): display bubble chart for time of day

* chore(frontend): better types of stuff

* docs: better wording for authentication caveat

* feat(backend): setting to exclude exercise from analytics

* feat(utils/database): respect new exercise setting

* fix(services/fitness): handle edge case for updating exercise settings

* feat(frontend): allow excluding exercise from analytics

* feat(frontend): display the active episode for shows and podcasts

* feat(frontend): remove scroll margin when it is no longer first exercise

* fix(providers): do not unwrap directly

* perf(services/fitness): do not cast json to text when filtering on muscles

* chore(enums): some other changes

* feat(migrations): new columns for daily_user_activity

* feat(migrations): drop entire table and recreate it

* feat(backend): adjust daily user activity calculation to new database schema

* fix(services/statistics): adjust daily user activity calculation to new database schema

* fix(services/statistics): change fallback to include in same millenium

* chore(backend): make the expiry of application cache nullable

* chore(backend): change names of jobs

* feat: more resilient logic for validating pro keys

* chore(backend): general changes

* perf(utils/dependent): only get key if cache is being respect

* chore(migrations): add fixme comment

* feat: change "re-evaluate" to "revise"

* fix(frontend): change btn text

* feat(backend): allow scheduling user for workout revision

* chore(utils/database): add log after scheduling

* feat(backend): deploy all changes at once

* feat(backend): implement scheduled workout revision

* chore(services/fitness): add log statement

* build(ts): update nodejs deps

* perf(utils/database): preselect all exercises

* fix(frontend): send old event attribute

* docs: move instructions around

* docs: change orders of headings

* docs: change word of release section

* refactor(models/common): order of enum elements

* feat(models/common): add key for metadata recently consumed

* feat(utils/dependent): mark metadata as recently consumed when marking progress

* feat(backend): return whether media is recently consumed

* feat(frontend): highlight media which are currently in progress

* chore(frontend): change some colors

* chore(frontend): sort prop ordering

* fix(frontend): make box-shadow smaller

* refactor(backend): functions to mark and get entity recently consumed

* feat(backend): get whether person and metadata group were recently consumed

* feat(backend): mark metadata as recently consumed

* feat(frontend): display when entity interacted with

* chore(migrations): schedule all users for workout revision

* fix(utils/dependent): use Epley formula for one rm calculation below 10 reps

* fix(migrations): insert correct cache value into database

* fix(migrations): run query only when there are more than 0 users

* chore(services/fitness): add log for each user whose workouts are being revised

* fix(utils/dependent): use Epley for reps higher than 10

* refactor(utils/dependent): use filter instead of mutable variable

* ci: Run CI

* fix(services/misc): do not get recommendations for custom metadata

* chore(backend): lift up analytics

* chore(frontend): adapt to new gql schema

* feat(backend): return entire analytics from single endpoint

* Revert "feat(backend): return entire analytics from single endpoint"

This reverts commit f20a4de.

* feat(frontend): respect features enabled when displaying fitness charts

* chore(frontend): run formatter

* feat(frontend): allow starting media from outside

* refactor(frontend): remove duplicated code

* feat(frontend): load analytics page on client side

* fix(frontend): do not display counter if not allowed

* feat(frontend): change the time of day graph

* feat(frontend): display time ranges for analytics page

* build(frontend): add screenshot deps

* feat(frontend): button to download the analytics page as png

* fix(frontend): add background color to container to fix screenshots

* feat(frontend): move to using new grid container

* feat(frontend): do not display border if not applicable

* feat(backend): remove the activity section

* feat(frontend): move activity graph to analytics section

* feat(frontend): adjust activity section to be more in sync with other graphs

* feat(frontend): use radar chart for time of day

* feat(frontend): display workout counts

* fix(frontend): time of day

* Revert "Revert "feat(backend): return entire analytics from single endpoint""

This reverts commit 001debc.

* feat(backend): return user analytics correctly

* feat(frontend): display all entity types in scatter chart

* ci: Run CI

* feat(frontend): display polar radius axis

* chore(frontend): always display chart

* Revert "chore(frontend): always display chart"

This reverts commit d80fc94.

* feat(frontend): filter out hours which do not have anything associated

* chore(frontend): sort attributes by length

* feat(backend): start making identifier the primary column

* feat(backend): allow naming exercises similarly

* feat(migrations): change names of indices

* feat(frontend): start adapting to new graphql schema

* chore(frontend): adapt to new gql schema

* ci: Run CI

* fix(frontend): cleanup remaining stuff

* fix(backend): do not schedule user for workout revision if exercise name changed

* feat(backend): change `name` key of workouts to `id`

* feat(frontend): adapt to new gql schema

* fix(services/importer): send correct details to the importer

* refactor(backend): extract common fn to generate exercise id

* fix(services/importer): select correct attribute of exercise

* fix(services/importer): select correct attribute of exercise

* chore(services/importer): import set lot for strong app

* feat(backend): send user measurements

* fix(migrations): collapse two queries into one

* feat(frontend): do not change case a lot

* fix(frontend): render filter only on the frontend

* ci: Run CI

* refactor(backend): do not create new services for integrations

* fix(frontend): remove curly braces

* ci: Run CI

* build(backend): change dependency tree

* build(backend): change dependency tree

* refactor(backend): move models around

* refactor(models/common): move structs around

* feat(backend): get rid of latest user summary query

* feat(frontend): adapt to new graphql schema

* refactor(backend): collapse two queries into one

* feat(frontend): adapt to new gql schema

* feat(backend): add query to get user analytics parameters

* fix(services/statistics): apply null ordering

* build(backend): change dependency tree

* refactor(services/statistics): call function serially

* feat(frontend): use new loader query

* feat(frontend): capture screen after 1.5 seconds

* perf(backend): save user's analytics parameters

* ci: Run CI

* perf(models): do not serialize none values

* fix(frontend): better wording

* chore(frontend): remove useless zod usage

* chore(services/importer): add some more logs in plex importer

* refactor(backend): sync data to owned collection separately

* feat(backend): migrate for existing plex sink integrations

* fix(services/user): respect sync to owned collection in input

* feat(frontend): adapt to new gql schema

* fix(frontend): do not make input required

* docs: add info about ryot yank integration

* feat(backend): allow syncing to owned collection from plex

* ci: Run CI

* docs: improve documentation

* feat(backend): return only the id for workouts and workout templates list queries

* fix(services/fitness): specify column of correct model

* feat(frontend): adapt to new gql schema

* feat(frontend): add skeleton loader for fitness entity

* feat(frontend): make loader more presentable

* refactor(frontend): some minor changes

* fix(frontend): handle cases when no daily user activities are present

* feat(backend): do not use application cache for user workout revision

* feat(backend): return some other data

* feat(frontend): display fitness statistics

* feat(frontend): display distance travelled

* feat(backend): return total rest time

* fix(utils/database): store rest time in correct unit

* feat(frontend): display rest time

* ci: Run CI

* refactor(frontend): create correct props

* feat(frontend): make the text dim

* feat(ts-utils): add function to format numbers

* feat(frontend): format workout reps number with compact notation

* fix(frontend): better position for workout btn

* feat(frontend): display watermark in captured screenshot

* feat(frontend): hide counter in captured screenshot

* fix(frontend): additional padding for statistics card

* fix(frontend): additional padding for statistics card

* feat(frontend): add pro validation for saving image

* refactor(frontend): change it to an enum

* refactor(frontend): change watch times to enum

* feat(frontend): hide analytics graph for non pro users

* ci: Run CI
  • Loading branch information
IgnisDa authored Dec 11, 2024
2 parents c1a65d6 + c097c4a commit 97936a0
Show file tree
Hide file tree
Showing 117 changed files with 4,873 additions and 3,184 deletions.
31 changes: 18 additions & 13 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 2 additions & 5 deletions apps/backend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,11 @@ axum = { workspace = true }
aws-sdk-s3 = { workspace = true }
background = { path = "../../crates/background" }
cache-service = { path = "../../crates/services/cache" }
chrono = { workspace = true }
chrono-tz = { workspace = true }
collection-resolver = { path = "../../crates/resolvers/collection" }
collection-service = { path = "../../crates/services/collection" }
common-utils = { path = "../../crates/utils/common" }
config = { path = "../../crates/config" }
database-models = { path = "../../crates/models/database" }
dependent-models = { path = "../../crates/models/dependent" }
dotenvy = { workspace = true }
env-utils = { path = "../../crates/utils/env" }
Expand All @@ -31,6 +29,7 @@ file-storage-resolver = { path = "../../crates/resolvers/file-storage" }
file-storage-service = { path = "../../crates/services/file-storage" }
fitness-resolver = { path = "../../crates/resolvers/fitness" }
fitness-service = { path = "../../crates/services/fitness" }
futures = { workspace = true }
http = { workspace = true }
importer-resolver = { path = "../../crates/resolvers/importer" }
importer-service = { path = "../../crates/services/importer" }
Expand All @@ -46,9 +45,7 @@ reqwest = { workspace = true }
router-resolver = { path = "../../crates/resolvers/router" }
sea-orm = { workspace = true }
sea-orm-migration = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
serde_with = { workspace = true }
schematic = { workspace = true }
statistics-resolver = { path = "../../crates/resolvers/statistics" }
statistics-service = { path = "../../crates/services/statistics" }
Expand All @@ -58,6 +55,6 @@ tower = { workspace = true }
tower-http = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true }
unkey = { workspace = true }
traits = { path = "../../crates/traits" }
user-resolver = { path = "../../crates/resolvers/user" }
user-service = { path = "../../crates/services/user" }
18 changes: 8 additions & 10 deletions apps/backend/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ use exporter_resolver::{ExporterMutation, ExporterQuery};
use exporter_service::ExporterService;
use file_storage_resolver::{FileStorageMutation, FileStorageQuery};
use file_storage_service::FileStorageService;
use fitness_resolver::{ExerciseMutation, ExerciseQuery};
use fitness_service::ExerciseService;
use fitness_resolver::{FitnessMutation, FitnessQuery};
use fitness_service::FitnessService;
use importer_resolver::{ImporterMutation, ImporterQuery};
use importer_service::ImporterService;
use integration_service::IntegrationService;
Expand Down Expand Up @@ -49,15 +49,14 @@ pub struct AppServices {
pub app_router: Router,
pub importer_service: Arc<ImporterService>,
pub exporter_service: Arc<ExporterService>,
pub exercise_service: Arc<ExerciseService>,
pub fitness_service: Arc<FitnessService>,
pub statistics_service: Arc<StatisticsService>,
pub integration_service: Arc<IntegrationService>,
pub miscellaneous_service: Arc<MiscellaneousService>,
}

#[allow(clippy::too_many_arguments)]
pub async fn create_app_services(
is_pro: bool,
db: DatabaseConnection,
timezone: chrono_tz::Tz,
s3_client: aws_sdk_s3::Client,
Expand All @@ -73,7 +72,6 @@ pub async fn create_app_services(
let cache_service = CacheService::new(&db);
let supporting_service = Arc::new(
SupportingService::new(
is_pro,
&db,
timezone,
cache_service,
Expand All @@ -87,7 +85,7 @@ pub async fn create_app_services(
);
let user_service = Arc::new(UserService(supporting_service.clone()));
let importer_service = Arc::new(ImporterService(supporting_service.clone()));
let exercise_service = Arc::new(ExerciseService(supporting_service.clone()));
let fitness_service = Arc::new(FitnessService(supporting_service.clone()));
let exporter_service = Arc::new(ExporterService(supporting_service.clone()));
let collection_service = Arc::new(CollectionService(supporting_service.clone()));
let statistics_service = Arc::new(StatisticsService(supporting_service.clone()));
Expand All @@ -104,7 +102,7 @@ pub async fn create_app_services(
.data(user_service.clone())
.data(importer_service.clone())
.data(exporter_service.clone())
.data(exercise_service.clone())
.data(fitness_service.clone())
.data(statistics_service.clone())
.data(collection_service.clone())
.data(file_storage_service.clone())
Expand Down Expand Up @@ -149,7 +147,7 @@ pub async fn create_app_services(
app_router,
importer_service,
exporter_service,
exercise_service,
fitness_service,
statistics_service,
integration_service,
miscellaneous_service,
Expand Down Expand Up @@ -192,7 +190,7 @@ pub struct QueryRoot(
MiscellaneousQuery,
ImporterQuery,
ExporterQuery,
ExerciseQuery,
FitnessQuery,
FileStorageQuery,
StatisticsQuery,
CollectionQuery,
Expand All @@ -204,7 +202,7 @@ pub struct MutationRoot(
MiscellaneousMutation,
ImporterMutation,
ExporterMutation,
ExerciseMutation,
FitnessMutation,
FileStorageMutation,
CollectionMutation,
UserMutation,
Expand Down
49 changes: 36 additions & 13 deletions apps/backend/src/job.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,41 @@ use apalis::prelude::*;
use background::{ApplicationJob, CoreApplicationJob, ScheduledJob};
use common_utils::ryot_log;
use exporter_service::ExporterService;
use fitness_service::ExerciseService;
use fitness_service::FitnessService;
use importer_service::ImporterService;
use integration_service::IntegrationService;
use media_models::CommitMediaInput;
use miscellaneous_service::MiscellaneousService;
use statistics_service::StatisticsService;
use traits::TraceOk;

pub async fn background_jobs(
pub async fn run_background_jobs(
information: ScheduledJob,
misc_service: Data<Arc<MiscellaneousService>>,
) -> Result<(), Error> {
ryot_log!(debug, "Running job at {:#?}", information.0);
misc_service.perform_background_jobs().await.unwrap();
misc_service.perform_background_jobs().await.trace_ok();
Ok(())
}

pub async fn sync_integrations_data(
pub async fn run_frequent_jobs(
_information: ScheduledJob,
fitness_service: Data<Arc<FitnessService>>,
misc_service: Data<Arc<MiscellaneousService>>,
integration_service: Data<Arc<IntegrationService>>,
) -> Result<(), Error> {
integration_service.yank_integrations_data().await.unwrap();
misc_service
.perform_server_key_validation()
.await
.trace_ok();
integration_service
.yank_integrations_data()
.await
.trace_ok();
fitness_service
.process_users_scheduled_for_workout_revision()
.await
.trace_ok();
Ok(())
}

Expand Down Expand Up @@ -67,7 +81,7 @@ pub async fn perform_application_job(
integration_service: Data<Arc<IntegrationService>>,
importer_service: Data<Arc<ImporterService>>,
exporter_service: Data<Arc<ExporterService>>,
exercise_service: Data<Arc<ExerciseService>>,
fitness_service: Data<Arc<FitnessService>>,
statistics_service: Data<Arc<StatisticsService>>,
) -> Result<(), Error> {
let name = information.to_string();
Expand All @@ -84,10 +98,9 @@ pub async fn perform_application_job(
.await
.is_ok()
}
ApplicationJob::ReEvaluateUserWorkouts(user_id) => exercise_service
.re_evaluate_user_workouts(user_id)
.await
.is_ok(),
ApplicationJob::ReviseUserWorkouts(user_id) => {
fitness_service.revise_user_workouts(user_id).await.is_ok()
}
ApplicationJob::UpdateMetadata(metadata_id, force_update) => misc_service
.update_metadata_and_notify_users(&metadata_id, force_update)
.await
Expand All @@ -104,7 +117,7 @@ pub async fn perform_application_job(
.update_metadata_group(&metadata_group_id)
.await
.is_ok(),
ApplicationJob::UpdateGithubExerciseJob(exercise) => exercise_service
ApplicationJob::UpdateGithubExerciseJob(exercise) => fitness_service
.update_github_exercise(exercise)
.await
.is_ok(),
Expand All @@ -126,12 +139,22 @@ pub async fn perform_application_job(
ApplicationJob::PerformExport(user_id) => {
exporter_service.perform_export(user_id).await.is_ok()
}
ApplicationJob::UpdateExerciseLibrary => exercise_service
ApplicationJob::UpdateExerciseLibrary => fitness_service
.deploy_update_exercise_library_job()
.await
.is_ok(),
ApplicationJob::SyncIntegrationsData => {
integration_service.yank_integrations_data().await.is_ok()
integration_service
.yank_integrations_data()
.await
.trace_ok();
integration_service
.sync_integrations_data_to_owned_collection()
.await
.is_ok()
}
ApplicationJob::PerformServerKeyValidation => {
misc_service.perform_server_key_validation().await.is_ok()
}
ApplicationJob::HandleEntityAddedToCollectionEvent(collection_to_entity_id) => {
integration_service
Expand Down
Loading

0 comments on commit 97936a0

Please sign in to comment.