mirror of
https://github.com/xuthus83/pigallery2.git
synced 2024-11-03 21:04:03 +08:00
parent
c06620a795
commit
849ebbec9e
@ -1,23 +1,23 @@
|
|||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import { NextFunction, Request, Response } from 'express';
|
import {NextFunction, Request, Response} from 'express';
|
||||||
import { ErrorCodes, ErrorDTO } from '../../../common/entities/Error';
|
import {ErrorCodes, ErrorDTO} from '../../../common/entities/Error';
|
||||||
import { ContentWrapper } from '../../../common/entities/ConentWrapper';
|
import {ContentWrapper} from '../../../common/entities/ConentWrapper';
|
||||||
import {
|
import {
|
||||||
ParentDirectoryDTO,
|
ParentDirectoryDTO,
|
||||||
SubDirectoryDTO,
|
SubDirectoryDTO,
|
||||||
} from '../../../common/entities/DirectoryDTO';
|
} from '../../../common/entities/DirectoryDTO';
|
||||||
import { ProjectPath } from '../../ProjectPath';
|
import {ProjectPath} from '../../ProjectPath';
|
||||||
import { Config } from '../../../common/config/private/Config';
|
import {Config} from '../../../common/config/private/Config';
|
||||||
import { ThumbnailSourceType } from '../../model/threading/PhotoWorker';
|
import {ThumbnailSourceType} from '../../model/threading/PhotoWorker';
|
||||||
import { MediaDTO } from '../../../common/entities/MediaDTO';
|
import {MediaDTO} from '../../../common/entities/MediaDTO';
|
||||||
import { PhotoProcessing } from '../../model/fileprocessing/PhotoProcessing';
|
import {PhotoProcessing} from '../../model/fileprocessing/PhotoProcessing';
|
||||||
import { PersonWithSampleRegion } from '../../../common/entities/PersonDTO';
|
import {PersonWithSampleRegion} from '../../../common/entities/PersonDTO';
|
||||||
import { ServerTime } from '../ServerTimingMWs';
|
import {ServerTime} from '../ServerTimingMWs';
|
||||||
|
|
||||||
export class ThumbnailGeneratorMWs {
|
export class ThumbnailGeneratorMWs {
|
||||||
private static ThumbnailMap: { [key: number]: number } =
|
private static ThumbnailMapEntries =
|
||||||
Config.Client.Media.Thumbnail.generateThumbnailMap();
|
Config.Client.Media.Thumbnail.generateThumbnailMapEntries();
|
||||||
|
|
||||||
@ServerTime('2.th', 'Thumbnail decoration')
|
@ServerTime('2.th', 'Thumbnail decoration')
|
||||||
public static async addThumbnailInformation(
|
public static async addThumbnailInformation(
|
||||||
@ -34,6 +34,10 @@ export class ThumbnailGeneratorMWs {
|
|||||||
if (cw.notModified === true) {
|
if (cw.notModified === true) {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// regenerate in case the list change since startup
|
||||||
|
ThumbnailGeneratorMWs.ThumbnailMapEntries =
|
||||||
|
Config.Client.Media.Thumbnail.generateThumbnailMapEntries();
|
||||||
if (cw.directory) {
|
if (cw.directory) {
|
||||||
ThumbnailGeneratorMWs.addThInfoTODir(cw.directory);
|
ThumbnailGeneratorMWs.addThInfoTODir(cw.directory);
|
||||||
}
|
}
|
||||||
@ -209,8 +213,6 @@ export class ThumbnailGeneratorMWs {
|
|||||||
private static addThInfoTODir(
|
private static addThInfoTODir(
|
||||||
directory: ParentDirectoryDTO | SubDirectoryDTO
|
directory: ParentDirectoryDTO | SubDirectoryDTO
|
||||||
): void {
|
): void {
|
||||||
ThumbnailGeneratorMWs.ThumbnailMap =
|
|
||||||
Config.Client.Media.Thumbnail.generateThumbnailMap();
|
|
||||||
if (typeof directory.media !== 'undefined') {
|
if (typeof directory.media !== 'undefined') {
|
||||||
ThumbnailGeneratorMWs.addThInfoToPhotos(directory.media);
|
ThumbnailGeneratorMWs.addThInfoToPhotos(directory.media);
|
||||||
}
|
}
|
||||||
@ -220,8 +222,8 @@ export class ThumbnailGeneratorMWs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static addThInfoToPhotos(photos: MediaDTO[]): void {
|
private static addThInfoToPhotos(photos: MediaDTO[]): void {
|
||||||
for (const item of photos) {
|
for (let i = 0; i < photos.length; ++i) {
|
||||||
this.addThInfoToAPhoto(item);
|
this.addThInfoToAPhoto(photos[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,19 +234,18 @@ export class ThumbnailGeneratorMWs {
|
|||||||
photo.directory.name,
|
photo.directory.name,
|
||||||
photo.name
|
photo.name
|
||||||
);
|
);
|
||||||
for (const _s of Object.keys(ThumbnailGeneratorMWs.ThumbnailMap)) {
|
for (let i = 0; i < ThumbnailGeneratorMWs.ThumbnailMapEntries.length; ++i) {
|
||||||
const size = parseInt(_s)
|
const entry = ThumbnailGeneratorMWs.ThumbnailMapEntries[i];
|
||||||
const thPath = PhotoProcessing.generateConvertedPath(
|
const thPath = PhotoProcessing.generateConvertedPath(
|
||||||
fullMediaPath,
|
fullMediaPath,
|
||||||
size
|
entry.size
|
||||||
);
|
);
|
||||||
if (fs.existsSync(thPath) !== true) {
|
if (fs.existsSync(thPath) !== true) {
|
||||||
if (typeof photo.missingThumbnails === 'undefined') {
|
if (typeof photo.missingThumbnails === 'undefined') {
|
||||||
photo.missingThumbnails = 0;
|
photo.missingThumbnails = 0;
|
||||||
}
|
}
|
||||||
// this is a bitwise operation
|
// this is a bitwise operation
|
||||||
photo.missingThumbnails +=
|
photo.missingThumbnails += entry.bit;
|
||||||
ThumbnailGeneratorMWs.ThumbnailMap[size];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-inferrable-types */
|
/* eslint-disable @typescript-eslint/no-inferrable-types */
|
||||||
import 'reflect-metadata';
|
import 'reflect-metadata';
|
||||||
import { SortingMethods } from '../../entities/SortingMethods';
|
import {SortingMethods} from '../../entities/SortingMethods';
|
||||||
import { UserRoles } from '../../entities/UserDTO';
|
import {UserRoles} from '../../entities/UserDTO';
|
||||||
import { ConfigProperty, SubConfigClass } from 'typeconfig/common';
|
import {ConfigProperty, SubConfigClass} from 'typeconfig/common';
|
||||||
import { IPrivateConfig } from '../private/PrivateConfig';
|
import {IPrivateConfig} from '../private/PrivateConfig';
|
||||||
|
|
||||||
export enum MapProviders {
|
export enum MapProviders {
|
||||||
OpenStreetMap = 1,
|
OpenStreetMap = 1,
|
||||||
@ -15,11 +15,11 @@ export enum MapProviders {
|
|||||||
export class AutoCompleteConfig {
|
export class AutoCompleteConfig {
|
||||||
@ConfigProperty()
|
@ConfigProperty()
|
||||||
enabled: boolean = true;
|
enabled: boolean = true;
|
||||||
@ConfigProperty({ type: 'unsignedInt' })
|
@ConfigProperty({type: 'unsignedInt'})
|
||||||
targetItemsPerCategory: number = 5;
|
targetItemsPerCategory: number = 5;
|
||||||
@ConfigProperty({ type: 'unsignedInt' })
|
@ConfigProperty({type: 'unsignedInt'})
|
||||||
maxItems: number = 30;
|
maxItems: number = 30;
|
||||||
@ConfigProperty({ type: 'unsignedInt' })
|
@ConfigProperty({type: 'unsignedInt'})
|
||||||
cacheTimeout: number = 1000 * 60 * 60;
|
cacheTimeout: number = 1000 * 60 * 60;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,11 +27,11 @@ export class AutoCompleteConfig {
|
|||||||
export class ClientSearchConfig {
|
export class ClientSearchConfig {
|
||||||
@ConfigProperty()
|
@ConfigProperty()
|
||||||
enabled: boolean = true;
|
enabled: boolean = true;
|
||||||
@ConfigProperty({ type: 'unsignedInt' })
|
@ConfigProperty({type: 'unsignedInt'})
|
||||||
searchCacheTimeout: number = 1000 * 60 * 60;
|
searchCacheTimeout: number = 1000 * 60 * 60;
|
||||||
@ConfigProperty()
|
@ConfigProperty()
|
||||||
AutoComplete: AutoCompleteConfig = new AutoCompleteConfig();
|
AutoComplete: AutoCompleteConfig = new AutoCompleteConfig();
|
||||||
@ConfigProperty({ type: 'unsignedInt' })
|
@ConfigProperty({type: 'unsignedInt'})
|
||||||
maxMediaResult: number = 10000;
|
maxMediaResult: number = 10000;
|
||||||
@ConfigProperty({
|
@ConfigProperty({
|
||||||
description: 'Search returns also with directories, not just media',
|
description: 'Search returns also with directories, not just media',
|
||||||
@ -42,7 +42,7 @@ export class ClientSearchConfig {
|
|||||||
'Search also returns with metafiles from directories that contain a media file of the matched search result',
|
'Search also returns with metafiles from directories that contain a media file of the matched search result',
|
||||||
})
|
})
|
||||||
listMetafiles: boolean = true;
|
listMetafiles: boolean = true;
|
||||||
@ConfigProperty({ type: 'unsignedInt' })
|
@ConfigProperty({type: 'unsignedInt'})
|
||||||
maxDirectoryResult: number = 200;
|
maxDirectoryResult: number = 200;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ export class ClientSharingConfig {
|
|||||||
|
|
||||||
@SubConfigClass()
|
@SubConfigClass()
|
||||||
export class ClientRandomPhotoConfig {
|
export class ClientRandomPhotoConfig {
|
||||||
@ConfigProperty({ description: 'Enables random link generation.' })
|
@ConfigProperty({description: 'Enables random link generation.'})
|
||||||
enabled: boolean = true;
|
enabled: boolean = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,23 +92,23 @@ export class ClientMapConfig {
|
|||||||
maxPreviewMarkers: number = 50;
|
maxPreviewMarkers: number = 50;
|
||||||
@ConfigProperty()
|
@ConfigProperty()
|
||||||
useImageMarkers: boolean = true;
|
useImageMarkers: boolean = true;
|
||||||
@ConfigProperty({ type: MapProviders })
|
@ConfigProperty({type: MapProviders})
|
||||||
mapProvider: MapProviders = MapProviders.OpenStreetMap;
|
mapProvider: MapProviders = MapProviders.OpenStreetMap;
|
||||||
@ConfigProperty()
|
@ConfigProperty()
|
||||||
mapboxAccessToken: string = '';
|
mapboxAccessToken: string = '';
|
||||||
@ConfigProperty({ arrayType: MapLayers })
|
@ConfigProperty({arrayType: MapLayers})
|
||||||
customLayers: MapLayers[] = [new MapLayers()];
|
customLayers: MapLayers[] = [new MapLayers()];
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubConfigClass()
|
@SubConfigClass()
|
||||||
export class ClientThumbnailConfig {
|
export class ClientThumbnailConfig {
|
||||||
@ConfigProperty({ type: 'unsignedInt', max: 100 })
|
@ConfigProperty({type: 'unsignedInt', max: 100})
|
||||||
iconSize: number = 45;
|
iconSize: number = 45;
|
||||||
@ConfigProperty({ type: 'unsignedInt' })
|
@ConfigProperty({type: 'unsignedInt'})
|
||||||
personThumbnailSize: number = 200;
|
personThumbnailSize: number = 200;
|
||||||
@ConfigProperty({ arrayType: 'unsignedInt' })
|
@ConfigProperty({arrayType: 'unsignedInt'})
|
||||||
thumbnailSizes: number[] = [240, 480];
|
thumbnailSizes: number[] = [240, 480];
|
||||||
@ConfigProperty({ volatile: true })
|
@ConfigProperty({volatile: true})
|
||||||
concurrentThumbnailGenerations: number = 1;
|
concurrentThumbnailGenerations: number = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -121,6 +121,13 @@ export class ClientThumbnailConfig {
|
|||||||
});
|
});
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a map for bitwise operation from icon and normal thumbnails
|
||||||
|
*/
|
||||||
|
generateThumbnailMapEntries(): { size: number, bit: number }[] {
|
||||||
|
return Object.entries(this.generateThumbnailMap()).map(v => ({size: parseInt(v[0]), bit: v[1]}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubConfigClass()
|
@SubConfigClass()
|
||||||
@ -137,7 +144,7 @@ export class ClientOtherConfig {
|
|||||||
enableCache: boolean = true;
|
enableCache: boolean = true;
|
||||||
@ConfigProperty()
|
@ConfigProperty()
|
||||||
enableOnScrollRendering: boolean = true;
|
enableOnScrollRendering: boolean = true;
|
||||||
@ConfigProperty({ type: SortingMethods })
|
@ConfigProperty({type: SortingMethods})
|
||||||
defaultPhotoSortingMethod: SortingMethods = SortingMethods.ascDate;
|
defaultPhotoSortingMethod: SortingMethods = SortingMethods.ascDate;
|
||||||
@ConfigProperty({
|
@ConfigProperty({
|
||||||
description:
|
description:
|
||||||
@ -227,9 +234,9 @@ export class ClientFacesConfig {
|
|||||||
enabled: boolean = true;
|
enabled: boolean = true;
|
||||||
@ConfigProperty()
|
@ConfigProperty()
|
||||||
keywordsToPersons: boolean = true;
|
keywordsToPersons: boolean = true;
|
||||||
@ConfigProperty({ type: UserRoles })
|
@ConfigProperty({type: UserRoles})
|
||||||
writeAccessMinRole: UserRoles = UserRoles.Admin;
|
writeAccessMinRole: UserRoles = UserRoles.Admin;
|
||||||
@ConfigProperty({ type: UserRoles })
|
@ConfigProperty({type: UserRoles})
|
||||||
readAccessMinRole: UserRoles = UserRoles.User;
|
readAccessMinRole: UserRoles = UserRoles.User;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,9 +262,9 @@ export class ClientConfig {
|
|||||||
Other: ClientOtherConfig = new ClientOtherConfig();
|
Other: ClientOtherConfig = new ClientOtherConfig();
|
||||||
@ConfigProperty()
|
@ConfigProperty()
|
||||||
authenticationRequired: boolean = true;
|
authenticationRequired: boolean = true;
|
||||||
@ConfigProperty({ type: UserRoles })
|
@ConfigProperty({type: UserRoles})
|
||||||
unAuthenticatedUserRole: UserRoles = UserRoles.Admin;
|
unAuthenticatedUserRole: UserRoles = UserRoles.Admin;
|
||||||
@ConfigProperty({ arrayType: 'string', volatile: true })
|
@ConfigProperty({arrayType: 'string', volatile: true})
|
||||||
languages: string[] | undefined;
|
languages: string[] | undefined;
|
||||||
@ConfigProperty()
|
@ConfigProperty()
|
||||||
Media: ClientMediaConfig = new ClientMediaConfig();
|
Media: ClientMediaConfig = new ClientMediaConfig();
|
||||||
|
@ -164,6 +164,10 @@ export class ContentWrapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m.missingThumbnails === 0) {
|
||||||
|
delete m.missingThumbnails;
|
||||||
|
}
|
||||||
|
|
||||||
if (MediaDTOUtils.isPhoto(m)) {
|
if (MediaDTOUtils.isPhoto(m)) {
|
||||||
delete (m as VideoDTO).metadata.bitRate;
|
delete (m as VideoDTO).metadata.bitRate;
|
||||||
delete (m as VideoDTO).metadata.duration;
|
delete (m as VideoDTO).metadata.duration;
|
||||||
|
@ -34,6 +34,9 @@ describe('ContentWrapper', () => {
|
|||||||
delete (m as PhotoDTO).metadata.faces;
|
delete (m as PhotoDTO).metadata.faces;
|
||||||
delete (m as PhotoDTO).metadata.positionData;
|
delete (m as PhotoDTO).metadata.positionData;
|
||||||
}
|
}
|
||||||
|
if (m.missingThumbnails === 0) {
|
||||||
|
delete m.missingThumbnails;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (let i = 0; i < content.metaFile.length; ++i) {
|
for (let i = 0; i < content.metaFile.length; ++i) {
|
||||||
delete content.metaFile[i].id;
|
delete content.metaFile[i].id;
|
||||||
|
Loading…
Reference in New Issue
Block a user