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