simple-photo-gallery 2.0.11-rc.9 → 2.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/fonts/dejavu/DejaVuSans-Bold.ttf +0 -0
- package/assets/fonts/dejavu/LICENSE.txt +78 -0
- package/dist/index.cjs +149 -90
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +146 -87
- package/dist/index.js.map +1 -1
- package/dist/lib/browser.cjs +29 -0
- package/dist/lib/browser.cjs.map +1 -0
- package/dist/lib/browser.d.cts +8 -0
- package/dist/lib/browser.d.ts +8 -0
- package/dist/lib/browser.js +23 -0
- package/dist/lib/browser.js.map +1 -0
- package/dist/lib/index.cjs +47 -2
- package/dist/lib/index.cjs.map +1 -1
- package/dist/lib/index.js +46 -2
- package/dist/lib/index.js.map +1 -1
- package/package.json +9 -4
package/dist/index.cjs
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var process4 = require('process');
|
|
5
5
|
var commander = require('commander');
|
|
6
6
|
var consola = require('consola');
|
|
7
7
|
var child_process = require('child_process');
|
|
8
8
|
var fs8 = require('fs');
|
|
9
|
-
var
|
|
9
|
+
var path = require('path');
|
|
10
10
|
var buffer = require('buffer');
|
|
11
|
+
var url = require('url');
|
|
11
12
|
var sharp2 = require('sharp');
|
|
12
13
|
var blurhash = require('blurhash');
|
|
13
14
|
var common = require('@simple-photo-gallery/common');
|
|
@@ -21,9 +22,9 @@ var semverParser = require('semver-parser');
|
|
|
21
22
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
22
23
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
23
24
|
|
|
24
|
-
var
|
|
25
|
+
var process4__default = /*#__PURE__*/_interopDefault(process4);
|
|
25
26
|
var fs8__default = /*#__PURE__*/_interopDefault(fs8);
|
|
26
|
-
var
|
|
27
|
+
var path__default = /*#__PURE__*/_interopDefault(path);
|
|
27
28
|
var sharp2__default = /*#__PURE__*/_interopDefault(sharp2);
|
|
28
29
|
var ExifReader__default = /*#__PURE__*/_interopDefault(ExifReader);
|
|
29
30
|
var ffprobe__default = /*#__PURE__*/_interopDefault(ffprobe);
|
|
@@ -91,10 +92,42 @@ async function generateBlurHash(imagePath, componentX = 4, componentY = 3) {
|
|
|
91
92
|
}
|
|
92
93
|
|
|
93
94
|
// src/modules/build/utils/index.ts
|
|
94
|
-
|
|
95
|
+
var __dirname$1 = path__default.default.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))));
|
|
96
|
+
var SOCIAL_CARD_FONT_RELATIVE_PATH = path__default.default.join("assets", "fonts", "dejavu", "DejaVuSans-Bold.ttf");
|
|
97
|
+
var socialCardFontBase64;
|
|
98
|
+
function resolveFromCurrentDir(...segments) {
|
|
99
|
+
return path__default.default.resolve(__dirname$1, ...segments);
|
|
100
|
+
}
|
|
101
|
+
function findSocialCardFontPath() {
|
|
102
|
+
const fontCandidates = [
|
|
103
|
+
resolveFromCurrentDir("../../../../", SOCIAL_CARD_FONT_RELATIVE_PATH),
|
|
104
|
+
path__default.default.resolve(__dirname$1, "../", SOCIAL_CARD_FONT_RELATIVE_PATH),
|
|
105
|
+
path__default.default.resolve(__dirname$1, "../../", SOCIAL_CARD_FONT_RELATIVE_PATH),
|
|
106
|
+
path__default.default.resolve(process4__default.default.cwd(), SOCIAL_CARD_FONT_RELATIVE_PATH),
|
|
107
|
+
path__default.default.resolve(process4__default.default.cwd(), "../", SOCIAL_CARD_FONT_RELATIVE_PATH)
|
|
108
|
+
];
|
|
109
|
+
for (const candidate of fontCandidates) {
|
|
110
|
+
if (fs8__default.default.existsSync(candidate)) {
|
|
111
|
+
return candidate;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
function getSocialCardFontBase64() {
|
|
117
|
+
if (socialCardFontBase64 !== void 0) {
|
|
118
|
+
return socialCardFontBase64;
|
|
119
|
+
}
|
|
120
|
+
const fontPath = findSocialCardFontPath();
|
|
121
|
+
if (!fontPath) {
|
|
122
|
+
socialCardFontBase64 = null;
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
socialCardFontBase64 = fs8__default.default.readFileSync(fontPath).toString("base64");
|
|
126
|
+
return socialCardFontBase64;
|
|
127
|
+
}
|
|
95
128
|
async function createGallerySocialMediaCardImage(headerPhotoPath, title, ouputPath, ui) {
|
|
96
129
|
ui?.start(`Creating social media card image`);
|
|
97
|
-
const headerBasename =
|
|
130
|
+
const headerBasename = path__default.default.basename(headerPhotoPath, path__default.default.extname(headerPhotoPath));
|
|
98
131
|
if (fs8__default.default.existsSync(ouputPath)) {
|
|
99
132
|
ui?.success(`Social media card image already exists`);
|
|
100
133
|
return headerBasename;
|
|
@@ -103,11 +136,21 @@ async function createGallerySocialMediaCardImage(headerPhotoPath, title, ouputPa
|
|
|
103
136
|
const resizedImageBuffer = await image.resize(1200, 631, { fit: "cover" }).jpeg({ quality: 90 }).toBuffer();
|
|
104
137
|
const outputPath = ouputPath;
|
|
105
138
|
await sharp2__default.default(resizedImageBuffer).toFile(outputPath);
|
|
139
|
+
const fontBase64 = getSocialCardFontBase64();
|
|
140
|
+
const fontFace = fontBase64 ? `
|
|
141
|
+
@font-face {
|
|
142
|
+
font-family: 'DejaVu Sans';
|
|
143
|
+
src: url('data:font/ttf;base64,${fontBase64}') format('truetype');
|
|
144
|
+
font-weight: 700;
|
|
145
|
+
font-style: normal;
|
|
146
|
+
}` : "";
|
|
147
|
+
const fontFamily = fontBase64 ? "'DejaVu Sans', Arial, sans-serif" : "Arial, sans-serif";
|
|
106
148
|
const svgText = `
|
|
107
149
|
<svg width="1200" height="631" xmlns="http://www.w3.org/2000/svg">
|
|
108
150
|
<defs>
|
|
109
151
|
<style>
|
|
110
|
-
|
|
152
|
+
${fontFace}
|
|
153
|
+
.title { font-family: ${fontFamily}; font-size: 96px; font-weight: bold; fill: white; stroke: black; stroke-width: 5; paint-order: stroke; text-anchor: middle; }
|
|
111
154
|
</style>
|
|
112
155
|
</defs>
|
|
113
156
|
<text x="600" y="250" class="title">${title}</text>
|
|
@@ -121,7 +164,7 @@ async function createGallerySocialMediaCardImage(headerPhotoPath, title, ouputPa
|
|
|
121
164
|
async function createOptimizedHeaderImage(headerPhotoPath, outputFolder, ui) {
|
|
122
165
|
ui?.start(`Creating optimized header images`);
|
|
123
166
|
const image = await loadImage(headerPhotoPath);
|
|
124
|
-
const headerBasename =
|
|
167
|
+
const headerBasename = path__default.default.basename(headerPhotoPath, path__default.default.extname(headerPhotoPath));
|
|
125
168
|
const generatedFiles = [];
|
|
126
169
|
ui?.debug("Generating blurhash for header image");
|
|
127
170
|
const blurHash = await generateBlurHash(headerPhotoPath);
|
|
@@ -130,22 +173,22 @@ async function createOptimizedHeaderImage(headerPhotoPath, outputFolder, ui) {
|
|
|
130
173
|
ui?.debug(`Creating landscape header image ${width}`);
|
|
131
174
|
const avifFilename = `${headerBasename}_landscape_${width}.avif`;
|
|
132
175
|
const jpgFilename = `${headerBasename}_landscape_${width}.jpg`;
|
|
133
|
-
if (fs8__default.default.existsSync(
|
|
176
|
+
if (fs8__default.default.existsSync(path__default.default.join(outputFolder, avifFilename))) {
|
|
134
177
|
ui?.debug(`Landscape header image ${width} AVIF already exists`);
|
|
135
178
|
} else {
|
|
136
179
|
await cropAndResizeImage(
|
|
137
180
|
image.clone(),
|
|
138
|
-
|
|
181
|
+
path__default.default.join(outputFolder, avifFilename),
|
|
139
182
|
width,
|
|
140
183
|
width * landscapeYFactor,
|
|
141
184
|
"avif"
|
|
142
185
|
);
|
|
143
186
|
}
|
|
144
187
|
generatedFiles.push(avifFilename);
|
|
145
|
-
if (fs8__default.default.existsSync(
|
|
188
|
+
if (fs8__default.default.existsSync(path__default.default.join(outputFolder, jpgFilename))) {
|
|
146
189
|
ui?.debug(`Landscape header image ${width} JPG already exists`);
|
|
147
190
|
} else {
|
|
148
|
-
await cropAndResizeImage(image.clone(),
|
|
191
|
+
await cropAndResizeImage(image.clone(), path__default.default.join(outputFolder, jpgFilename), width, width * landscapeYFactor, "jpg");
|
|
149
192
|
}
|
|
150
193
|
generatedFiles.push(jpgFilename);
|
|
151
194
|
}
|
|
@@ -154,16 +197,16 @@ async function createOptimizedHeaderImage(headerPhotoPath, outputFolder, ui) {
|
|
|
154
197
|
ui?.debug(`Creating portrait header image ${width}`);
|
|
155
198
|
const avifFilename = `${headerBasename}_portrait_${width}.avif`;
|
|
156
199
|
const jpgFilename = `${headerBasename}_portrait_${width}.jpg`;
|
|
157
|
-
if (fs8__default.default.existsSync(
|
|
200
|
+
if (fs8__default.default.existsSync(path__default.default.join(outputFolder, avifFilename))) {
|
|
158
201
|
ui?.debug(`Portrait header image ${width} AVIF already exists`);
|
|
159
202
|
} else {
|
|
160
|
-
await cropAndResizeImage(image.clone(),
|
|
203
|
+
await cropAndResizeImage(image.clone(), path__default.default.join(outputFolder, avifFilename), width, width * portraitYFactor, "avif");
|
|
161
204
|
}
|
|
162
205
|
generatedFiles.push(avifFilename);
|
|
163
|
-
if (fs8__default.default.existsSync(
|
|
206
|
+
if (fs8__default.default.existsSync(path__default.default.join(outputFolder, jpgFilename))) {
|
|
164
207
|
ui?.debug(`Portrait header image ${width} JPG already exists`);
|
|
165
208
|
} else {
|
|
166
|
-
await cropAndResizeImage(image.clone(),
|
|
209
|
+
await cropAndResizeImage(image.clone(), path__default.default.join(outputFolder, jpgFilename), width, width * portraitYFactor, "jpg");
|
|
167
210
|
}
|
|
168
211
|
generatedFiles.push(jpgFilename);
|
|
169
212
|
}
|
|
@@ -196,12 +239,12 @@ function cleanupOldHeaderImages(outputFolder, currentHeaderBasename, ui) {
|
|
|
196
239
|
const landscapeMatch = file.match(/^(.+)_landscape_\d+\.(avif|jpg)$/);
|
|
197
240
|
const portraitMatch = file.match(/^(.+)_portrait_\d+\.(avif|jpg)$/);
|
|
198
241
|
if (landscapeMatch && landscapeMatch[1] !== currentHeaderBasename) {
|
|
199
|
-
const filePath =
|
|
242
|
+
const filePath = path__default.default.join(outputFolder, file);
|
|
200
243
|
ui?.debug(`Deleting old landscape header image: ${file}`);
|
|
201
244
|
fs8__default.default.unlinkSync(filePath);
|
|
202
245
|
deletedCount++;
|
|
203
246
|
} else if (portraitMatch && portraitMatch[1] !== currentHeaderBasename) {
|
|
204
|
-
const filePath =
|
|
247
|
+
const filePath = path__default.default.join(outputFolder, file);
|
|
205
248
|
ui?.debug(`Deleting old portrait header image: ${file}`);
|
|
206
249
|
fs8__default.default.unlinkSync(filePath);
|
|
207
250
|
deletedCount++;
|
|
@@ -215,7 +258,7 @@ function cleanupOldHeaderImages(outputFolder, currentHeaderBasename, ui) {
|
|
|
215
258
|
}
|
|
216
259
|
function findGalleries(basePath, recursive) {
|
|
217
260
|
const galleryDirs = [];
|
|
218
|
-
const galleryJsonPath =
|
|
261
|
+
const galleryJsonPath = path__default.default.join(basePath, "gallery", "gallery.json");
|
|
219
262
|
if (fs8__default.default.existsSync(galleryJsonPath)) {
|
|
220
263
|
galleryDirs.push(basePath);
|
|
221
264
|
}
|
|
@@ -224,7 +267,7 @@ function findGalleries(basePath, recursive) {
|
|
|
224
267
|
const entries = fs8__default.default.readdirSync(basePath, { withFileTypes: true });
|
|
225
268
|
for (const entry of entries) {
|
|
226
269
|
if (entry.isDirectory() && entry.name !== "gallery") {
|
|
227
|
-
const subPath =
|
|
270
|
+
const subPath = path__default.default.join(basePath, entry.name);
|
|
228
271
|
const subResults = findGalleries(subPath, recursive);
|
|
229
272
|
galleryDirs.push(...subResults);
|
|
230
273
|
}
|
|
@@ -283,20 +326,20 @@ function migrateGalleryJson(deprecatedGalleryData, galleryJsonPath, ui) {
|
|
|
283
326
|
ui.start("Old gallery.json format detected. Migrating gallery.json to the new data format.");
|
|
284
327
|
let mediaBasePath;
|
|
285
328
|
const imagePath = deprecatedGalleryData.sections[0].images[0].path;
|
|
286
|
-
if (imagePath && imagePath !==
|
|
287
|
-
mediaBasePath =
|
|
329
|
+
if (imagePath && imagePath !== path__default.default.join("..", path__default.default.basename(imagePath))) {
|
|
330
|
+
mediaBasePath = path__default.default.resolve(path__default.default.join(path__default.default.dirname(galleryJsonPath)), path__default.default.dirname(imagePath));
|
|
288
331
|
}
|
|
289
332
|
const sections = deprecatedGalleryData.sections.map((section) => ({
|
|
290
333
|
...section,
|
|
291
334
|
images: section.images.map((image) => ({
|
|
292
335
|
...image,
|
|
293
336
|
path: void 0,
|
|
294
|
-
filename:
|
|
337
|
+
filename: path__default.default.basename(image.path)
|
|
295
338
|
}))
|
|
296
339
|
}));
|
|
297
340
|
const galleryData = {
|
|
298
341
|
...deprecatedGalleryData,
|
|
299
|
-
headerImage:
|
|
342
|
+
headerImage: path__default.default.basename(deprecatedGalleryData.headerImage),
|
|
300
343
|
sections,
|
|
301
344
|
mediaBasePath
|
|
302
345
|
};
|
|
@@ -308,7 +351,7 @@ function migrateGalleryJson(deprecatedGalleryData, galleryJsonPath, ui) {
|
|
|
308
351
|
return galleryData;
|
|
309
352
|
}
|
|
310
353
|
function getMediaFileType(fileName) {
|
|
311
|
-
const ext =
|
|
354
|
+
const ext = path__default.default.extname(fileName).toLowerCase();
|
|
312
355
|
if (IMAGE_EXTENSIONS.has(ext)) return "image";
|
|
313
356
|
if (VIDEO_EXTENSIONS.has(ext)) return "video";
|
|
314
357
|
return null;
|
|
@@ -336,7 +379,7 @@ async function scanDirectory(dirPath, ui) {
|
|
|
336
379
|
mediaFiles.push(mediaFile);
|
|
337
380
|
}
|
|
338
381
|
} else if (entry.isDirectory() && entry.name !== "gallery") {
|
|
339
|
-
subGalleryDirectories.push(
|
|
382
|
+
subGalleryDirectories.push(path__default.default.join(dirPath, entry.name));
|
|
340
383
|
}
|
|
341
384
|
}
|
|
342
385
|
} catch (error) {
|
|
@@ -371,13 +414,13 @@ async function getGallerySettingsFromUser(galleryName, defaultImage, ui) {
|
|
|
371
414
|
});
|
|
372
415
|
return { title, description, url, headerImage };
|
|
373
416
|
}
|
|
374
|
-
async function createGalleryJson(mediaFiles, galleryJsonPath, scanPath, subGalleries = [], useDefaultSettings, ui) {
|
|
375
|
-
const galleryDir =
|
|
376
|
-
const isSameLocation =
|
|
417
|
+
async function createGalleryJson(mediaFiles, galleryJsonPath, scanPath, subGalleries = [], useDefaultSettings, ctaBanner, ui) {
|
|
418
|
+
const galleryDir = path__default.default.dirname(galleryJsonPath);
|
|
419
|
+
const isSameLocation = path__default.default.relative(scanPath, path__default.default.join(galleryDir, "..")) === "";
|
|
377
420
|
const mediaBasePath = isSameLocation ? void 0 : scanPath;
|
|
378
421
|
const relativeSubGalleries = subGalleries.map((subGallery) => ({
|
|
379
422
|
...subGallery,
|
|
380
|
-
headerImage: subGallery.headerImage ?
|
|
423
|
+
headerImage: subGallery.headerImage ? path__default.default.relative(galleryDir, subGallery.headerImage) : ""
|
|
381
424
|
}));
|
|
382
425
|
let galleryData = {
|
|
383
426
|
title: "My Gallery",
|
|
@@ -393,14 +436,15 @@ async function createGalleryJson(mediaFiles, galleryJsonPath, scanPath, subGalle
|
|
|
393
436
|
subGalleries: {
|
|
394
437
|
title: "Sub Galleries",
|
|
395
438
|
galleries: relativeSubGalleries
|
|
396
|
-
}
|
|
439
|
+
},
|
|
440
|
+
...ctaBanner !== void 0 && { ctaBanner }
|
|
397
441
|
};
|
|
398
442
|
if (!useDefaultSettings) {
|
|
399
443
|
galleryData = {
|
|
400
444
|
...galleryData,
|
|
401
445
|
...await getGallerySettingsFromUser(
|
|
402
|
-
|
|
403
|
-
|
|
446
|
+
path__default.default.basename(path__default.default.join(galleryDir, "..")),
|
|
447
|
+
path__default.default.basename(mediaFiles[0]?.filename || ""),
|
|
404
448
|
ui
|
|
405
449
|
)
|
|
406
450
|
};
|
|
@@ -408,8 +452,8 @@ async function createGalleryJson(mediaFiles, galleryJsonPath, scanPath, subGalle
|
|
|
408
452
|
await fs8.promises.writeFile(galleryJsonPath, JSON.stringify(galleryData, null, 2));
|
|
409
453
|
}
|
|
410
454
|
async function galleryExists(outputPath) {
|
|
411
|
-
const galleryPath =
|
|
412
|
-
const galleryJsonPath =
|
|
455
|
+
const galleryPath = path__default.default.join(outputPath, "gallery");
|
|
456
|
+
const galleryJsonPath = path__default.default.join(galleryPath, "gallery.json");
|
|
413
457
|
try {
|
|
414
458
|
await fs8.promises.access(galleryJsonPath);
|
|
415
459
|
return true;
|
|
@@ -417,7 +461,7 @@ async function galleryExists(outputPath) {
|
|
|
417
461
|
return false;
|
|
418
462
|
}
|
|
419
463
|
}
|
|
420
|
-
async function processDirectory(scanPath, outputPath, recursive, useDefaultSettings, force, ui) {
|
|
464
|
+
async function processDirectory(scanPath, outputPath, recursive, useDefaultSettings, force, ctaBanner, ui) {
|
|
421
465
|
ui.start(`Scanning ${scanPath}`);
|
|
422
466
|
let totalFiles = 0;
|
|
423
467
|
let totalGalleries = 1;
|
|
@@ -428,10 +472,11 @@ async function processDirectory(scanPath, outputPath, recursive, useDefaultSetti
|
|
|
428
472
|
for (const subGalleryDir of subGalleryDirectories) {
|
|
429
473
|
const result2 = await processDirectory(
|
|
430
474
|
subGalleryDir,
|
|
431
|
-
|
|
475
|
+
path__default.default.join(outputPath, path__default.default.basename(subGalleryDir)),
|
|
432
476
|
recursive,
|
|
433
477
|
useDefaultSettings,
|
|
434
478
|
force,
|
|
479
|
+
ctaBanner,
|
|
435
480
|
ui
|
|
436
481
|
);
|
|
437
482
|
totalFiles += result2.totalFiles;
|
|
@@ -442,8 +487,8 @@ async function processDirectory(scanPath, outputPath, recursive, useDefaultSetti
|
|
|
442
487
|
}
|
|
443
488
|
}
|
|
444
489
|
if (mediaFiles.length > 0 || subGalleries.length > 0) {
|
|
445
|
-
const galleryPath =
|
|
446
|
-
const galleryJsonPath =
|
|
490
|
+
const galleryPath = path__default.default.join(outputPath, "gallery");
|
|
491
|
+
const galleryJsonPath = path__default.default.join(galleryPath, "gallery.json");
|
|
447
492
|
const exists = await galleryExists(outputPath);
|
|
448
493
|
if (exists && !force) {
|
|
449
494
|
const shouldOverride = await ui.prompt(`Gallery already exists at ${galleryJsonPath}. Do you want to override it?`, {
|
|
@@ -457,7 +502,7 @@ async function processDirectory(scanPath, outputPath, recursive, useDefaultSetti
|
|
|
457
502
|
}
|
|
458
503
|
try {
|
|
459
504
|
await fs8.promises.mkdir(galleryPath, { recursive: true });
|
|
460
|
-
await createGalleryJson(mediaFiles, galleryJsonPath, scanPath, subGalleries, useDefaultSettings, ui);
|
|
505
|
+
await createGalleryJson(mediaFiles, galleryJsonPath, scanPath, subGalleries, useDefaultSettings, ctaBanner, ui);
|
|
461
506
|
ui.success(
|
|
462
507
|
`Create gallery with ${mediaFiles.length} files and ${subGalleries.length} subgalleries at: ${galleryJsonPath}`
|
|
463
508
|
);
|
|
@@ -468,20 +513,28 @@ async function processDirectory(scanPath, outputPath, recursive, useDefaultSetti
|
|
|
468
513
|
}
|
|
469
514
|
const result = { totalFiles, totalGalleries };
|
|
470
515
|
if (mediaFiles.length > 0 || subGalleries.length > 0) {
|
|
471
|
-
const dirName =
|
|
516
|
+
const dirName = path__default.default.basename(scanPath);
|
|
472
517
|
result.subGallery = {
|
|
473
518
|
title: capitalizeTitle(dirName),
|
|
474
519
|
headerImage: mediaFiles[0]?.filename || "",
|
|
475
|
-
path:
|
|
520
|
+
path: path__default.default.join("..", dirName)
|
|
476
521
|
};
|
|
477
522
|
}
|
|
478
523
|
return result;
|
|
479
524
|
}
|
|
480
525
|
async function init(options, ui) {
|
|
481
526
|
try {
|
|
482
|
-
const scanPath =
|
|
483
|
-
const outputPath = options.gallery ?
|
|
484
|
-
const result = await processDirectory(
|
|
527
|
+
const scanPath = path__default.default.resolve(options.photos);
|
|
528
|
+
const outputPath = options.gallery ? path__default.default.resolve(options.gallery) : scanPath;
|
|
529
|
+
const result = await processDirectory(
|
|
530
|
+
scanPath,
|
|
531
|
+
outputPath,
|
|
532
|
+
options.recursive,
|
|
533
|
+
options.default,
|
|
534
|
+
options.force,
|
|
535
|
+
options.ctaBanner,
|
|
536
|
+
ui
|
|
537
|
+
);
|
|
485
538
|
ui.box(
|
|
486
539
|
`Created ${result.totalGalleries} ${result.totalGalleries === 1 ? "gallery" : "galleries"} with ${result.totalFiles} media ${result.totalFiles === 1 ? "file" : "files"}`
|
|
487
540
|
);
|
|
@@ -596,7 +649,7 @@ async function processImage(imagePath, thumbnailPath, thumbnailPathRetina, thumb
|
|
|
596
649
|
const blurHash = await generateBlurHash(thumbnailPath);
|
|
597
650
|
return {
|
|
598
651
|
type: "image",
|
|
599
|
-
filename:
|
|
652
|
+
filename: path__default.default.basename(imagePath),
|
|
600
653
|
alt: description,
|
|
601
654
|
width: imageDimensions.width,
|
|
602
655
|
height: imageDimensions.height,
|
|
@@ -627,7 +680,7 @@ async function processVideo(videoPath, thumbnailPath, thumbnailPathRetina, thumb
|
|
|
627
680
|
const blurHash = await generateBlurHash(thumbnailPath);
|
|
628
681
|
return {
|
|
629
682
|
type: "video",
|
|
630
|
-
filename:
|
|
683
|
+
filename: path__default.default.basename(videoPath),
|
|
631
684
|
alt: void 0,
|
|
632
685
|
width: videoDimensions.width,
|
|
633
686
|
height: videoDimensions.height,
|
|
@@ -643,11 +696,11 @@ async function processVideo(videoPath, thumbnailPath, thumbnailPathRetina, thumb
|
|
|
643
696
|
}
|
|
644
697
|
async function processMediaFile(mediaFile, mediaBasePath, thumbnailsPath, thumbnailSize, ui) {
|
|
645
698
|
try {
|
|
646
|
-
const filePath =
|
|
699
|
+
const filePath = path__default.default.resolve(path__default.default.join(mediaBasePath, mediaFile.filename));
|
|
647
700
|
const fileName = mediaFile.filename;
|
|
648
|
-
const fileNameWithoutExt =
|
|
701
|
+
const fileNameWithoutExt = path__default.default.parse(fileName).name;
|
|
649
702
|
const thumbnailFileName = `${fileNameWithoutExt}.avif`;
|
|
650
|
-
const thumbnailPath =
|
|
703
|
+
const thumbnailPath = path__default.default.join(thumbnailsPath, thumbnailFileName);
|
|
651
704
|
const thumbnailPathRetina = thumbnailPath.replace(".avif", "@2x.avif");
|
|
652
705
|
const lastMediaTimestamp = mediaFile.lastMediaTimestamp ? new Date(mediaFile.lastMediaTimestamp) : void 0;
|
|
653
706
|
const verbose = ui.level === consola.LogLevels.debug;
|
|
@@ -673,8 +726,14 @@ async function processMediaFile(mediaFile, mediaBasePath, thumbnailsPath, thumbn
|
|
|
673
726
|
}
|
|
674
727
|
updatedMediaFile.filename = mediaFile.filename;
|
|
675
728
|
if (updatedMediaFile.thumbnail) {
|
|
676
|
-
updatedMediaFile.thumbnail.path =
|
|
677
|
-
updatedMediaFile.thumbnail.pathRetina =
|
|
729
|
+
updatedMediaFile.thumbnail.path = path__default.default.basename(thumbnailPath);
|
|
730
|
+
updatedMediaFile.thumbnail.pathRetina = path__default.default.basename(thumbnailPathRetina);
|
|
731
|
+
if (mediaFile.thumbnail?.baseUrl) {
|
|
732
|
+
updatedMediaFile.thumbnail.baseUrl = mediaFile.thumbnail.baseUrl;
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
if (mediaFile.url) {
|
|
736
|
+
updatedMediaFile.url = mediaFile.url;
|
|
678
737
|
}
|
|
679
738
|
return updatedMediaFile;
|
|
680
739
|
} catch (error) {
|
|
@@ -683,14 +742,14 @@ async function processMediaFile(mediaFile, mediaBasePath, thumbnailsPath, thumbn
|
|
|
683
742
|
}
|
|
684
743
|
}
|
|
685
744
|
async function processGalleryThumbnails(galleryDir, ui) {
|
|
686
|
-
const galleryJsonPath =
|
|
687
|
-
const thumbnailsPath =
|
|
745
|
+
const galleryJsonPath = path__default.default.join(galleryDir, "gallery", "gallery.json");
|
|
746
|
+
const thumbnailsPath = path__default.default.join(galleryDir, "gallery", "images");
|
|
688
747
|
ui.start(`Creating thumbnails: ${galleryDir}`);
|
|
689
748
|
try {
|
|
690
749
|
fs8__default.default.mkdirSync(thumbnailsPath, { recursive: true });
|
|
691
750
|
const galleryData = parseGalleryJson(galleryJsonPath, ui);
|
|
692
751
|
const thumbnailSize = galleryData.thumbnailSize || DEFAULT_THUMBNAIL_SIZE;
|
|
693
|
-
const mediaBasePath = galleryData.mediaBasePath ??
|
|
752
|
+
const mediaBasePath = galleryData.mediaBasePath ?? path__default.default.join(galleryDir);
|
|
694
753
|
let processedCount = 0;
|
|
695
754
|
for (const section of galleryData.sections) {
|
|
696
755
|
for (const [index, mediaFile] of section.images.entries()) {
|
|
@@ -737,8 +796,8 @@ function copyPhotos(galleryData, galleryDir, ui) {
|
|
|
737
796
|
for (const section of galleryData.sections) {
|
|
738
797
|
for (const image of section.images) {
|
|
739
798
|
if (galleryData.mediaBasePath) {
|
|
740
|
-
const sourcePath =
|
|
741
|
-
const destPath =
|
|
799
|
+
const sourcePath = path__default.default.join(galleryData.mediaBasePath, image.filename);
|
|
800
|
+
const destPath = path__default.default.join(galleryDir, image.filename);
|
|
742
801
|
ui.debug(`Copying photo to ${destPath}`);
|
|
743
802
|
fs8__default.default.copyFileSync(sourcePath, destPath);
|
|
744
803
|
}
|
|
@@ -777,17 +836,17 @@ async function scanAndAppendNewFiles(galleryDir, galleryJsonPath, galleryData, u
|
|
|
777
836
|
}
|
|
778
837
|
async function buildGallery(galleryDir, templateDir, scan, shouldCreateThumbnails, ui, baseUrl, thumbsBaseUrl) {
|
|
779
838
|
ui.start(`Building gallery ${galleryDir}`);
|
|
780
|
-
const galleryJsonPath =
|
|
839
|
+
const galleryJsonPath = path__default.default.join(galleryDir, "gallery", "gallery.json");
|
|
781
840
|
let galleryData = parseGalleryJson(galleryJsonPath, ui);
|
|
782
841
|
if (scan) {
|
|
783
842
|
galleryData = await scanAndAppendNewFiles(galleryDir, galleryJsonPath, galleryData, ui);
|
|
784
843
|
}
|
|
785
|
-
const socialMediaCardImagePath =
|
|
844
|
+
const socialMediaCardImagePath = path__default.default.join(galleryDir, "gallery", "images", "social-media-card.jpg");
|
|
786
845
|
const mediaBasePath = galleryData.mediaBasePath;
|
|
787
846
|
const mediaBaseUrl = baseUrl || galleryData.mediaBaseUrl;
|
|
788
|
-
const headerImagePath = mediaBasePath ?
|
|
789
|
-
const imagesFolder =
|
|
790
|
-
const currentHeaderBasename =
|
|
847
|
+
const headerImagePath = mediaBasePath ? path__default.default.join(mediaBasePath, galleryData.headerImage) : path__default.default.resolve(galleryDir, galleryData.headerImage);
|
|
848
|
+
const imagesFolder = path__default.default.join(galleryDir, "gallery", "images");
|
|
849
|
+
const currentHeaderBasename = path__default.default.basename(headerImagePath, path__default.default.extname(headerImagePath));
|
|
791
850
|
if (shouldCreateThumbnails) {
|
|
792
851
|
if (!fs8__default.default.existsSync(imagesFolder)) {
|
|
793
852
|
fs8__default.default.mkdirSync(imagesFolder, { recursive: true });
|
|
@@ -830,7 +889,7 @@ async function buildGallery(galleryDir, templateDir, scan, shouldCreateThumbnail
|
|
|
830
889
|
}
|
|
831
890
|
if (!galleryData.metadata.image) {
|
|
832
891
|
ui.debug("Updating gallery.json with social media card URL");
|
|
833
|
-
galleryData.metadata.image = thumbsBaseUrl ? `${thumbsBaseUrl}/${
|
|
892
|
+
galleryData.metadata.image = thumbsBaseUrl ? `${thumbsBaseUrl}/${path__default.default.basename(socialMediaCardImagePath)}` : `${galleryData.url || ""}/${path__default.default.relative(galleryDir, socialMediaCardImagePath)}`;
|
|
834
893
|
fs8__default.default.writeFileSync(galleryJsonPath, JSON.stringify(galleryData, null, 2));
|
|
835
894
|
}
|
|
836
895
|
if (shouldCreateThumbnails) {
|
|
@@ -838,20 +897,20 @@ async function buildGallery(galleryDir, templateDir, scan, shouldCreateThumbnail
|
|
|
838
897
|
}
|
|
839
898
|
ui.debug("Building gallery from template");
|
|
840
899
|
try {
|
|
841
|
-
|
|
842
|
-
|
|
900
|
+
process4__default.default.env.GALLERY_JSON_PATH = galleryJsonPath;
|
|
901
|
+
process4__default.default.env.GALLERY_OUTPUT_DIR = path__default.default.join(galleryDir, "gallery");
|
|
843
902
|
child_process.execSync("npx astro build", { cwd: templateDir, stdio: ui.level === consola.LogLevels.debug ? "inherit" : "ignore" });
|
|
844
903
|
} catch (error) {
|
|
845
904
|
ui.error(`Build failed for ${galleryDir}`);
|
|
846
905
|
throw error;
|
|
847
906
|
}
|
|
848
|
-
const outputDir =
|
|
849
|
-
const buildDir =
|
|
907
|
+
const outputDir = path__default.default.join(galleryDir, "gallery");
|
|
908
|
+
const buildDir = path__default.default.join(outputDir, "_build");
|
|
850
909
|
ui.debug(`Copying build output to ${outputDir}`);
|
|
851
910
|
fs8__default.default.cpSync(buildDir, outputDir, { recursive: true });
|
|
852
911
|
ui.debug("Moving index.html to gallery directory");
|
|
853
|
-
fs8__default.default.copyFileSync(
|
|
854
|
-
fs8__default.default.rmSync(
|
|
912
|
+
fs8__default.default.copyFileSync(path__default.default.join(outputDir, "index.html"), path__default.default.join(galleryDir, "index.html"));
|
|
913
|
+
fs8__default.default.rmSync(path__default.default.join(outputDir, "index.html"));
|
|
855
914
|
ui.debug("Cleaning up build directory");
|
|
856
915
|
fs8__default.default.rmSync(buildDir, { recursive: true, force: true });
|
|
857
916
|
ui.success(`Gallery built successfully`);
|
|
@@ -864,12 +923,12 @@ async function build(options, ui) {
|
|
|
864
923
|
return { processedGalleryCount: 0 };
|
|
865
924
|
}
|
|
866
925
|
const themePath = await undefined("@simple-photo-gallery/theme-modern/package.json");
|
|
867
|
-
const themeDir =
|
|
926
|
+
const themeDir = path__default.default.dirname(new URL(themePath).pathname);
|
|
868
927
|
let totalGalleries = 0;
|
|
869
928
|
for (const dir of galleryDirs) {
|
|
870
|
-
const baseUrl = options.baseUrl ? `${options.baseUrl}${
|
|
871
|
-
const thumbsBaseUrl = options.thumbsBaseUrl ? `${options.thumbsBaseUrl}${
|
|
872
|
-
await buildGallery(
|
|
929
|
+
const baseUrl = options.baseUrl ? `${options.baseUrl}${path__default.default.relative(options.gallery, dir)}` : void 0;
|
|
930
|
+
const thumbsBaseUrl = options.thumbsBaseUrl ? `${options.thumbsBaseUrl}${path__default.default.relative(options.gallery, dir)}` : void 0;
|
|
931
|
+
await buildGallery(path__default.default.resolve(dir), themeDir, options.scan, options.thumbnails, ui, baseUrl, thumbsBaseUrl);
|
|
873
932
|
++totalGalleries;
|
|
874
933
|
}
|
|
875
934
|
ui.box(`Built ${totalGalleries} ${totalGalleries === 1 ? "gallery" : "galleries"} successfully`);
|
|
@@ -885,7 +944,7 @@ async function build(options, ui) {
|
|
|
885
944
|
}
|
|
886
945
|
async function cleanGallery(galleryDir, ui) {
|
|
887
946
|
let filesRemoved = 0;
|
|
888
|
-
const indexHtmlPath =
|
|
947
|
+
const indexHtmlPath = path__default.default.join(galleryDir, "index.html");
|
|
889
948
|
if (fs8__default.default.existsSync(indexHtmlPath)) {
|
|
890
949
|
try {
|
|
891
950
|
fs8__default.default.rmSync(indexHtmlPath);
|
|
@@ -895,7 +954,7 @@ async function cleanGallery(galleryDir, ui) {
|
|
|
895
954
|
ui?.warn(`Failed to remove index.html: ${error}`);
|
|
896
955
|
}
|
|
897
956
|
}
|
|
898
|
-
const galleryPath =
|
|
957
|
+
const galleryPath = path__default.default.join(galleryDir, "gallery");
|
|
899
958
|
if (fs8__default.default.existsSync(galleryPath)) {
|
|
900
959
|
try {
|
|
901
960
|
fs8__default.default.rmSync(galleryPath, { recursive: true, force: true });
|
|
@@ -914,7 +973,7 @@ async function cleanGallery(galleryDir, ui) {
|
|
|
914
973
|
}
|
|
915
974
|
async function clean(options, ui) {
|
|
916
975
|
try {
|
|
917
|
-
const basePath =
|
|
976
|
+
const basePath = path__default.default.resolve(options.gallery);
|
|
918
977
|
if (!fs8__default.default.existsSync(basePath)) {
|
|
919
978
|
ui.error(`Directory does not exist: ${basePath}`);
|
|
920
979
|
return { processedGalleryCount: 0 };
|
|
@@ -963,7 +1022,7 @@ var ApiTelemetryClient = class {
|
|
|
963
1022
|
axios__default.default.post(this.endpoint, event, {
|
|
964
1023
|
headers: {
|
|
965
1024
|
"content-type": "application/json",
|
|
966
|
-
"user-agent": `simple-photo-gallery/${event.packageVersion} (${
|
|
1025
|
+
"user-agent": `simple-photo-gallery/${event.packageVersion} (${process4__default.default.platform}; ${process4__default.default.arch})`
|
|
967
1026
|
}
|
|
968
1027
|
});
|
|
969
1028
|
} catch {
|
|
@@ -973,7 +1032,7 @@ var ApiTelemetryClient = class {
|
|
|
973
1032
|
var ConsoleTelemetryClient = class {
|
|
974
1033
|
async record(event) {
|
|
975
1034
|
const serialized = JSON.stringify(event, null, 2);
|
|
976
|
-
|
|
1035
|
+
process4.stdout.write(`TELEMETRY EVENT: ${serialized}
|
|
977
1036
|
`);
|
|
978
1037
|
}
|
|
979
1038
|
};
|
|
@@ -1000,11 +1059,11 @@ var TelemetryService = class {
|
|
|
1000
1059
|
if (override) {
|
|
1001
1060
|
return override === "1";
|
|
1002
1061
|
}
|
|
1003
|
-
if (
|
|
1062
|
+
if (process4__default.default.env.CI || process4__default.default.env.DO_NOT_TRACK) {
|
|
1004
1063
|
return false;
|
|
1005
1064
|
}
|
|
1006
|
-
if (
|
|
1007
|
-
return
|
|
1065
|
+
if (process4__default.default.env.SPG_TELEMETRY) {
|
|
1066
|
+
return process4__default.default.env.SPG_TELEMETRY === "1";
|
|
1008
1067
|
}
|
|
1009
1068
|
const stored = this.getStoredPreference();
|
|
1010
1069
|
if (stored === void 0) {
|
|
@@ -1046,7 +1105,7 @@ var TelemetryService = class {
|
|
|
1046
1105
|
durationMs: now - startedAt,
|
|
1047
1106
|
packageName: this.packageName,
|
|
1048
1107
|
packageVersion: this.packageVersion,
|
|
1049
|
-
nodeVersion:
|
|
1108
|
+
nodeVersion: process4__default.default.version,
|
|
1050
1109
|
osPlatform: os__default.default.platform(),
|
|
1051
1110
|
osRelease: os__default.default.release(),
|
|
1052
1111
|
osArch: os__default.default.arch(),
|
|
@@ -1080,7 +1139,7 @@ var TelemetryService = class {
|
|
|
1080
1139
|
/** Returns the telemetry client. */
|
|
1081
1140
|
getClient() {
|
|
1082
1141
|
if (!this.client) {
|
|
1083
|
-
switch (
|
|
1142
|
+
switch (process4__default.default.env.SPG_TELEMETRY_PROVIDER) {
|
|
1084
1143
|
case "none": {
|
|
1085
1144
|
this.client = void 0;
|
|
1086
1145
|
break;
|
|
@@ -1172,7 +1231,7 @@ async function waitForUpdateCheck(checkPromise) {
|
|
|
1172
1231
|
// package.json
|
|
1173
1232
|
var package_default = {
|
|
1174
1233
|
name: "simple-photo-gallery",
|
|
1175
|
-
version: "2.0.
|
|
1234
|
+
version: "2.0.12"};
|
|
1176
1235
|
|
|
1177
1236
|
// src/index.ts
|
|
1178
1237
|
var program = new commander.Command();
|
|
@@ -1214,7 +1273,7 @@ function withCommandContext(handler) {
|
|
|
1214
1273
|
} catch (error) {
|
|
1215
1274
|
ui.debug(error);
|
|
1216
1275
|
errorInfo = error instanceof Error ? { name: error.name, message: error.message } : { name: "UnknownError", message: String(error) };
|
|
1217
|
-
|
|
1276
|
+
process4__default.default.exitCode = 1;
|
|
1218
1277
|
}
|
|
1219
1278
|
const updateInfo = await waitForUpdateCheck(updateCheckPromise);
|
|
1220
1279
|
if (updateInfo) {
|
|
@@ -1236,14 +1295,14 @@ function withCommandContext(handler) {
|
|
|
1236
1295
|
program.command("init").description("Initialize a gallery by scaning a folder for images and videos").option(
|
|
1237
1296
|
"-p, --photos <path>",
|
|
1238
1297
|
"Path to the folder where the photos are stored. Default: current working directory",
|
|
1239
|
-
|
|
1298
|
+
process4__default.default.cwd()
|
|
1240
1299
|
).option(
|
|
1241
1300
|
"-g, --gallery <path>",
|
|
1242
1301
|
"Path to the directory where the gallery will be initialized. Default: same directory as the photos folder"
|
|
1243
|
-
).option("-r, --recursive", "Recursively create galleries from all photos subdirectories", false).option("-d, --default", "Use default gallery settings instead of asking the user", false).option("-f, --force", "Force override existing galleries without asking", false).action(withCommandContext((options, ui) => init(options, ui)));
|
|
1244
|
-
program.command("thumbnails").description("Create thumbnails for all media files in the gallery").option("-g, --gallery <path>", "Path to the directory of the gallery. Default: current working directory",
|
|
1245
|
-
program.command("build").description("Build the HTML gallery in the specified directory").option("-g, --gallery <path>", "Path to the directory of the gallery. Default: current working directory",
|
|
1246
|
-
program.command("clean").description("Remove all gallery files and folders (index.html, gallery/)").option("-g, --gallery <path>", "Path to the directory of the gallery. Default: current working directory",
|
|
1302
|
+
).option("-r, --recursive", "Recursively create galleries from all photos subdirectories", false).option("-d, --default", "Use default gallery settings instead of asking the user", false).option("-f, --force", "Force override existing galleries without asking", false).option("--cta-banner", "Add a Simple Photo Gallery call-to-action banner to the end of the gallery", false).action(withCommandContext((options, ui) => init(options, ui)));
|
|
1303
|
+
program.command("thumbnails").description("Create thumbnails for all media files in the gallery").option("-g, --gallery <path>", "Path to the directory of the gallery. Default: current working directory", process4__default.default.cwd()).option("-r, --recursive", "Scan subdirectories recursively", false).action(withCommandContext((options, ui) => thumbnails(options, ui)));
|
|
1304
|
+
program.command("build").description("Build the HTML gallery in the specified directory").option("-g, --gallery <path>", "Path to the directory of the gallery. Default: current working directory", process4__default.default.cwd()).option("-r, --recursive", "Scan subdirectories recursively", false).option("-b, --base-url <url>", "Base URL where the photos are hosted").option("-t, --thumbs-base-url <url>", "Base URL where the thumbnails are hosted").option("--no-thumbnails", "Skip creating thumbnails when building the gallery", true).option("--no-scan", "Do not scan for new photos when building the gallery", true).action(withCommandContext((options, ui) => build(options, ui)));
|
|
1305
|
+
program.command("clean").description("Remove all gallery files and folders (index.html, gallery/)").option("-g, --gallery <path>", "Path to the directory of the gallery. Default: current working directory", process4__default.default.cwd()).option("-r, --recursive", "Clean subdirectories recursively", false).action(withCommandContext((options, ui) => clean(options, ui)));
|
|
1247
1306
|
program.command("telemetry").description("Manage anonymous telemetry preferences. Use 1 to enable, 0 to disable, or no argument to check status").option("-s, --state <state>", "Enable (1) or disable (0) telemetry", parseTelemetryOption).action(withCommandContext((options, ui) => telemetry(options, ui, telemetryService)));
|
|
1248
1307
|
program.parse();
|
|
1249
1308
|
//# sourceMappingURL=index.cjs.map
|