1
0
mirror of https://github.com/xuthus83/pigallery2.git synced 2025-01-14 14:43:17 +08:00

fixing gallery manager bug, implementing tests

This commit is contained in:
Patrik J. Braun 2018-11-24 11:50:11 +01:00
parent 7cc5f6d6b1
commit 7576e1678f
6 changed files with 486 additions and 225 deletions

View File

@ -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<DirectoryEntity> {
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<void> {
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;
(<DirectoryEntity>scannedDirectory).lastScanned = scannedDirectory.lastScanned;
currentDir = await directoryRepository.save(<DirectoryEntity>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;
(<DirectoryEntity>scannedDirectory.directories[i]).lastScanned = null; // new child dir, not fully scanned yet
const d = await directoryRepository.save(<DirectoryEntity>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 = (<PhotoDTO>scannedDirectory.media[i]).metadata;
mediaToSave.push(media);
}
}
await this.saveMedia(connection, mediaToSave);
await mediaRepository.remove(indexedMedia);
}
private async saveMedia(connection: Connection, mediaList: MediaDTO[]): Promise<MediaEntity[]> {
const list = await connection.getRepository(VideoEntity).save(<VideoEntity[]>mediaList.filter(m => MediaDTO.isVideo(m)));
return list.concat(await connection.getRepository(PhotoEntity).save(<PhotoEntity[]>mediaList.filter(m => MediaDTO.isPhoto(m))));
}
async getRandomPhoto(queryFilter: RandomQuery): Promise<PhotoDTO> {
public async getRandomPhoto(queryFilter: RandomQuery): Promise<PhotoDTO> {
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;
(<DirectoryEntity>scannedDirectory).lastScanned = scannedDirectory.lastScanned;
currentDir = await directoryRepository.save(<DirectoryEntity>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;
(<DirectoryEntity>scannedDirectory.directories[i]).lastScanned = null; // new child dir, not fully scanned yet
const d = await directoryRepository.save(<DirectoryEntity>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<MediaEntity[]> {
const list = await connection.getRepository(VideoEntity).save(<VideoEntity[]>mediaList.filter(m => MediaDTO.isVideo(m)));
return list.concat(await connection.getRepository(PhotoEntity).save(<PhotoEntity[]>mediaList.filter(m => MediaDTO.isPhoto(m))));
}
}

View File

@ -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;
});
}
};
}

View File

@ -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<DirectoryEntity> {
return super.selectParentDir(connection, directoryName, directoryParent);
}
public async fillParentDir(connection: Connection, dir: DirectoryEntity): Promise<void> {
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);
});
});

View File

@ -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)) {

View File

@ -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,

View File

@ -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;
}
}