Personal-Website/gatsby-node.js
2021-06-18 19:13:24 -07:00

117 lines
3.0 KiB
JavaScript

const fs = require('fs');
const util = require('util');
const path = require('path');
const { read } = require('fast-exif');
const iptc = require('node-iptc');
const Vibrant = require('node-vibrant');
const R = require('ramda');
const readFile = util.promisify(fs.readFile);
function convertDMSToDD(dms, positiveDirection) {
const res = dms
.map((item, i) => {
return item / Math.pow(60, i);
})
.reduce((a, b) => a + b);
return positiveDirection ? res : -res;
}
function transformMetaToNodeData(exifData, iptcData, vibrantData) {
const gps = { longitude: null, latitude: null };
if (exifData) {
if (
exifData.gps &&
exifData.gps.GPSLongitude &&
exifData.gps.GPSLatitude
) {
gps.longitude = convertDMSToDD(
exifData.gps.GPSLongitude,
exifData.gps.GPSLongitudeRef === 'E'
);
gps.latitude = convertDMSToDD(
exifData.gps.GPSLatitude,
exifData.gps.GPSLatitudeRef === 'N'
);
}
}
const vibrant = R.map((swatch) => ({
rgb: swatch.getRgb(),
titleTextColor: swatch.getTitleTextColor(),
bodyTextColor: swatch.getBodyTextColor(),
})
, vibrantData);
return {
exif: exifData?.exif,
gps,
dateTaken: exifData?.exif?.DateTimeOriginal,
iptc: iptcData || undefined,
vibrant,
};
}
exports.onCreateNode = async function ({ node, getNode, actions }) {
const { createNodeField } = actions;
if (node.internal.type === 'ImageSharp') {
const parent = getNode(node.parent);
const file = await readFile(parent.absolutePath);
const iptcData = iptc(file);
const exifData = await read(parent.absolutePath);
const vibrantData = await Vibrant.from(parent.absolutePath)
.quality(1)
.getPalette();
createNodeField({
node,
name: 'imageMeta',
value: transformMetaToNodeData(exifData, iptcData, vibrantData),
});
}
};
// Implement the Gatsby API “createPages”. This is called once the
// data layer is bootstrapped to let plugins create pages from data.
exports.createPages = async ({ graphql, actions, reporter }) => {
const { createPage } = actions;
// get all images
const galleryImages = await graphql(`
{
allFile(filter: {
sourceInstanceName: { eq: "gallery" }}
) {
edges {
node {
relativePath,
base
}
}
}
}
`);
// Handle errors
if (galleryImages.errors) {
reporter.panicOnBuild('Error while running GraphQL query.');
return;
}
// Create pages for each markdown file.
const galleryImageTemplate = path.resolve('src/components/GalleryImage.js');
galleryImages.data.allFile.edges.forEach(({ node }) => {
// const path = node.base
createPage({
path: `photogallery/${node.base}`,
component: galleryImageTemplate,
// In your blog post template's graphql query, you can use pagePath
// as a GraphQL variable to query for data from the markdown file.
context: {
imageFilename: node.base,
},
});
});
};