simple-photo-gallery 2.0.11 → 2.0.13
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 +90 -80
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +89 -79
- package/dist/index.js.map +1 -1
- package/dist/lib/index.cjs +19 -9
- package/dist/lib/index.cjs.map +1 -1
- package/dist/lib/index.js +19 -9
- package/dist/lib/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ 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 path from 'path';
|
|
8
8
|
import { Buffer } from 'buffer';
|
|
9
9
|
import { fileURLToPath } from 'url';
|
|
10
10
|
import sharp2 from 'sharp';
|
|
@@ -77,36 +77,43 @@ async function generateBlurHash(imagePath, componentX = 4, componentY = 3) {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
// src/modules/build/utils/index.ts
|
|
80
|
-
var __dirname =
|
|
81
|
-
var SOCIAL_CARD_FONT_RELATIVE_PATH =
|
|
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
82
|
var socialCardFontBase64;
|
|
83
83
|
function resolveFromCurrentDir(...segments) {
|
|
84
|
-
return
|
|
84
|
+
return path.resolve(__dirname, ...segments);
|
|
85
85
|
}
|
|
86
86
|
function findSocialCardFontPath() {
|
|
87
87
|
const fontCandidates = [
|
|
88
88
|
resolveFromCurrentDir("../../../../", SOCIAL_CARD_FONT_RELATIVE_PATH),
|
|
89
|
-
|
|
90
|
-
|
|
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)
|
|
91
94
|
];
|
|
92
95
|
for (const candidate of fontCandidates) {
|
|
93
96
|
if (fs8.existsSync(candidate)) {
|
|
94
97
|
return candidate;
|
|
95
98
|
}
|
|
96
99
|
}
|
|
97
|
-
|
|
100
|
+
return null;
|
|
98
101
|
}
|
|
99
102
|
function getSocialCardFontBase64() {
|
|
100
|
-
if (socialCardFontBase64) {
|
|
103
|
+
if (socialCardFontBase64 !== void 0) {
|
|
101
104
|
return socialCardFontBase64;
|
|
102
105
|
}
|
|
103
106
|
const fontPath = findSocialCardFontPath();
|
|
107
|
+
if (!fontPath) {
|
|
108
|
+
socialCardFontBase64 = null;
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
104
111
|
socialCardFontBase64 = fs8.readFileSync(fontPath).toString("base64");
|
|
105
112
|
return socialCardFontBase64;
|
|
106
113
|
}
|
|
107
114
|
async function createGallerySocialMediaCardImage(headerPhotoPath, title, ouputPath, ui) {
|
|
108
115
|
ui?.start(`Creating social media card image`);
|
|
109
|
-
const headerBasename =
|
|
116
|
+
const headerBasename = path.basename(headerPhotoPath, path.extname(headerPhotoPath));
|
|
110
117
|
if (fs8.existsSync(ouputPath)) {
|
|
111
118
|
ui?.success(`Social media card image already exists`);
|
|
112
119
|
return headerBasename;
|
|
@@ -116,17 +123,20 @@ async function createGallerySocialMediaCardImage(headerPhotoPath, title, ouputPa
|
|
|
116
123
|
const outputPath = ouputPath;
|
|
117
124
|
await sharp2(resizedImageBuffer).toFile(outputPath);
|
|
118
125
|
const fontBase64 = getSocialCardFontBase64();
|
|
119
|
-
const
|
|
120
|
-
<svg width="1200" height="631" xmlns="http://www.w3.org/2000/svg">
|
|
121
|
-
<defs>
|
|
122
|
-
<style>
|
|
126
|
+
const fontFace = fontBase64 ? `
|
|
123
127
|
@font-face {
|
|
124
128
|
font-family: 'DejaVu Sans';
|
|
125
129
|
src: url('data:font/ttf;base64,${fontBase64}') format('truetype');
|
|
126
130
|
font-weight: 700;
|
|
127
131
|
font-style: normal;
|
|
128
|
-
}
|
|
129
|
-
|
|
132
|
+
}` : "";
|
|
133
|
+
const fontFamily = fontBase64 ? "'DejaVu Sans', Arial, sans-serif" : "Arial, sans-serif";
|
|
134
|
+
const svgText = `
|
|
135
|
+
<svg width="1200" height="631" xmlns="http://www.w3.org/2000/svg">
|
|
136
|
+
<defs>
|
|
137
|
+
<style>
|
|
138
|
+
${fontFace}
|
|
139
|
+
.title { font-family: ${fontFamily}; font-size: 96px; font-weight: bold; fill: white; stroke: black; stroke-width: 5; paint-order: stroke; text-anchor: middle; }
|
|
130
140
|
</style>
|
|
131
141
|
</defs>
|
|
132
142
|
<text x="600" y="250" class="title">${title}</text>
|
|
@@ -140,7 +150,7 @@ async function createGallerySocialMediaCardImage(headerPhotoPath, title, ouputPa
|
|
|
140
150
|
async function createOptimizedHeaderImage(headerPhotoPath, outputFolder, ui) {
|
|
141
151
|
ui?.start(`Creating optimized header images`);
|
|
142
152
|
const image = await loadImage(headerPhotoPath);
|
|
143
|
-
const headerBasename =
|
|
153
|
+
const headerBasename = path.basename(headerPhotoPath, path.extname(headerPhotoPath));
|
|
144
154
|
const generatedFiles = [];
|
|
145
155
|
ui?.debug("Generating blurhash for header image");
|
|
146
156
|
const blurHash = await generateBlurHash(headerPhotoPath);
|
|
@@ -149,22 +159,22 @@ async function createOptimizedHeaderImage(headerPhotoPath, outputFolder, ui) {
|
|
|
149
159
|
ui?.debug(`Creating landscape header image ${width}`);
|
|
150
160
|
const avifFilename = `${headerBasename}_landscape_${width}.avif`;
|
|
151
161
|
const jpgFilename = `${headerBasename}_landscape_${width}.jpg`;
|
|
152
|
-
if (fs8.existsSync(
|
|
162
|
+
if (fs8.existsSync(path.join(outputFolder, avifFilename))) {
|
|
153
163
|
ui?.debug(`Landscape header image ${width} AVIF already exists`);
|
|
154
164
|
} else {
|
|
155
165
|
await cropAndResizeImage(
|
|
156
166
|
image.clone(),
|
|
157
|
-
|
|
167
|
+
path.join(outputFolder, avifFilename),
|
|
158
168
|
width,
|
|
159
169
|
width * landscapeYFactor,
|
|
160
170
|
"avif"
|
|
161
171
|
);
|
|
162
172
|
}
|
|
163
173
|
generatedFiles.push(avifFilename);
|
|
164
|
-
if (fs8.existsSync(
|
|
174
|
+
if (fs8.existsSync(path.join(outputFolder, jpgFilename))) {
|
|
165
175
|
ui?.debug(`Landscape header image ${width} JPG already exists`);
|
|
166
176
|
} else {
|
|
167
|
-
await cropAndResizeImage(image.clone(),
|
|
177
|
+
await cropAndResizeImage(image.clone(), path.join(outputFolder, jpgFilename), width, width * landscapeYFactor, "jpg");
|
|
168
178
|
}
|
|
169
179
|
generatedFiles.push(jpgFilename);
|
|
170
180
|
}
|
|
@@ -173,16 +183,16 @@ async function createOptimizedHeaderImage(headerPhotoPath, outputFolder, ui) {
|
|
|
173
183
|
ui?.debug(`Creating portrait header image ${width}`);
|
|
174
184
|
const avifFilename = `${headerBasename}_portrait_${width}.avif`;
|
|
175
185
|
const jpgFilename = `${headerBasename}_portrait_${width}.jpg`;
|
|
176
|
-
if (fs8.existsSync(
|
|
186
|
+
if (fs8.existsSync(path.join(outputFolder, avifFilename))) {
|
|
177
187
|
ui?.debug(`Portrait header image ${width} AVIF already exists`);
|
|
178
188
|
} else {
|
|
179
|
-
await cropAndResizeImage(image.clone(),
|
|
189
|
+
await cropAndResizeImage(image.clone(), path.join(outputFolder, avifFilename), width, width * portraitYFactor, "avif");
|
|
180
190
|
}
|
|
181
191
|
generatedFiles.push(avifFilename);
|
|
182
|
-
if (fs8.existsSync(
|
|
192
|
+
if (fs8.existsSync(path.join(outputFolder, jpgFilename))) {
|
|
183
193
|
ui?.debug(`Portrait header image ${width} JPG already exists`);
|
|
184
194
|
} else {
|
|
185
|
-
await cropAndResizeImage(image.clone(),
|
|
195
|
+
await cropAndResizeImage(image.clone(), path.join(outputFolder, jpgFilename), width, width * portraitYFactor, "jpg");
|
|
186
196
|
}
|
|
187
197
|
generatedFiles.push(jpgFilename);
|
|
188
198
|
}
|
|
@@ -215,12 +225,12 @@ function cleanupOldHeaderImages(outputFolder, currentHeaderBasename, ui) {
|
|
|
215
225
|
const landscapeMatch = file.match(/^(.+)_landscape_\d+\.(avif|jpg)$/);
|
|
216
226
|
const portraitMatch = file.match(/^(.+)_portrait_\d+\.(avif|jpg)$/);
|
|
217
227
|
if (landscapeMatch && landscapeMatch[1] !== currentHeaderBasename) {
|
|
218
|
-
const filePath =
|
|
228
|
+
const filePath = path.join(outputFolder, file);
|
|
219
229
|
ui?.debug(`Deleting old landscape header image: ${file}`);
|
|
220
230
|
fs8.unlinkSync(filePath);
|
|
221
231
|
deletedCount++;
|
|
222
232
|
} else if (portraitMatch && portraitMatch[1] !== currentHeaderBasename) {
|
|
223
|
-
const filePath =
|
|
233
|
+
const filePath = path.join(outputFolder, file);
|
|
224
234
|
ui?.debug(`Deleting old portrait header image: ${file}`);
|
|
225
235
|
fs8.unlinkSync(filePath);
|
|
226
236
|
deletedCount++;
|
|
@@ -234,7 +244,7 @@ function cleanupOldHeaderImages(outputFolder, currentHeaderBasename, ui) {
|
|
|
234
244
|
}
|
|
235
245
|
function findGalleries(basePath, recursive) {
|
|
236
246
|
const galleryDirs = [];
|
|
237
|
-
const galleryJsonPath =
|
|
247
|
+
const galleryJsonPath = path.join(basePath, "gallery", "gallery.json");
|
|
238
248
|
if (fs8.existsSync(galleryJsonPath)) {
|
|
239
249
|
galleryDirs.push(basePath);
|
|
240
250
|
}
|
|
@@ -243,7 +253,7 @@ function findGalleries(basePath, recursive) {
|
|
|
243
253
|
const entries = fs8.readdirSync(basePath, { withFileTypes: true });
|
|
244
254
|
for (const entry of entries) {
|
|
245
255
|
if (entry.isDirectory() && entry.name !== "gallery") {
|
|
246
|
-
const subPath =
|
|
256
|
+
const subPath = path.join(basePath, entry.name);
|
|
247
257
|
const subResults = findGalleries(subPath, recursive);
|
|
248
258
|
galleryDirs.push(...subResults);
|
|
249
259
|
}
|
|
@@ -302,20 +312,20 @@ function migrateGalleryJson(deprecatedGalleryData, galleryJsonPath, ui) {
|
|
|
302
312
|
ui.start("Old gallery.json format detected. Migrating gallery.json to the new data format.");
|
|
303
313
|
let mediaBasePath;
|
|
304
314
|
const imagePath = deprecatedGalleryData.sections[0].images[0].path;
|
|
305
|
-
if (imagePath && imagePath !==
|
|
306
|
-
mediaBasePath =
|
|
315
|
+
if (imagePath && imagePath !== path.join("..", path.basename(imagePath))) {
|
|
316
|
+
mediaBasePath = path.resolve(path.join(path.dirname(galleryJsonPath)), path.dirname(imagePath));
|
|
307
317
|
}
|
|
308
318
|
const sections = deprecatedGalleryData.sections.map((section) => ({
|
|
309
319
|
...section,
|
|
310
320
|
images: section.images.map((image) => ({
|
|
311
321
|
...image,
|
|
312
322
|
path: void 0,
|
|
313
|
-
filename:
|
|
323
|
+
filename: path.basename(image.path)
|
|
314
324
|
}))
|
|
315
325
|
}));
|
|
316
326
|
const galleryData = {
|
|
317
327
|
...deprecatedGalleryData,
|
|
318
|
-
headerImage:
|
|
328
|
+
headerImage: path.basename(deprecatedGalleryData.headerImage),
|
|
319
329
|
sections,
|
|
320
330
|
mediaBasePath
|
|
321
331
|
};
|
|
@@ -327,7 +337,7 @@ function migrateGalleryJson(deprecatedGalleryData, galleryJsonPath, ui) {
|
|
|
327
337
|
return galleryData;
|
|
328
338
|
}
|
|
329
339
|
function getMediaFileType(fileName) {
|
|
330
|
-
const ext =
|
|
340
|
+
const ext = path.extname(fileName).toLowerCase();
|
|
331
341
|
if (IMAGE_EXTENSIONS.has(ext)) return "image";
|
|
332
342
|
if (VIDEO_EXTENSIONS.has(ext)) return "video";
|
|
333
343
|
return null;
|
|
@@ -355,7 +365,7 @@ async function scanDirectory(dirPath, ui) {
|
|
|
355
365
|
mediaFiles.push(mediaFile);
|
|
356
366
|
}
|
|
357
367
|
} else if (entry.isDirectory() && entry.name !== "gallery") {
|
|
358
|
-
subGalleryDirectories.push(
|
|
368
|
+
subGalleryDirectories.push(path.join(dirPath, entry.name));
|
|
359
369
|
}
|
|
360
370
|
}
|
|
361
371
|
} catch (error) {
|
|
@@ -391,12 +401,12 @@ async function getGallerySettingsFromUser(galleryName, defaultImage, ui) {
|
|
|
391
401
|
return { title, description, url, headerImage };
|
|
392
402
|
}
|
|
393
403
|
async function createGalleryJson(mediaFiles, galleryJsonPath, scanPath, subGalleries = [], useDefaultSettings, ctaBanner, ui) {
|
|
394
|
-
const galleryDir =
|
|
395
|
-
const isSameLocation =
|
|
404
|
+
const galleryDir = path.dirname(galleryJsonPath);
|
|
405
|
+
const isSameLocation = path.relative(scanPath, path.join(galleryDir, "..")) === "";
|
|
396
406
|
const mediaBasePath = isSameLocation ? void 0 : scanPath;
|
|
397
407
|
const relativeSubGalleries = subGalleries.map((subGallery) => ({
|
|
398
408
|
...subGallery,
|
|
399
|
-
headerImage: subGallery.headerImage ?
|
|
409
|
+
headerImage: subGallery.headerImage ? path.relative(galleryDir, subGallery.headerImage) : ""
|
|
400
410
|
}));
|
|
401
411
|
let galleryData = {
|
|
402
412
|
title: "My Gallery",
|
|
@@ -419,8 +429,8 @@ async function createGalleryJson(mediaFiles, galleryJsonPath, scanPath, subGalle
|
|
|
419
429
|
galleryData = {
|
|
420
430
|
...galleryData,
|
|
421
431
|
...await getGallerySettingsFromUser(
|
|
422
|
-
|
|
423
|
-
|
|
432
|
+
path.basename(path.join(galleryDir, "..")),
|
|
433
|
+
path.basename(mediaFiles[0]?.filename || ""),
|
|
424
434
|
ui
|
|
425
435
|
)
|
|
426
436
|
};
|
|
@@ -428,8 +438,8 @@ async function createGalleryJson(mediaFiles, galleryJsonPath, scanPath, subGalle
|
|
|
428
438
|
await promises.writeFile(galleryJsonPath, JSON.stringify(galleryData, null, 2));
|
|
429
439
|
}
|
|
430
440
|
async function galleryExists(outputPath) {
|
|
431
|
-
const galleryPath =
|
|
432
|
-
const galleryJsonPath =
|
|
441
|
+
const galleryPath = path.join(outputPath, "gallery");
|
|
442
|
+
const galleryJsonPath = path.join(galleryPath, "gallery.json");
|
|
433
443
|
try {
|
|
434
444
|
await promises.access(galleryJsonPath);
|
|
435
445
|
return true;
|
|
@@ -448,7 +458,7 @@ async function processDirectory(scanPath, outputPath, recursive, useDefaultSetti
|
|
|
448
458
|
for (const subGalleryDir of subGalleryDirectories) {
|
|
449
459
|
const result2 = await processDirectory(
|
|
450
460
|
subGalleryDir,
|
|
451
|
-
|
|
461
|
+
path.join(outputPath, path.basename(subGalleryDir)),
|
|
452
462
|
recursive,
|
|
453
463
|
useDefaultSettings,
|
|
454
464
|
force,
|
|
@@ -463,8 +473,8 @@ async function processDirectory(scanPath, outputPath, recursive, useDefaultSetti
|
|
|
463
473
|
}
|
|
464
474
|
}
|
|
465
475
|
if (mediaFiles.length > 0 || subGalleries.length > 0) {
|
|
466
|
-
const galleryPath =
|
|
467
|
-
const galleryJsonPath =
|
|
476
|
+
const galleryPath = path.join(outputPath, "gallery");
|
|
477
|
+
const galleryJsonPath = path.join(galleryPath, "gallery.json");
|
|
468
478
|
const exists = await galleryExists(outputPath);
|
|
469
479
|
if (exists && !force) {
|
|
470
480
|
const shouldOverride = await ui.prompt(`Gallery already exists at ${galleryJsonPath}. Do you want to override it?`, {
|
|
@@ -489,19 +499,19 @@ async function processDirectory(scanPath, outputPath, recursive, useDefaultSetti
|
|
|
489
499
|
}
|
|
490
500
|
const result = { totalFiles, totalGalleries };
|
|
491
501
|
if (mediaFiles.length > 0 || subGalleries.length > 0) {
|
|
492
|
-
const dirName =
|
|
502
|
+
const dirName = path.basename(scanPath);
|
|
493
503
|
result.subGallery = {
|
|
494
504
|
title: capitalizeTitle(dirName),
|
|
495
505
|
headerImage: mediaFiles[0]?.filename || "",
|
|
496
|
-
path:
|
|
506
|
+
path: path.join("..", dirName)
|
|
497
507
|
};
|
|
498
508
|
}
|
|
499
509
|
return result;
|
|
500
510
|
}
|
|
501
511
|
async function init(options, ui) {
|
|
502
512
|
try {
|
|
503
|
-
const scanPath =
|
|
504
|
-
const outputPath = options.gallery ?
|
|
513
|
+
const scanPath = path.resolve(options.photos);
|
|
514
|
+
const outputPath = options.gallery ? path.resolve(options.gallery) : scanPath;
|
|
505
515
|
const result = await processDirectory(
|
|
506
516
|
scanPath,
|
|
507
517
|
outputPath,
|
|
@@ -625,7 +635,7 @@ async function processImage(imagePath, thumbnailPath, thumbnailPathRetina, thumb
|
|
|
625
635
|
const blurHash = await generateBlurHash(thumbnailPath);
|
|
626
636
|
return {
|
|
627
637
|
type: "image",
|
|
628
|
-
filename:
|
|
638
|
+
filename: path.basename(imagePath),
|
|
629
639
|
alt: description,
|
|
630
640
|
width: imageDimensions.width,
|
|
631
641
|
height: imageDimensions.height,
|
|
@@ -656,7 +666,7 @@ async function processVideo(videoPath, thumbnailPath, thumbnailPathRetina, thumb
|
|
|
656
666
|
const blurHash = await generateBlurHash(thumbnailPath);
|
|
657
667
|
return {
|
|
658
668
|
type: "video",
|
|
659
|
-
filename:
|
|
669
|
+
filename: path.basename(videoPath),
|
|
660
670
|
alt: void 0,
|
|
661
671
|
width: videoDimensions.width,
|
|
662
672
|
height: videoDimensions.height,
|
|
@@ -672,11 +682,11 @@ async function processVideo(videoPath, thumbnailPath, thumbnailPathRetina, thumb
|
|
|
672
682
|
}
|
|
673
683
|
async function processMediaFile(mediaFile, mediaBasePath, thumbnailsPath, thumbnailSize, ui) {
|
|
674
684
|
try {
|
|
675
|
-
const filePath =
|
|
685
|
+
const filePath = path.resolve(path.join(mediaBasePath, mediaFile.filename));
|
|
676
686
|
const fileName = mediaFile.filename;
|
|
677
|
-
const fileNameWithoutExt =
|
|
687
|
+
const fileNameWithoutExt = path.parse(fileName).name;
|
|
678
688
|
const thumbnailFileName = `${fileNameWithoutExt}.avif`;
|
|
679
|
-
const thumbnailPath =
|
|
689
|
+
const thumbnailPath = path.join(thumbnailsPath, thumbnailFileName);
|
|
680
690
|
const thumbnailPathRetina = thumbnailPath.replace(".avif", "@2x.avif");
|
|
681
691
|
const lastMediaTimestamp = mediaFile.lastMediaTimestamp ? new Date(mediaFile.lastMediaTimestamp) : void 0;
|
|
682
692
|
const verbose = ui.level === LogLevels.debug;
|
|
@@ -702,8 +712,8 @@ async function processMediaFile(mediaFile, mediaBasePath, thumbnailsPath, thumbn
|
|
|
702
712
|
}
|
|
703
713
|
updatedMediaFile.filename = mediaFile.filename;
|
|
704
714
|
if (updatedMediaFile.thumbnail) {
|
|
705
|
-
updatedMediaFile.thumbnail.path =
|
|
706
|
-
updatedMediaFile.thumbnail.pathRetina =
|
|
715
|
+
updatedMediaFile.thumbnail.path = path.basename(thumbnailPath);
|
|
716
|
+
updatedMediaFile.thumbnail.pathRetina = path.basename(thumbnailPathRetina);
|
|
707
717
|
if (mediaFile.thumbnail?.baseUrl) {
|
|
708
718
|
updatedMediaFile.thumbnail.baseUrl = mediaFile.thumbnail.baseUrl;
|
|
709
719
|
}
|
|
@@ -718,14 +728,14 @@ async function processMediaFile(mediaFile, mediaBasePath, thumbnailsPath, thumbn
|
|
|
718
728
|
}
|
|
719
729
|
}
|
|
720
730
|
async function processGalleryThumbnails(galleryDir, ui) {
|
|
721
|
-
const galleryJsonPath =
|
|
722
|
-
const thumbnailsPath =
|
|
731
|
+
const galleryJsonPath = path.join(galleryDir, "gallery", "gallery.json");
|
|
732
|
+
const thumbnailsPath = path.join(galleryDir, "gallery", "images");
|
|
723
733
|
ui.start(`Creating thumbnails: ${galleryDir}`);
|
|
724
734
|
try {
|
|
725
735
|
fs8.mkdirSync(thumbnailsPath, { recursive: true });
|
|
726
736
|
const galleryData = parseGalleryJson(galleryJsonPath, ui);
|
|
727
737
|
const thumbnailSize = galleryData.thumbnailSize || DEFAULT_THUMBNAIL_SIZE;
|
|
728
|
-
const mediaBasePath = galleryData.mediaBasePath ??
|
|
738
|
+
const mediaBasePath = galleryData.mediaBasePath ?? path.join(galleryDir);
|
|
729
739
|
let processedCount = 0;
|
|
730
740
|
for (const section of galleryData.sections) {
|
|
731
741
|
for (const [index, mediaFile] of section.images.entries()) {
|
|
@@ -772,8 +782,8 @@ function copyPhotos(galleryData, galleryDir, ui) {
|
|
|
772
782
|
for (const section of galleryData.sections) {
|
|
773
783
|
for (const image of section.images) {
|
|
774
784
|
if (galleryData.mediaBasePath) {
|
|
775
|
-
const sourcePath =
|
|
776
|
-
const destPath =
|
|
785
|
+
const sourcePath = path.join(galleryData.mediaBasePath, image.filename);
|
|
786
|
+
const destPath = path.join(galleryDir, image.filename);
|
|
777
787
|
ui.debug(`Copying photo to ${destPath}`);
|
|
778
788
|
fs8.copyFileSync(sourcePath, destPath);
|
|
779
789
|
}
|
|
@@ -812,17 +822,17 @@ async function scanAndAppendNewFiles(galleryDir, galleryJsonPath, galleryData, u
|
|
|
812
822
|
}
|
|
813
823
|
async function buildGallery(galleryDir, templateDir, scan, shouldCreateThumbnails, ui, baseUrl, thumbsBaseUrl) {
|
|
814
824
|
ui.start(`Building gallery ${galleryDir}`);
|
|
815
|
-
const galleryJsonPath =
|
|
825
|
+
const galleryJsonPath = path.join(galleryDir, "gallery", "gallery.json");
|
|
816
826
|
let galleryData = parseGalleryJson(galleryJsonPath, ui);
|
|
817
827
|
if (scan) {
|
|
818
828
|
galleryData = await scanAndAppendNewFiles(galleryDir, galleryJsonPath, galleryData, ui);
|
|
819
829
|
}
|
|
820
|
-
const socialMediaCardImagePath =
|
|
830
|
+
const socialMediaCardImagePath = path.join(galleryDir, "gallery", "images", "social-media-card.jpg");
|
|
821
831
|
const mediaBasePath = galleryData.mediaBasePath;
|
|
822
832
|
const mediaBaseUrl = baseUrl || galleryData.mediaBaseUrl;
|
|
823
|
-
const headerImagePath = mediaBasePath ?
|
|
824
|
-
const imagesFolder =
|
|
825
|
-
const currentHeaderBasename =
|
|
833
|
+
const headerImagePath = mediaBasePath ? path.join(mediaBasePath, galleryData.headerImage) : path.resolve(galleryDir, galleryData.headerImage);
|
|
834
|
+
const imagesFolder = path.join(galleryDir, "gallery", "images");
|
|
835
|
+
const currentHeaderBasename = path.basename(headerImagePath, path.extname(headerImagePath));
|
|
826
836
|
if (shouldCreateThumbnails) {
|
|
827
837
|
if (!fs8.existsSync(imagesFolder)) {
|
|
828
838
|
fs8.mkdirSync(imagesFolder, { recursive: true });
|
|
@@ -865,7 +875,7 @@ async function buildGallery(galleryDir, templateDir, scan, shouldCreateThumbnail
|
|
|
865
875
|
}
|
|
866
876
|
if (!galleryData.metadata.image) {
|
|
867
877
|
ui.debug("Updating gallery.json with social media card URL");
|
|
868
|
-
galleryData.metadata.image = thumbsBaseUrl ? `${thumbsBaseUrl}/${
|
|
878
|
+
galleryData.metadata.image = thumbsBaseUrl ? `${thumbsBaseUrl}/${path.basename(socialMediaCardImagePath)}` : `${galleryData.url || ""}/${path.relative(galleryDir, socialMediaCardImagePath)}`;
|
|
869
879
|
fs8.writeFileSync(galleryJsonPath, JSON.stringify(galleryData, null, 2));
|
|
870
880
|
}
|
|
871
881
|
if (shouldCreateThumbnails) {
|
|
@@ -874,19 +884,19 @@ async function buildGallery(galleryDir, templateDir, scan, shouldCreateThumbnail
|
|
|
874
884
|
ui.debug("Building gallery from template");
|
|
875
885
|
try {
|
|
876
886
|
process4.env.GALLERY_JSON_PATH = galleryJsonPath;
|
|
877
|
-
process4.env.GALLERY_OUTPUT_DIR =
|
|
887
|
+
process4.env.GALLERY_OUTPUT_DIR = path.join(galleryDir, "gallery");
|
|
878
888
|
execSync("npx astro build", { cwd: templateDir, stdio: ui.level === LogLevels.debug ? "inherit" : "ignore" });
|
|
879
889
|
} catch (error) {
|
|
880
890
|
ui.error(`Build failed for ${galleryDir}`);
|
|
881
891
|
throw error;
|
|
882
892
|
}
|
|
883
|
-
const outputDir =
|
|
884
|
-
const buildDir =
|
|
893
|
+
const outputDir = path.join(galleryDir, "gallery");
|
|
894
|
+
const buildDir = path.join(outputDir, "_build");
|
|
885
895
|
ui.debug(`Copying build output to ${outputDir}`);
|
|
886
896
|
fs8.cpSync(buildDir, outputDir, { recursive: true });
|
|
887
897
|
ui.debug("Moving index.html to gallery directory");
|
|
888
|
-
fs8.copyFileSync(
|
|
889
|
-
fs8.rmSync(
|
|
898
|
+
fs8.copyFileSync(path.join(outputDir, "index.html"), path.join(galleryDir, "index.html"));
|
|
899
|
+
fs8.rmSync(path.join(outputDir, "index.html"));
|
|
890
900
|
ui.debug("Cleaning up build directory");
|
|
891
901
|
fs8.rmSync(buildDir, { recursive: true, force: true });
|
|
892
902
|
ui.success(`Gallery built successfully`);
|
|
@@ -899,12 +909,12 @@ async function build(options, ui) {
|
|
|
899
909
|
return { processedGalleryCount: 0 };
|
|
900
910
|
}
|
|
901
911
|
const themePath = await import.meta.resolve("@simple-photo-gallery/theme-modern/package.json");
|
|
902
|
-
const themeDir =
|
|
912
|
+
const themeDir = path.dirname(new URL(themePath).pathname);
|
|
903
913
|
let totalGalleries = 0;
|
|
904
914
|
for (const dir of galleryDirs) {
|
|
905
|
-
const baseUrl = options.baseUrl ? `${options.baseUrl}${
|
|
906
|
-
const thumbsBaseUrl = options.thumbsBaseUrl ? `${options.thumbsBaseUrl}${
|
|
907
|
-
await buildGallery(
|
|
915
|
+
const baseUrl = options.baseUrl ? `${options.baseUrl}${path.relative(options.gallery, dir)}` : void 0;
|
|
916
|
+
const thumbsBaseUrl = options.thumbsBaseUrl ? `${options.thumbsBaseUrl}${path.relative(options.gallery, dir)}` : void 0;
|
|
917
|
+
await buildGallery(path.resolve(dir), themeDir, options.scan, options.thumbnails, ui, baseUrl, thumbsBaseUrl);
|
|
908
918
|
++totalGalleries;
|
|
909
919
|
}
|
|
910
920
|
ui.box(`Built ${totalGalleries} ${totalGalleries === 1 ? "gallery" : "galleries"} successfully`);
|
|
@@ -920,7 +930,7 @@ async function build(options, ui) {
|
|
|
920
930
|
}
|
|
921
931
|
async function cleanGallery(galleryDir, ui) {
|
|
922
932
|
let filesRemoved = 0;
|
|
923
|
-
const indexHtmlPath =
|
|
933
|
+
const indexHtmlPath = path.join(galleryDir, "index.html");
|
|
924
934
|
if (fs8.existsSync(indexHtmlPath)) {
|
|
925
935
|
try {
|
|
926
936
|
fs8.rmSync(indexHtmlPath);
|
|
@@ -930,7 +940,7 @@ async function cleanGallery(galleryDir, ui) {
|
|
|
930
940
|
ui?.warn(`Failed to remove index.html: ${error}`);
|
|
931
941
|
}
|
|
932
942
|
}
|
|
933
|
-
const galleryPath =
|
|
943
|
+
const galleryPath = path.join(galleryDir, "gallery");
|
|
934
944
|
if (fs8.existsSync(galleryPath)) {
|
|
935
945
|
try {
|
|
936
946
|
fs8.rmSync(galleryPath, { recursive: true, force: true });
|
|
@@ -949,7 +959,7 @@ async function cleanGallery(galleryDir, ui) {
|
|
|
949
959
|
}
|
|
950
960
|
async function clean(options, ui) {
|
|
951
961
|
try {
|
|
952
|
-
const basePath =
|
|
962
|
+
const basePath = path.resolve(options.gallery);
|
|
953
963
|
if (!fs8.existsSync(basePath)) {
|
|
954
964
|
ui.error(`Directory does not exist: ${basePath}`);
|
|
955
965
|
return { processedGalleryCount: 0 };
|
|
@@ -1207,7 +1217,7 @@ async function waitForUpdateCheck(checkPromise) {
|
|
|
1207
1217
|
// package.json
|
|
1208
1218
|
var package_default = {
|
|
1209
1219
|
name: "simple-photo-gallery",
|
|
1210
|
-
version: "2.0.
|
|
1220
|
+
version: "2.0.13"};
|
|
1211
1221
|
|
|
1212
1222
|
// src/index.ts
|
|
1213
1223
|
var program = new Command();
|