mirror of
https://github.com/bpatrik/pigallery2.git
synced 2024-12-02 09:12:07 +02:00
Implementing listing metafiles in search result
This commit is contained in:
parent
57ac433c46
commit
3541eae141
6
package-lock.json
generated
6
package-lock.json
generated
@ -14296,7 +14296,8 @@
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.20",
|
||||
"resolved": "",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
|
||||
"dev": true
|
||||
},
|
||||
"minimist": {
|
||||
@ -21616,7 +21617,8 @@
|
||||
},
|
||||
"y18n": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
|
||||
"integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
|
||||
"dev": true
|
||||
},
|
||||
"yallist": {
|
||||
|
@ -33,6 +33,7 @@ import {ISQLGalleryManager} from './IGalleryManager';
|
||||
import {ISQLSearchManager} from './ISearchManager';
|
||||
import {MediaDTO} from '../../../../common/entities/MediaDTO';
|
||||
import {Utils} from '../../../../common/Utils';
|
||||
import {FileEntity} from './enitites/FileEntity';
|
||||
|
||||
export class SearchManager implements ISQLSearchManager {
|
||||
|
||||
@ -156,13 +157,15 @@ export class SearchManager implements ISQLSearchManager {
|
||||
const facesQuery = Config.Server.Database.type === DatabaseType.mysql ?
|
||||
'CONCAT(\'[\' , GROUP_CONCAT( \'{"name": "\' , person.name , \'", "box": {"top":\' , faces.box.top , \', "left":\' , faces.box.left , \', "height":\' , faces.box.height ,\', "width":\' , faces.box.width , \'}}\' ) ,\']\') as media_metadataFaces' :
|
||||
'\'[\' || GROUP_CONCAT( \'{"name": "\' || person.name || \'", "box": {"top":\' || faces.box.top || \', "left":\' || faces.box.left || \', "height":\' || faces.box.height ||\', "width":\' || faces.box.width || \'}}\' ) ||\']\' as media_metadataFaces';
|
||||
const directorySelect = ['directory.id', 'directory.name', 'directory.path'];
|
||||
|
||||
|
||||
const rawAndEntries = await connection
|
||||
.getRepository(MediaEntity)
|
||||
.createQueryBuilder('media')
|
||||
.select(['media', facesQuery])
|
||||
.select(['media', ...directorySelect, facesQuery])
|
||||
.where(this.buildWhereQuery(query))
|
||||
.leftJoinAndSelect('media.directory', 'directory')
|
||||
.leftJoin('media.directory', 'directory')
|
||||
.leftJoin('media.metadata.faces', 'faces')
|
||||
.leftJoin('faces.person', 'person')
|
||||
.limit(Config.Client.Search.maxMediaResult + 1)
|
||||
@ -181,6 +184,20 @@ export class SearchManager implements ISQLSearchManager {
|
||||
result.resultOverflow = true;
|
||||
}
|
||||
|
||||
if (Config.Client.Search.listMetafiles === true) {
|
||||
result.metaFile = await connection.getRepository(FileEntity)
|
||||
.createQueryBuilder('file')
|
||||
.select(['file', ...directorySelect])
|
||||
.innerJoin(q => q.from(MediaEntity, 'media')
|
||||
.select('distinct directory.id')
|
||||
.where(this.buildWhereQuery(query))
|
||||
.leftJoin('media.directory', 'directory'),
|
||||
'dir',
|
||||
'file.directory=dir.id')
|
||||
.leftJoin('file.directory', 'directory')
|
||||
.getMany();
|
||||
}
|
||||
|
||||
if (Config.Client.Search.listDirectories === true) {
|
||||
const dirQuery = this.filterDirectoryQuery(query);
|
||||
if (dirQuery !== null) {
|
||||
|
@ -1,10 +1,10 @@
|
||||
import {Column, Entity, Index, ManyToOne, OneToMany, PrimaryGeneratedColumn, TableInheritance, Unique, ValueTransformer} from 'typeorm';
|
||||
import {Column, Entity, Index, ManyToOne, OneToMany, PrimaryGeneratedColumn, TableInheritance, Unique} from 'typeorm';
|
||||
import {DirectoryEntity} from './DirectoryEntity';
|
||||
import {MediaDimension, MediaDTO, MediaMetadata} from '../../../../../common/entities/MediaDTO';
|
||||
import {OrientationTypes} from 'ts-exif-parser';
|
||||
import {CameraMetadataEntity, PositionMetaDataEntity} from './PhotoEntity';
|
||||
import {FaceRegionEntry} from './FaceRegionEntry';
|
||||
import {columnCharsetCS} from './EntityUtils';
|
||||
import {CameraMetadata, GPSMetadata, PositionMetaData} from '../../../../../common/entities/PhotoDTO';
|
||||
|
||||
export class MediaDimensionEntity implements MediaDimension {
|
||||
|
||||
@ -16,6 +16,80 @@ export class MediaDimensionEntity implements MediaDimension {
|
||||
}
|
||||
|
||||
|
||||
export class CameraMetadataEntity implements CameraMetadata {
|
||||
|
||||
@Column('int', {nullable: true, unsigned: true})
|
||||
ISO: number;
|
||||
|
||||
|
||||
@Column({
|
||||
type: 'text', nullable: true,
|
||||
charset: columnCharsetCS.charset,
|
||||
collation: columnCharsetCS.collation
|
||||
})
|
||||
model: string;
|
||||
|
||||
|
||||
@Column({
|
||||
type: 'text', nullable: true,
|
||||
charset: columnCharsetCS.charset,
|
||||
collation: columnCharsetCS.collation
|
||||
})
|
||||
make: string;
|
||||
|
||||
@Column('float', {nullable: true})
|
||||
fStop: number;
|
||||
|
||||
@Column('float', {nullable: true})
|
||||
exposure: number;
|
||||
|
||||
@Column('float', {nullable: true})
|
||||
focalLength: number;
|
||||
|
||||
@Column('text', {nullable: true})
|
||||
lens: string;
|
||||
}
|
||||
|
||||
|
||||
export class GPSMetadataEntity implements GPSMetadata {
|
||||
|
||||
@Column('float', {nullable: true})
|
||||
latitude: number;
|
||||
@Column('float', {nullable: true})
|
||||
longitude: number;
|
||||
@Column('int', {nullable: true})
|
||||
altitude: number;
|
||||
}
|
||||
|
||||
|
||||
export class PositionMetaDataEntity implements PositionMetaData {
|
||||
|
||||
@Column(type => GPSMetadataEntity)
|
||||
GPSData: GPSMetadataEntity;
|
||||
|
||||
@Column({
|
||||
type: 'text', nullable: true,
|
||||
charset: columnCharsetCS.charset,
|
||||
collation: columnCharsetCS.collation
|
||||
})
|
||||
country: string;
|
||||
|
||||
@Column({
|
||||
type: 'text', nullable: true,
|
||||
charset: columnCharsetCS.charset,
|
||||
collation: columnCharsetCS.collation
|
||||
})
|
||||
state: string;
|
||||
|
||||
@Column({
|
||||
type: 'text', nullable: true,
|
||||
charset: columnCharsetCS.charset,
|
||||
collation: columnCharsetCS.collation
|
||||
})
|
||||
city: string;
|
||||
}
|
||||
|
||||
|
||||
export class MediaMetadataEntity implements MediaMetadata {
|
||||
@Column('text')
|
||||
caption: string;
|
||||
|
@ -3,78 +3,7 @@ import {CameraMetadata, GPSMetadata, PhotoDTO, PhotoMetadata, PositionMetaData}
|
||||
import {MediaEntity, MediaMetadataEntity} from './MediaEntity';
|
||||
import {columnCharsetCS} from './EntityUtils';
|
||||
|
||||
export class CameraMetadataEntity implements CameraMetadata {
|
||||
|
||||
@Column('int', {nullable: true, unsigned: true})
|
||||
ISO: number;
|
||||
|
||||
|
||||
@Column({
|
||||
type: 'text', nullable: true,
|
||||
charset: columnCharsetCS.charset,
|
||||
collation: columnCharsetCS.collation
|
||||
})
|
||||
model: string;
|
||||
|
||||
|
||||
@Column({
|
||||
type: 'text', nullable: true,
|
||||
charset: columnCharsetCS.charset,
|
||||
collation: columnCharsetCS.collation
|
||||
})
|
||||
make: string;
|
||||
|
||||
@Column('float', {nullable: true})
|
||||
fStop: number;
|
||||
|
||||
@Column('float', {nullable: true})
|
||||
exposure: number;
|
||||
|
||||
@Column('float', {nullable: true})
|
||||
focalLength: number;
|
||||
|
||||
@Column('text', {nullable: true})
|
||||
lens: string;
|
||||
}
|
||||
|
||||
|
||||
export class GPSMetadataEntity implements GPSMetadata {
|
||||
|
||||
@Column('float', {nullable: true})
|
||||
latitude: number;
|
||||
@Column('float', {nullable: true})
|
||||
longitude: number;
|
||||
@Column('int', {nullable: true})
|
||||
altitude: number;
|
||||
}
|
||||
|
||||
|
||||
export class PositionMetaDataEntity implements PositionMetaData {
|
||||
|
||||
@Column(type => GPSMetadataEntity)
|
||||
GPSData: GPSMetadataEntity;
|
||||
|
||||
@Column({
|
||||
type: 'text', nullable: true,
|
||||
charset: columnCharsetCS.charset,
|
||||
collation: columnCharsetCS.collation
|
||||
})
|
||||
country: string;
|
||||
|
||||
@Column({
|
||||
type: 'text', nullable: true,
|
||||
charset: columnCharsetCS.charset,
|
||||
collation: columnCharsetCS.collation
|
||||
})
|
||||
state: string;
|
||||
|
||||
@Column({
|
||||
type: 'text', nullable: true,
|
||||
charset: columnCharsetCS.charset,
|
||||
collation: columnCharsetCS.collation
|
||||
})
|
||||
city: string;
|
||||
}
|
||||
|
||||
|
||||
export class PhotoMetadataEntity extends MediaMetadataEntity implements PhotoMetadata {
|
||||
|
@ -31,6 +31,10 @@ export class ClientSearchConfig {
|
||||
maxMediaResult: number = 10000;
|
||||
@ConfigProperty({description: 'Search returns also with directories, not just media'})
|
||||
listDirectories: boolean = false;
|
||||
@ConfigProperty({
|
||||
description: 'Search also returns with metafiles from directories that contain a media file of the matched search result'
|
||||
})
|
||||
listMetafiles: boolean = false;
|
||||
@ConfigProperty({type: 'unsignedInt'})
|
||||
maxDirectoryResult: number = 200;
|
||||
}
|
||||
|
@ -52,6 +52,14 @@
|
||||
[simplifiedMode]="simplifiedMode">
|
||||
</app-settings-entry>
|
||||
|
||||
<app-settings-entry
|
||||
name="List metafiles"
|
||||
description="Search also returns with metafiles from directories that contain a media file of the matched search result"
|
||||
i18n-description i18n-name
|
||||
[ngModel]="states.listMetafiles"
|
||||
[simplifiedMode]="simplifiedMode">
|
||||
</app-settings-entry>
|
||||
|
||||
|
||||
|
||||
</ng-container>
|
||||
|
@ -2828,6 +2828,14 @@
|
||||
<source>Shows albums tab in the top bar and enables creating saved searches.</source>
|
||||
<target>Shows albums tab in the top bar and enables creating saved searches.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="709142926386769059" datatype="html">
|
||||
<source>List metafiles</source>
|
||||
<target>List metafiles</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="500999559591740527" datatype="html">
|
||||
<source>Search also returns with metafiles from directories that contain a media file of the matched search result</source>
|
||||
<target>Search also returns with metafiles from directories that contain a media file of the matched search result</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
@ -2828,6 +2828,14 @@
|
||||
<source>Shows albums tab in the top bar and enables creating saved searches.</source>
|
||||
<target>Shows albums tab in the top bar and enables creating saved searches.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="709142926386769059" datatype="html">
|
||||
<source>List metafiles</source>
|
||||
<target>List metafiles</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="500999559591740527" datatype="html">
|
||||
<source>Search also returns with metafiles from directories that contain a media file of the matched search result</source>
|
||||
<target>Search also returns with metafiles from directories that contain a media file of the matched search result</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
@ -2828,6 +2828,14 @@
|
||||
<source>Shows albums tab in the top bar and enables creating saved searches.</source>
|
||||
<target>Shows albums tab in the top bar and enables creating saved searches.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="709142926386769059" datatype="html">
|
||||
<source>List metafiles</source>
|
||||
<target>List metafiles</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="500999559591740527" datatype="html">
|
||||
<source>Search also returns with metafiles from directories that contain a media file of the matched search result</source>
|
||||
<target>Search also returns with metafiles from directories that contain a media file of the matched search result</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
@ -2828,6 +2828,14 @@
|
||||
<source>Shows albums tab in the top bar and enables creating saved searches.</source>
|
||||
<target>Megjeleníti az Album fület a felső sávban és engedélyezi a mentett keresések létrehozásást</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="709142926386769059" datatype="html">
|
||||
<source>List metafiles</source>
|
||||
<target>Metafájlok listázása</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="500999559591740527" datatype="html">
|
||||
<source>Search also returns with metafiles from directories that contain a media file of the matched search result</source>
|
||||
<target>A kersési eredmény tartalmazza azokat a metaffájlkoat is, amelyek egy mappában vannak a keresett képpel/videóval.</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -2828,6 +2828,14 @@
|
||||
<source>Shows albums tab in the top bar and enables creating saved searches.</source>
|
||||
<target>Shows albums tab in the top bar and enables creating saved searches.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="709142926386769059" datatype="html">
|
||||
<source>List metafiles</source>
|
||||
<target>List metafiles</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="500999559591740527" datatype="html">
|
||||
<source>Search also returns with metafiles from directories that contain a media file of the matched search result</source>
|
||||
<target>Search also returns with metafiles from directories that contain a media file of the matched search result</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
@ -2828,6 +2828,14 @@
|
||||
<source>Shows albums tab in the top bar and enables creating saved searches.</source>
|
||||
<target>Shows albums tab in the top bar and enables creating saved searches.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="709142926386769059" datatype="html">
|
||||
<source>List metafiles</source>
|
||||
<target>List metafiles</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="500999559591740527" datatype="html">
|
||||
<source>Search also returns with metafiles from directories that contain a media file of the matched search result</source>
|
||||
<target>Search also returns with metafiles from directories that contain a media file of the matched search result</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
@ -2828,6 +2828,14 @@
|
||||
<source>Shows albums tab in the top bar and enables creating saved searches.</source>
|
||||
<target>Shows albums tab in the top bar and enables creating saved searches.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="709142926386769059" datatype="html">
|
||||
<source>List metafiles</source>
|
||||
<target>List metafiles</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="500999559591740527" datatype="html">
|
||||
<source>Search also returns with metafiles from directories that contain a media file of the matched search result</source>
|
||||
<target>Search also returns with metafiles from directories that contain a media file of the matched search result</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
@ -2828,6 +2828,14 @@
|
||||
<source>Shows albums tab in the top bar and enables creating saved searches.</source>
|
||||
<target>Shows albums tab in the top bar and enables creating saved searches.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="709142926386769059" datatype="html">
|
||||
<source>List metafiles</source>
|
||||
<target>List metafiles</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="500999559591740527" datatype="html">
|
||||
<source>Search also returns with metafiles from directories that contain a media file of the matched search result</source>
|
||||
<target>Search also returns with metafiles from directories that contain a media file of the matched search result</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
@ -2828,6 +2828,14 @@
|
||||
<source>Shows albums tab in the top bar and enables creating saved searches.</source>
|
||||
<target>Shows albums tab in the top bar and enables creating saved searches.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="709142926386769059" datatype="html">
|
||||
<source>List metafiles</source>
|
||||
<target>List metafiles</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="500999559591740527" datatype="html">
|
||||
<source>Search also returns with metafiles from directories that contain a media file of the matched search result</source>
|
||||
<target>Search also returns with metafiles from directories that contain a media file of the matched search result</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
@ -7,16 +7,15 @@ import {UserEntity} from '../../../../../src/backend/model/database/sql/enitites
|
||||
import {UserRoles} from '../../../../../src/common/entities/UserDTO';
|
||||
import {PasswordHelper} from '../../../../../src/backend/model/PasswordHelper';
|
||||
import {DirectoryEntity} from '../../../../../src/backend/model/database/sql/enitites/DirectoryEntity';
|
||||
import {PhotoEntity, PhotoMetadataEntity} from '../../../../../src/backend/model/database/sql/enitites/PhotoEntity';
|
||||
import {
|
||||
CameraMetadataEntity,
|
||||
GPSMetadataEntity,
|
||||
PhotoEntity,
|
||||
PhotoMetadataEntity,
|
||||
MediaDimensionEntity,
|
||||
PositionMetaDataEntity
|
||||
} from '../../../../../src/backend/model/database/sql/enitites/PhotoEntity';
|
||||
import {MediaDimensionEntity} from '../../../../../src/backend/model/database/sql/enitites/MediaEntity';
|
||||
} from '../../../../../src/backend/model/database/sql/enitites/MediaEntity';
|
||||
import {VersionEntity} from '../../../../../src/backend/model/database/sql/enitites/VersionEntity';
|
||||
import {DatabaseType, ServerConfig} from '../../../../../src/common/config/private/PrivateConfig';
|
||||
import {DatabaseType} from '../../../../../src/common/config/private/PrivateConfig';
|
||||
import {ProjectPath} from '../../../../../src/backend/ProjectPath';
|
||||
|
||||
|
||||
|
@ -200,6 +200,9 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
|
||||
delete m.directory.preview;
|
||||
delete m.directory.metaFile;
|
||||
const ret = Utils.clone(m);
|
||||
delete ret.directory.lastScanned;
|
||||
delete ret.directory.lastModified;
|
||||
delete ret.directory.mediaCount;
|
||||
if ((ret.metadata as PhotoMetadata).faces && !(ret.metadata as PhotoMetadata).faces.length) {
|
||||
delete (ret.metadata as PhotoMetadata).faces;
|
||||
}
|
||||
|
@ -1,11 +1,10 @@
|
||||
import {MediaDimensionEntity} from '../../../../../src/backend/model/database/sql/enitites/MediaEntity';
|
||||
import {
|
||||
CameraMetadataEntity,
|
||||
GPSMetadataEntity,
|
||||
PhotoEntity,
|
||||
PhotoMetadataEntity,
|
||||
MediaDimensionEntity,
|
||||
PositionMetaDataEntity
|
||||
} from '../../../../../src/backend/model/database/sql/enitites/PhotoEntity';
|
||||
} from '../../../../../src/backend/model/database/sql/enitites/MediaEntity';
|
||||
import {PhotoEntity, PhotoMetadataEntity} from '../../../../../src/backend/model/database/sql/enitites/PhotoEntity';
|
||||
import {OrientationTypes} from 'ts-exif-parser';
|
||||
import {DirectoryEntity} from '../../../../../src/backend/model/database/sql/enitites/DirectoryEntity';
|
||||
import {VideoEntity, VideoMetadataEntity} from '../../../../../src/backend/model/database/sql/enitites/VideoEntity';
|
||||
|
Loading…
Reference in New Issue
Block a user