From 516b27d7ad60f8e2d01353a8f84c19b39c9173c3 Mon Sep 17 00:00:00 2001 From: trivernis Date: Mon, 7 Feb 2022 20:26:58 +0100 Subject: [PATCH] Add job to generate missing thumbnails on startup Signed-off-by: trivernis --- mediarepo-api/Cargo.toml | 2 +- mediarepo-api/src/client_api/job.rs | 16 ++++------ .../src/tauri_plugin/commands/job.rs | 4 +-- .../src/tauri_plugin/custom_schemes.rs | 4 +-- mediarepo-api/src/types/jobs.rs | 1 + mediarepo-daemon/Cargo.lock | 2 +- .../dao/job/generate_missing_thumbnails.rs | 30 +++++++++++++++++++ .../mediarepo-logic/src/dao/job/mod.rs | 1 + .../mediarepo-socket/src/namespaces/jobs.rs | 6 ++++ mediarepo-ui/src-tauri/Cargo.lock | 2 +- mediarepo-ui/src/api/api-types/job.ts | 3 +- mediarepo-ui/src/api/api-types/requests.ts | 1 + .../repositories-tab.component.ts | 4 ++- .../src/app/services/file/file.service.ts | 2 +- .../src/app/services/job/job.service.ts | 4 +-- 15 files changed, 59 insertions(+), 23 deletions(-) create mode 100644 mediarepo-daemon/mediarepo-logic/src/dao/job/generate_missing_thumbnails.rs diff --git a/mediarepo-api/Cargo.toml b/mediarepo-api/Cargo.toml index ce2ebd9..172fe84 100644 --- a/mediarepo-api/Cargo.toml +++ b/mediarepo-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mediarepo-api" -version = "0.29.0" +version = "0.30.0" edition = "2018" license = "gpl-3" diff --git a/mediarepo-api/src/client_api/job.rs b/mediarepo-api/src/client_api/job.rs index f338d42..cfbe8d1 100644 --- a/mediarepo-api/src/client_api/job.rs +++ b/mediarepo-api/src/client_api/job.rs @@ -26,17 +26,11 @@ impl JobApi { /// Runs a job of the given type and returns when it has finished #[tracing::instrument(level = "debug", skip(self))] - pub async fn run_job(&self, job_type: JobType) -> ApiResult<()> { - self.emit( - "run_job", - RunJobRequest { - job_type, - sync: true, - }, - ) - .await_reply() - .with_timeout(Duration::from_secs(3600)) - .await?; + pub async fn run_job(&self, job_type: JobType, sync: bool) -> ApiResult<()> { + self.emit("run_job", RunJobRequest { job_type, sync }) + .await_reply() + .with_timeout(Duration::from_secs(3600)) + .await?; Ok(()) } diff --git a/mediarepo-api/src/tauri_plugin/commands/job.rs b/mediarepo-api/src/tauri_plugin/commands/job.rs index 8866b8b..313e613 100644 --- a/mediarepo-api/src/tauri_plugin/commands/job.rs +++ b/mediarepo-api/src/tauri_plugin/commands/job.rs @@ -3,9 +3,9 @@ use crate::tauri_plugin::error::PluginResult; use crate::types::jobs::JobType; #[tauri::command] -pub async fn run_job(api_state: ApiAccess<'_>, job_type: JobType) -> PluginResult<()> { +pub async fn run_job(api_state: ApiAccess<'_>, job_type: JobType, sync: bool) -> PluginResult<()> { let api = api_state.api().await?; - api.job.run_job(job_type).await?; + api.job.run_job(job_type, sync).await?; Ok(()) } diff --git a/mediarepo-api/src/tauri_plugin/custom_schemes.rs b/mediarepo-api/src/tauri_plugin/custom_schemes.rs index 436b8f4..41e458d 100644 --- a/mediarepo-api/src/tauri_plugin/custom_schemes.rs +++ b/mediarepo-api/src/tauri_plugin/custom_schemes.rs @@ -122,8 +122,8 @@ async fn thumb_scheme(app: &AppHandle, request: &Request) -> Resu .file .get_thumbnail_of_size( FileIdentifier::CD(hash.to_string()), - ((height as f32 * 0.8) as u32, (width as f32 * 0.8) as u32), - ((height as f32 * 1.2) as u32, (width as f32 * 1.2) as u32), + ((height as f32 * 0.5) as u32, (width as f32 * 0.5) as u32), + ((height as f32 * 1.5) as u32, (width as f32 * 1.5) as u32), ) .await?; tracing::debug!("Received {} content bytes", bytes.len()); diff --git a/mediarepo-api/src/types/jobs.rs b/mediarepo-api/src/types/jobs.rs index e8b9d3b..6cbed1a 100644 --- a/mediarepo-api/src/types/jobs.rs +++ b/mediarepo-api/src/types/jobs.rs @@ -10,6 +10,7 @@ pub struct RunJobRequest { pub enum JobType { MigrateContentDescriptors, CalculateSizes, + GenerateThumbnails, CheckIntegrity, Vacuum, } diff --git a/mediarepo-daemon/Cargo.lock b/mediarepo-daemon/Cargo.lock index 58ccaee..019f586 100644 --- a/mediarepo-daemon/Cargo.lock +++ b/mediarepo-daemon/Cargo.lock @@ -1361,7 +1361,7 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" [[package]] name = "mediarepo-api" -version = "0.29.0" +version = "0.30.0" dependencies = [ "bromine", "chrono", diff --git a/mediarepo-daemon/mediarepo-logic/src/dao/job/generate_missing_thumbnails.rs b/mediarepo-daemon/mediarepo-logic/src/dao/job/generate_missing_thumbnails.rs new file mode 100644 index 0000000..edc84d9 --- /dev/null +++ b/mediarepo-daemon/mediarepo-logic/src/dao/job/generate_missing_thumbnails.rs @@ -0,0 +1,30 @@ +use crate::dao::job::JobDao; +use crate::dao::DaoProvider; +use mediarepo_core::error::RepoResult; +use mediarepo_core::futures; +use mediarepo_core::thumbnailer::ThumbnailSize; + +impl JobDao { + /// Generates thumbnails for files that are still missing some + #[tracing::instrument(level = "debug", skip(self))] + pub async fn generate_missing_thumbnails(&self) -> RepoResult<()> { + let file_dao = self.file(); + let files = file_dao.all().await?; + let mut missing_thumbnails = Vec::new(); + + for file in files { + if file_dao.thumbnails(file.encoded_cd()).await?.is_empty() { + missing_thumbnails.push(file); + } + } + + futures::future::join_all(missing_thumbnails.into_iter().map(|f| async { + file_dao + .create_thumbnails(f, vec![ThumbnailSize::Medium]) + .await + })) + .await; + + Ok(()) + } +} diff --git a/mediarepo-daemon/mediarepo-logic/src/dao/job/mod.rs b/mediarepo-daemon/mediarepo-logic/src/dao/job/mod.rs index 16bace3..31ab290 100644 --- a/mediarepo-daemon/mediarepo-logic/src/dao/job/mod.rs +++ b/mediarepo-daemon/mediarepo-logic/src/dao/job/mod.rs @@ -1,5 +1,6 @@ use crate::dao_provider; +pub mod generate_missing_thumbnails; pub mod migrate_content_descriptors; pub mod sqlite_operations; diff --git a/mediarepo-daemon/mediarepo-socket/src/namespaces/jobs.rs b/mediarepo-daemon/mediarepo-socket/src/namespaces/jobs.rs index 3a31cdf..c912b70 100644 --- a/mediarepo-daemon/mediarepo-socket/src/namespaces/jobs.rs +++ b/mediarepo-daemon/mediarepo-socket/src/namespaces/jobs.rs @@ -27,11 +27,17 @@ impl JobsNamespace { let run_request = event.payload::()?; let job_dao = get_repo_from_context(ctx).await.job(); + if !run_request.sync { + // early response to indicate that the job will be run + ctx.emit_to(Self::name(), "run_job", ()).await?; + } + match run_request.job_type { JobType::MigrateContentDescriptors => job_dao.migrate_content_descriptors().await?, JobType::CalculateSizes => calculate_all_sizes(ctx).await?, JobType::CheckIntegrity => job_dao.check_integrity().await?, JobType::Vacuum => job_dao.vacuum().await?, + JobType::GenerateThumbnails => job_dao.generate_missing_thumbnails().await?, } Ok(Response::empty()) diff --git a/mediarepo-ui/src-tauri/Cargo.lock b/mediarepo-ui/src-tauri/Cargo.lock index 1182d6f..7f08709 100644 --- a/mediarepo-ui/src-tauri/Cargo.lock +++ b/mediarepo-ui/src-tauri/Cargo.lock @@ -1500,7 +1500,7 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" [[package]] name = "mediarepo-api" -version = "0.29.0" +version = "0.30.0" dependencies = [ "async-trait", "bromine", diff --git a/mediarepo-ui/src/api/api-types/job.ts b/mediarepo-ui/src/api/api-types/job.ts index cda973f..8edff1d 100644 --- a/mediarepo-ui/src/api/api-types/job.ts +++ b/mediarepo-ui/src/api/api-types/job.ts @@ -1,4 +1,5 @@ export type JobType = "MigrateContentDescriptors" | "CalculateSizes" | "CheckIntegrity" - | "Vacuum"; + | "Vacuum" + | "GenerateThumbnails"; diff --git a/mediarepo-ui/src/api/api-types/requests.ts b/mediarepo-ui/src/api/api-types/requests.ts index f0bec62..2a813b6 100644 --- a/mediarepo-ui/src/api/api-types/requests.ts +++ b/mediarepo-ui/src/api/api-types/requests.ts @@ -107,6 +107,7 @@ export type SetFrontendStateRequest = { export type RunJobRequest = { jobType: JobType, + sync: boolean, }; export type AddSortingPresetRequest = { diff --git a/mediarepo-ui/src/app/components/core/repositories-tab/repositories-tab.component.ts b/mediarepo-ui/src/app/components/core/repositories-tab/repositories-tab.component.ts index ecb4843..e045c04 100644 --- a/mediarepo-ui/src/app/components/core/repositories-tab/repositories-tab.component.ts +++ b/mediarepo-ui/src/app/components/core/repositories-tab/repositories-tab.component.ts @@ -119,7 +119,9 @@ export class RepositoriesTabComponent implements OnInit, AfterViewInit { "Migrating content descriptors to new format..."); await this.jobService.runJob("MigrateContentDescriptors"); dialogContext.message.next("Calculating repository sizes..."); - await this.jobService.runJob("CalculateSizes"); + await this.jobService.runJob("CalculateSizes", false); + dialogContext.message.next("Generating missing thumbnails..."); + await this.jobService.runJob("GenerateThumbnails"); dialogContext.message.next("Finished repository startup"); } diff --git a/mediarepo-ui/src/app/services/file/file.service.ts b/mediarepo-ui/src/app/services/file/file.service.ts index ab783a9..512f534 100644 --- a/mediarepo-ui/src/app/services/file/file.service.ts +++ b/mediarepo-ui/src/app/services/file/file.service.ts @@ -78,7 +78,7 @@ export class FileService { */ public buildThumbnailUrl(file: File, height: number, width: number): SafeResourceUrl { return this.sanitizer.bypassSecurityTrustResourceUrl( - `thumb://${file.cd}?width=${250}&height=${250}`); + `thumb://${file.cd}?width=${height}&height=${width}`); } /** diff --git a/mediarepo-ui/src/app/services/job/job.service.ts b/mediarepo-ui/src/app/services/job/job.service.ts index 404fc08..44057c3 100644 --- a/mediarepo-ui/src/app/services/job/job.service.ts +++ b/mediarepo-ui/src/app/services/job/job.service.ts @@ -10,7 +10,7 @@ export class JobService { constructor() { } - public async runJob(jobType: JobType): Promise { - return MediarepoApi.runJob({ jobType }); + public async runJob(jobType: JobType, sync: boolean = true): Promise { + return MediarepoApi.runJob({ jobType, sync }); } }