113 lines
3.3 KiB
TypeScript
113 lines
3.3 KiB
TypeScript
import { Command } from "commander";
|
|
import { createFileNode, createImageNode, createHeadingNode } from "./lexical";
|
|
import { extractShootingConditions, createImageCaption } from "./exif";
|
|
import { uploadFile, uploadImage, uploadPost } from "./api";
|
|
import { getBasenameWithExtension, prepareFiles } from "./files";
|
|
|
|
new Command()
|
|
.name("darktable-publish")
|
|
.description("Publish files to GHOST CMS with optional metadata.")
|
|
.option("-t, --title [string]", "Specify the title")
|
|
.option("-s, --slug [string]", "Specify the slug")
|
|
.option("-k, --keywords [string...]", "Specify blog post keywords (tags)")
|
|
.argument("<files...>", "Files to process")
|
|
.action(async (files, options) => {
|
|
if (!options.title) {
|
|
throw new Error("Please specify a title.");
|
|
}
|
|
|
|
if (!options.slug) {
|
|
throw new Error("Please specify a slug.");
|
|
}
|
|
|
|
const parsedFiles = await prepareFiles(files);
|
|
|
|
const [
|
|
shootingConditions,
|
|
uploadedJpegImages,
|
|
uploadedJpegFiles,
|
|
uploadedRawFiles,
|
|
] = await Promise.all([
|
|
Promise.all(parsedFiles.map(extractShootingConditions)),
|
|
Promise.all(parsedFiles.map((f) => uploadImage(f.jpegPath))),
|
|
Promise.all(parsedFiles.map((f) => uploadFile(f.jpegPath))),
|
|
Promise.all(
|
|
parsedFiles.map((f) =>
|
|
f.rawPath ? uploadFile(f.rawPath) : Promise.resolve(undefined),
|
|
),
|
|
),
|
|
]);
|
|
|
|
const aggregatedFiles = parsedFiles.map((file, index) => ({
|
|
...file,
|
|
shootingConditions: shootingConditions[index],
|
|
uploadedJpegImage: uploadedJpegImages[index],
|
|
uploadedJpegFile: uploadedJpegFiles[index],
|
|
uploadedRawFile: uploadedRawFiles[index],
|
|
}));
|
|
|
|
const result: any = {
|
|
root: {
|
|
children: [],
|
|
direction: "ltr",
|
|
format: "",
|
|
indent: 0,
|
|
type: "root",
|
|
version: 1,
|
|
},
|
|
};
|
|
|
|
if (aggregatedFiles.length > 1) {
|
|
aggregatedFiles.slice(1).forEach((file) =>
|
|
result.root.children.push(
|
|
createImageNode({
|
|
src: file.uploadedJpegImage,
|
|
caption: createImageCaption(file.shootingConditions),
|
|
}),
|
|
),
|
|
);
|
|
}
|
|
|
|
result.root.children.push(createHeadingNode("Downloads", "h2"));
|
|
|
|
aggregatedFiles.forEach((file) => {
|
|
result.root.children.push(
|
|
createFileNode({
|
|
src: file.uploadedJpegFile,
|
|
name: getBasenameWithExtension(file.jpegPath),
|
|
size: file.jpegSize,
|
|
}),
|
|
);
|
|
|
|
if (file.uploadedRawFile && file.rawPath && file.rawSize) {
|
|
result.root.children.push(
|
|
createFileNode({
|
|
src: file.uploadedRawFile,
|
|
name: getBasenameWithExtension(file.rawPath),
|
|
size: file.rawSize,
|
|
}),
|
|
);
|
|
}
|
|
});
|
|
|
|
const post = {
|
|
title: options.title,
|
|
slug: options.slug,
|
|
lexical: JSON.stringify(result),
|
|
feature_image: aggregatedFiles[0].uploadedJpegImage,
|
|
feature_image_caption: createImageCaption(
|
|
aggregatedFiles[0].shootingConditions,
|
|
),
|
|
status: "published",
|
|
visibility: "public",
|
|
tags: options.keywords,
|
|
published_at: aggregatedFiles[0].shootingConditions.timestamp,
|
|
};
|
|
|
|
const url = await uploadPost(post);
|
|
console.log(url);
|
|
|
|
process.exit(0);
|
|
})
|
|
.parse();
|