diff --git a/backend/model/sql/GalleryManager.ts b/backend/model/sql/GalleryManager.ts index a09f2a06..2d4df232 100644 --- a/backend/model/sql/GalleryManager.ts +++ b/backend/model/sql/GalleryManager.ts @@ -150,15 +150,19 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager { const media: MediaEntity[] = currentDir.media; delete currentDir.media; currentDir = await directoryRepository.save(currentDir); - media.forEach(m => m.directory = currentDir); - currentDir.media = await this.saveMedia(connection, media); + if (media) { + media.forEach(m => m.directory = currentDir); + currentDir.media = await this.saveMedia(connection, media); + } } else { const media = scannedDirectory.media; delete scannedDirectory.media; (scannedDirectory).lastScanned = scannedDirectory.lastScanned; currentDir = await directoryRepository.save(scannedDirectory); - media.forEach(m => m.directory = currentDir); - currentDir.media = await this.saveMedia(connection, media); + if (media) { + media.forEach(m => m.directory = currentDir); + currentDir.media = await this.saveMedia(connection, media); + } } const childDirectories = await directoryRepository.createQueryBuilder('directory') diff --git a/backend/model/sql/SQLConnection.ts b/backend/model/sql/SQLConnection.ts index 4bcedd91..252fe233 100644 --- a/backend/model/sql/SQLConnection.ts +++ b/backend/model/sql/SQLConnection.ts @@ -40,7 +40,7 @@ export class SQLConnection { VersionEntity ]; options.synchronize = false; - // options.logging = "all"; + // options.logging = 'all'; this.connection = await createConnection(options); await SQLConnection.schemeSync(this.connection); } diff --git a/backend/model/sql/SearchManager.ts b/backend/model/sql/SearchManager.ts index 436ce488..bf45a80f 100644 --- a/backend/model/sql/SearchManager.ts +++ b/backend/model/sql/SearchManager.ts @@ -4,6 +4,7 @@ import {SearchResultDTO} from '../../../common/entities/SearchResultDTO'; import {SQLConnection} from './SQLConnection'; import {PhotoEntity} from './enitites/PhotoEntity'; import {DirectoryEntity} from './enitites/DirectoryEntity'; +import {MediaEntity} from './enitites/MediaEntity'; export class SearchManager implements ISearchManager { @@ -24,32 +25,32 @@ export class SearchManager implements ISearchManager { const connection = await SQLConnection.getConnection(); - let result: Array = []; + let result: AutoCompleteItem[] = []; const photoRepository = connection.getRepository(PhotoEntity); + const mediaRepository = connection.getRepository(MediaEntity); const directoryRepository = connection.getRepository(DirectoryEntity); (await photoRepository - .createQueryBuilder('media') - .select('DISTINCT(media.metadata.keywords)') - .where('media.metadata.keywords LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) + .createQueryBuilder('photo') + .select('DISTINCT(photo.metadata.keywords)') + .where('photo.metadata.keywords LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) .limit(5) .getRawMany()) - .map(r => >r.metadataKeywords.split(',')) + .map(r => >(r.metadataKeywords).split(',')) .forEach(keywords => { result = result.concat(this.encapsulateAutoComplete(keywords .filter(k => k.toLowerCase().indexOf(text.toLowerCase()) !== -1), SearchTypes.keyword)); }); - (await photoRepository - .createQueryBuilder('media') - .select('media.metadata.positionData.country as country,' + - 'mediao.metadata.positionData.state as state, media.metadata.positionData.city as city') - .where('media.metadata.positionData.country LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) - .orWhere('media.metadata.positionData.state LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) - .orWhere('media.metadata.positionData.city LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) - .groupBy('media.metadata.positionData.country, media.metadata.positionData.state, media.metadata.positionData.city') + .createQueryBuilder('photo') + .select('photo.metadata.positionData.country as country, ' + + 'photo.metadata.positionData.state as state, photo.metadata.positionData.city as city') + .where('photo.metadata.positionData.country LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) + .orWhere('photo.metadata.positionData.state LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) + .orWhere('photo.metadata.positionData.city LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) + .groupBy('photo.metadata.positionData.country, photo.metadata.positionData.state, photo.metadata.positionData.city') .limit(5) .getRawMany()) .filter(pm => !!pm) @@ -59,7 +60,7 @@ export class SearchManager implements ISearchManager { .filter(p => p.toLowerCase().indexOf(text.toLowerCase()) !== -1), SearchTypes.position)); }); - result = result.concat(this.encapsulateAutoComplete((await photoRepository + result = result.concat(this.encapsulateAutoComplete((await mediaRepository .createQueryBuilder('media') .select('DISTINCT(media.name)') .where('media.name LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'}) diff --git a/backend/model/sql/enitites/PhotoEntity.ts b/backend/model/sql/enitites/PhotoEntity.ts index 7e0ce869..7d4643eb 100644 --- a/backend/model/sql/enitites/PhotoEntity.ts +++ b/backend/model/sql/enitites/PhotoEntity.ts @@ -55,7 +55,7 @@ export class PositionMetaDataEntity implements PositionMetaData { export class PhotoMetadataEntity extends MediaMetadataEntity implements PhotoMetadata { - +/* @Column('simple-array') keywords: string[]; @@ -67,7 +67,7 @@ export class PhotoMetadataEntity extends MediaMetadataEntity implements PhotoMet @Column('tinyint', {default: OrientationTypes.TOP_LEFT}) orientation: OrientationTypes; - +*/ } diff --git a/backend/model/threading/DiskMangerWorker.ts b/backend/model/threading/DiskMangerWorker.ts index 7094ba99..3cb39b35 100644 --- a/backend/model/threading/DiskMangerWorker.ts +++ b/backend/model/threading/DiskMangerWorker.ts @@ -226,7 +226,7 @@ export class DiskMangerWorker { metadata.creationDate = (iptcData.date_time ? iptcData.date_time.getTime() : metadata.creationDate); } catch (err) { - Logger.debug(LOG_TAG, 'Error parsing iptc data', fullPath, err); + // Logger.debug(LOG_TAG, "Error parsing iptc data", fullPath, err); } metadata.creationDate = metadata.creationDate || 0; diff --git a/test/backend/unit/model/sql/SearchManager.ts b/test/backend/unit/model/sql/SearchManager.ts index b16f31e5..16fb5f5c 100644 --- a/test/backend/unit/model/sql/SearchManager.ts +++ b/test/backend/unit/model/sql/SearchManager.ts @@ -16,6 +16,8 @@ import {AutoCompleteItem, SearchTypes} from '../../../../../common/entities/Auto import {SearchResultDTO} from '../../../../../common/entities/SearchResultDTO'; import {DirectoryEntity} from '../../../../../backend/model/sql/enitites/DirectoryEntity'; import {MediaDimensionEntity} from '../../../../../backend/model/sql/enitites/MediaEntity'; +import {OrientationTypes} from 'ts-exif-parser'; +import {Utils} from '../../../../../common/Utils'; describe('SearchManager', () => { @@ -57,6 +59,11 @@ describe('SearchManager', () => { m.size = sd; m.creationDate = Date.now(); m.fileSize = 123456789; + m.orientation = OrientationTypes.TOP_LEFT; + + // TODO: remove when typeorm is fixed + m.duration = null; + m.bitRate = null; const d = new PhotoEntity(); @@ -155,85 +162,86 @@ describe('SearchManager', () => { it('should search', async () => { const sm = new SearchManager(); - expect((await sm.search('sw', null))).to.deep.equal({ + + expect(Utils.clone(await sm.search('sw', null))).to.deep.equal(Utils.clone({ searchText: 'sw', searchType: null, directories: [], media: [p, p2], resultOverflow: false - }); + })); - expect((await sm.search('Tatooine', SearchTypes.position))).to.deep.equal({ + expect(Utils.clone(await sm.search('Tatooine', SearchTypes.position))).to.deep.equal(Utils.clone({ searchText: 'Tatooine', searchType: SearchTypes.position, directories: [], media: [p], resultOverflow: false - }); + })); - expect((await sm.search('ortm', SearchTypes.keyword))).to.deep.equal({ + expect(Utils.clone(await sm.search('ortm', SearchTypes.keyword))).to.deep.equal(Utils.clone({ searchText: 'ortm', searchType: SearchTypes.keyword, directories: [], media: [p2], resultOverflow: false - }); + })); - expect((await sm.search('ortm', SearchTypes.keyword))).to.deep.equal({ + expect(Utils.clone(await sm.search('ortm', SearchTypes.keyword))).to.deep.equal(Utils.clone({ searchText: 'ortm', searchType: SearchTypes.keyword, directories: [], media: [p2], resultOverflow: false - }); + })); - expect((await sm.search('wa', SearchTypes.keyword))).to.deep.equal({ + expect(Utils.clone(await sm.search('wa', SearchTypes.keyword))).to.deep.equal(Utils.clone({ searchText: 'wa', searchType: SearchTypes.keyword, directories: [dir], media: [p, p2], resultOverflow: false - }); + })); }); it('should instant search', async () => { const sm = new SearchManager(); - expect((await sm.instantSearch('sw'))).to.deep.equal({ + expect(Utils.clone(await sm.instantSearch('sw'))).to.deep.equal(Utils.clone({ searchText: 'sw', directories: [], - photos: [p, p2], + media: [p, p2], resultOverflow: false - }); + })); - expect((await sm.instantSearch('Tatooine'))).to.deep.equal({ + expect(Utils.clone(await sm.instantSearch('Tatooine'))).to.deep.equal(Utils.clone({ searchText: 'Tatooine', directories: [], - photos: [p], + media: [p], resultOverflow: false - }); + })); - expect((await sm.instantSearch('ortm'))).to.deep.equal({ + expect(Utils.clone(await sm.instantSearch('ortm'))).to.deep.equal(Utils.clone({ searchText: 'ortm', directories: [], - photos: [p2], + media: [p2], resultOverflow: false - }); + })); - expect((await sm.instantSearch('ortm'))).to.deep.equal({ + expect(Utils.clone(await sm.instantSearch('ortm'))).to.deep.equal(Utils.clone({ searchText: 'ortm', directories: [], - photos: [p2], + media: [p2], resultOverflow: false - }); + })); - expect((await sm.instantSearch('wa'))).to.deep.equal({ + expect(Utils.clone(await sm.instantSearch('wa'))).to.deep.equal(Utils.clone({ searchText: 'wa', directories: [dir], - photos: [p, p2], + media: [p, p2], resultOverflow: false - }); + })); });