Skip to content

Commit

Permalink
convert image urls to media nodes w/ local files
Browse files Browse the repository at this point in the history
  • Loading branch information
nocash committed Dec 19, 2018
1 parent e15ae5a commit c011adb
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 18 deletions.
42 changes: 29 additions & 13 deletions gatsby-node.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,38 @@
const GhostAPI = require('./api');
const {createNodeFactories} = require('./nodes');
const {getImagesFromApiResults} = require('./lib');

exports.sourceNodes = async ({actions}, configOptions) => {
const {createNode} = actions;
exports.sourceNodes = async ({actions, createNodeId, store, cache}, configOptions) => {
const {createNode, touchNode} = actions;
const imageArgs = {createNode, createNodeId, touchNode, store, cache};

return Promise.all([
const [posts, tags, users] = await Promise.all([
GhostAPI.fetchAllPosts(configOptions),
GhostAPI.fetchAllTags(configOptions),
GhostAPI.fetchAllUsers(configOptions)
]).then(([posts, tags, users]) => {
const {
buildPostNode,
buildTagNode,
buildAuthorNode
} = createNodeFactories({posts, tags, users});
]);

posts.forEach(post => createNode(buildPostNode(post)));
tags.forEach(tag => createNode(buildTagNode(tag)));
users.forEach(user => createNode(buildAuthorNode(user)));
});
const {
buildPostNode,
buildTagNode,
buildAuthorNode,
buildMediaNode
} = createNodeFactories({posts, tags, users}, imageArgs);

for (const post of posts) {
createNode(await buildPostNode(post));
}

for (const tag of tags) {
createNode(buildTagNode(tag));
}

for (const user of users) {
createNode(buildAuthorNode(user));
}

const images = getImagesFromApiResults([posts, tags, users]);
for (const image of images) {
createNode(await buildMediaNode(image));
}
};
9 changes: 9 additions & 0 deletions lib.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports.getImagesFromApiResults = results => results
.reduce((acc, entities) => acc.concat(entities))
.reduce((acc, entity) => acc.concat([
entity.feature_image,
entity.cover_image,
entity.profile_image
]), [])
.filter(url => !!url)
.map(url => ({id: url, url}));
85 changes: 80 additions & 5 deletions nodes.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,48 @@
const createNodeHelpers = require('gatsby-node-helpers').default;
const {createRemoteFileNode} = require('gatsby-source-filesystem');

const TYPE_PREFIX = 'Ghost';
const {
createNodeFactory,
generateNodeId
} = createNodeHelpers({
typePrefix: 'Ghost'
typePrefix: TYPE_PREFIX
});

const POST = 'Post';
const TAG = 'Tag';
const AUTHOR = 'Author';
const MEDIA = 'Media';

async function downloadImageAndCreateFileNode(
{url},
{createNode, createNodeId, touchNode, store, cache},
) {
let fileNodeID;

const mediaDataCacheKey = `${TYPE_PREFIX}__Media__${url}`;
const cacheMediaData = await cache.get(mediaDataCacheKey);

if (cacheMediaData) {
fileNodeID = cacheMediaData.fileNodeID;
touchNode({nodeId: fileNodeID});
return fileNodeID;
}

const fileNode = await createRemoteFileNode({
url,
store,
cache,
createNode,
createNodeId
});

if (fileNode) {
fileNodeID = fileNode.id;
await cache.set(mediaDataCacheKey, {fileNodeID});
return fileNodeID;
}
}

function mapPostToTags(post, tags) {
const postHasTags = post.tags && Array.isArray(post.tags) && post.tags.length;
Expand Down Expand Up @@ -63,20 +96,62 @@ function mapPostToUsers(post, users) {
}
}

module.exports.createNodeFactories = ({tags, users}) => {
async function mapImagesToMedia(node) {
if (node.feature_image) {
node.feature_image___NODE = generateNodeId(MEDIA, node.feature_image);
delete node.feature_image;
}

if (node.profile_image) {
node.profile_image___NODE = generateNodeId(MEDIA, node.profile_image);
delete node.profile_image;
}

if (node.cover_image) {
node.cover_image___NODE = generateNodeId(MEDIA, node.cover_image);
delete node.cover_image;
}
}

async function createLocalFileFromMedia(node, imageArgs) {
node.localFile___NODE = await downloadImageAndCreateFileNode(
{url: node.url.split('?')[0]},
imageArgs
);
}

module.exports.createNodeFactories = ({tags, users}, imageArgs) => {
const postNodeMiddleware = (node) => {
mapPostToTags(node, tags);
mapPostToUsers(node, users);
mapImagesToMedia(node);
return node;
};

const tagNodeMiddleware = (node) => {
mapImagesToMedia(node);
return node;
};

const authorNodeMiddleware = (node) => {
mapImagesToMedia(node);
return node;
};

const mediaNodeMiddleware = async (node) => {
await createLocalFileFromMedia(node, imageArgs);
return node;
};

const buildPostNode = createNodeFactory(POST, postNodeMiddleware);
const buildTagNode = createNodeFactory(TAG);
const buildAuthorNode = createNodeFactory(AUTHOR);
const buildTagNode = createNodeFactory(TAG, tagNodeMiddleware);
const buildAuthorNode = createNodeFactory(AUTHOR, authorNodeMiddleware);
const buildMediaNode = createNodeFactory(MEDIA, mediaNodeMiddleware);

return {
buildPostNode,
buildTagNode,
buildAuthorNode
buildAuthorNode,
buildMediaNode
};
};

0 comments on commit c011adb

Please sign in to comment.