diff --git a/backend/model/sql/GalleryManager.ts b/backend/model/sql/GalleryManager.ts index ac2916b4..8e944c99 100644 --- a/backend/model/sql/GalleryManager.ts +++ b/backend/model/sql/GalleryManager.ts @@ -20,6 +20,49 @@ import {VideoEntity} from './enitites/VideoEntity'; export class GalleryManager implements IGalleryManager, ISQLGalleryManager { + protected async selectParentDir(connection: Connection, directoryName: string, directoryParent: string): Promise { + return await connection + .getRepository(DirectoryEntity) + .createQueryBuilder('directory') + .where('directory.name = :name AND directory.path = :path', { + name: directoryName, + path: directoryParent + }) + .leftJoinAndSelect('directory.directories', 'directories') + .leftJoinAndSelect('directory.media', 'media') + .getOne(); + } + + protected async fillParentDir(connection: Connection, dir: DirectoryEntity): Promise { + if (dir.media) { + for (let i = 0; i < dir.media.length; i++) { + dir.media[i].directory = dir; + dir.media[i].readyThumbnails = []; + dir.media[i].readyIcon = false; + } + } + if (dir.directories) { + for (let i = 0; i < dir.directories.length; i++) { + dir.directories[i].media = await connection + .getRepository(MediaEntity) + .createQueryBuilder('media') + .where('media.directory = :dir', { + dir: dir.directories[i].id + }) + .orderBy('media.metadata.creationDate', 'ASC') + .limit(Config.Server.indexing.folderPreviewSize) + .getMany(); + dir.directories[i].isPartial = true; + + for (let j = 0; j < dir.directories[i].media.length; j++) { + dir.directories[i].media[j].directory = dir.directories[i]; + dir.directories[i].media[j].readyThumbnails = []; + dir.directories[i].media[j].readyIcon = false; + } + } + } + } + public async listDirectory(relativeDirectoryName: string, knownLastModified?: number, @@ -30,16 +73,7 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager { const connection = await SQLConnection.getConnection(); const stat = fs.statSync(path.join(ProjectPath.ImageFolder, relativeDirectoryName)); const lastModified = Math.max(stat.ctime.getTime(), stat.mtime.getTime()); - const dir = await connection - .getRepository(DirectoryEntity) - .createQueryBuilder('directory') - .where('directory.name = :name AND directory.path = :path', { - name: directoryName, - path: directoryParent - }) - .leftJoinAndSelect('directory.directories', 'directories') - .leftJoinAndSelect('directory.media', 'media') - .getOne(); + const dir = await this.selectParentDir(connection, directoryName, directoryParent); if (dir && dir.lastScanned != null) { @@ -56,33 +90,7 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager { return null; } } - if (dir.media) { - for (let i = 0; i < dir.media.length; i++) { - dir.media[i].directory = dir; - dir.media[i].readyThumbnails = []; - dir.media[i].readyIcon = false; - } - } - if (dir.directories) { - for (let i = 0; i < dir.directories.length; i++) { - dir.directories[i].media = await connection - .getRepository(MediaEntity) - .createQueryBuilder('media') - .where('media.directory = :dir', { - dir: dir.directories[i].id - }) - .orderBy('media.metadata.creationDate', 'ASC') - .limit(Config.Server.indexing.folderPreviewSize) - .getMany(); - dir.directories[i].isPartial = true; - - for (let j = 0; j < dir.directories[i].media.length; j++) { - dir.directories[i].media[j].directory = dir.directories[i]; - dir.directories[i].media[j].readyThumbnails = []; - dir.directories[i].media[j].readyIcon = false; - } - } - } + await this.fillParentDir(connection, dir); if (dir.lastModified !== lastModified) { @@ -130,118 +138,7 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager { } - private async saveToDB(scannedDirectory: DirectoryDTO) { - const connection = await SQLConnection.getConnection(); - - // saving to db - const directoryRepository = connection.getRepository(DirectoryEntity); - const mediaRepository = connection.getRepository(MediaEntity); - - - let currentDir: DirectoryEntity = await directoryRepository.createQueryBuilder('directory') - .where('directory.name = :name AND directory.path = :path', { - name: scannedDirectory.name, - path: scannedDirectory.path - }).getOne(); - - if (!!currentDir) {// Updated parent dir (if it was in the DB previously) - currentDir.lastModified = scannedDirectory.lastModified; - currentDir.lastScanned = scannedDirectory.lastScanned; - const media: MediaEntity[] = currentDir.media; - delete currentDir.media; - currentDir = await directoryRepository.save(currentDir); - 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); - if (media) { - media.forEach(m => m.directory = currentDir); - currentDir.media = await this.saveMedia(connection, media); - } - } - - const childDirectories = await directoryRepository.createQueryBuilder('directory') - .where('directory.parent = :dir', { - dir: currentDir.id - }).getMany(); - - for (let i = 0; i < scannedDirectory.directories.length; i++) { - // Was this child Dir already indexed before? - let directory: DirectoryEntity = null; - for (let j = 0; j < childDirectories.length; j++) { - if (childDirectories[j].name === scannedDirectory.directories[i].name) { - directory = childDirectories[j]; - childDirectories.splice(j, 1); - break; - } - } - - if (directory != null) { // update existing directory - if (!directory.parent || !directory.parent.id) { // set parent if not set yet - directory.parent = currentDir; - delete directory.media; - await directoryRepository.save(directory); - } - } else { - scannedDirectory.directories[i].parent = currentDir; - (scannedDirectory.directories[i]).lastScanned = null; // new child dir, not fully scanned yet - const d = await directoryRepository.save(scannedDirectory.directories[i]); - for (let j = 0; j < scannedDirectory.directories[i].media.length; j++) { - scannedDirectory.directories[i].media[j].directory = d; - } - - await this.saveMedia(connection, scannedDirectory.directories[i].media); - } - } - - // Remove child Dirs that are not anymore in the parent dir - await directoryRepository.remove(childDirectories); - - - const indexedMedia = await mediaRepository.createQueryBuilder('media') - .where('media.directory = :dir', { - dir: currentDir.id - }).getMany(); - - - const mediaToSave = []; - for (let i = 0; i < scannedDirectory.media.length; i++) { - let media = null; - for (let j = 0; j < indexedMedia.length; j++) { - if (indexedMedia[j].name === scannedDirectory.media[i].name) { - media = indexedMedia[j]; - indexedMedia.splice(j, 1); - break; - } - } - if (media == null) { - scannedDirectory.media[i].directory = null; - media = Utils.clone(scannedDirectory.media[i]); - scannedDirectory.media[i].directory = scannedDirectory; - media.directory = currentDir; - } - - - if (!Utils.equalsFilter(media.metadata, scannedDirectory.media[i].metadata)) { - media.metadata = (scannedDirectory.media[i]).metadata; - mediaToSave.push(media); - } - } - await this.saveMedia(connection, mediaToSave); - await mediaRepository.remove(indexedMedia); - } - - private async saveMedia(connection: Connection, mediaList: MediaDTO[]): Promise { - const list = await connection.getRepository(VideoEntity).save(mediaList.filter(m => MediaDTO.isVideo(m))); - return list.concat(await connection.getRepository(PhotoEntity).save(mediaList.filter(m => MediaDTO.isPhoto(m)))); - } - - async getRandomPhoto(queryFilter: RandomQuery): Promise { + public async getRandomPhoto(queryFilter: RandomQuery): Promise { const connection = await SQLConnection.getConnection(); const photosRepository = connection.getRepository(PhotoEntity); const query = photosRepository.createQueryBuilder('photo'); @@ -299,4 +196,114 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager { } + protected async saveToDB(scannedDirectory: DirectoryDTO) { + const connection = await SQLConnection.getConnection(); + + // saving to db + const directoryRepository = connection.getRepository(DirectoryEntity); + const mediaRepository = connection.getRepository(MediaEntity); + + + let currentDir: DirectoryEntity = await directoryRepository.createQueryBuilder('directory') + .where('directory.name = :name AND directory.path = :path', { + name: scannedDirectory.name, + path: scannedDirectory.path + }).getOne(); + + if (!!currentDir) {// Updated parent dir (if it was in the DB previously) + currentDir.lastModified = scannedDirectory.lastModified; + currentDir.lastScanned = scannedDirectory.lastScanned; + // const media: MediaEntity[] = currentDir.media; + // delete currentDir.media; + currentDir = await directoryRepository.save(currentDir); + /*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); + /* if (media) { + media.forEach(m => m.directory = currentDir); + currentDir.media = await this.saveMedia(connection, media); + }*/ + } + + // save subdirectories + const childDirectories = await directoryRepository.createQueryBuilder('directory') + .where('directory.parent = :dir', { + dir: currentDir.id + }).getMany(); + + for (let i = 0; i < scannedDirectory.directories.length; i++) { + // Was this child Dir already indexed before? + let directory: DirectoryEntity = null; + for (let j = 0; j < childDirectories.length; j++) { + if (childDirectories[j].name === scannedDirectory.directories[i].name) { + directory = childDirectories[j]; + childDirectories.splice(j, 1); + break; + } + } + + if (directory != null) { // update existing directory + if (!directory.parent || !directory.parent.id) { // set parent if not set yet + directory.parent = currentDir; + delete directory.media; + await directoryRepository.save(directory); + } + } else { + scannedDirectory.directories[i].parent = currentDir; + (scannedDirectory.directories[i]).lastScanned = null; // new child dir, not fully scanned yet + const d = await directoryRepository.save(scannedDirectory.directories[i]); + for (let j = 0; j < scannedDirectory.directories[i].media.length; j++) { + scannedDirectory.directories[i].media[j].directory = d; + } + + await this.saveMedia(connection, scannedDirectory.directories[i].media); + } + } + + // Remove child Dirs that are not anymore in the parent dir + await directoryRepository.remove(childDirectories); + + // save media + const indexedMedia = await mediaRepository.createQueryBuilder('media') + .where('media.directory = :dir', { + dir: currentDir.id + }).getMany(); + + + const mediaToSave = []; + for (let i = 0; i < scannedDirectory.media.length; i++) { + let media: MediaDTO = null; + for (let j = 0; j < indexedMedia.length; j++) { + if (indexedMedia[j].name === scannedDirectory.media[i].name) { + media = indexedMedia[j]; + indexedMedia.splice(j, 1); + break; + } + } + if (media == null) { //not in DB yet + scannedDirectory.media[i].directory = null; + media = Utils.clone(scannedDirectory.media[i]); + scannedDirectory.media[i].directory = scannedDirectory; + media.directory = currentDir; + mediaToSave.push(media); + }else if (!Utils.equalsFilter(media.metadata, scannedDirectory.media[i].metadata)) { + media.metadata = scannedDirectory.media[i].metadata; + mediaToSave.push(media); + } + } + await this.saveMedia(connection, mediaToSave); + await mediaRepository.remove(indexedMedia); + } + + protected async saveMedia(connection: Connection, mediaList: MediaDTO[]): Promise { + const list = await connection.getRepository(VideoEntity).save(mediaList.filter(m => MediaDTO.isVideo(m))); + return list.concat(await connection.getRepository(PhotoEntity).save(mediaList.filter(m => MediaDTO.isPhoto(m)))); + } + } diff --git a/common/entities/DirectoryDTO.ts b/common/entities/DirectoryDTO.ts index 2c87de43..8a7a0ace 100644 --- a/common/entities/DirectoryDTO.ts +++ b/common/entities/DirectoryDTO.ts @@ -15,8 +15,8 @@ export interface DirectoryDTO { export module DirectoryDTO { export const addReferences = (dir: DirectoryDTO): void => { - dir.media.forEach((photo: MediaDTO) => { - photo.directory = dir; + dir.media.forEach((media: MediaDTO) => { + media.directory = dir; }); dir.directories.forEach((directory: DirectoryDTO) => { @@ -25,15 +25,17 @@ export module DirectoryDTO { }); }; - export const removeReferences = (dir: DirectoryDTO) => { - dir.media.forEach((photo: PhotoDTO) => { - photo.directory = null; + export const removeReferences = (dir: DirectoryDTO): void => { + dir.media.forEach((media: MediaDTO) => { + media.directory = null; }); - dir.directories.forEach((directory: DirectoryDTO) => { - removeReferences(directory); - directory.parent = null; - }); + if (dir.directories) { + dir.directories.forEach((directory: DirectoryDTO) => { + removeReferences(directory); + directory.parent = null; + }); + } }; } diff --git a/test/backend/unit/model/sql/GalleryManager.ts b/test/backend/unit/model/sql/GalleryManager.ts new file mode 100644 index 00000000..a59bc452 --- /dev/null +++ b/test/backend/unit/model/sql/GalleryManager.ts @@ -0,0 +1,144 @@ +import {expect} from 'chai'; +import * as fs from 'fs'; +import * as path from 'path'; +import {Config} from '../../../../../common/config/private/Config'; +import {DatabaseType, ReIndexingSensitivity} from '../../../../../common/config/private/IPrivateConfig'; +import {SQLConnection} from '../../../../../backend/model/sql/SQLConnection'; +import {GalleryManager} from '../../../../../backend/model/sql/GalleryManager'; +import {DirectoryDTO} from '../../../../../common/entities/DirectoryDTO'; +import {TestHelper} from './TestHelper'; +import {Connection} from 'typeorm'; +import {DirectoryEntity} from '../../../../../backend/model/sql/enitites/DirectoryEntity'; +import {Utils} from '../../../../../common/Utils'; +import {MediaDTO} from '../../../../../common/entities/MediaDTO'; + + +class GalleryManagerTest extends GalleryManager { + + + public async selectParentDir(connection: Connection, directoryName: string, directoryParent: string): Promise { + return super.selectParentDir(connection, directoryName, directoryParent); + } + + public async fillParentDir(connection: Connection, dir: DirectoryEntity): Promise { + return super.fillParentDir(connection, dir); + } + + public async saveToDB(scannedDirectory: DirectoryDTO) { + return super.saveToDB(scannedDirectory); + } +} + +describe('GalleryManager', () => { + + + const tempDir = path.join(__dirname, '../../tmp'); + const dbPath = path.join(tempDir, 'test.db'); + + + const setUpSqlDB = async () => { + if (fs.existsSync(dbPath)) { + fs.unlinkSync(dbPath); + } + if (!fs.existsSync(tempDir)) { + fs.mkdirSync(tempDir); + } + + Config.Server.database.type = DatabaseType.sqlite; + Config.Server.database.sqlite.storage = dbPath; + + }; + + const tearDownSqlDB = async () => { + await SQLConnection.close(); + if (fs.existsSync(dbPath)) { + fs.unlinkSync(dbPath); + } + if (fs.existsSync(tempDir)) { + fs.rmdirSync(tempDir); + } + }; + + beforeEach(async () => { + await setUpSqlDB(); + }); + + afterEach(async () => { + await tearDownSqlDB(); + }); + + const removeIds = (dir: DirectoryDTO) => { + delete dir.id; + dir.media.forEach((media: MediaDTO) => { + delete media.id; + + }); + + if (dir.directories) { + dir.directories.forEach((directory: DirectoryDTO) => { + removeIds(directory); + }); + } + }; + + it('should save parent directory', async () => { + const gm = new GalleryManagerTest(); + + const parent = TestHelper.getRandomizedDirectoryEntry(); + const p1 = TestHelper.getRandomizedPhotoEntry(parent, 'Photo1'); + const p2 = TestHelper.getRandomizedPhotoEntry(parent, 'Photo2'); + const subDir = TestHelper.getRandomizedDirectoryEntry(parent, 'subDir'); + const sp1 = TestHelper.getRandomizedPhotoEntry(subDir, 'subPhoto1'); + const sp2 = TestHelper.getRandomizedPhotoEntry(subDir, 'subPhoto2'); + + + DirectoryDTO.removeReferences(parent); + await gm.saveToDB(Utils.clone(parent)); + + const conn = await SQLConnection.getConnection(); + const selected = await gm.selectParentDir(conn, parent.name, parent.path); + await gm.fillParentDir(conn, selected); + + DirectoryDTO.removeReferences(selected); + removeIds(selected); + subDir.isPartial = true; + delete subDir.directories; + expect(selected).to.deep.equal(parent); + + }); + + + it('should update sub directory', async () => { + const gm = new GalleryManagerTest(); + + const parent = TestHelper.getRandomizedDirectoryEntry(); + parent.name = 'parent'; + const p1 = TestHelper.getRandomizedPhotoEntry(parent); + const subDir = TestHelper.getRandomizedDirectoryEntry(parent, 'subDir'); + subDir.name = 'subDir'; + const sp1 = TestHelper.getRandomizedPhotoEntry(subDir, 'subPhoto1'); + + DirectoryDTO.removeReferences(parent); + await gm.saveToDB(Utils.clone(parent)); + + const sp2 = TestHelper.getRandomizedPhotoEntry(subDir, 'subPhoto2'); + const sp3 = TestHelper.getRandomizedPhotoEntry(subDir, 'subPhoto3'); + + DirectoryDTO.removeReferences(subDir); + await gm.saveToDB(Utils.clone(subDir)); + + const conn = await SQLConnection.getConnection(); + const selected = await gm.selectParentDir(conn, subDir.name, subDir.path); + await gm.fillParentDir(conn, selected); + + // subDir.isPartial = true; + // delete subDir.directories; + DirectoryDTO.removeReferences(selected); + delete subDir.parent; + removeIds(selected); + // selected.directories[0].parent = selected; + expect(selected).to.deep.equal(subDir); + + }); + +}); diff --git a/test/backend/unit/model/sql/SearchManager.ts b/test/backend/unit/model/sql/SearchManager.ts index 16fb5f5c..69a39e90 100644 --- a/test/backend/unit/model/sql/SearchManager.ts +++ b/test/backend/unit/model/sql/SearchManager.ts @@ -18,6 +18,8 @@ import {DirectoryEntity} from '../../../../../backend/model/sql/enitites/Directo import {MediaDimensionEntity} from '../../../../../backend/model/sql/enitites/MediaEntity'; import {OrientationTypes} from 'ts-exif-parser'; import {Utils} from '../../../../../common/Utils'; +import {TestHelper} from './TestHelper'; +import {afterEach, beforeEach, describe, it} from '@angular/core/testing/src/testing_internal'; describe('SearchManager', () => { @@ -25,66 +27,9 @@ describe('SearchManager', () => { const tempDir = path.join(__dirname, '../../tmp'); const dbPath = path.join(tempDir, 'test.db'); - const dir = new DirectoryEntity(); - dir.name = 'wars dir'; - dir.path = '.'; - dir.lastModified = Date.now(); - dir.lastScanned = null; - - const getPhoto = () => { - const sd = new MediaDimensionEntity(); - sd.height = 200; - sd.width = 200; - const gps = new GPSMetadataEntity(); - /* gps.altitude = 1; - gps.latitude = 1; - gps.longitude = 1;*/ - const pd = new PositionMetaDataEntity(); - /* pd.city = "New York"; - pd.country = "Alderan"; - pd.state = "Death star";*/ - pd.GPSData = gps; - const cd = new CameraMetadataEntity(); - /* cd.ISO = 100; - cd.model = "60D"; - cd.maker = "Canon"; - cd.fStop = 1; - cd.exposure = 1; - cd.focalLength = 1;*/ - cd.lens = 'Lens'; - const m = new PhotoMetadataEntity(); - m.keywords = ['apple']; - m.cameraData = cd; - m.positionData = pd; - 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(); - d.name = 'test media.jpg'; - d.directory = dir; - d.metadata = m; - return d; - }; - - const p = getPhoto(); - p.metadata.keywords = ['Boba Fett', 'star wars', 'Anakin', 'death star']; - p.metadata.positionData.city = 'Mos Eisley'; - p.metadata.positionData.country = 'Tatooine'; - p.name = 'sw1'; - - const p2 = getPhoto(); - p2.metadata.keywords = ['Padmé Amidala', 'star wars', 'Natalie Portman', 'death star']; - p2.metadata.positionData.city = 'Derem City'; - p2.metadata.positionData.state = 'Research City'; - p2.metadata.positionData.country = 'Kamino'; - p2.name = 'sw2'; + const dir = TestHelper.getDirectoryEntry(); + const p = TestHelper.getPhotoEntry1(dir); + const p2 = TestHelper.getPhotoEntry2(dir); const setUpSqlDB = async () => { if (fs.existsSync(dbPath)) { diff --git a/test/backend/unit/model/sql/SharingManager.ts b/test/backend/unit/model/sql/SharingManager.ts index b46098b1..d11b72bd 100644 --- a/test/backend/unit/model/sql/SharingManager.ts +++ b/test/backend/unit/model/sql/SharingManager.ts @@ -61,9 +61,9 @@ describe('SharingManager', () => { it('should create sharing', async () => { - let sm = new SharingManager(); + const sm = new SharingManager(); - let sharing: SharingDTO = { + const sharing: SharingDTO = { id: null, sharingKey: 'testKey', path: '/', @@ -86,9 +86,9 @@ describe('SharingManager', () => { it('should find sharing', async () => { - let sm = new SharingManager(); + const sm = new SharingManager(); - let sharing: SharingDTO = { + const sharing: SharingDTO = { id: null, sharingKey: 'testKey', path: '/', @@ -111,9 +111,9 @@ describe('SharingManager', () => { it('should update sharing', async () => { - let sm = new SharingManager(); + const sm = new SharingManager(); - let sharing: SharingDTO = { + const sharing: SharingDTO = { id: null, sharingKey: 'testKey', path: '/', @@ -129,7 +129,7 @@ describe('SharingManager', () => { expect(saved.expires).to.equals(sharing.expires); expect(saved.includeSubfolders).to.equals(sharing.includeSubfolders); - let update: SharingDTO = { + const update: SharingDTO = { id: saved.id, sharingKey: saved.sharingKey, path: saved.path, diff --git a/test/backend/unit/model/sql/TestHelper.ts b/test/backend/unit/model/sql/TestHelper.ts new file mode 100644 index 00000000..86cce854 --- /dev/null +++ b/test/backend/unit/model/sql/TestHelper.ts @@ -0,0 +1,163 @@ +import {MediaDimensionEntity} from '../../../../../backend/model/sql/enitites/MediaEntity'; +import { + CameraMetadataEntity, + GPSMetadataEntity, PhotoEntity, + PhotoMetadataEntity, + PositionMetaDataEntity +} from '../../../../../backend/model/sql/enitites/PhotoEntity'; +import * as path from 'path'; +import {OrientationTypes} from 'ts-exif-parser'; +import {DirectoryEntity} from '../../../../../backend/model/sql/enitites/DirectoryEntity'; +import {Utils} from '../../../../../common/Utils'; + +export class TestHelper { + + public static getDirectoryEntry() { + + const dir = new DirectoryEntity(); + dir.name = 'wars dir'; + dir.path = '.'; + dir.lastModified = Date.now(); + dir.lastScanned = null; + + return dir; + } + + public static getPhotoEntry(dir: DirectoryEntity) { + const sd = new MediaDimensionEntity(); + sd.height = 200; + sd.width = 200; + const gps = new GPSMetadataEntity(); + gps.altitude = 1; + gps.latitude = 1; + gps.longitude = 1; + const pd = new PositionMetaDataEntity(); + pd.city = 'New York'; + pd.country = 'Alderan'; + pd.state = 'Kamino'; + pd.GPSData = gps; + const cd = new CameraMetadataEntity(); + cd.ISO = 100; + cd.model = '60D'; + cd.maker = 'Canon'; + cd.fStop = 1; + cd.exposure = 1; + cd.focalLength = 1; + cd.lens = 'Lens'; + const m = new PhotoMetadataEntity(); + m.keywords = ['apple']; + m.cameraData = cd; + m.positionData = pd; + 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(); + d.name = 'test media.jpg'; + d.directory = dir; + d.metadata = m; + return d; + } + + public static getPhotoEntry1(dir: DirectoryEntity) { + const p = TestHelper.getPhotoEntry(dir); + + p.metadata.keywords = ['Boba Fett', 'star wars', 'Anakin', 'death star']; + p.metadata.positionData.city = 'Mos Eisley'; + p.metadata.positionData.country = 'Tatooine'; + p.name = 'sw1'; + return p; + } + + public static getPhotoEntry2(dir: DirectoryEntity) { + const p = TestHelper.getPhotoEntry(dir); + + p.metadata.keywords = ['Padmé Amidala', 'star wars', 'Natalie Portman', 'death star']; + p.metadata.positionData.city = 'Derem City'; + p.metadata.positionData.state = 'Research City'; + p.metadata.positionData.country = 'Kamino'; + p.name = 'sw2'; + return p; + } + + + public static getRandomizedDirectoryEntry(parent: DirectoryEntity = null, forceStr = null) { + + const dir = new DirectoryEntity(); + dir.name = forceStr || Math.random().toString(36).substring(7); + dir.path = '.'; + if (parent !== null) { + dir.path = path.join(parent.path, parent.name); + parent.directories.push(dir); + } + dir.directories = []; + dir.media = []; + dir.lastModified = Date.now(); + dir.lastScanned = null; + + return dir; + } + + public static getRandomizedPhotoEntry(dir: DirectoryEntity, forceStr = null) { + + + const rndStr = () => { + return forceStr + '_' + Math.random().toString(36).substring(7); + }; + + + const rndInt = (max = 5000) => { + return Math.floor(Math.random() * max); + }; + + const sd = new MediaDimensionEntity(); + sd.height = rndInt(); + sd.width = rndInt(); + const gps = new GPSMetadataEntity(); + gps.altitude = rndInt(1000); + gps.latitude = rndInt(1000); + gps.longitude = rndInt(1000); + const pd = new PositionMetaDataEntity(); + pd.city = rndStr(); + pd.country = rndStr(); + pd.state = rndStr(); + pd.GPSData = gps; + const cd = new CameraMetadataEntity(); + cd.ISO = rndInt(500); + cd.model = rndStr(); + cd.maker = rndStr(); + cd.fStop = rndInt(10); + cd.exposure = rndInt(10); + cd.focalLength = rndInt(10); + cd.lens = rndStr(); + const m = new PhotoMetadataEntity(); + m.keywords = [rndStr(), rndStr()]; + m.cameraData = cd; + m.positionData = pd; + m.size = sd; + m.creationDate = Date.now(); + m.fileSize = rndInt(10000); + m.orientation = OrientationTypes.TOP_LEFT; + + // TODO: remove when typeorm is fixed + m.duration = null; + m.bitRate = null; + + + const d = new PhotoEntity(); + d.name = rndStr() + '.jpg'; + d.directory = dir; + d.metadata = m; + + dir.media.push(d); + return d; + } + + +}