simple-photo-gallery 2.0.13 → 2.0.15-rc.18
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/dist/index.cjs +83 -129
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +80 -125
- package/dist/index.js.map +1 -1
- package/dist/lib/index.cjs +1 -49
- package/dist/lib/index.cjs.map +1 -1
- package/dist/lib/index.js +1 -47
- package/dist/lib/index.js.map +1 -1
- package/package.json +4 -5
- package/assets/fonts/dejavu/DejaVuSans-Bold.ttf +0 -0
- package/assets/fonts/dejavu/LICENSE.txt +0 -78
package/dist/index.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
2
|
+
import process3, { stdout } from 'process';
|
|
3
3
|
import { Command } from 'commander';
|
|
4
4
|
import { LogLevels, createConsola } from 'consola';
|
|
5
5
|
import { execSync, spawn } from 'child_process';
|
|
6
6
|
import fs8, { promises } from 'fs';
|
|
7
|
-
import
|
|
7
|
+
import path7 from 'path';
|
|
8
8
|
import { Buffer } from 'buffer';
|
|
9
|
-
import { fileURLToPath } from 'url';
|
|
10
9
|
import sharp2 from 'sharp';
|
|
11
10
|
import { encode } from 'blurhash';
|
|
12
11
|
import { GalleryDataSchema, GalleryDataDeprecatedSchema } from '@simple-photo-gallery/common';
|
|
@@ -77,43 +76,9 @@ async function generateBlurHash(imagePath, componentX = 4, componentY = 3) {
|
|
|
77
76
|
}
|
|
78
77
|
|
|
79
78
|
// src/modules/build/utils/index.ts
|
|
80
|
-
var __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
81
|
-
var SOCIAL_CARD_FONT_RELATIVE_PATH = path.join("assets", "fonts", "dejavu", "DejaVuSans-Bold.ttf");
|
|
82
|
-
var socialCardFontBase64;
|
|
83
|
-
function resolveFromCurrentDir(...segments) {
|
|
84
|
-
return path.resolve(__dirname, ...segments);
|
|
85
|
-
}
|
|
86
|
-
function findSocialCardFontPath() {
|
|
87
|
-
const fontCandidates = [
|
|
88
|
-
resolveFromCurrentDir("../../../../", SOCIAL_CARD_FONT_RELATIVE_PATH),
|
|
89
|
-
path.resolve(__dirname, "../", SOCIAL_CARD_FONT_RELATIVE_PATH),
|
|
90
|
-
path.resolve(__dirname, "../../", SOCIAL_CARD_FONT_RELATIVE_PATH),
|
|
91
|
-
path.resolve(process4.cwd(), SOCIAL_CARD_FONT_RELATIVE_PATH),
|
|
92
|
-
path.resolve(process4.cwd(), "../", SOCIAL_CARD_FONT_RELATIVE_PATH),
|
|
93
|
-
path.resolve(process4.cwd(), "../simple-photo-gallery/", SOCIAL_CARD_FONT_RELATIVE_PATH)
|
|
94
|
-
];
|
|
95
|
-
for (const candidate of fontCandidates) {
|
|
96
|
-
if (fs8.existsSync(candidate)) {
|
|
97
|
-
return candidate;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
return null;
|
|
101
|
-
}
|
|
102
|
-
function getSocialCardFontBase64() {
|
|
103
|
-
if (socialCardFontBase64 !== void 0) {
|
|
104
|
-
return socialCardFontBase64;
|
|
105
|
-
}
|
|
106
|
-
const fontPath = findSocialCardFontPath();
|
|
107
|
-
if (!fontPath) {
|
|
108
|
-
socialCardFontBase64 = null;
|
|
109
|
-
return null;
|
|
110
|
-
}
|
|
111
|
-
socialCardFontBase64 = fs8.readFileSync(fontPath).toString("base64");
|
|
112
|
-
return socialCardFontBase64;
|
|
113
|
-
}
|
|
114
79
|
async function createGallerySocialMediaCardImage(headerPhotoPath, title, ouputPath, ui) {
|
|
115
80
|
ui?.start(`Creating social media card image`);
|
|
116
|
-
const headerBasename =
|
|
81
|
+
const headerBasename = path7.basename(headerPhotoPath, path7.extname(headerPhotoPath));
|
|
117
82
|
if (fs8.existsSync(ouputPath)) {
|
|
118
83
|
ui?.success(`Social media card image already exists`);
|
|
119
84
|
return headerBasename;
|
|
@@ -122,21 +87,11 @@ async function createGallerySocialMediaCardImage(headerPhotoPath, title, ouputPa
|
|
|
122
87
|
const resizedImageBuffer = await image.resize(1200, 631, { fit: "cover" }).jpeg({ quality: 90 }).toBuffer();
|
|
123
88
|
const outputPath = ouputPath;
|
|
124
89
|
await sharp2(resizedImageBuffer).toFile(outputPath);
|
|
125
|
-
const fontBase64 = getSocialCardFontBase64();
|
|
126
|
-
const fontFace = fontBase64 ? `
|
|
127
|
-
@font-face {
|
|
128
|
-
font-family: 'DejaVu Sans';
|
|
129
|
-
src: url('data:font/ttf;base64,${fontBase64}') format('truetype');
|
|
130
|
-
font-weight: 700;
|
|
131
|
-
font-style: normal;
|
|
132
|
-
}` : "";
|
|
133
|
-
const fontFamily = fontBase64 ? "'DejaVu Sans', Arial, sans-serif" : "Arial, sans-serif";
|
|
134
90
|
const svgText = `
|
|
135
91
|
<svg width="1200" height="631" xmlns="http://www.w3.org/2000/svg">
|
|
136
92
|
<defs>
|
|
137
93
|
<style>
|
|
138
|
-
|
|
139
|
-
.title { font-family: ${fontFamily}; font-size: 96px; font-weight: bold; fill: white; stroke: black; stroke-width: 5; paint-order: stroke; text-anchor: middle; }
|
|
94
|
+
.title { font-family: 'Arial, sans-serif'; font-size: 96px; font-weight: bold; fill: white; stroke: black; stroke-width: 5; paint-order: stroke; text-anchor: middle; }
|
|
140
95
|
</style>
|
|
141
96
|
</defs>
|
|
142
97
|
<text x="600" y="250" class="title">${title}</text>
|
|
@@ -150,7 +105,7 @@ async function createGallerySocialMediaCardImage(headerPhotoPath, title, ouputPa
|
|
|
150
105
|
async function createOptimizedHeaderImage(headerPhotoPath, outputFolder, ui) {
|
|
151
106
|
ui?.start(`Creating optimized header images`);
|
|
152
107
|
const image = await loadImage(headerPhotoPath);
|
|
153
|
-
const headerBasename =
|
|
108
|
+
const headerBasename = path7.basename(headerPhotoPath, path7.extname(headerPhotoPath));
|
|
154
109
|
const generatedFiles = [];
|
|
155
110
|
ui?.debug("Generating blurhash for header image");
|
|
156
111
|
const blurHash = await generateBlurHash(headerPhotoPath);
|
|
@@ -159,22 +114,22 @@ async function createOptimizedHeaderImage(headerPhotoPath, outputFolder, ui) {
|
|
|
159
114
|
ui?.debug(`Creating landscape header image ${width}`);
|
|
160
115
|
const avifFilename = `${headerBasename}_landscape_${width}.avif`;
|
|
161
116
|
const jpgFilename = `${headerBasename}_landscape_${width}.jpg`;
|
|
162
|
-
if (fs8.existsSync(
|
|
117
|
+
if (fs8.existsSync(path7.join(outputFolder, avifFilename))) {
|
|
163
118
|
ui?.debug(`Landscape header image ${width} AVIF already exists`);
|
|
164
119
|
} else {
|
|
165
120
|
await cropAndResizeImage(
|
|
166
121
|
image.clone(),
|
|
167
|
-
|
|
122
|
+
path7.join(outputFolder, avifFilename),
|
|
168
123
|
width,
|
|
169
124
|
width * landscapeYFactor,
|
|
170
125
|
"avif"
|
|
171
126
|
);
|
|
172
127
|
}
|
|
173
128
|
generatedFiles.push(avifFilename);
|
|
174
|
-
if (fs8.existsSync(
|
|
129
|
+
if (fs8.existsSync(path7.join(outputFolder, jpgFilename))) {
|
|
175
130
|
ui?.debug(`Landscape header image ${width} JPG already exists`);
|
|
176
131
|
} else {
|
|
177
|
-
await cropAndResizeImage(image.clone(),
|
|
132
|
+
await cropAndResizeImage(image.clone(), path7.join(outputFolder, jpgFilename), width, width * landscapeYFactor, "jpg");
|
|
178
133
|
}
|
|
179
134
|
generatedFiles.push(jpgFilename);
|
|
180
135
|
}
|
|
@@ -183,16 +138,16 @@ async function createOptimizedHeaderImage(headerPhotoPath, outputFolder, ui) {
|
|
|
183
138
|
ui?.debug(`Creating portrait header image ${width}`);
|
|
184
139
|
const avifFilename = `${headerBasename}_portrait_${width}.avif`;
|
|
185
140
|
const jpgFilename = `${headerBasename}_portrait_${width}.jpg`;
|
|
186
|
-
if (fs8.existsSync(
|
|
141
|
+
if (fs8.existsSync(path7.join(outputFolder, avifFilename))) {
|
|
187
142
|
ui?.debug(`Portrait header image ${width} AVIF already exists`);
|
|
188
143
|
} else {
|
|
189
|
-
await cropAndResizeImage(image.clone(),
|
|
144
|
+
await cropAndResizeImage(image.clone(), path7.join(outputFolder, avifFilename), width, width * portraitYFactor, "avif");
|
|
190
145
|
}
|
|
191
146
|
generatedFiles.push(avifFilename);
|
|
192
|
-
if (fs8.existsSync(
|
|
147
|
+
if (fs8.existsSync(path7.join(outputFolder, jpgFilename))) {
|
|
193
148
|
ui?.debug(`Portrait header image ${width} JPG already exists`);
|
|
194
149
|
} else {
|
|
195
|
-
await cropAndResizeImage(image.clone(),
|
|
150
|
+
await cropAndResizeImage(image.clone(), path7.join(outputFolder, jpgFilename), width, width * portraitYFactor, "jpg");
|
|
196
151
|
}
|
|
197
152
|
generatedFiles.push(jpgFilename);
|
|
198
153
|
}
|
|
@@ -225,12 +180,12 @@ function cleanupOldHeaderImages(outputFolder, currentHeaderBasename, ui) {
|
|
|
225
180
|
const landscapeMatch = file.match(/^(.+)_landscape_\d+\.(avif|jpg)$/);
|
|
226
181
|
const portraitMatch = file.match(/^(.+)_portrait_\d+\.(avif|jpg)$/);
|
|
227
182
|
if (landscapeMatch && landscapeMatch[1] !== currentHeaderBasename) {
|
|
228
|
-
const filePath =
|
|
183
|
+
const filePath = path7.join(outputFolder, file);
|
|
229
184
|
ui?.debug(`Deleting old landscape header image: ${file}`);
|
|
230
185
|
fs8.unlinkSync(filePath);
|
|
231
186
|
deletedCount++;
|
|
232
187
|
} else if (portraitMatch && portraitMatch[1] !== currentHeaderBasename) {
|
|
233
|
-
const filePath =
|
|
188
|
+
const filePath = path7.join(outputFolder, file);
|
|
234
189
|
ui?.debug(`Deleting old portrait header image: ${file}`);
|
|
235
190
|
fs8.unlinkSync(filePath);
|
|
236
191
|
deletedCount++;
|
|
@@ -244,7 +199,7 @@ function cleanupOldHeaderImages(outputFolder, currentHeaderBasename, ui) {
|
|
|
244
199
|
}
|
|
245
200
|
function findGalleries(basePath, recursive) {
|
|
246
201
|
const galleryDirs = [];
|
|
247
|
-
const galleryJsonPath =
|
|
202
|
+
const galleryJsonPath = path7.join(basePath, "gallery", "gallery.json");
|
|
248
203
|
if (fs8.existsSync(galleryJsonPath)) {
|
|
249
204
|
galleryDirs.push(basePath);
|
|
250
205
|
}
|
|
@@ -253,7 +208,7 @@ function findGalleries(basePath, recursive) {
|
|
|
253
208
|
const entries = fs8.readdirSync(basePath, { withFileTypes: true });
|
|
254
209
|
for (const entry of entries) {
|
|
255
210
|
if (entry.isDirectory() && entry.name !== "gallery") {
|
|
256
|
-
const subPath =
|
|
211
|
+
const subPath = path7.join(basePath, entry.name);
|
|
257
212
|
const subResults = findGalleries(subPath, recursive);
|
|
258
213
|
galleryDirs.push(...subResults);
|
|
259
214
|
}
|
|
@@ -312,20 +267,20 @@ function migrateGalleryJson(deprecatedGalleryData, galleryJsonPath, ui) {
|
|
|
312
267
|
ui.start("Old gallery.json format detected. Migrating gallery.json to the new data format.");
|
|
313
268
|
let mediaBasePath;
|
|
314
269
|
const imagePath = deprecatedGalleryData.sections[0].images[0].path;
|
|
315
|
-
if (imagePath && imagePath !==
|
|
316
|
-
mediaBasePath =
|
|
270
|
+
if (imagePath && imagePath !== path7.join("..", path7.basename(imagePath))) {
|
|
271
|
+
mediaBasePath = path7.resolve(path7.join(path7.dirname(galleryJsonPath)), path7.dirname(imagePath));
|
|
317
272
|
}
|
|
318
273
|
const sections = deprecatedGalleryData.sections.map((section) => ({
|
|
319
274
|
...section,
|
|
320
275
|
images: section.images.map((image) => ({
|
|
321
276
|
...image,
|
|
322
277
|
path: void 0,
|
|
323
|
-
filename:
|
|
278
|
+
filename: path7.basename(image.path)
|
|
324
279
|
}))
|
|
325
280
|
}));
|
|
326
281
|
const galleryData = {
|
|
327
282
|
...deprecatedGalleryData,
|
|
328
|
-
headerImage:
|
|
283
|
+
headerImage: path7.basename(deprecatedGalleryData.headerImage),
|
|
329
284
|
sections,
|
|
330
285
|
mediaBasePath
|
|
331
286
|
};
|
|
@@ -337,7 +292,7 @@ function migrateGalleryJson(deprecatedGalleryData, galleryJsonPath, ui) {
|
|
|
337
292
|
return galleryData;
|
|
338
293
|
}
|
|
339
294
|
function getMediaFileType(fileName) {
|
|
340
|
-
const ext =
|
|
295
|
+
const ext = path7.extname(fileName).toLowerCase();
|
|
341
296
|
if (IMAGE_EXTENSIONS.has(ext)) return "image";
|
|
342
297
|
if (VIDEO_EXTENSIONS.has(ext)) return "video";
|
|
343
298
|
return null;
|
|
@@ -365,7 +320,7 @@ async function scanDirectory(dirPath, ui) {
|
|
|
365
320
|
mediaFiles.push(mediaFile);
|
|
366
321
|
}
|
|
367
322
|
} else if (entry.isDirectory() && entry.name !== "gallery") {
|
|
368
|
-
subGalleryDirectories.push(
|
|
323
|
+
subGalleryDirectories.push(path7.join(dirPath, entry.name));
|
|
369
324
|
}
|
|
370
325
|
}
|
|
371
326
|
} catch (error) {
|
|
@@ -401,12 +356,12 @@ async function getGallerySettingsFromUser(galleryName, defaultImage, ui) {
|
|
|
401
356
|
return { title, description, url, headerImage };
|
|
402
357
|
}
|
|
403
358
|
async function createGalleryJson(mediaFiles, galleryJsonPath, scanPath, subGalleries = [], useDefaultSettings, ctaBanner, ui) {
|
|
404
|
-
const galleryDir =
|
|
405
|
-
const isSameLocation =
|
|
359
|
+
const galleryDir = path7.dirname(galleryJsonPath);
|
|
360
|
+
const isSameLocation = path7.relative(scanPath, path7.join(galleryDir, "..")) === "";
|
|
406
361
|
const mediaBasePath = isSameLocation ? void 0 : scanPath;
|
|
407
362
|
const relativeSubGalleries = subGalleries.map((subGallery) => ({
|
|
408
363
|
...subGallery,
|
|
409
|
-
headerImage: subGallery.headerImage ?
|
|
364
|
+
headerImage: subGallery.headerImage ? path7.relative(galleryDir, subGallery.headerImage) : ""
|
|
410
365
|
}));
|
|
411
366
|
let galleryData = {
|
|
412
367
|
title: "My Gallery",
|
|
@@ -429,8 +384,8 @@ async function createGalleryJson(mediaFiles, galleryJsonPath, scanPath, subGalle
|
|
|
429
384
|
galleryData = {
|
|
430
385
|
...galleryData,
|
|
431
386
|
...await getGallerySettingsFromUser(
|
|
432
|
-
|
|
433
|
-
|
|
387
|
+
path7.basename(path7.join(galleryDir, "..")),
|
|
388
|
+
path7.basename(mediaFiles[0]?.filename || ""),
|
|
434
389
|
ui
|
|
435
390
|
)
|
|
436
391
|
};
|
|
@@ -438,8 +393,8 @@ async function createGalleryJson(mediaFiles, galleryJsonPath, scanPath, subGalle
|
|
|
438
393
|
await promises.writeFile(galleryJsonPath, JSON.stringify(galleryData, null, 2));
|
|
439
394
|
}
|
|
440
395
|
async function galleryExists(outputPath) {
|
|
441
|
-
const galleryPath =
|
|
442
|
-
const galleryJsonPath =
|
|
396
|
+
const galleryPath = path7.join(outputPath, "gallery");
|
|
397
|
+
const galleryJsonPath = path7.join(galleryPath, "gallery.json");
|
|
443
398
|
try {
|
|
444
399
|
await promises.access(galleryJsonPath);
|
|
445
400
|
return true;
|
|
@@ -458,7 +413,7 @@ async function processDirectory(scanPath, outputPath, recursive, useDefaultSetti
|
|
|
458
413
|
for (const subGalleryDir of subGalleryDirectories) {
|
|
459
414
|
const result2 = await processDirectory(
|
|
460
415
|
subGalleryDir,
|
|
461
|
-
|
|
416
|
+
path7.join(outputPath, path7.basename(subGalleryDir)),
|
|
462
417
|
recursive,
|
|
463
418
|
useDefaultSettings,
|
|
464
419
|
force,
|
|
@@ -473,8 +428,8 @@ async function processDirectory(scanPath, outputPath, recursive, useDefaultSetti
|
|
|
473
428
|
}
|
|
474
429
|
}
|
|
475
430
|
if (mediaFiles.length > 0 || subGalleries.length > 0) {
|
|
476
|
-
const galleryPath =
|
|
477
|
-
const galleryJsonPath =
|
|
431
|
+
const galleryPath = path7.join(outputPath, "gallery");
|
|
432
|
+
const galleryJsonPath = path7.join(galleryPath, "gallery.json");
|
|
478
433
|
const exists = await galleryExists(outputPath);
|
|
479
434
|
if (exists && !force) {
|
|
480
435
|
const shouldOverride = await ui.prompt(`Gallery already exists at ${galleryJsonPath}. Do you want to override it?`, {
|
|
@@ -499,19 +454,19 @@ async function processDirectory(scanPath, outputPath, recursive, useDefaultSetti
|
|
|
499
454
|
}
|
|
500
455
|
const result = { totalFiles, totalGalleries };
|
|
501
456
|
if (mediaFiles.length > 0 || subGalleries.length > 0) {
|
|
502
|
-
const dirName =
|
|
457
|
+
const dirName = path7.basename(scanPath);
|
|
503
458
|
result.subGallery = {
|
|
504
459
|
title: capitalizeTitle(dirName),
|
|
505
460
|
headerImage: mediaFiles[0]?.filename || "",
|
|
506
|
-
path:
|
|
461
|
+
path: path7.join("..", dirName)
|
|
507
462
|
};
|
|
508
463
|
}
|
|
509
464
|
return result;
|
|
510
465
|
}
|
|
511
466
|
async function init(options, ui) {
|
|
512
467
|
try {
|
|
513
|
-
const scanPath =
|
|
514
|
-
const outputPath = options.gallery ?
|
|
468
|
+
const scanPath = path7.resolve(options.photos);
|
|
469
|
+
const outputPath = options.gallery ? path7.resolve(options.gallery) : scanPath;
|
|
515
470
|
const result = await processDirectory(
|
|
516
471
|
scanPath,
|
|
517
472
|
outputPath,
|
|
@@ -635,7 +590,7 @@ async function processImage(imagePath, thumbnailPath, thumbnailPathRetina, thumb
|
|
|
635
590
|
const blurHash = await generateBlurHash(thumbnailPath);
|
|
636
591
|
return {
|
|
637
592
|
type: "image",
|
|
638
|
-
filename:
|
|
593
|
+
filename: path7.basename(imagePath),
|
|
639
594
|
alt: description,
|
|
640
595
|
width: imageDimensions.width,
|
|
641
596
|
height: imageDimensions.height,
|
|
@@ -666,7 +621,7 @@ async function processVideo(videoPath, thumbnailPath, thumbnailPathRetina, thumb
|
|
|
666
621
|
const blurHash = await generateBlurHash(thumbnailPath);
|
|
667
622
|
return {
|
|
668
623
|
type: "video",
|
|
669
|
-
filename:
|
|
624
|
+
filename: path7.basename(videoPath),
|
|
670
625
|
alt: void 0,
|
|
671
626
|
width: videoDimensions.width,
|
|
672
627
|
height: videoDimensions.height,
|
|
@@ -682,11 +637,11 @@ async function processVideo(videoPath, thumbnailPath, thumbnailPathRetina, thumb
|
|
|
682
637
|
}
|
|
683
638
|
async function processMediaFile(mediaFile, mediaBasePath, thumbnailsPath, thumbnailSize, ui) {
|
|
684
639
|
try {
|
|
685
|
-
const filePath =
|
|
640
|
+
const filePath = path7.resolve(path7.join(mediaBasePath, mediaFile.filename));
|
|
686
641
|
const fileName = mediaFile.filename;
|
|
687
|
-
const fileNameWithoutExt =
|
|
642
|
+
const fileNameWithoutExt = path7.parse(fileName).name;
|
|
688
643
|
const thumbnailFileName = `${fileNameWithoutExt}.avif`;
|
|
689
|
-
const thumbnailPath =
|
|
644
|
+
const thumbnailPath = path7.join(thumbnailsPath, thumbnailFileName);
|
|
690
645
|
const thumbnailPathRetina = thumbnailPath.replace(".avif", "@2x.avif");
|
|
691
646
|
const lastMediaTimestamp = mediaFile.lastMediaTimestamp ? new Date(mediaFile.lastMediaTimestamp) : void 0;
|
|
692
647
|
const verbose = ui.level === LogLevels.debug;
|
|
@@ -712,8 +667,8 @@ async function processMediaFile(mediaFile, mediaBasePath, thumbnailsPath, thumbn
|
|
|
712
667
|
}
|
|
713
668
|
updatedMediaFile.filename = mediaFile.filename;
|
|
714
669
|
if (updatedMediaFile.thumbnail) {
|
|
715
|
-
updatedMediaFile.thumbnail.path =
|
|
716
|
-
updatedMediaFile.thumbnail.pathRetina =
|
|
670
|
+
updatedMediaFile.thumbnail.path = path7.basename(thumbnailPath);
|
|
671
|
+
updatedMediaFile.thumbnail.pathRetina = path7.basename(thumbnailPathRetina);
|
|
717
672
|
if (mediaFile.thumbnail?.baseUrl) {
|
|
718
673
|
updatedMediaFile.thumbnail.baseUrl = mediaFile.thumbnail.baseUrl;
|
|
719
674
|
}
|
|
@@ -728,14 +683,14 @@ async function processMediaFile(mediaFile, mediaBasePath, thumbnailsPath, thumbn
|
|
|
728
683
|
}
|
|
729
684
|
}
|
|
730
685
|
async function processGalleryThumbnails(galleryDir, ui) {
|
|
731
|
-
const galleryJsonPath =
|
|
732
|
-
const thumbnailsPath =
|
|
686
|
+
const galleryJsonPath = path7.join(galleryDir, "gallery", "gallery.json");
|
|
687
|
+
const thumbnailsPath = path7.join(galleryDir, "gallery", "images");
|
|
733
688
|
ui.start(`Creating thumbnails: ${galleryDir}`);
|
|
734
689
|
try {
|
|
735
690
|
fs8.mkdirSync(thumbnailsPath, { recursive: true });
|
|
736
691
|
const galleryData = parseGalleryJson(galleryJsonPath, ui);
|
|
737
692
|
const thumbnailSize = galleryData.thumbnailSize || DEFAULT_THUMBNAIL_SIZE;
|
|
738
|
-
const mediaBasePath = galleryData.mediaBasePath ??
|
|
693
|
+
const mediaBasePath = galleryData.mediaBasePath ?? path7.join(galleryDir);
|
|
739
694
|
let processedCount = 0;
|
|
740
695
|
for (const section of galleryData.sections) {
|
|
741
696
|
for (const [index, mediaFile] of section.images.entries()) {
|
|
@@ -782,8 +737,8 @@ function copyPhotos(galleryData, galleryDir, ui) {
|
|
|
782
737
|
for (const section of galleryData.sections) {
|
|
783
738
|
for (const image of section.images) {
|
|
784
739
|
if (galleryData.mediaBasePath) {
|
|
785
|
-
const sourcePath =
|
|
786
|
-
const destPath =
|
|
740
|
+
const sourcePath = path7.join(galleryData.mediaBasePath, image.filename);
|
|
741
|
+
const destPath = path7.join(galleryDir, image.filename);
|
|
787
742
|
ui.debug(`Copying photo to ${destPath}`);
|
|
788
743
|
fs8.copyFileSync(sourcePath, destPath);
|
|
789
744
|
}
|
|
@@ -822,17 +777,17 @@ async function scanAndAppendNewFiles(galleryDir, galleryJsonPath, galleryData, u
|
|
|
822
777
|
}
|
|
823
778
|
async function buildGallery(galleryDir, templateDir, scan, shouldCreateThumbnails, ui, baseUrl, thumbsBaseUrl) {
|
|
824
779
|
ui.start(`Building gallery ${galleryDir}`);
|
|
825
|
-
const galleryJsonPath =
|
|
780
|
+
const galleryJsonPath = path7.join(galleryDir, "gallery", "gallery.json");
|
|
826
781
|
let galleryData = parseGalleryJson(galleryJsonPath, ui);
|
|
827
782
|
if (scan) {
|
|
828
783
|
galleryData = await scanAndAppendNewFiles(galleryDir, galleryJsonPath, galleryData, ui);
|
|
829
784
|
}
|
|
830
|
-
const socialMediaCardImagePath =
|
|
785
|
+
const socialMediaCardImagePath = path7.join(galleryDir, "gallery", "images", "social-media-card.jpg");
|
|
831
786
|
const mediaBasePath = galleryData.mediaBasePath;
|
|
832
787
|
const mediaBaseUrl = baseUrl || galleryData.mediaBaseUrl;
|
|
833
|
-
const headerImagePath = mediaBasePath ?
|
|
834
|
-
const imagesFolder =
|
|
835
|
-
const currentHeaderBasename =
|
|
788
|
+
const headerImagePath = mediaBasePath ? path7.join(mediaBasePath, galleryData.headerImage) : path7.resolve(galleryDir, galleryData.headerImage);
|
|
789
|
+
const imagesFolder = path7.join(galleryDir, "gallery", "images");
|
|
790
|
+
const currentHeaderBasename = path7.basename(headerImagePath, path7.extname(headerImagePath));
|
|
836
791
|
if (shouldCreateThumbnails) {
|
|
837
792
|
if (!fs8.existsSync(imagesFolder)) {
|
|
838
793
|
fs8.mkdirSync(imagesFolder, { recursive: true });
|
|
@@ -875,7 +830,7 @@ async function buildGallery(galleryDir, templateDir, scan, shouldCreateThumbnail
|
|
|
875
830
|
}
|
|
876
831
|
if (!galleryData.metadata.image) {
|
|
877
832
|
ui.debug("Updating gallery.json with social media card URL");
|
|
878
|
-
galleryData.metadata.image = thumbsBaseUrl ? `${thumbsBaseUrl}/${
|
|
833
|
+
galleryData.metadata.image = thumbsBaseUrl ? `${thumbsBaseUrl}/${path7.basename(socialMediaCardImagePath)}` : `${galleryData.url || ""}/${path7.relative(galleryDir, socialMediaCardImagePath)}`;
|
|
879
834
|
fs8.writeFileSync(galleryJsonPath, JSON.stringify(galleryData, null, 2));
|
|
880
835
|
}
|
|
881
836
|
if (shouldCreateThumbnails) {
|
|
@@ -883,20 +838,20 @@ async function buildGallery(galleryDir, templateDir, scan, shouldCreateThumbnail
|
|
|
883
838
|
}
|
|
884
839
|
ui.debug("Building gallery from template");
|
|
885
840
|
try {
|
|
886
|
-
|
|
887
|
-
|
|
841
|
+
process3.env.GALLERY_JSON_PATH = galleryJsonPath;
|
|
842
|
+
process3.env.GALLERY_OUTPUT_DIR = path7.join(galleryDir, "gallery");
|
|
888
843
|
execSync("npx astro build", { cwd: templateDir, stdio: ui.level === LogLevels.debug ? "inherit" : "ignore" });
|
|
889
844
|
} catch (error) {
|
|
890
845
|
ui.error(`Build failed for ${galleryDir}`);
|
|
891
846
|
throw error;
|
|
892
847
|
}
|
|
893
|
-
const outputDir =
|
|
894
|
-
const buildDir =
|
|
848
|
+
const outputDir = path7.join(galleryDir, "gallery");
|
|
849
|
+
const buildDir = path7.join(outputDir, "_build");
|
|
895
850
|
ui.debug(`Copying build output to ${outputDir}`);
|
|
896
851
|
fs8.cpSync(buildDir, outputDir, { recursive: true });
|
|
897
852
|
ui.debug("Moving index.html to gallery directory");
|
|
898
|
-
fs8.copyFileSync(
|
|
899
|
-
fs8.rmSync(
|
|
853
|
+
fs8.copyFileSync(path7.join(outputDir, "index.html"), path7.join(galleryDir, "index.html"));
|
|
854
|
+
fs8.rmSync(path7.join(outputDir, "index.html"));
|
|
900
855
|
ui.debug("Cleaning up build directory");
|
|
901
856
|
fs8.rmSync(buildDir, { recursive: true, force: true });
|
|
902
857
|
ui.success(`Gallery built successfully`);
|
|
@@ -909,12 +864,12 @@ async function build(options, ui) {
|
|
|
909
864
|
return { processedGalleryCount: 0 };
|
|
910
865
|
}
|
|
911
866
|
const themePath = await import.meta.resolve("@simple-photo-gallery/theme-modern/package.json");
|
|
912
|
-
const themeDir =
|
|
867
|
+
const themeDir = path7.dirname(new URL(themePath).pathname);
|
|
913
868
|
let totalGalleries = 0;
|
|
914
869
|
for (const dir of galleryDirs) {
|
|
915
|
-
const baseUrl = options.baseUrl ? `${options.baseUrl}${
|
|
916
|
-
const thumbsBaseUrl = options.thumbsBaseUrl ? `${options.thumbsBaseUrl}${
|
|
917
|
-
await buildGallery(
|
|
870
|
+
const baseUrl = options.baseUrl ? `${options.baseUrl}${path7.relative(options.gallery, dir)}` : void 0;
|
|
871
|
+
const thumbsBaseUrl = options.thumbsBaseUrl ? `${options.thumbsBaseUrl}${path7.relative(options.gallery, dir)}` : void 0;
|
|
872
|
+
await buildGallery(path7.resolve(dir), themeDir, options.scan, options.thumbnails, ui, baseUrl, thumbsBaseUrl);
|
|
918
873
|
++totalGalleries;
|
|
919
874
|
}
|
|
920
875
|
ui.box(`Built ${totalGalleries} ${totalGalleries === 1 ? "gallery" : "galleries"} successfully`);
|
|
@@ -930,7 +885,7 @@ async function build(options, ui) {
|
|
|
930
885
|
}
|
|
931
886
|
async function cleanGallery(galleryDir, ui) {
|
|
932
887
|
let filesRemoved = 0;
|
|
933
|
-
const indexHtmlPath =
|
|
888
|
+
const indexHtmlPath = path7.join(galleryDir, "index.html");
|
|
934
889
|
if (fs8.existsSync(indexHtmlPath)) {
|
|
935
890
|
try {
|
|
936
891
|
fs8.rmSync(indexHtmlPath);
|
|
@@ -940,7 +895,7 @@ async function cleanGallery(galleryDir, ui) {
|
|
|
940
895
|
ui?.warn(`Failed to remove index.html: ${error}`);
|
|
941
896
|
}
|
|
942
897
|
}
|
|
943
|
-
const galleryPath =
|
|
898
|
+
const galleryPath = path7.join(galleryDir, "gallery");
|
|
944
899
|
if (fs8.existsSync(galleryPath)) {
|
|
945
900
|
try {
|
|
946
901
|
fs8.rmSync(galleryPath, { recursive: true, force: true });
|
|
@@ -959,7 +914,7 @@ async function cleanGallery(galleryDir, ui) {
|
|
|
959
914
|
}
|
|
960
915
|
async function clean(options, ui) {
|
|
961
916
|
try {
|
|
962
|
-
const basePath =
|
|
917
|
+
const basePath = path7.resolve(options.gallery);
|
|
963
918
|
if (!fs8.existsSync(basePath)) {
|
|
964
919
|
ui.error(`Directory does not exist: ${basePath}`);
|
|
965
920
|
return { processedGalleryCount: 0 };
|
|
@@ -1008,7 +963,7 @@ var ApiTelemetryClient = class {
|
|
|
1008
963
|
axios.post(this.endpoint, event, {
|
|
1009
964
|
headers: {
|
|
1010
965
|
"content-type": "application/json",
|
|
1011
|
-
"user-agent": `simple-photo-gallery/${event.packageVersion} (${
|
|
966
|
+
"user-agent": `simple-photo-gallery/${event.packageVersion} (${process3.platform}; ${process3.arch})`
|
|
1012
967
|
}
|
|
1013
968
|
});
|
|
1014
969
|
} catch {
|
|
@@ -1045,11 +1000,11 @@ var TelemetryService = class {
|
|
|
1045
1000
|
if (override) {
|
|
1046
1001
|
return override === "1";
|
|
1047
1002
|
}
|
|
1048
|
-
if (
|
|
1003
|
+
if (process3.env.CI || process3.env.DO_NOT_TRACK) {
|
|
1049
1004
|
return false;
|
|
1050
1005
|
}
|
|
1051
|
-
if (
|
|
1052
|
-
return
|
|
1006
|
+
if (process3.env.SPG_TELEMETRY) {
|
|
1007
|
+
return process3.env.SPG_TELEMETRY === "1";
|
|
1053
1008
|
}
|
|
1054
1009
|
const stored = this.getStoredPreference();
|
|
1055
1010
|
if (stored === void 0) {
|
|
@@ -1091,7 +1046,7 @@ var TelemetryService = class {
|
|
|
1091
1046
|
durationMs: now - startedAt,
|
|
1092
1047
|
packageName: this.packageName,
|
|
1093
1048
|
packageVersion: this.packageVersion,
|
|
1094
|
-
nodeVersion:
|
|
1049
|
+
nodeVersion: process3.version,
|
|
1095
1050
|
osPlatform: os.platform(),
|
|
1096
1051
|
osRelease: os.release(),
|
|
1097
1052
|
osArch: os.arch(),
|
|
@@ -1125,7 +1080,7 @@ var TelemetryService = class {
|
|
|
1125
1080
|
/** Returns the telemetry client. */
|
|
1126
1081
|
getClient() {
|
|
1127
1082
|
if (!this.client) {
|
|
1128
|
-
switch (
|
|
1083
|
+
switch (process3.env.SPG_TELEMETRY_PROVIDER) {
|
|
1129
1084
|
case "none": {
|
|
1130
1085
|
this.client = void 0;
|
|
1131
1086
|
break;
|
|
@@ -1217,7 +1172,7 @@ async function waitForUpdateCheck(checkPromise) {
|
|
|
1217
1172
|
// package.json
|
|
1218
1173
|
var package_default = {
|
|
1219
1174
|
name: "simple-photo-gallery",
|
|
1220
|
-
version: "2.0.
|
|
1175
|
+
version: "2.0.15-rc.18"};
|
|
1221
1176
|
|
|
1222
1177
|
// src/index.ts
|
|
1223
1178
|
var program = new Command();
|
|
@@ -1259,7 +1214,7 @@ function withCommandContext(handler) {
|
|
|
1259
1214
|
} catch (error) {
|
|
1260
1215
|
ui.debug(error);
|
|
1261
1216
|
errorInfo = error instanceof Error ? { name: error.name, message: error.message } : { name: "UnknownError", message: String(error) };
|
|
1262
|
-
|
|
1217
|
+
process3.exitCode = 1;
|
|
1263
1218
|
}
|
|
1264
1219
|
const updateInfo = await waitForUpdateCheck(updateCheckPromise);
|
|
1265
1220
|
if (updateInfo) {
|
|
@@ -1281,14 +1236,14 @@ function withCommandContext(handler) {
|
|
|
1281
1236
|
program.command("init").description("Initialize a gallery by scaning a folder for images and videos").option(
|
|
1282
1237
|
"-p, --photos <path>",
|
|
1283
1238
|
"Path to the folder where the photos are stored. Default: current working directory",
|
|
1284
|
-
|
|
1239
|
+
process3.cwd()
|
|
1285
1240
|
).option(
|
|
1286
1241
|
"-g, --gallery <path>",
|
|
1287
1242
|
"Path to the directory where the gallery will be initialized. Default: same directory as the photos folder"
|
|
1288
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).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)));
|
|
1289
|
-
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",
|
|
1290
|
-
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",
|
|
1291
|
-
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",
|
|
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", process3.cwd()).option("-r, --recursive", "Scan subdirectories recursively", false).action(withCommandContext((options, ui) => thumbnails(options, ui)));
|
|
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", process3.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)));
|
|
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", process3.cwd()).option("-r, --recursive", "Clean subdirectories recursively", false).action(withCommandContext((options, ui) => clean(options, ui)));
|
|
1292
1247
|
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)));
|
|
1293
1248
|
program.parse();
|
|
1294
1249
|
//# sourceMappingURL=index.js.map
|