Add job to generate missing thumbnails on startup

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/14/head
trivernis 2 years ago
parent 2dbd266f4f
commit 516b27d7ad
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

@ -1,6 +1,6 @@
[package]
name = "mediarepo-api"
version = "0.29.0"
version = "0.30.0"
edition = "2018"
license = "gpl-3"

@ -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(())
}

@ -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(())
}

@ -122,8 +122,8 @@ async fn thumb_scheme<R: Runtime>(app: &AppHandle<R>, 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());

@ -10,6 +10,7 @@ pub struct RunJobRequest {
pub enum JobType {
MigrateContentDescriptors,
CalculateSizes,
GenerateThumbnails,
CheckIntegrity,
Vacuum,
}

@ -1361,7 +1361,7 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
[[package]]
name = "mediarepo-api"
version = "0.29.0"
version = "0.30.0"
dependencies = [
"bromine",
"chrono",

@ -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(())
}
}

@ -1,5 +1,6 @@
use crate::dao_provider;
pub mod generate_missing_thumbnails;
pub mod migrate_content_descriptors;
pub mod sqlite_operations;

@ -27,11 +27,17 @@ impl JobsNamespace {
let run_request = event.payload::<RunJobRequest>()?;
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())

@ -1500,7 +1500,7 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
[[package]]
name = "mediarepo-api"
version = "0.29.0"
version = "0.30.0"
dependencies = [
"async-trait",
"bromine",

@ -1,4 +1,5 @@
export type JobType = "MigrateContentDescriptors"
| "CalculateSizes"
| "CheckIntegrity"
| "Vacuum";
| "Vacuum"
| "GenerateThumbnails";

@ -107,6 +107,7 @@ export type SetFrontendStateRequest = {
export type RunJobRequest = {
jobType: JobType,
sync: boolean,
};
export type AddSortingPresetRequest = {

@ -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");
}

@ -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}`);
}
/**

@ -10,7 +10,7 @@ export class JobService {
constructor() {
}
public async runJob(jobType: JobType): Promise<void> {
return MediarepoApi.runJob({ jobType });
public async runJob(jobType: JobType, sync: boolean = true): Promise<void> {
return MediarepoApi.runJob({ jobType, sync });
}
}

Loading…
Cancel
Save