Add darktable ghost publish plugin
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
This commit is contained in:
115
hosts/common/configs/user/gui/darktable/publish/src/index.ts
Normal file
115
hosts/common/configs/user/gui/darktable/publish/src/index.ts
Normal file
@@ -0,0 +1,115 @@
|
||||
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();
|
Reference in New Issue
Block a user