159 lines
4.4 KiB
TypeScript
159 lines
4.4 KiB
TypeScript
import { readdirSync, readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
|
|
import { parse } from 'yaml';
|
|
import { yellow, red } from 'colors';
|
|
|
|
const rimraf = require('rimraf');
|
|
const sizeOf = require('image-size');
|
|
const clipper = require('image-clipper');
|
|
const canvas = require('canvas');
|
|
|
|
|
|
clipper.configure('canvas', canvas);
|
|
|
|
|
|
const albumsPath = "./public/pictures/albums";
|
|
|
|
|
|
function getDirectories(path: string) {
|
|
return readdirSync(path, { withFileTypes: true })
|
|
.filter(item => item.isDirectory()).map(item => item.name);
|
|
}
|
|
|
|
|
|
function getFiles(path: string) {
|
|
return readdirSync(path, { withFileTypes: true })
|
|
.filter(item => !item.isDirectory()).map(item => item.name);
|
|
}
|
|
|
|
|
|
function _genPreview(original: string, preview: string) {
|
|
const originalSize = sizeOf(original);
|
|
|
|
let minSize = Math.min(originalSize.width, originalSize.height);
|
|
|
|
if (minSize % 2 == 1)
|
|
minSize -= 1;
|
|
|
|
const centerX = Math.floor(originalSize.width / 2);
|
|
const centerY = Math.floor(originalSize.height / 2);
|
|
|
|
clipper(original, function() {
|
|
this.crop(centerX - minSize / 2, centerY - minSize / 2, minSize, minSize)
|
|
.resize(600, 600)
|
|
.quality(85)
|
|
.toFile(preview, () => {});
|
|
});
|
|
}
|
|
|
|
|
|
function generatePriview(config: { folderName: string,
|
|
files: string[],
|
|
files_360: string[] }) {
|
|
const albumPath = `${albumsPath}/${config.folderName}`;
|
|
const previewsPath = `${albumPath}/generated_previews`;
|
|
|
|
if (existsSync(previewsPath)) {
|
|
rimraf.sync(previewsPath);
|
|
}
|
|
|
|
mkdirSync(previewsPath);
|
|
|
|
config.files.forEach((item) => {
|
|
const filePath = `${albumPath}/photos/${item}`;
|
|
const previewPath = `${albumPath}/generated_previews/${item}`;
|
|
|
|
_genPreview(filePath, previewPath);
|
|
});
|
|
|
|
config.files_360.forEach((item) => {
|
|
const filePath = `${albumPath}/360_photos/${item}`;
|
|
const previewPath = `${albumPath}/generated_previews/${item}`;
|
|
|
|
_genPreview(filePath, previewPath);
|
|
});
|
|
}
|
|
|
|
|
|
function processAlbum(folderName: string) {
|
|
let config = {};
|
|
|
|
const albumPath = `${albumsPath}/${folderName}`;
|
|
|
|
const directories = getDirectories(albumPath);
|
|
const files = getFiles(albumPath);
|
|
|
|
let photos = [];
|
|
|
|
if (directories.includes('photos')) {
|
|
photos = getFiles(`${albumPath}/photos`);
|
|
} else {
|
|
console.warn(yellow(`Warning: Folder ${albumPath}/photos does not exist!`));
|
|
}
|
|
|
|
let photos360 = [];
|
|
|
|
if (directories.includes('360_photos')) {
|
|
photos360 = getFiles(`${albumPath}/360_photos`);
|
|
} else {
|
|
console.warn(yellow(`Warning: Folder ${albumPath}/360_photos does not exist!`));
|
|
}
|
|
|
|
if (files.includes('album.yml')) {
|
|
const configData = readFileSync(`${albumPath}/album.yml`, 'utf-8');
|
|
|
|
let parsedData: object | null = null;
|
|
|
|
try {
|
|
parsedData = parse(configData);
|
|
} catch (YAMLSemanticError) {
|
|
console.error(red(`Error: ${albumsPath}/album.yml parse error!`));
|
|
}
|
|
|
|
if (parsedData !== null) {
|
|
['name', 'description', 'protected', 'coverFileName'].forEach(item => {
|
|
if (parsedData[item] !== undefined) {
|
|
config[item] = parsedData[item];
|
|
} else {
|
|
console.error(red(`Error: File ${albumPath}/album.yml does not contains "${item}" key!`));
|
|
}
|
|
});
|
|
|
|
if (parsedData['coverFileName']) {
|
|
if (!photos.includes(parsedData['coverFileName'])) {
|
|
console.error(red(`Error: Cover file ${albumPath}/photos/${parsedData['coverFileName']} does not exists!`));
|
|
}
|
|
}
|
|
|
|
if (parsedData['photoDescription']) {
|
|
Object.keys(parsedData['photoDescription']).forEach(item => {
|
|
if (!photos.includes(item) && !photos360.includes(item)) {
|
|
console.warn(yellow(`Warning: Description for ${albumPath}/photos/${item} , but it doesn't exist!`));
|
|
}
|
|
});
|
|
|
|
config['photoDescription'] = parsedData['photoDescription'];
|
|
}
|
|
}
|
|
} else {
|
|
console.error(red(`Error: File ${albumPath}/album.yml does not exists!`));
|
|
}
|
|
|
|
config['folderName'] = folderName;
|
|
|
|
config['files'] = photos;
|
|
|
|
config['files_360'] = photos360;
|
|
|
|
generatePriview(config as { folderName: string,
|
|
files: string[],
|
|
files_360: string[] }
|
|
);
|
|
|
|
return config;
|
|
}
|
|
|
|
|
|
const albumsConfig = getDirectories(albumsPath).map(item => processAlbum(item));
|
|
|
|
writeFileSync('./public/generated_albums_config.json', JSON.stringify(albumsConfig));
|