mirror of
https://github.com/bpatrik/pigallery2.git
synced 2024-12-23 01:27:14 +02:00
Renaming preview to cover to reduce confusion #679
This commit is contained in:
parent
dd9f804f2c
commit
3c9c7e01a3
@ -216,8 +216,8 @@ export class ThumbnailGeneratorMWs {
|
||||
if (typeof directory.media !== 'undefined') {
|
||||
ThumbnailGeneratorMWs.addThInfoToPhotos(directory.media, directory);
|
||||
}
|
||||
if (directory.preview) {
|
||||
ThumbnailGeneratorMWs.addThInfoToAPhoto(directory.preview, directory);
|
||||
if (directory.cover) {
|
||||
ThumbnailGeneratorMWs.addThInfoToAPhoto(directory.cover, directory);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@ import {UserManager} from './database/UserManager';
|
||||
import {IndexingManager} from './database/IndexingManager';
|
||||
import {SearchManager} from './database/SearchManager';
|
||||
import {VersionManager} from './database/VersionManager';
|
||||
import {PreviewManager} from './database/PreviewManager';
|
||||
import {CoverManager} from './database/CoverManager';
|
||||
import {AlbumManager} from './database/AlbumManager';
|
||||
import {PersonManager} from './database/PersonManager';
|
||||
import {SharingManager} from './database/SharingManager';
|
||||
@ -27,7 +27,7 @@ export class ObjectManagers {
|
||||
private sharingManager: SharingManager;
|
||||
private indexingManager: IndexingManager;
|
||||
private personManager: PersonManager;
|
||||
private previewManager: PreviewManager;
|
||||
private coverManager: CoverManager;
|
||||
private versionManager: VersionManager;
|
||||
private jobManager: JobManager;
|
||||
private locationManager: LocationManager;
|
||||
@ -85,16 +85,16 @@ export class ObjectManagers {
|
||||
this.managers.push(this.personManager);
|
||||
}
|
||||
|
||||
get PreviewManager(): PreviewManager {
|
||||
return this.previewManager;
|
||||
get CoverManager(): CoverManager {
|
||||
return this.coverManager;
|
||||
}
|
||||
|
||||
set PreviewManager(value: PreviewManager) {
|
||||
if (this.previewManager) {
|
||||
this.managers.splice(this.managers.indexOf(this.previewManager), 1);
|
||||
set CoverManager(value: CoverManager) {
|
||||
if (this.coverManager) {
|
||||
this.managers.splice(this.managers.indexOf(this.coverManager), 1);
|
||||
}
|
||||
this.previewManager = value;
|
||||
this.managers.push(this.previewManager);
|
||||
this.coverManager = value;
|
||||
this.managers.push(this.coverManager);
|
||||
}
|
||||
|
||||
get IndexingManager(): IndexingManager {
|
||||
@ -204,7 +204,7 @@ export class ObjectManagers {
|
||||
ObjectManagers.getInstance().GalleryManager = new GalleryManager();
|
||||
ObjectManagers.getInstance().IndexingManager = new IndexingManager();
|
||||
ObjectManagers.getInstance().PersonManager = new PersonManager();
|
||||
ObjectManagers.getInstance().PreviewManager = new PreviewManager();
|
||||
ObjectManagers.getInstance().CoverManager = new CoverManager();
|
||||
ObjectManagers.getInstance().SearchManager = new SearchManager();
|
||||
ObjectManagers.getInstance().SharingManager = new SharingManager();
|
||||
ObjectManagers.getInstance().UserManager = new UserManager();
|
||||
|
@ -19,15 +19,15 @@ export class AlbumManager implements IObjectManager {
|
||||
|
||||
private static async updateAlbum(album: SavedSearchEntity): Promise<void> {
|
||||
const connection = await SQLConnection.getConnection();
|
||||
const preview =
|
||||
await ObjectManagers.getInstance().PreviewManager.getAlbumPreview(album);
|
||||
const cover =
|
||||
await ObjectManagers.getInstance().CoverManager.getAlbumCover(album);
|
||||
const count = await
|
||||
ObjectManagers.getInstance().SearchManager.getCount((album as SavedSearchDTO).searchQuery);
|
||||
|
||||
await connection
|
||||
.createQueryBuilder()
|
||||
.update(AlbumBaseEntity)
|
||||
.set({preview, count})
|
||||
.set({cover: cover, count})
|
||||
.where('id = :id', {id: album.id})
|
||||
.execute();
|
||||
}
|
||||
@ -81,17 +81,17 @@ export class AlbumManager implements IObjectManager {
|
||||
return await connection
|
||||
.getRepository(AlbumBaseEntity)
|
||||
.createQueryBuilder('album')
|
||||
.leftJoin('album.preview', 'preview')
|
||||
.leftJoin('preview.directory', 'directory')
|
||||
.select(['album', 'preview.name', 'directory.name', 'directory.path'])
|
||||
.leftJoin('album.cover', 'cover')
|
||||
.leftJoin('cover.directory', 'directory')
|
||||
.select(['album', 'cover.name', 'directory.name', 'directory.path'])
|
||||
.getMany();
|
||||
}
|
||||
|
||||
public async onNewDataVersion(): Promise<void> {
|
||||
await this.resetPreviews();
|
||||
await this.resetCovers();
|
||||
}
|
||||
|
||||
public async resetPreviews(): Promise<void> {
|
||||
public async resetCovers(): Promise<void> {
|
||||
this.isDBValid = false;
|
||||
}
|
||||
|
||||
|
@ -11,24 +11,24 @@ import {DirectoryEntity} from './enitites/DirectoryEntity';
|
||||
import {ParentDirectoryDTO} from '../../../common/entities/DirectoryDTO';
|
||||
import * as path from 'path';
|
||||
import {Utils} from '../../../common/Utils';
|
||||
import {PreviewPhotoDTO} from '../../../common/entities/PhotoDTO';
|
||||
import {CoverPhotoDTO} from '../../../common/entities/PhotoDTO';
|
||||
import {IObjectManager} from './IObjectManager';
|
||||
import {Logger} from '../../Logger';
|
||||
|
||||
const LOG_TAG = '[PreviewManager]';
|
||||
const LOG_TAG = '[CoverManager]';
|
||||
|
||||
// ID is need within the backend so it can be saved to DB (ID is the external key)
|
||||
export interface PreviewPhotoDTOWithID extends PreviewPhotoDTO {
|
||||
export interface CoverPhotoDTOWithID extends CoverPhotoDTO {
|
||||
id: number;
|
||||
}
|
||||
|
||||
export class PreviewManager implements IObjectManager {
|
||||
export class CoverManager implements IObjectManager {
|
||||
private static DIRECTORY_SELECT = ['directory.name', 'directory.path'];
|
||||
|
||||
private static setSorting<T>(
|
||||
query: SelectQueryBuilder<T>
|
||||
): SelectQueryBuilder<T> {
|
||||
for (const sort of Config.Preview.Sorting) {
|
||||
for (const sort of Config.AlbumCover.Sorting) {
|
||||
switch (sort) {
|
||||
case SortingMethods.descDate:
|
||||
query.addOrderBy('media.metadata.creationDate', 'DESC');
|
||||
@ -54,24 +54,24 @@ export class PreviewManager implements IObjectManager {
|
||||
return query;
|
||||
}
|
||||
|
||||
public async resetPreviews(): Promise<void> {
|
||||
public async resetCovers(): Promise<void> {
|
||||
const connection = await SQLConnection.getConnection();
|
||||
await connection
|
||||
.createQueryBuilder()
|
||||
.update(DirectoryEntity)
|
||||
.set({validPreview: false})
|
||||
.set({validCover: false})
|
||||
.execute();
|
||||
}
|
||||
|
||||
public async onNewDataVersion(changedDir: ParentDirectoryDTO): Promise<void> {
|
||||
// Invalidating Album preview
|
||||
// Invalidating Album cover
|
||||
let fullPath = DiskMangerWorker.normalizeDirPath(
|
||||
path.join(changedDir.path, changedDir.name)
|
||||
);
|
||||
const query = (await SQLConnection.getConnection())
|
||||
.createQueryBuilder()
|
||||
.update(DirectoryEntity)
|
||||
.set({validPreview: false});
|
||||
.set({validCover: false});
|
||||
|
||||
let i = 0;
|
||||
const root = DiskMangerWorker.pathFromRelativeDirName('.');
|
||||
@ -105,79 +105,79 @@ export class PreviewManager implements IObjectManager {
|
||||
await query.execute();
|
||||
}
|
||||
|
||||
public async getAlbumPreview(album: {
|
||||
public async getAlbumCover(album: {
|
||||
searchQuery: SearchQueryDTO;
|
||||
}): Promise<PreviewPhotoDTOWithID> {
|
||||
}): Promise<CoverPhotoDTOWithID> {
|
||||
const albumQuery: Brackets = await
|
||||
ObjectManagers.getInstance().SearchManager.prepareAndBuildWhereQuery(album.searchQuery);
|
||||
const connection = await SQLConnection.getConnection();
|
||||
|
||||
const previewQuery = (): SelectQueryBuilder<MediaEntity> => {
|
||||
const coverQuery = (): SelectQueryBuilder<MediaEntity> => {
|
||||
const query = connection
|
||||
.getRepository(MediaEntity)
|
||||
.createQueryBuilder('media')
|
||||
.innerJoin('media.directory', 'directory')
|
||||
.select(['media.name', 'media.id', ...PreviewManager.DIRECTORY_SELECT])
|
||||
.select(['media.name', 'media.id', ...CoverManager.DIRECTORY_SELECT])
|
||||
.where(albumQuery);
|
||||
PreviewManager.setSorting(query);
|
||||
CoverManager.setSorting(query);
|
||||
return query;
|
||||
};
|
||||
let previewMedia = null;
|
||||
let coverMedia = null;
|
||||
if (
|
||||
Config.Preview.SearchQuery &&
|
||||
!Utils.equalsFilter(Config.Preview.SearchQuery, {
|
||||
Config.AlbumCover.SearchQuery &&
|
||||
!Utils.equalsFilter(Config.AlbumCover.SearchQuery, {
|
||||
type: SearchQueryTypes.any_text,
|
||||
text: '',
|
||||
} as TextSearch)
|
||||
) {
|
||||
try {
|
||||
const previewFilterQuery = await
|
||||
ObjectManagers.getInstance().SearchManager.prepareAndBuildWhereQuery(Config.Preview.SearchQuery);
|
||||
previewMedia = await previewQuery()
|
||||
.andWhere(previewFilterQuery)
|
||||
const coverFilterQuery = await
|
||||
ObjectManagers.getInstance().SearchManager.prepareAndBuildWhereQuery(Config.AlbumCover.SearchQuery);
|
||||
coverMedia = await coverQuery()
|
||||
.andWhere(coverFilterQuery)
|
||||
.limit(1)
|
||||
.getOne();
|
||||
} catch (e) {
|
||||
Logger.error('Cant get album preview using:', JSON.stringify(album.searchQuery), JSON.stringify(Config.Preview.SearchQuery));
|
||||
Logger.error('Cant get album cover using:', JSON.stringify(album.searchQuery), JSON.stringify(Config.AlbumCover.SearchQuery));
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
if (!previewMedia) {
|
||||
if (!coverMedia) {
|
||||
try {
|
||||
previewMedia = await previewQuery().limit(1).getOne();
|
||||
coverMedia = await coverQuery().limit(1).getOne();
|
||||
} catch (e) {
|
||||
Logger.error('Cant get album preview using:', JSON.stringify(album.searchQuery));
|
||||
Logger.error('Cant get album cover using:', JSON.stringify(album.searchQuery));
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
return previewMedia || null;
|
||||
return coverMedia || null;
|
||||
}
|
||||
|
||||
public async getPartialDirsWithoutPreviews(): Promise<
|
||||
public async getPartialDirsWithoutCovers(): Promise<
|
||||
{ id: number; name: string; path: string }[]
|
||||
> {
|
||||
const connection = await SQLConnection.getConnection();
|
||||
return await connection
|
||||
.getRepository(DirectoryEntity)
|
||||
.createQueryBuilder('directory')
|
||||
.where('directory.validPreview = :validPreview', {validPreview: 0}) // 0 === false
|
||||
.where('directory.validCover = :validCover', {validCover: 0}) // 0 === false
|
||||
.select(['name', 'id', 'path'])
|
||||
.getRawMany();
|
||||
}
|
||||
|
||||
public async setAndGetPreviewForDirectory(dir: {
|
||||
public async setAndGetCoverForDirectory(dir: {
|
||||
id: number;
|
||||
name: string;
|
||||
path: string;
|
||||
}): Promise<PreviewPhotoDTOWithID> {
|
||||
}): Promise<CoverPhotoDTOWithID> {
|
||||
const connection = await SQLConnection.getConnection();
|
||||
const previewQuery = (): SelectQueryBuilder<MediaEntity> => {
|
||||
const coverQuery = (): SelectQueryBuilder<MediaEntity> => {
|
||||
const query = connection
|
||||
.getRepository(MediaEntity)
|
||||
.createQueryBuilder('media')
|
||||
.innerJoin('media.directory', 'directory')
|
||||
.select(['media.name', 'media.id', ...PreviewManager.DIRECTORY_SELECT])
|
||||
.select(['media.name', 'media.id', ...CoverManager.DIRECTORY_SELECT])
|
||||
.where(
|
||||
new Brackets((q: WhereExpression) => {
|
||||
q.where('media.directory = :dir', {
|
||||
@ -201,40 +201,40 @@ export class PreviewManager implements IObjectManager {
|
||||
'ASC'
|
||||
);
|
||||
|
||||
PreviewManager.setSorting(query);
|
||||
CoverManager.setSorting(query);
|
||||
return query;
|
||||
};
|
||||
|
||||
let previewMedia: PreviewPhotoDTOWithID = null;
|
||||
let coverMedia: CoverPhotoDTOWithID = null;
|
||||
if (
|
||||
Config.Preview.SearchQuery &&
|
||||
!Utils.equalsFilter(Config.Preview.SearchQuery, {
|
||||
Config.AlbumCover.SearchQuery &&
|
||||
!Utils.equalsFilter(Config.AlbumCover.SearchQuery, {
|
||||
type: SearchQueryTypes.any_text,
|
||||
text: '',
|
||||
} as TextSearch)
|
||||
) {
|
||||
previewMedia = await previewQuery()
|
||||
coverMedia = await coverQuery()
|
||||
.andWhere(
|
||||
await ObjectManagers.getInstance().SearchManager.prepareAndBuildWhereQuery(Config.Preview.SearchQuery)
|
||||
await ObjectManagers.getInstance().SearchManager.prepareAndBuildWhereQuery(Config.AlbumCover.SearchQuery)
|
||||
)
|
||||
.limit(1)
|
||||
.getOne();
|
||||
}
|
||||
|
||||
if (!previewMedia) {
|
||||
previewMedia = await previewQuery().limit(1).getOne();
|
||||
if (!coverMedia) {
|
||||
coverMedia = await coverQuery().limit(1).getOne();
|
||||
}
|
||||
|
||||
// set validPreview bit to true even if there is no preview (to prevent future updates)
|
||||
// set validCover bit to true even if there is no cover (to prevent future updates)
|
||||
await connection
|
||||
.createQueryBuilder()
|
||||
.update(DirectoryEntity)
|
||||
.set({preview: previewMedia, validPreview: true})
|
||||
.set({cover: coverMedia, validCover: true})
|
||||
.where('id = :dir', {
|
||||
dir: dir.id,
|
||||
})
|
||||
.execute();
|
||||
|
||||
return previewMedia || null;
|
||||
return coverMedia || null;
|
||||
}
|
||||
}
|
@ -86,9 +86,9 @@ export class GalleryManager {
|
||||
relativeDirectoryName
|
||||
);
|
||||
for (const subDir of ret.directories) {
|
||||
if (!subDir.preview) {
|
||||
// if subdirectories do not have photos, so cannot show a preview, try getting one from DB
|
||||
await this.fillPreviewForSubDir(connection, subDir);
|
||||
if (!subDir.cover) {
|
||||
// if subdirectories do not have photos, so cannot show a cover, try getting one from DB
|
||||
await this.fillCoverForSubDir(connection, subDir);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -292,15 +292,15 @@ export class GalleryManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets preview for the directory and caches it in the DB
|
||||
* Sets cover for the directory and caches it in the DB
|
||||
*/
|
||||
public async fillPreviewForSubDir(
|
||||
public async fillCoverForSubDir(
|
||||
connection: Connection,
|
||||
dir: SubDirectoryDTO
|
||||
): Promise<void> {
|
||||
if (!dir.validPreview) {
|
||||
dir.preview =
|
||||
await ObjectManagers.getInstance().PreviewManager.setAndGetPreviewForDirectory(
|
||||
if (!dir.validCover) {
|
||||
dir.cover =
|
||||
await ObjectManagers.getInstance().CoverManager.setAndGetCoverForDirectory(
|
||||
dir
|
||||
);
|
||||
}
|
||||
@ -336,15 +336,15 @@ export class GalleryManager {
|
||||
})
|
||||
.leftJoinAndSelect('directory.directories', 'directories')
|
||||
.leftJoinAndSelect('directory.media', 'media')
|
||||
.leftJoinAndSelect('directories.preview', 'preview')
|
||||
.leftJoinAndSelect('preview.directory', 'previewDirectory')
|
||||
.leftJoinAndSelect('directories.cover', 'cover')
|
||||
.leftJoinAndSelect('cover.directory', 'coverDirectory')
|
||||
.select([
|
||||
'directory',
|
||||
'directories',
|
||||
'media',
|
||||
'preview.name',
|
||||
'previewDirectory.name',
|
||||
'previewDirectory.path',
|
||||
'cover.name',
|
||||
'coverDirectory.name',
|
||||
'coverDirectory.path',
|
||||
]);
|
||||
|
||||
// TODO: do better filtering
|
||||
@ -360,7 +360,7 @@ export class GalleryManager {
|
||||
const dir = await query.getOne();
|
||||
if (dir.directories) {
|
||||
for (const item of dir.directories) {
|
||||
await this.fillPreviewForSubDir(connection, item);
|
||||
await this.fillCoverForSubDir(connection, item);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -320,21 +320,21 @@ export class SearchManager {
|
||||
.getRepository(DirectoryEntity)
|
||||
.createQueryBuilder('directory')
|
||||
.where(this.buildWhereQuery(dirQuery, true))
|
||||
.leftJoinAndSelect('directory.preview', 'preview')
|
||||
.leftJoinAndSelect('preview.directory', 'previewDirectory')
|
||||
.leftJoinAndSelect('directory.cover', 'cover')
|
||||
.leftJoinAndSelect('cover.directory', 'coverDirectory')
|
||||
.limit(Config.Search.maxDirectoryResult + 1)
|
||||
.select([
|
||||
'directory',
|
||||
'preview.name',
|
||||
'previewDirectory.name',
|
||||
'previewDirectory.path',
|
||||
'cover.name',
|
||||
'coverDirectory.name',
|
||||
'coverDirectory.path',
|
||||
])
|
||||
.getMany();
|
||||
|
||||
// setting previews
|
||||
// setting covers
|
||||
if (result.directories) {
|
||||
for (const item of result.directories) {
|
||||
await ObjectManagers.getInstance().GalleryManager.fillPreviewForSubDir(connection, item as DirectoryEntity);
|
||||
await ObjectManagers.getInstance().GalleryManager.fillCoverForSubDir(connection, item as DirectoryEntity);
|
||||
}
|
||||
}
|
||||
if (
|
||||
|
@ -46,7 +46,7 @@ export class DirectoryEntity
|
||||
public lastModified: number;
|
||||
|
||||
/**
|
||||
* Last time the directory was fully scanned, not only for a few media to create a preview
|
||||
* Last time the directory was fully scanned, not only for a few media to create a cover
|
||||
*/
|
||||
@Column({
|
||||
type: 'bigint',
|
||||
@ -75,11 +75,11 @@ export class DirectoryEntity
|
||||
|
||||
// not saving to database, it is only assigned when querying the DB
|
||||
@ManyToOne((type) => MediaEntity, { onDelete: 'SET NULL' })
|
||||
public preview: MediaEntity;
|
||||
public cover: MediaEntity;
|
||||
|
||||
// On galley change, preview will be invalid
|
||||
// On galley change, cover will be invalid
|
||||
@Column({ type: 'boolean', default: false })
|
||||
validPreview: boolean;
|
||||
validCover: boolean;
|
||||
|
||||
@OneToMany((type) => MediaEntity, (media) => media.directory)
|
||||
public media: MediaEntity[];
|
||||
|
@ -24,5 +24,5 @@ export class AlbumBaseEntity implements AlbumBaseDTO {
|
||||
count: number;
|
||||
|
||||
@ManyToOne((type) => MediaEntity, {onDelete: 'SET NULL', nullable: true})
|
||||
public preview: MediaEntity;
|
||||
public cover: MediaEntity;
|
||||
}
|
||||
|
@ -17,9 +17,9 @@ import {
|
||||
} from '../../../common/config/public/ClientConfig';
|
||||
import {
|
||||
DatabaseType,
|
||||
ServerAlbumCoverConfig,
|
||||
ServerDataBaseConfig,
|
||||
ServerJobConfig,
|
||||
ServerPreviewConfig,
|
||||
ServerThumbnailConfig,
|
||||
ServerVideoConfig,
|
||||
} from '../../../common/config/private/PrivateConfig';
|
||||
@ -31,8 +31,8 @@ const LOG_TAG = '[ConfigDiagnostics]';
|
||||
|
||||
export class ConfigDiagnostics {
|
||||
static testAlbumsConfig(
|
||||
albumConfig: ClientAlbumConfig,
|
||||
original: PrivateConfigClass
|
||||
albumConfig: ClientAlbumConfig,
|
||||
original: PrivateConfigClass
|
||||
): void {
|
||||
Logger.debug(LOG_TAG, 'Testing album config');
|
||||
// nothing to check
|
||||
@ -51,27 +51,27 @@ export class ConfigDiagnostics {
|
||||
}
|
||||
|
||||
static async testDatabase(
|
||||
databaseConfig: ServerDataBaseConfig
|
||||
databaseConfig: ServerDataBaseConfig
|
||||
): Promise<void> {
|
||||
Logger.debug(LOG_TAG, 'Testing database config');
|
||||
await SQLConnection.tryConnection(databaseConfig);
|
||||
if (databaseConfig.type === DatabaseType.sqlite) {
|
||||
try {
|
||||
await this.checkReadWritePermission(
|
||||
SQLConnection.getSQLiteDB(databaseConfig)
|
||||
SQLConnection.getSQLiteDB(databaseConfig)
|
||||
);
|
||||
} catch (e) {
|
||||
throw new Error(
|
||||
'Cannot read or write sqlite storage file: ' +
|
||||
SQLConnection.getSQLiteDB(databaseConfig)
|
||||
'Cannot read or write sqlite storage file: ' +
|
||||
SQLConnection.getSQLiteDB(databaseConfig)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static async testMetaFileConfig(
|
||||
metaFileConfig: ClientMetaFileConfig,
|
||||
config: PrivateConfigClass
|
||||
metaFileConfig: ClientMetaFileConfig,
|
||||
config: PrivateConfigClass
|
||||
): Promise<void> {
|
||||
Logger.debug(LOG_TAG, 'Testing meta file config');
|
||||
if (metaFileConfig.gpx === true && config.Map.enabled === false) {
|
||||
@ -96,19 +96,19 @@ export class ConfigDiagnostics {
|
||||
ffmpeg().getAvailableCodecs((err: Error) => {
|
||||
if (err) {
|
||||
return reject(
|
||||
new Error(
|
||||
'Error accessing ffmpeg, cant find executable: ' +
|
||||
err.toString()
|
||||
)
|
||||
new Error(
|
||||
'Error accessing ffmpeg, cant find executable: ' +
|
||||
err.toString()
|
||||
)
|
||||
);
|
||||
}
|
||||
ffmpeg(__dirname + '/blank.jpg').ffprobe((err2: Error) => {
|
||||
if (err2) {
|
||||
return reject(
|
||||
new Error(
|
||||
'Error accessing ffmpeg-probe, cant find executable: ' +
|
||||
err2.toString()
|
||||
)
|
||||
new Error(
|
||||
'Error accessing ffmpeg-probe, cant find executable: ' +
|
||||
err2.toString()
|
||||
)
|
||||
);
|
||||
}
|
||||
return resolve();
|
||||
@ -156,7 +156,7 @@ export class ConfigDiagnostics {
|
||||
|
||||
|
||||
static async testThumbnailConfig(
|
||||
thumbnailConfig: ServerThumbnailConfig
|
||||
thumbnailConfig: ServerThumbnailConfig
|
||||
): Promise<void> {
|
||||
Logger.debug(LOG_TAG, 'Testing thumbnail config');
|
||||
|
||||
@ -167,7 +167,7 @@ export class ConfigDiagnostics {
|
||||
|
||||
if (isNaN(thumbnailConfig.iconSize) || thumbnailConfig.iconSize <= 0) {
|
||||
throw new Error(
|
||||
'IconSize has to be >= 0 integer, got: ' + thumbnailConfig.iconSize
|
||||
'IconSize has to be >= 0 integer, got: ' + thumbnailConfig.iconSize
|
||||
);
|
||||
}
|
||||
|
||||
@ -182,16 +182,16 @@ export class ConfigDiagnostics {
|
||||
}
|
||||
|
||||
static async testTasksConfig(
|
||||
task: ServerJobConfig,
|
||||
config: PrivateConfigClass
|
||||
task: ServerJobConfig,
|
||||
config: PrivateConfigClass
|
||||
): Promise<void> {
|
||||
Logger.debug(LOG_TAG, 'Testing tasks config');
|
||||
return;
|
||||
}
|
||||
|
||||
static async testFacesConfig(
|
||||
faces: ClientFacesConfig,
|
||||
config: PrivateConfigClass
|
||||
faces: ClientFacesConfig,
|
||||
config: PrivateConfigClass
|
||||
): Promise<void> {
|
||||
Logger.debug(LOG_TAG, 'Testing faces config');
|
||||
if (faces.enabled === true) {
|
||||
@ -202,29 +202,29 @@ export class ConfigDiagnostics {
|
||||
}
|
||||
|
||||
static async testSearchConfig(
|
||||
search: ClientSearchConfig,
|
||||
config: PrivateConfigClass
|
||||
search: ClientSearchConfig,
|
||||
config: PrivateConfigClass
|
||||
): Promise<void> {
|
||||
Logger.debug(LOG_TAG, 'Testing search config');
|
||||
//nothing to check
|
||||
}
|
||||
|
||||
static async testSharingConfig(
|
||||
sharing: ClientSharingConfig,
|
||||
config: PrivateConfigClass
|
||||
sharing: ClientSharingConfig,
|
||||
config: PrivateConfigClass
|
||||
): Promise<void> {
|
||||
Logger.debug(LOG_TAG, 'Testing sharing config');
|
||||
if (
|
||||
sharing.enabled === true &&
|
||||
config.Users.authenticationRequired === false
|
||||
sharing.enabled === true &&
|
||||
config.Users.authenticationRequired === false
|
||||
) {
|
||||
throw new Error('In case of no authentication, sharing is not supported');
|
||||
}
|
||||
}
|
||||
|
||||
static async testRandomPhotoConfig(
|
||||
sharing: ClientRandomPhotoConfig,
|
||||
config: PrivateConfigClass
|
||||
sharing: ClientRandomPhotoConfig,
|
||||
config: PrivateConfigClass
|
||||
): Promise<void> {
|
||||
Logger.debug(LOG_TAG, 'Testing random photo config');
|
||||
//nothing to check
|
||||
@ -236,14 +236,14 @@ export class ConfigDiagnostics {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
map.mapProvider === MapProviders.Mapbox &&
|
||||
(!map.mapboxAccessToken || map.mapboxAccessToken.length === 0)
|
||||
map.mapProvider === MapProviders.Mapbox &&
|
||||
(!map.mapboxAccessToken || map.mapboxAccessToken.length === 0)
|
||||
) {
|
||||
throw new Error('Mapbox needs a valid api key.');
|
||||
}
|
||||
if (
|
||||
map.mapProvider === MapProviders.Custom &&
|
||||
(!map.customLayers || map.customLayers.length === 0)
|
||||
map.mapProvider === MapProviders.Custom &&
|
||||
(!map.customLayers || map.customLayers.length === 0)
|
||||
) {
|
||||
throw new Error('Custom maps need at least one valid layer');
|
||||
}
|
||||
@ -256,14 +256,14 @@ export class ConfigDiagnostics {
|
||||
}
|
||||
}
|
||||
|
||||
static async testPreviewConfig(settings: ServerPreviewConfig): Promise<void> {
|
||||
Logger.debug(LOG_TAG, 'Testing preview config');
|
||||
static async testAlbumCoverConfig(settings: ServerAlbumCoverConfig): Promise<void> {
|
||||
Logger.debug(LOG_TAG, 'Testing cover config');
|
||||
const sp = new SearchQueryParser();
|
||||
if (
|
||||
!Utils.equalsFilter(
|
||||
sp.parse(sp.stringify(settings.SearchQuery)),
|
||||
settings.SearchQuery
|
||||
)
|
||||
!Utils.equalsFilter(
|
||||
sp.parse(sp.stringify(settings.SearchQuery)),
|
||||
settings.SearchQuery
|
||||
)
|
||||
) {
|
||||
throw new Error('SearchQuery is not valid. Got: ' + JSON.stringify(sp.parse(sp.stringify(settings.SearchQuery))));
|
||||
}
|
||||
@ -280,7 +280,7 @@ export class ConfigDiagnostics {
|
||||
await ConfigDiagnostics.testImageFolder(config.Media.folder);
|
||||
await ConfigDiagnostics.testThumbnailConfig(config.Media.Thumbnail);
|
||||
await ConfigDiagnostics.testSearchConfig(config.Search, config);
|
||||
await ConfigDiagnostics.testPreviewConfig(config.Preview);
|
||||
await ConfigDiagnostics.testAlbumCoverConfig(config.AlbumCover);
|
||||
await ConfigDiagnostics.testFacesConfig(config.Faces, config);
|
||||
await ConfigDiagnostics.testTasksConfig(config.Jobs, config);
|
||||
await ConfigDiagnostics.testSharingConfig(config.Sharing, config);
|
||||
@ -303,8 +303,8 @@ export class ConfigDiagnostics {
|
||||
const err: Error = ex;
|
||||
Logger.warn(LOG_TAG, '[SQL error]', err.toString());
|
||||
Logger.error(
|
||||
LOG_TAG,
|
||||
'Error during initializing SQL DB, check DB connection and settings'
|
||||
LOG_TAG,
|
||||
'Error during initializing SQL DB, check DB connection and settings'
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
@ -315,15 +315,15 @@ export class ConfigDiagnostics {
|
||||
const err: Error = ex;
|
||||
|
||||
Logger.warn(
|
||||
LOG_TAG,
|
||||
'[Thumbnail hardware acceleration] module error: ',
|
||||
err.toString()
|
||||
LOG_TAG,
|
||||
'[Thumbnail hardware acceleration] module error: ',
|
||||
err.toString()
|
||||
);
|
||||
Logger.warn(
|
||||
LOG_TAG,
|
||||
'Thumbnail hardware acceleration is not possible.' +
|
||||
' \'sharp\' node module is not found.' +
|
||||
' Falling back temporally to JS based thumbnail generation'
|
||||
LOG_TAG,
|
||||
'Thumbnail hardware acceleration is not possible.' +
|
||||
' \'sharp\' node module is not found.' +
|
||||
' Falling back temporally to JS based thumbnail generation'
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
@ -341,32 +341,32 @@ export class ConfigDiagnostics {
|
||||
} catch (ex) {
|
||||
const err: Error = ex;
|
||||
NotificationManager.warning(
|
||||
'Video support error, switching off..',
|
||||
err.toString()
|
||||
'Video support error, switching off..',
|
||||
err.toString()
|
||||
);
|
||||
Logger.warn(
|
||||
LOG_TAG,
|
||||
'Video support error, switching off..',
|
||||
err.toString()
|
||||
LOG_TAG,
|
||||
'Video support error, switching off..',
|
||||
err.toString()
|
||||
);
|
||||
Config.Media.Video.enabled = false;
|
||||
}
|
||||
|
||||
try {
|
||||
await ConfigDiagnostics.testMetaFileConfig(
|
||||
Config.MetaFile,
|
||||
Config
|
||||
Config.MetaFile,
|
||||
Config
|
||||
);
|
||||
} catch (ex) {
|
||||
const err: Error = ex;
|
||||
NotificationManager.warning(
|
||||
'Meta file support error, switching off gpx..',
|
||||
err.toString()
|
||||
'Meta file support error, switching off gpx..',
|
||||
err.toString()
|
||||
);
|
||||
Logger.warn(
|
||||
LOG_TAG,
|
||||
'Meta file support error, switching off..',
|
||||
err.toString()
|
||||
LOG_TAG,
|
||||
'Meta file support error, switching off..',
|
||||
err.toString()
|
||||
);
|
||||
Config.MetaFile.gpx = false;
|
||||
}
|
||||
@ -376,13 +376,13 @@ export class ConfigDiagnostics {
|
||||
} catch (ex) {
|
||||
const err: Error = ex;
|
||||
NotificationManager.warning(
|
||||
'Albums support error, switching off..',
|
||||
err.toString()
|
||||
'Albums support error, switching off..',
|
||||
err.toString()
|
||||
);
|
||||
Logger.warn(
|
||||
LOG_TAG,
|
||||
'Meta file support error, switching off..',
|
||||
err.toString()
|
||||
LOG_TAG,
|
||||
'Meta file support error, switching off..',
|
||||
err.toString()
|
||||
);
|
||||
Config.Album.enabled = false;
|
||||
}
|
||||
@ -396,7 +396,7 @@ export class ConfigDiagnostics {
|
||||
}
|
||||
try {
|
||||
await ConfigDiagnostics.testThumbnailConfig(
|
||||
Config.Media.Thumbnail
|
||||
Config.Media.Thumbnail
|
||||
);
|
||||
} catch (ex) {
|
||||
const err: Error = ex;
|
||||
@ -409,32 +409,32 @@ export class ConfigDiagnostics {
|
||||
} catch (ex) {
|
||||
const err: Error = ex;
|
||||
NotificationManager.warning(
|
||||
'Search is not supported with these settings. Disabling temporally. ' +
|
||||
'Please adjust the config properly.',
|
||||
err.toString()
|
||||
'Search is not supported with these settings. Disabling temporally. ' +
|
||||
'Please adjust the config properly.',
|
||||
err.toString()
|
||||
);
|
||||
Logger.warn(
|
||||
LOG_TAG,
|
||||
'Search is not supported with these settings, switching off..',
|
||||
err.toString()
|
||||
LOG_TAG,
|
||||
'Search is not supported with these settings, switching off..',
|
||||
err.toString()
|
||||
);
|
||||
Config.Search.enabled = false;
|
||||
}
|
||||
|
||||
try {
|
||||
await ConfigDiagnostics.testPreviewConfig(Config.Preview);
|
||||
await ConfigDiagnostics.testAlbumCoverConfig(Config.AlbumCover);
|
||||
} catch (ex) {
|
||||
const err: Error = ex;
|
||||
NotificationManager.warning(
|
||||
'Preview settings are not valid, resetting search query',
|
||||
err.toString()
|
||||
'Cover settings are not valid, resetting search query',
|
||||
err.toString()
|
||||
);
|
||||
Logger.warn(
|
||||
LOG_TAG,
|
||||
'Preview settings are not valid, resetting search query',
|
||||
err.toString()
|
||||
LOG_TAG,
|
||||
'Cover settings are not valid, resetting search query',
|
||||
err.toString()
|
||||
);
|
||||
Config.Preview.SearchQuery = {
|
||||
Config.AlbumCover.SearchQuery = {
|
||||
type: SearchQueryTypes.any_text,
|
||||
text: '',
|
||||
} as TextSearch;
|
||||
@ -445,14 +445,14 @@ export class ConfigDiagnostics {
|
||||
} catch (ex) {
|
||||
const err: Error = ex;
|
||||
NotificationManager.warning(
|
||||
'Faces are not supported with these settings. Disabling temporally. ' +
|
||||
'Please adjust the config properly.',
|
||||
err.toString()
|
||||
'Faces are not supported with these settings. Disabling temporally. ' +
|
||||
'Please adjust the config properly.',
|
||||
err.toString()
|
||||
);
|
||||
Logger.warn(
|
||||
LOG_TAG,
|
||||
'Faces are not supported with these settings, switching off..',
|
||||
err.toString()
|
||||
LOG_TAG,
|
||||
'Faces are not supported with these settings, switching off..',
|
||||
err.toString()
|
||||
);
|
||||
Config.Faces.enabled = false;
|
||||
}
|
||||
@ -462,14 +462,14 @@ export class ConfigDiagnostics {
|
||||
} catch (ex) {
|
||||
const err: Error = ex;
|
||||
NotificationManager.warning(
|
||||
'Some Tasks are not supported with these settings. Disabling temporally. ' +
|
||||
'Please adjust the config properly.',
|
||||
err.toString()
|
||||
'Some Tasks are not supported with these settings. Disabling temporally. ' +
|
||||
'Please adjust the config properly.',
|
||||
err.toString()
|
||||
);
|
||||
Logger.warn(
|
||||
LOG_TAG,
|
||||
'Some Tasks not supported with these settings, switching off..',
|
||||
err.toString()
|
||||
LOG_TAG,
|
||||
'Some Tasks not supported with these settings, switching off..',
|
||||
err.toString()
|
||||
);
|
||||
Config.Faces.enabled = false;
|
||||
}
|
||||
@ -479,34 +479,34 @@ export class ConfigDiagnostics {
|
||||
} catch (ex) {
|
||||
const err: Error = ex;
|
||||
NotificationManager.warning(
|
||||
'Sharing is not supported with these settings. Disabling temporally. ' +
|
||||
'Please adjust the config properly.',
|
||||
err.toString()
|
||||
'Sharing is not supported with these settings. Disabling temporally. ' +
|
||||
'Please adjust the config properly.',
|
||||
err.toString()
|
||||
);
|
||||
Logger.warn(
|
||||
LOG_TAG,
|
||||
'Sharing is not supported with these settings, switching off..',
|
||||
err.toString()
|
||||
LOG_TAG,
|
||||
'Sharing is not supported with these settings, switching off..',
|
||||
err.toString()
|
||||
);
|
||||
Config.Sharing.enabled = false;
|
||||
}
|
||||
|
||||
try {
|
||||
await ConfigDiagnostics.testRandomPhotoConfig(
|
||||
Config.Sharing,
|
||||
Config
|
||||
Config.Sharing,
|
||||
Config
|
||||
);
|
||||
} catch (ex) {
|
||||
const err: Error = ex;
|
||||
NotificationManager.warning(
|
||||
'Random Media is not supported with these settings. Disabling temporally. ' +
|
||||
'Please adjust the config properly.',
|
||||
err.toString()
|
||||
'Random Media is not supported with these settings. Disabling temporally. ' +
|
||||
'Please adjust the config properly.',
|
||||
err.toString()
|
||||
);
|
||||
Logger.warn(
|
||||
LOG_TAG,
|
||||
'Random Media is not supported with these settings, switching off..',
|
||||
err.toString()
|
||||
LOG_TAG,
|
||||
'Random Media is not supported with these settings, switching off..',
|
||||
err.toString()
|
||||
);
|
||||
Config.Sharing.enabled = false;
|
||||
}
|
||||
@ -516,15 +516,15 @@ export class ConfigDiagnostics {
|
||||
} catch (ex) {
|
||||
const err: Error = ex;
|
||||
NotificationManager.warning(
|
||||
'Maps is not supported with these settings. Using open street maps temporally. ' +
|
||||
'Please adjust the config properly.',
|
||||
err.toString()
|
||||
'Maps is not supported with these settings. Using open street maps temporally. ' +
|
||||
'Please adjust the config properly.',
|
||||
err.toString()
|
||||
);
|
||||
Logger.warn(
|
||||
LOG_TAG,
|
||||
'Maps is not supported with these settings. Using open street maps temporally ' +
|
||||
'Please adjust the config properly.',
|
||||
err.toString()
|
||||
LOG_TAG,
|
||||
'Maps is not supported with these settings. Using open street maps temporally ' +
|
||||
'Please adjust the config properly.',
|
||||
err.toString()
|
||||
);
|
||||
Config.Map.mapProvider = MapProviders.OpenStreetMap;
|
||||
}
|
||||
|
@ -5,12 +5,12 @@ import {VideoConvertingJob} from './jobs/VideoConvertingJob';
|
||||
import {PhotoConvertingJob} from './jobs/PhotoConvertingJob';
|
||||
import {ThumbnailGenerationJob} from './jobs/ThumbnailGenerationJob';
|
||||
import {TempFolderCleaningJob} from './jobs/TempFolderCleaningJob';
|
||||
import {PreviewFillingJob} from './jobs/PreviewFillingJob';
|
||||
import {PreviewRestJob} from './jobs/PreviewResetJob';
|
||||
import {AlbumCoverFillingJob} from './jobs/AlbumCoverFillingJob';
|
||||
import {GPXCompressionJob} from './jobs/GPXCompressionJob';
|
||||
import {AlbumRestJob} from './jobs/AlbumResetJob';
|
||||
import {GPXCompressionResetJob} from './jobs/GPXCompressionResetJob';
|
||||
import {TopPickSendJob} from './jobs/TopPickSendJob';
|
||||
import {AlbumCoverRestJob} from './jobs/AlbumCoverResetJob';
|
||||
|
||||
export class JobRepository {
|
||||
private static instance: JobRepository = null;
|
||||
@ -37,8 +37,8 @@ export class JobRepository {
|
||||
|
||||
JobRepository.Instance.register(new IndexingJob());
|
||||
JobRepository.Instance.register(new GalleryRestJob());
|
||||
JobRepository.Instance.register(new PreviewFillingJob());
|
||||
JobRepository.Instance.register(new PreviewRestJob());
|
||||
JobRepository.Instance.register(new AlbumCoverFillingJob());
|
||||
JobRepository.Instance.register(new AlbumCoverRestJob());
|
||||
JobRepository.Instance.register(new VideoConvertingJob());
|
||||
JobRepository.Instance.register(new PhotoConvertingJob());
|
||||
JobRepository.Instance.register(new ThumbnailGenerationJob());
|
||||
|
@ -2,10 +2,10 @@ import {ObjectManagers} from '../../ObjectManagers';
|
||||
import {ConfigTemplateEntry, DefaultsJobs,} from '../../../../common/entities/job/JobDTO';
|
||||
import {Job} from './Job';
|
||||
|
||||
export class PreviewFillingJob extends Job {
|
||||
public readonly Name = DefaultsJobs[DefaultsJobs['Preview Filling']];
|
||||
export class AlbumCoverFillingJob extends Job {
|
||||
public readonly Name = DefaultsJobs[DefaultsJobs['Album Cover Filling']];
|
||||
public readonly ConfigTemplate: ConfigTemplateEntry[] = null;
|
||||
directoryToSetPreview: { id: number; name: string; path: string }[] = null;
|
||||
directoryToSetCover: { id: number; name: string; path: string }[] = null;
|
||||
status: 'Persons' | 'Albums' | 'Directory' = 'Persons';
|
||||
|
||||
public get Supported(): boolean {
|
||||
@ -17,11 +17,11 @@ export class PreviewFillingJob extends Job {
|
||||
}
|
||||
|
||||
protected async step(): Promise<boolean> {
|
||||
if (!this.directoryToSetPreview) {
|
||||
if (!this.directoryToSetCover) {
|
||||
this.Progress.log('Loading Directories to process');
|
||||
this.directoryToSetPreview =
|
||||
await ObjectManagers.getInstance().PreviewManager.getPartialDirsWithoutPreviews();
|
||||
this.Progress.Left = this.directoryToSetPreview.length + 2;
|
||||
this.directoryToSetCover =
|
||||
await ObjectManagers.getInstance().CoverManager.getPartialDirsWithoutCovers();
|
||||
this.Progress.Left = this.directoryToSetCover.length + 2;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -31,18 +31,18 @@ export class PreviewFillingJob extends Job {
|
||||
this.status = 'Albums';
|
||||
return true;
|
||||
case 'Albums':
|
||||
await this.stepAlbumPreview();
|
||||
await this.stepAlbumCover();
|
||||
this.status = 'Directory';
|
||||
return true;
|
||||
case 'Directory':
|
||||
return await this.stepDirectoryPreview();
|
||||
return await this.stepDirectoryCover();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private async stepAlbumPreview(): Promise<boolean> {
|
||||
private async stepAlbumCover(): Promise<boolean> {
|
||||
await ObjectManagers.getInstance().AlbumManager.getAlbums();
|
||||
this.Progress.log('Updating Albums preview');
|
||||
this.Progress.log('Updating Albums cover');
|
||||
this.Progress.Processed++;
|
||||
return false;
|
||||
}
|
||||
@ -54,22 +54,22 @@ export class PreviewFillingJob extends Job {
|
||||
return false;
|
||||
}
|
||||
|
||||
private async stepDirectoryPreview(): Promise<boolean> {
|
||||
if (this.directoryToSetPreview.length === 0) {
|
||||
this.directoryToSetPreview =
|
||||
await ObjectManagers.getInstance().PreviewManager.getPartialDirsWithoutPreviews();
|
||||
private async stepDirectoryCover(): Promise<boolean> {
|
||||
if (this.directoryToSetCover.length === 0) {
|
||||
this.directoryToSetCover =
|
||||
await ObjectManagers.getInstance().CoverManager.getPartialDirsWithoutCovers();
|
||||
// double check if there is really no more
|
||||
if (this.directoryToSetPreview.length > 0) {
|
||||
if (this.directoryToSetCover.length > 0) {
|
||||
return true; // continue
|
||||
}
|
||||
this.Progress.Left = 0;
|
||||
return false;
|
||||
}
|
||||
const directory = this.directoryToSetPreview.shift();
|
||||
this.Progress.log('Setting preview: ' + directory.path + directory.name);
|
||||
this.Progress.Left = this.directoryToSetPreview.length;
|
||||
const directory = this.directoryToSetCover.shift();
|
||||
this.Progress.log('Setting cover: ' + directory.path + directory.name);
|
||||
this.Progress.Left = this.directoryToSetCover.length;
|
||||
|
||||
await ObjectManagers.getInstance().PreviewManager.setAndGetPreviewForDirectory(
|
||||
await ObjectManagers.getInstance().CoverManager.setAndGetCoverForDirectory(
|
||||
directory
|
||||
);
|
||||
this.Progress.Processed++;
|
26
src/backend/model/jobs/jobs/AlbumCoverResetJob.ts
Normal file
26
src/backend/model/jobs/jobs/AlbumCoverResetJob.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import {ObjectManagers} from '../../ObjectManagers';
|
||||
import {ConfigTemplateEntry, DefaultsJobs,} from '../../../../common/entities/job/JobDTO';
|
||||
import {Job} from './Job';
|
||||
|
||||
export class AlbumCoverRestJob extends Job {
|
||||
public readonly Name = DefaultsJobs[DefaultsJobs['Album Cover Reset']];
|
||||
public readonly ConfigTemplate: ConfigTemplateEntry[] = null;
|
||||
protected readonly IsInstant = true;
|
||||
|
||||
public get Supported(): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected async init(): Promise<void> {
|
||||
// abstract function
|
||||
}
|
||||
|
||||
protected async step(): Promise<boolean> {
|
||||
this.Progress.Left = 1;
|
||||
this.Progress.Processed++;
|
||||
await ObjectManagers.getInstance().CoverManager.resetCovers();
|
||||
await ObjectManagers.getInstance().AlbumManager.resetCovers();
|
||||
await ObjectManagers.getInstance().PersonManager.resetPreviews();
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
import { ObjectManagers } from '../../ObjectManagers';
|
||||
import { Config } from '../../../../common/config/private/Config';
|
||||
import {
|
||||
ConfigTemplateEntry,
|
||||
DefaultsJobs,
|
||||
} from '../../../../common/entities/job/JobDTO';
|
||||
import { Job } from './Job';
|
||||
import { DatabaseType } from '../../../../common/config/private/PrivateConfig';
|
||||
|
||||
export class PreviewRestJob extends Job {
|
||||
public readonly Name = DefaultsJobs[DefaultsJobs['Preview Reset']];
|
||||
public readonly ConfigTemplate: ConfigTemplateEntry[] = null;
|
||||
protected readonly IsInstant = true;
|
||||
|
||||
public get Supported(): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected async init(): Promise<void> {
|
||||
// abstract function
|
||||
}
|
||||
|
||||
protected async step(): Promise<boolean> {
|
||||
this.Progress.Left = 1;
|
||||
this.Progress.Processed++;
|
||||
await ObjectManagers.getInstance().PreviewManager.resetPreviews();
|
||||
await ObjectManagers.getInstance().AlbumManager.resetPreviews();
|
||||
await ObjectManagers.getInstance().PersonManager.resetPreviews();
|
||||
return false;
|
||||
}
|
||||
}
|
@ -124,8 +124,8 @@ export class DiskMangerWorker {
|
||||
directories: [],
|
||||
isPartial: false,
|
||||
mediaCount: 0,
|
||||
preview: null,
|
||||
validPreview: false,
|
||||
cover: null,
|
||||
validCover: false,
|
||||
media: [],
|
||||
metaFile: [],
|
||||
};
|
||||
@ -146,7 +146,7 @@ export class DiskMangerWorker {
|
||||
if ((await fsp.stat(fullFilePath)).isDirectory()) {
|
||||
if (
|
||||
settings.noDirectory === true ||
|
||||
settings.previewOnly === true ||
|
||||
settings.coverOnly === true ||
|
||||
(await DiskMangerWorker.excludeDir(
|
||||
file,
|
||||
relativeDirectoryName,
|
||||
@ -156,11 +156,11 @@ export class DiskMangerWorker {
|
||||
continue;
|
||||
}
|
||||
|
||||
// create preview directory
|
||||
// create cover directory
|
||||
const d = (await DiskMangerWorker.scanDirectory(
|
||||
path.join(relativeDirectoryName, file),
|
||||
{
|
||||
previewOnly: true,
|
||||
coverOnly: true,
|
||||
}
|
||||
)) as SubDirectoryDTO;
|
||||
|
||||
@ -182,27 +182,27 @@ export class DiskMangerWorker {
|
||||
: await MetadataLoader.loadPhotoMetadata(fullFilePath),
|
||||
} as PhotoDTO;
|
||||
|
||||
if (!directory.preview) {
|
||||
directory.preview = Utils.clone(photo);
|
||||
if (!directory.cover) {
|
||||
directory.cover = Utils.clone(photo);
|
||||
|
||||
directory.preview.directory = {
|
||||
directory.cover.directory = {
|
||||
path: directory.path,
|
||||
name: directory.name,
|
||||
};
|
||||
}
|
||||
// add the preview photo to the list of media, so it will be saved to the DB
|
||||
// and can be queried to populate previews,
|
||||
// add the cover photo to the list of media, so it will be saved to the DB
|
||||
// and can be queried to populate covers,
|
||||
// otherwise we do not return media list that is only partial
|
||||
directory.media.push(photo);
|
||||
|
||||
if (settings.previewOnly === true) {
|
||||
if (settings.coverOnly === true) {
|
||||
break;
|
||||
}
|
||||
} else if (VideoProcessing.isVideo(fullFilePath)) {
|
||||
if (
|
||||
Config.Media.Video.enabled === false ||
|
||||
settings.noVideo === true ||
|
||||
settings.previewOnly === true
|
||||
settings.coverOnly === true
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
@ -227,7 +227,7 @@ export class DiskMangerWorker {
|
||||
if (
|
||||
!DiskMangerWorker.isEnabledMetaFile(fullFilePath) ||
|
||||
settings.noMetaFile === true ||
|
||||
settings.previewOnly === true
|
||||
settings.coverOnly === true
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
@ -261,7 +261,7 @@ export class DiskMangerWorker {
|
||||
}
|
||||
|
||||
export interface DirectoryScanSettings {
|
||||
previewOnly?: boolean;
|
||||
coverOnly?: boolean;
|
||||
noMetaFile?: boolean;
|
||||
noVideo?: boolean;
|
||||
noPhoto?: boolean;
|
||||
|
@ -45,7 +45,6 @@ export class MetadataLoader {
|
||||
|
||||
try {
|
||||
for (const stream of data.streams) {
|
||||
console.log(stream);
|
||||
if (stream.width) {
|
||||
metadata.size.width = stream.width;
|
||||
metadata.size.height = stream.height;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/**
|
||||
* This version indicates that the sql/entities/*Entity.ts files got changed and the db needs to be recreated
|
||||
*/
|
||||
export const DataStructureVersion = 31;
|
||||
export const DataStructureVersion = 32;
|
||||
|
@ -667,15 +667,15 @@ export class ServerJobConfig {
|
||||
{indexChangesOnly: true} // set config explicitly, so it is not undefined on the UI
|
||||
),
|
||||
new JobScheduleConfig(
|
||||
DefaultsJobs[DefaultsJobs['Preview Filling']],
|
||||
DefaultsJobs[DefaultsJobs['Preview Filling']],
|
||||
DefaultsJobs[DefaultsJobs['Album Cover Filling']],
|
||||
DefaultsJobs[DefaultsJobs['Album Cover Filling']],
|
||||
new AfterJobTriggerConfig(DefaultsJobs[DefaultsJobs['Indexing']]),
|
||||
{}
|
||||
),
|
||||
new JobScheduleConfig(
|
||||
DefaultsJobs[DefaultsJobs['Thumbnail Generation']],
|
||||
DefaultsJobs[DefaultsJobs['Thumbnail Generation']],
|
||||
new AfterJobTriggerConfig(DefaultsJobs[DefaultsJobs['Preview Filling']]),
|
||||
new AfterJobTriggerConfig(DefaultsJobs[DefaultsJobs['Album Cover Filling']]),
|
||||
{sizes: [240], indexedOnly: true}
|
||||
),
|
||||
new JobScheduleConfig(
|
||||
@ -872,11 +872,11 @@ export class ServerPhotoConfig extends ClientPhotoConfig {
|
||||
}
|
||||
|
||||
@SubConfigClass({softReadonly: true})
|
||||
export class ServerPreviewConfig {
|
||||
export class ServerAlbumCoverConfig {
|
||||
@ConfigProperty({
|
||||
type: 'object',
|
||||
tags: {
|
||||
name: $localize`Preview Filter query`,
|
||||
name: $localize`Cover Filter query`,
|
||||
uiResetNeeded: {db: true},
|
||||
priority: ConfigPriority.advanced,
|
||||
uiType: 'SearchQuery'
|
||||
@ -890,11 +890,11 @@ export class ServerPreviewConfig {
|
||||
@ConfigProperty({
|
||||
arrayType: SortingMethods,
|
||||
tags: {
|
||||
name: $localize`Preview Sorting`,
|
||||
name: $localize`Cover Sorting`,
|
||||
uiResetNeeded: {db: true},
|
||||
priority: ConfigPriority.advanced
|
||||
},
|
||||
description: $localize`If multiple preview is available sorts them by these methods and selects the first one.`,
|
||||
description: $localize`If multiple cover is available sorts them by these methods and selects the first one.`,
|
||||
})
|
||||
Sorting: SortingMethods[] = [
|
||||
SortingMethods.descRating,
|
||||
@ -1120,18 +1120,18 @@ export class ServerConfig extends ClientConfig {
|
||||
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
name: $localize`Preview`,
|
||||
name: $localize`Album cover`,
|
||||
uiIcon: 'ionImageOutline',
|
||||
uiJob: [
|
||||
{
|
||||
job: DefaultsJobs[DefaultsJobs['Preview Filling']],
|
||||
job: DefaultsJobs[DefaultsJobs['Album Cover Filling']],
|
||||
}, {
|
||||
job: DefaultsJobs[DefaultsJobs['Preview Reset']],
|
||||
job: DefaultsJobs[DefaultsJobs['Album Cover Reset']],
|
||||
hideProgress: true
|
||||
}]
|
||||
} as TAGS
|
||||
})
|
||||
Preview: ServerPreviewConfig = new ServerPreviewConfig();
|
||||
AlbumCover: ServerAlbumCoverConfig = new ServerAlbumCoverConfig();
|
||||
|
||||
@ConfigProperty({
|
||||
tags: {
|
||||
|
@ -251,15 +251,15 @@ export class ContentWrapper {
|
||||
}
|
||||
|
||||
private static packDirectory(cw: ContentWrapper, dir: DirectoryBaseDTO | SearchResultDTO, isSearchResult = false): void {
|
||||
if ((dir as DirectoryBaseDTO).preview) {
|
||||
(dir as DirectoryBaseDTO).preview.directory = {
|
||||
path: (dir as DirectoryBaseDTO).preview.directory.path,
|
||||
name: (dir as DirectoryBaseDTO).preview.directory.name,
|
||||
if ((dir as DirectoryBaseDTO).cover) {
|
||||
(dir as DirectoryBaseDTO).cover.directory = {
|
||||
path: (dir as DirectoryBaseDTO).cover.directory.path,
|
||||
name: (dir as DirectoryBaseDTO).cover.directory.name,
|
||||
} as DirectoryPathDTO;
|
||||
|
||||
// make sure that it is not a same object as one of the photo in the media[]
|
||||
// as the next foreach would remove the directory
|
||||
(dir as DirectoryBaseDTO).preview = Utils.clone((dir as DirectoryBaseDTO).preview);
|
||||
(dir as DirectoryBaseDTO).cover = Utils.clone((dir as DirectoryBaseDTO).cover);
|
||||
}
|
||||
|
||||
if (dir.media) {
|
||||
@ -284,7 +284,7 @@ export class ContentWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
delete (dir as DirectoryBaseDTO).validPreview; // should not go to the client side;
|
||||
delete (dir as DirectoryBaseDTO).validCover; // should not go to the client side;
|
||||
}
|
||||
|
||||
private static deMapify(cw: ContentWrapper, media: FileDTO, isSearchResult: boolean): void {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { MediaDTO, MediaDTOUtils } from './MediaDTO';
|
||||
import { FileDTO } from './FileDTO';
|
||||
import { PhotoDTO, PreviewPhotoDTO } from './PhotoDTO';
|
||||
import { PhotoDTO, CoverPhotoDTO } from './PhotoDTO';
|
||||
import { Utils } from '../Utils';
|
||||
|
||||
export interface DirectoryPathDTO {
|
||||
@ -24,8 +24,8 @@ export interface DirectoryBaseDTO<S extends FileDTO = MediaDTO>
|
||||
directories?: DirectoryBaseDTO<S>[];
|
||||
media?: S[];
|
||||
metaFile?: FileDTO[];
|
||||
preview?: PreviewPhotoDTO;
|
||||
validPreview?: boolean; // does not go to the client side
|
||||
cover?: CoverPhotoDTO;
|
||||
validCover?: boolean; // does not go to the client side
|
||||
}
|
||||
|
||||
export interface ParentDirectoryDTO<S extends FileDTO = MediaDTO>
|
||||
@ -53,8 +53,8 @@ export interface SubDirectoryDTO<S extends FileDTO = MediaDTO>
|
||||
isPartial?: boolean;
|
||||
parent: ParentDirectoryDTO<S>;
|
||||
mediaCount: number;
|
||||
preview: PreviewPhotoDTO;
|
||||
validPreview?: boolean; // does not go to the client side
|
||||
cover: CoverPhotoDTO;
|
||||
validCover?: boolean; // does not go to the client side
|
||||
}
|
||||
|
||||
export const DirectoryDTOUtils = {
|
||||
@ -78,15 +78,15 @@ export const DirectoryDTOUtils = {
|
||||
},
|
||||
|
||||
removeReferences: (dir: DirectoryBaseDTO): DirectoryBaseDTO => {
|
||||
if (dir.preview) {
|
||||
dir.preview.directory = {
|
||||
path: dir.preview.directory.path,
|
||||
name: dir.preview.directory.name,
|
||||
if (dir.cover) {
|
||||
dir.cover.directory = {
|
||||
path: dir.cover.directory.path,
|
||||
name: dir.cover.directory.name,
|
||||
} as DirectoryPathDTO;
|
||||
|
||||
// make sure that it is not a same object as one of the photo in the media[]
|
||||
// as the next foreach would remove the directory
|
||||
dir.preview = Utils.clone(dir.preview);
|
||||
dir.cover = Utils.clone(dir.cover);
|
||||
}
|
||||
|
||||
if (dir.media) {
|
||||
@ -107,7 +107,7 @@ export const DirectoryDTOUtils = {
|
||||
});
|
||||
}
|
||||
|
||||
delete dir.validPreview; // should not go to the client side;
|
||||
delete dir.validCover; // should not go to the client side;
|
||||
|
||||
return dir;
|
||||
},
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { DirectoryPathDTO } from './DirectoryDTO';
|
||||
import { MediaDimension, MediaDTO, MediaMetadata } from './MediaDTO';
|
||||
|
||||
export interface PreviewPhotoDTO extends MediaDTO {
|
||||
export interface CoverPhotoDTO extends MediaDTO {
|
||||
name: string;
|
||||
directory: DirectoryPathDTO;
|
||||
}
|
||||
|
||||
export interface PhotoDTO extends PreviewPhotoDTO, MediaDTO {
|
||||
export interface PhotoDTO extends CoverPhotoDTO, MediaDTO {
|
||||
id: number;
|
||||
name: string;
|
||||
directory: DirectoryPathDTO;
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { PreviewPhotoDTO } from '../PhotoDTO';
|
||||
import { CoverPhotoDTO } from '../PhotoDTO';
|
||||
|
||||
export interface AlbumBaseDTO {
|
||||
id: number;
|
||||
name: string;
|
||||
preview?: PreviewPhotoDTO;
|
||||
cover?: CoverPhotoDTO;
|
||||
count: number;
|
||||
locked: boolean;
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { AlbumBaseDTO } from './AlbumBaseDTO';
|
||||
import { PreviewPhotoDTO } from '../PhotoDTO';
|
||||
import { CoverPhotoDTO } from '../PhotoDTO';
|
||||
import { SearchQueryDTO } from '../SearchQueryDTO';
|
||||
|
||||
export interface SavedSearchDTO extends AlbumBaseDTO {
|
||||
id: number;
|
||||
name: string;
|
||||
preview?: PreviewPhotoDTO;
|
||||
cover?: CoverPhotoDTO;
|
||||
count: number;
|
||||
locked: boolean;
|
||||
|
||||
|
@ -9,8 +9,8 @@ export enum DefaultsJobs {
|
||||
'Photo Converting' = 4,
|
||||
'Thumbnail Generation' = 5,
|
||||
'Temp Folder Cleaning' = 6,
|
||||
'Preview Filling' = 7,
|
||||
'Preview Reset' = 8,
|
||||
'Album Cover Filling' = 7,
|
||||
'Album Cover Reset' = 8,
|
||||
'GPX Compression' = 9,
|
||||
'Album Reset' = 10,
|
||||
'Delete Compressed GPX' = 11,
|
||||
|
@ -59,10 +59,10 @@ export class BackendtextService {
|
||||
return $localize`Video converting`;
|
||||
case DefaultsJobs['Temp Folder Cleaning']:
|
||||
return $localize`Temp folder cleaning`;
|
||||
case DefaultsJobs['Preview Filling']:
|
||||
return $localize`Preview filling`;
|
||||
case DefaultsJobs['Preview Reset']:
|
||||
return $localize`Preview reset`;
|
||||
case DefaultsJobs['Album Cover Filling']:
|
||||
return $localize`Album Cover filling`;
|
||||
case DefaultsJobs['Album Cover Reset']:
|
||||
return $localize`Album Cover reset`;
|
||||
case DefaultsJobs['GPX Compression']:
|
||||
return $localize`GPX compression`;
|
||||
default:
|
||||
|
@ -54,9 +54,9 @@ export class AlbumComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
if (this.album.preview) {
|
||||
if (this.album.cover) {
|
||||
this.thumbnail = this.thumbnailService.getThumbnail(
|
||||
new Media(this.album.preview, this.size, this.size)
|
||||
new Media(this.album.cover, this.size, this.size)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import {Utils} from '../../../../../../common/Utils';
|
||||
import {Media} from '../../Media';
|
||||
import {Thumbnail, ThumbnailManagerService,} from '../../thumbnailManager.service';
|
||||
import {QueryService} from '../../../../model/query.service';
|
||||
import {PreviewPhotoDTO} from '../../../../../../common/entities/PhotoDTO';
|
||||
import {CoverPhotoDTO} from '../../../../../../common/entities/PhotoDTO';
|
||||
import {Config} from '../../../../../../common/config/public/Config';
|
||||
|
||||
@Component({
|
||||
@ -27,8 +27,8 @@ export class GalleryDirectoryComponent implements OnInit, OnDestroy {
|
||||
) {
|
||||
}
|
||||
|
||||
public get SamplePhoto(): PreviewPhotoDTO {
|
||||
return this.directory.preview;
|
||||
public get SamplePhoto(): CoverPhotoDTO {
|
||||
return this.directory.cover;
|
||||
}
|
||||
|
||||
getSanitizedThUrl(): SafeStyle {
|
||||
@ -58,7 +58,7 @@ export class GalleryDirectoryComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
if (this.directory.preview) {
|
||||
if (this.directory.cover) {
|
||||
this.thumbnail = this.thumbnailService.getThumbnail(
|
||||
new Media(this.SamplePhoto, this.size, this.size)
|
||||
);
|
||||
|
@ -257,7 +257,7 @@ export class GalleryGridComponent
|
||||
}
|
||||
|
||||
// TODO: This is deprecated,
|
||||
// we do not post update galleries anymore since the preview member in the DriectoryDTO
|
||||
// we do not post update galleries anymore since the cover member in the DriectoryDTO
|
||||
private mergeNewPhotos(): void {
|
||||
// merge new data with old one
|
||||
let lastSameIndex = 0;
|
||||
|
@ -34,7 +34,7 @@
|
||||
{{Name}} <span i18n>config is not supported with these settings.</span>
|
||||
</div>
|
||||
<div class="row mt-2">
|
||||
<div class="col" *ngIf="states.tags?.uiJob && !states.tags?.uiJob[0].description">
|
||||
<div class="col-auto" *ngIf="states.tags?.uiJob && !states.tags?.uiJob[0].description">
|
||||
<ng-container
|
||||
*ngTemplateOutlet="JobTemplate; context:{ uiJob: states.tags?.uiJob }"
|
||||
></ng-container>
|
||||
|
@ -15,7 +15,7 @@ import {
|
||||
PhotoDTO,
|
||||
PhotoMetadata,
|
||||
PositionMetaData,
|
||||
PreviewPhotoDTO
|
||||
CoverPhotoDTO
|
||||
} from '../src/common/entities/PhotoDTO';
|
||||
import {DirectoryBaseDTO, DirectoryPathDTO} from '../src/common/entities/DirectoryDTO';
|
||||
import {FileDTO} from '../src/common/entities/FileDTO';
|
||||
@ -274,8 +274,8 @@ export class TestHelper {
|
||||
mediaCount: 0,
|
||||
directories: [],
|
||||
metaFile: [],
|
||||
preview: null,
|
||||
validPreview: false,
|
||||
cover: null,
|
||||
validCover: false,
|
||||
media: [],
|
||||
lastModified: Date.now(),
|
||||
lastScanned: null,
|
||||
@ -380,21 +380,21 @@ export class TestHelper {
|
||||
}
|
||||
|
||||
dir.media.push(p);
|
||||
TestHelper.updatePreview(dir);
|
||||
TestHelper.updateCover(dir);
|
||||
return p;
|
||||
}
|
||||
|
||||
static updatePreview(dir: DirectoryBaseDTO): void {
|
||||
static updateCover(dir: DirectoryBaseDTO): void {
|
||||
if (dir.media.length > 0) {
|
||||
dir.preview = dir.media.sort((a, b): number => b.metadata.creationDate - a.metadata.creationDate)[0];
|
||||
dir.cover = dir.media.sort((a, b): number => b.metadata.creationDate - a.metadata.creationDate)[0];
|
||||
} else {
|
||||
const filtered = dir.directories.filter((d): PreviewPhotoDTO => d.preview).map((d): PreviewPhotoDTO => d.preview);
|
||||
const filtered = dir.directories.filter((d): CoverPhotoDTO => d.cover).map((d): CoverPhotoDTO => d.cover);
|
||||
if (filtered.length > 0) {
|
||||
dir.preview = filtered.sort((a, b): number => b.metadata.creationDate - a.metadata.creationDate)[0];
|
||||
dir.cover = filtered.sort((a, b): number => b.metadata.creationDate - a.metadata.creationDate)[0];
|
||||
}
|
||||
}
|
||||
if (dir.parent) {
|
||||
TestHelper.updatePreview(dir.parent);
|
||||
TestHelper.updateCover(dir.parent);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -37,16 +37,16 @@ describe('AlbumManager', (sqlHelper: DBTestHelper) => {
|
||||
};
|
||||
|
||||
|
||||
const toAlbumPreview = (m: MediaDTO): MediaDTO => {
|
||||
const toAlbumCover = (m: MediaDTO): MediaDTO => {
|
||||
// generated dirs for test contain everything, not like return values from the server.
|
||||
const tmpDir: ParentDirectoryDTO = m.directory as ParentDirectoryDTO;
|
||||
const tmpM = tmpDir.media;
|
||||
const tmpD = tmpDir.directories;
|
||||
const tmpP = tmpDir.preview;
|
||||
const tmpP = tmpDir.cover;
|
||||
const tmpMT = tmpDir.metaFile;
|
||||
delete tmpDir.directories;
|
||||
delete tmpDir.media;
|
||||
delete tmpDir.preview;
|
||||
delete tmpDir.cover;
|
||||
delete tmpDir.metaFile;
|
||||
const ret = Utils.clone(m);
|
||||
delete ret.id;
|
||||
@ -54,7 +54,7 @@ describe('AlbumManager', (sqlHelper: DBTestHelper) => {
|
||||
delete ret.metadata;
|
||||
tmpDir.directories = tmpD;
|
||||
tmpDir.media = tmpM;
|
||||
tmpDir.preview = tmpP;
|
||||
tmpDir.cover = tmpP;
|
||||
tmpDir.metaFile = tmpMT;
|
||||
return ret;
|
||||
};
|
||||
@ -152,7 +152,7 @@ describe('AlbumManager', (sqlHelper: DBTestHelper) => {
|
||||
searchQuery: query,
|
||||
locked: false,
|
||||
count: 1,
|
||||
preview: toAlbumPreview(sqlHelper.testGalleyEntities.p)
|
||||
cover: toAlbumCover(sqlHelper.testGalleyEntities.p)
|
||||
} as SavedSearchDTO]));
|
||||
|
||||
|
||||
|
@ -71,13 +71,13 @@ describe('IndexingManager', (sqlHelper: DBTestHelper) => {
|
||||
|
||||
afterEach(async () => {
|
||||
Config.loadSync();
|
||||
Config.Preview.Sorting = [SortingMethods.descRating];
|
||||
Config.AlbumCover.Sorting = [SortingMethods.descRating];
|
||||
await sqlHelper.clearDB();
|
||||
});
|
||||
|
||||
const setPartial = (dir: DirectoryBaseDTO) => {
|
||||
if (!dir.preview && dir.media && dir.media.length > 0) {
|
||||
dir.preview = dir.media[0];
|
||||
if (!dir.cover && dir.media && dir.media.length > 0) {
|
||||
dir.cover = dir.media[0];
|
||||
}
|
||||
dir.isPartial = true;
|
||||
delete dir.directories;
|
||||
@ -94,11 +94,11 @@ describe('IndexingManager', (sqlHelper: DBTestHelper) => {
|
||||
const indexifyReturn = (dir: DirectoryBaseDTO): DirectoryBaseDTO => {
|
||||
const d = Utils.clone(dir);
|
||||
|
||||
delete d.preview;
|
||||
delete d.cover;
|
||||
if (d.directories) {
|
||||
for (const subD of d.directories) {
|
||||
if (subD.preview) {
|
||||
delete subD.preview.metadata;
|
||||
if (subD.cover) {
|
||||
delete subD.cover.metadata;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -111,8 +111,8 @@ describe('IndexingManager', (sqlHelper: DBTestHelper) => {
|
||||
dir.media.forEach((media: MediaDTO) => {
|
||||
delete media.id;
|
||||
});
|
||||
if (dir.preview) {
|
||||
delete dir.preview.id;
|
||||
if (dir.cover) {
|
||||
delete dir.cover.id;
|
||||
}
|
||||
if (dir.metaFile) {
|
||||
if (dir.metaFile.length === 0) {
|
||||
@ -288,7 +288,7 @@ describe('IndexingManager', (sqlHelper: DBTestHelper) => {
|
||||
});
|
||||
|
||||
|
||||
it('should select preview', async () => {
|
||||
it('should select cover', async () => {
|
||||
const selectDirectory = async (gmTest: GalleryManagerTest, dir: DirectoryBaseDTO): Promise<ParentDirectoryDTO> => {
|
||||
const conn = await SQLConnection.getConnection();
|
||||
const selected = await gmTest.getParentDirFromId(conn,
|
||||
@ -357,8 +357,8 @@ describe('IndexingManager', (sqlHelper: DBTestHelper) => {
|
||||
sp1.metadata.rating = 5;
|
||||
const sp2 = TestHelper.getRandomizedPhotoEntry(subDir, 'subPhoto2', 0);
|
||||
sp2.metadata.rating = 3;
|
||||
subDir.preview = sp1;
|
||||
Config.Preview.Sorting = [SortingMethods.descRating];
|
||||
subDir.cover = sp1;
|
||||
Config.AlbumCover.Sorting = [SortingMethods.descRating];
|
||||
|
||||
DirectoryDTOUtils.removeReferences(subDir);
|
||||
await im.saveToDB(Utils.clone(subDir) as ParentDirectoryDTO);
|
||||
@ -395,8 +395,8 @@ describe('IndexingManager', (sqlHelper: DBTestHelper) => {
|
||||
sp1.metadata.rating = 5;
|
||||
const sp2 = TestHelper.getRandomizedPhotoEntry(subDir, 'subPhoto2', 0);
|
||||
sp2.metadata.rating = 3;
|
||||
subDir.preview = sp1;
|
||||
Config.Preview.Sorting = [SortingMethods.descRating];
|
||||
subDir.cover = sp1;
|
||||
Config.AlbumCover.Sorting = [SortingMethods.descRating];
|
||||
|
||||
|
||||
DirectoryDTOUtils.removeReferences(subDir);
|
||||
@ -432,8 +432,8 @@ describe('IndexingManager', (sqlHelper: DBTestHelper) => {
|
||||
sp1.metadata.rating = 5;
|
||||
const sp2 = TestHelper.getRandomizedPhotoEntry(subDir, 'subPhoto2', 0);
|
||||
sp2.metadata.rating = 3;
|
||||
subDir.preview = sp1;
|
||||
Config.Preview.Sorting = [SortingMethods.descRating];
|
||||
subDir.cover = sp1;
|
||||
Config.AlbumCover.Sorting = [SortingMethods.descRating];
|
||||
|
||||
DirectoryDTOUtils.removeReferences(parent);
|
||||
await im.saveToDB(Utils.clone(parent) as ParentDirectoryDTO);
|
||||
@ -562,8 +562,8 @@ describe('IndexingManager', (sqlHelper: DBTestHelper) => {
|
||||
sp1.metadata.rating = 5;
|
||||
const sp2 = TestHelper.getRandomizedPhotoEntry(subDir, 'subPhoto2', 1);
|
||||
sp2.metadata.rating = 3;
|
||||
subDir.preview = sp1;
|
||||
Config.Preview.Sorting = [SortingMethods.descRating];
|
||||
subDir.cover = sp1;
|
||||
Config.AlbumCover.Sorting = [SortingMethods.descRating];
|
||||
|
||||
DirectoryDTOUtils.removeReferences(parent);
|
||||
const s1 = im.queueForSave(Utils.clone(parent) as ParentDirectoryDTO);
|
||||
@ -578,7 +578,7 @@ describe('IndexingManager', (sqlHelper: DBTestHelper) => {
|
||||
DirectoryDTOUtils.removeReferences(selected);
|
||||
removeIds(selected);
|
||||
setPartial(subDir);
|
||||
parent.directories.forEach(d => delete (d.preview.metadata as any).faces);
|
||||
parent.directories.forEach(d => delete (d.cover.metadata as any).faces);
|
||||
delete sp1.metadata.faces;
|
||||
delete sp2.metadata.faces;
|
||||
expect(Utils.clone(Utils.removeNullOrEmptyObj(selected)))
|
||||
@ -709,8 +709,8 @@ describe('IndexingManager', (sqlHelper: DBTestHelper) => {
|
||||
await im.saveToDB(dir);
|
||||
|
||||
const albums = await am.getAlbums();
|
||||
expect(albums[0].preview).to.be.an('object');
|
||||
delete albums[0].preview;
|
||||
expect(albums[0].cover).to.be.an('object');
|
||||
delete albums[0].cover;
|
||||
expect(albums).to.be.deep.equal([
|
||||
{
|
||||
id: 1,
|
||||
|
@ -10,7 +10,7 @@ import {Connection} from 'typeorm';
|
||||
import {PhotoDTO} from '../../../../../src/common/entities/PhotoDTO';
|
||||
import {VideoDTO} from '../../../../../src/common/entities/VideoDTO';
|
||||
import {FileDTO} from '../../../../../src/common/entities/FileDTO';
|
||||
import {PreviewManager} from '../../../../../src/backend/model/database/PreviewManager';
|
||||
import {CoverManager} from '../../../../../src/backend/model/database/CoverManager';
|
||||
import {Config} from '../../../../../src/common/config/private/Config';
|
||||
import {SortingMethods} from '../../../../../src/common/entities/SortingMethods';
|
||||
import {Utils} from '../../../../../src/common/Utils';
|
||||
@ -59,7 +59,7 @@ class GalleryManagerTest extends GalleryManager {
|
||||
}
|
||||
}
|
||||
|
||||
describe('PreviewManager', (sqlHelper: DBTestHelper) => {
|
||||
describe('CoverManager', (sqlHelper: DBTestHelper) => {
|
||||
describe = tmpDescribe;
|
||||
/**
|
||||
* dir
|
||||
@ -134,12 +134,12 @@ describe('PreviewManager', (sqlHelper: DBTestHelper) => {
|
||||
const tmpDir: DirectoryBaseDTO = m.directory as DirectoryBaseDTO;
|
||||
const tmpM = tmpDir.media;
|
||||
const tmpD = tmpDir.directories;
|
||||
const tmpP = tmpDir.preview;
|
||||
const tmpP = tmpDir.cover;
|
||||
const tmpMT = tmpDir.metaFile;
|
||||
delete tmpDir.directories;
|
||||
delete tmpDir.media;
|
||||
delete tmpDir.preview;
|
||||
delete tmpDir.validPreview;
|
||||
delete tmpDir.cover;
|
||||
delete tmpDir.validCover;
|
||||
delete tmpDir.metaFile;
|
||||
const ret = Utils.clone(m);
|
||||
delete (ret.directory as DirectoryBaseDTO).id;
|
||||
@ -149,7 +149,7 @@ describe('PreviewManager', (sqlHelper: DBTestHelper) => {
|
||||
delete (ret as PhotoDTO).metadata;
|
||||
tmpDir.directories = tmpD;
|
||||
tmpDir.media = tmpM;
|
||||
tmpDir.preview = tmpP;
|
||||
tmpDir.cover = tmpP;
|
||||
tmpDir.metaFile = tmpMT;
|
||||
return ret;
|
||||
};
|
||||
@ -160,83 +160,83 @@ describe('PreviewManager', (sqlHelper: DBTestHelper) => {
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
Config.Preview.SearchQuery = null;
|
||||
Config.Preview.Sorting = [SortingMethods.descRating, SortingMethods.descDate];
|
||||
Config.AlbumCover.SearchQuery = null;
|
||||
Config.AlbumCover.Sorting = [SortingMethods.descRating, SortingMethods.descDate];
|
||||
});
|
||||
|
||||
|
||||
it('should list directories without preview', async () => {
|
||||
const pm = new PreviewManager();
|
||||
it('should list directories without cover', async () => {
|
||||
const pm = new CoverManager();
|
||||
const partialDir = (d: DirectoryBaseDTO) => {
|
||||
return {id: d.id, name: d.name, path: d.path};
|
||||
};
|
||||
expect(await pm.getPartialDirsWithoutPreviews()).to.deep.equalInAnyOrder([partialDir(dir)]);
|
||||
expect(await pm.getPartialDirsWithoutCovers()).to.deep.equalInAnyOrder([partialDir(dir)]);
|
||||
const conn = await SQLConnection.getConnection();
|
||||
|
||||
await conn.createQueryBuilder()
|
||||
.update(DirectoryEntity).set({validPreview: false}).execute();
|
||||
.update(DirectoryEntity).set({validCover: false}).execute();
|
||||
|
||||
expect(await pm.getPartialDirsWithoutPreviews()).to.deep.equalInAnyOrder([dir, subDir, subDir2].map(d => partialDir(d)));
|
||||
expect(await pm.getPartialDirsWithoutCovers()).to.deep.equalInAnyOrder([dir, subDir, subDir2].map(d => partialDir(d)));
|
||||
});
|
||||
|
||||
it('should sort directory preview', async () => {
|
||||
const pm = new PreviewManager();
|
||||
Config.Preview.Sorting = [SortingMethods.descRating, SortingMethods.descDate];
|
||||
expect(Utils.clone(await pm.setAndGetPreviewForDirectory(subDir))).to.deep.equalInAnyOrder(previewifyMedia(p2));
|
||||
Config.Preview.Sorting = [SortingMethods.descDate];
|
||||
expect(Utils.clone(await pm.setAndGetPreviewForDirectory(subDir))).to.deep.equalInAnyOrder(previewifyMedia(pFaceLess));
|
||||
Config.Preview.Sorting = [SortingMethods.descRating];
|
||||
expect(Utils.clone(await pm.setAndGetPreviewForDirectory(dir))).to.deep.equalInAnyOrder(previewifyMedia(p4));
|
||||
Config.Preview.Sorting = [SortingMethods.descName];
|
||||
expect(Utils.clone(await pm.setAndGetPreviewForDirectory(dir))).to.deep.equalInAnyOrder(previewifyMedia(v));
|
||||
it('should sort directory cover', async () => {
|
||||
const pm = new CoverManager();
|
||||
Config.AlbumCover.Sorting = [SortingMethods.descRating, SortingMethods.descDate];
|
||||
expect(Utils.clone(await pm.setAndGetCoverForDirectory(subDir))).to.deep.equalInAnyOrder(previewifyMedia(p2));
|
||||
Config.AlbumCover.Sorting = [SortingMethods.descDate];
|
||||
expect(Utils.clone(await pm.setAndGetCoverForDirectory(subDir))).to.deep.equalInAnyOrder(previewifyMedia(pFaceLess));
|
||||
Config.AlbumCover.Sorting = [SortingMethods.descRating];
|
||||
expect(Utils.clone(await pm.setAndGetCoverForDirectory(dir))).to.deep.equalInAnyOrder(previewifyMedia(p4));
|
||||
Config.AlbumCover.Sorting = [SortingMethods.descName];
|
||||
expect(Utils.clone(await pm.setAndGetCoverForDirectory(dir))).to.deep.equalInAnyOrder(previewifyMedia(v));
|
||||
});
|
||||
|
||||
it('should get preview for directory', async () => {
|
||||
const pm = new PreviewManager();
|
||||
it('should get cover for directory', async () => {
|
||||
const pm = new CoverManager();
|
||||
|
||||
Config.Preview.SearchQuery = {type: SearchQueryTypes.any_text, text: 'Boba'} as TextSearch;
|
||||
expect(Utils.clone(await pm.setAndGetPreviewForDirectory(subDir))).to.deep.equalInAnyOrder(previewifyMedia(p));
|
||||
Config.Preview.SearchQuery = {type: SearchQueryTypes.any_text, text: 'Derem'} as TextSearch;
|
||||
expect(Utils.clone(await pm.setAndGetPreviewForDirectory(subDir))).to.deep.equalInAnyOrder(previewifyMedia(p2));
|
||||
expect(Utils.clone(await pm.setAndGetPreviewForDirectory(dir))).to.deep.equalInAnyOrder(previewifyMedia(p2));
|
||||
expect(Utils.clone(await pm.setAndGetPreviewForDirectory(subDir2))).to.deep.equalInAnyOrder(previewifyMedia(p4));
|
||||
Config.AlbumCover.SearchQuery = {type: SearchQueryTypes.any_text, text: 'Boba'} as TextSearch;
|
||||
expect(Utils.clone(await pm.setAndGetCoverForDirectory(subDir))).to.deep.equalInAnyOrder(previewifyMedia(p));
|
||||
Config.AlbumCover.SearchQuery = {type: SearchQueryTypes.any_text, text: 'Derem'} as TextSearch;
|
||||
expect(Utils.clone(await pm.setAndGetCoverForDirectory(subDir))).to.deep.equalInAnyOrder(previewifyMedia(p2));
|
||||
expect(Utils.clone(await pm.setAndGetCoverForDirectory(dir))).to.deep.equalInAnyOrder(previewifyMedia(p2));
|
||||
expect(Utils.clone(await pm.setAndGetCoverForDirectory(subDir2))).to.deep.equalInAnyOrder(previewifyMedia(p4));
|
||||
|
||||
});
|
||||
|
||||
it('should get preview for saved search', async () => {
|
||||
const pm = new PreviewManager();
|
||||
Config.Preview.SearchQuery = null;
|
||||
expect(Utils.clone(await pm.getAlbumPreview({
|
||||
it('should get cover for saved search', async () => {
|
||||
const pm = new CoverManager();
|
||||
Config.AlbumCover.SearchQuery = null;
|
||||
expect(Utils.clone(await pm.getAlbumCover({
|
||||
searchQuery: {
|
||||
type: SearchQueryTypes.any_text,
|
||||
text: 'sw'
|
||||
} as TextSearch
|
||||
}))).to.deep.equalInAnyOrder(previewifyMedia(p4));
|
||||
Config.Preview.SearchQuery = {type: SearchQueryTypes.any_text, text: 'Boba'} as TextSearch;
|
||||
expect(Utils.clone(await pm.getAlbumPreview({
|
||||
Config.AlbumCover.SearchQuery = {type: SearchQueryTypes.any_text, text: 'Boba'} as TextSearch;
|
||||
expect(Utils.clone(await pm.getAlbumCover({
|
||||
searchQuery: {
|
||||
type: SearchQueryTypes.any_text,
|
||||
text: 'sw'
|
||||
} as TextSearch
|
||||
}))).to.deep.equalInAnyOrder(previewifyMedia(p));
|
||||
Config.Preview.SearchQuery = {type: SearchQueryTypes.any_text, text: 'Derem'} as TextSearch;
|
||||
expect(Utils.clone(await pm.getAlbumPreview({
|
||||
Config.AlbumCover.SearchQuery = {type: SearchQueryTypes.any_text, text: 'Derem'} as TextSearch;
|
||||
expect(Utils.clone(await pm.getAlbumCover({
|
||||
searchQuery: {
|
||||
type: SearchQueryTypes.any_text,
|
||||
text: 'sw'
|
||||
} as TextSearch
|
||||
}))).to.deep.equalInAnyOrder(previewifyMedia(p2));
|
||||
// Having a preview search query that does not return valid result
|
||||
Config.Preview.SearchQuery = {type: SearchQueryTypes.any_text, text: 'wont find it'} as TextSearch;
|
||||
expect(Utils.clone(await pm.getAlbumPreview({
|
||||
Config.AlbumCover.SearchQuery = {type: SearchQueryTypes.any_text, text: 'wont find it'} as TextSearch;
|
||||
expect(Utils.clone(await pm.getAlbumCover({
|
||||
searchQuery: {
|
||||
type: SearchQueryTypes.any_text,
|
||||
text: 'Derem'
|
||||
} as TextSearch
|
||||
}))).to.deep.equalInAnyOrder(previewifyMedia(p2));
|
||||
// having a saved search that does not have any image
|
||||
Config.Preview.SearchQuery = {type: SearchQueryTypes.any_text, text: 'Derem'} as TextSearch;
|
||||
expect(Utils.clone(await pm.getAlbumPreview({
|
||||
Config.AlbumCover.SearchQuery = {type: SearchQueryTypes.any_text, text: 'Derem'} as TextSearch;
|
||||
expect(Utils.clone(await pm.getAlbumCover({
|
||||
searchQuery: {
|
||||
type: SearchQueryTypes.any_text,
|
||||
text: 'wont find it'
|
||||
@ -244,9 +244,9 @@ describe('PreviewManager', (sqlHelper: DBTestHelper) => {
|
||||
}))).to.deep.equal(null);
|
||||
});
|
||||
|
||||
it('should invalidate and update preview', async () => {
|
||||
it('should invalidate and update cover', async () => {
|
||||
const gm = new GalleryManagerTest();
|
||||
const pm = new PreviewManager();
|
||||
const pm = new CoverManager();
|
||||
const conn = await SQLConnection.getConnection();
|
||||
|
||||
const selectDir = async () => {
|
||||
@ -254,7 +254,7 @@ describe('PreviewManager', (sqlHelper: DBTestHelper) => {
|
||||
where: {id: subDir.id},
|
||||
join: {
|
||||
alias: 'dir',
|
||||
leftJoinAndSelect: {preview: 'dir.preview'}
|
||||
leftJoinAndSelect: {cover: 'dir.cover'}
|
||||
}
|
||||
});
|
||||
};
|
||||
@ -262,27 +262,27 @@ describe('PreviewManager', (sqlHelper: DBTestHelper) => {
|
||||
|
||||
let subdir = await selectDir();
|
||||
|
||||
expect(subdir.validPreview).to.equal(true);
|
||||
expect(subdir.preview.id).to.equal(p2.id);
|
||||
expect(subdir.validCover).to.equal(true);
|
||||
expect(subdir.cover.id).to.equal(p2.id);
|
||||
|
||||
// new version should invalidate
|
||||
await pm.onNewDataVersion(subDir as ParentDirectoryDTO);
|
||||
subdir = await selectDir();
|
||||
expect(subdir.validPreview).to.equal(false);
|
||||
// during invalidation, we do not remove the previous preview (it's good to show at least some photo)
|
||||
expect(subdir.preview.id).to.equal(p2.id);
|
||||
expect(subdir.validCover).to.equal(false);
|
||||
// during invalidation, we do not remove the previous cover (it's good to show at least some photo)
|
||||
expect(subdir.cover.id).to.equal(p2.id);
|
||||
|
||||
await conn.createQueryBuilder()
|
||||
.update(DirectoryEntity)
|
||||
.set({validPreview: false, preview: null}).execute();
|
||||
expect((await selectDir()).preview).to.equal(null);
|
||||
.set({validCover: false, cover: null}).execute();
|
||||
expect((await selectDir()).cover).to.equal(null);
|
||||
|
||||
|
||||
const res = await gm.getParentDirFromId(conn,
|
||||
(await gm.getDirIdAndTime(conn, dir.name, dir.path)).id);
|
||||
subdir = await selectDir();
|
||||
expect(subdir.validPreview).to.equal(true);
|
||||
expect(subdir.preview.id).to.equal(p2.id);
|
||||
expect(subdir.validCover).to.equal(true);
|
||||
expect(subdir.cover.id).to.equal(p2.id);
|
||||
|
||||
});
|
||||
|
||||
|
@ -218,12 +218,12 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
|
||||
const tmpDir: DirectoryBaseDTO = m.directory as DirectoryBaseDTO;
|
||||
const tmpM = tmpDir.media;
|
||||
const tmpD = tmpDir.directories;
|
||||
const tmpP = tmpDir.preview;
|
||||
const tmpP = tmpDir.cover;
|
||||
const tmpMT = tmpDir.metaFile;
|
||||
delete tmpDir.directories;
|
||||
delete tmpDir.media;
|
||||
delete tmpDir.preview;
|
||||
delete tmpDir.validPreview;
|
||||
delete tmpDir.cover;
|
||||
delete tmpDir.validCover;
|
||||
delete tmpDir.metaFile;
|
||||
const ret = Utils.clone(m);
|
||||
delete (ret.directory as DirectoryBaseDTO).lastScanned;
|
||||
@ -235,7 +235,7 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
|
||||
}
|
||||
tmpDir.directories = tmpD;
|
||||
tmpDir.media = tmpM;
|
||||
tmpDir.preview = tmpP;
|
||||
tmpDir.cover = tmpP;
|
||||
tmpDir.metaFile = tmpMT;
|
||||
return ret;
|
||||
};
|
||||
@ -243,7 +243,7 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
|
||||
const searchifyDir = (d: DirectoryBaseDTO): DirectoryBaseDTO => {
|
||||
const tmpM = d.media;
|
||||
const tmpD = d.directories;
|
||||
const tmpP = d.preview;
|
||||
const tmpP = d.cover;
|
||||
const tmpMT = d.metaFile;
|
||||
delete d.directories;
|
||||
delete d.media;
|
||||
@ -251,7 +251,7 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
|
||||
const ret = Utils.clone(d);
|
||||
d.directories = tmpD;
|
||||
d.media = tmpM;
|
||||
d.preview = tmpP;
|
||||
d.cover = tmpP;
|
||||
d.metaFile = tmpMT;
|
||||
ret.isPartial = true;
|
||||
return ret;
|
||||
@ -1433,8 +1433,8 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
|
||||
const sm = new SearchManager();
|
||||
|
||||
const cloned = Utils.clone(searchifyDir(subDir));
|
||||
cloned.validPreview = true;
|
||||
cloned.preview = {
|
||||
cloned.validCover = true;
|
||||
cloned.cover = {
|
||||
directory: {
|
||||
name: subDir.name,
|
||||
path: subDir.path
|
||||
|
Loading…
Reference in New Issue
Block a user