first commit
This commit is contained in:
119
build/tasks/content/ghost.js
Normal file
119
build/tasks/content/ghost.js
Normal file
@@ -0,0 +1,119 @@
|
||||
const path = require('path')
|
||||
const https = require('https')
|
||||
const Stream = require('stream').Transform
|
||||
const hasha = require('hasha')
|
||||
const md = require('markdown-it')()
|
||||
const {httpsGetAsync, parseJSONData} = require('../../lib/request')
|
||||
|
||||
const GLITCH_API_ROOT = '/ghost/api/v0.1/'
|
||||
|
||||
// Retrieve ghost access token
|
||||
const getToken = config => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const tokenReqData = `grant_type=password&username=${config.ghost.username}&password=${config.ghost.password}&client_id=${config.ghost.id}&client_secret=${config.ghost.secret}`
|
||||
const tokenReqOptions = {
|
||||
host: config.ghost.host,
|
||||
path: `${GLITCH_API_ROOT}authentication/token`,
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
'Content-Length': Buffer.byteLength(tokenReqData, 'utf8')}}
|
||||
const collectToken = https.request(tokenReqOptions, res => {
|
||||
const data = new Stream()
|
||||
res.on('data', chunk => data.push(chunk))
|
||||
res.on('end', parseJSONData.bind(null, data, resolve, reject))
|
||||
})
|
||||
collectToken.write(tokenReqData)
|
||||
collectToken.end()
|
||||
collectToken.on('error', error => reject(error))
|
||||
})
|
||||
}
|
||||
|
||||
const download = (image, config) => {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
const src = `https://${config.ghost.host}${image}`
|
||||
const dest = path.join(config.basepath, config.image_path, image)
|
||||
const data = new Stream()
|
||||
const res = await httpsGetAsync(src)
|
||||
res.on('data', chunk => data.push(chunk))
|
||||
res.on('end', () => {
|
||||
const buf = data.read()
|
||||
resolve({src, dest, hash: hasha(buf), original: buf, optimized: null, responsive: []})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// download images
|
||||
const downloadImages = async (posts, config) => {
|
||||
let images = []
|
||||
posts.posts.forEach((post, idx) => {
|
||||
let postImages = []
|
||||
if (post.image) postImages.push(post.image)
|
||||
// parse inline images
|
||||
md.parse(post.markdown).forEach(token => {
|
||||
if (token.type === 'image') postImages.push(token.attrs[0][1])
|
||||
if (Array.isArray(token.children)) {
|
||||
token.children.forEach(async child => {
|
||||
if (child.type === 'image') postImages.push(child.attrs[0][1])
|
||||
})
|
||||
}
|
||||
})
|
||||
images.push(Promise.all(postImages.map(image => download(image, config))))
|
||||
})
|
||||
return Promise.all(images)
|
||||
}
|
||||
|
||||
const mapPostPages = async (posts, images, config) => {
|
||||
const postsWithMappedImages = posts.posts.map((post, idx) => Object.assign({}, post, {image: images[idx].pop()}, {images: images[idx]}))
|
||||
const postsWithMappedFields = postsWithMappedImages.map(post => {
|
||||
return {
|
||||
id: post.id,
|
||||
uuid: post.uuid,
|
||||
title: post.title,
|
||||
slug: post.slug,
|
||||
url: post.url,
|
||||
article: !post.page,
|
||||
status: post.status,
|
||||
language: post.language,
|
||||
visibility: post.visibility,
|
||||
meta_title: post.meta_title || post.title,
|
||||
meta_description: post.meta_description,
|
||||
created_at: new Date(post.created_at),
|
||||
created_by: post.created_by,
|
||||
updated_at: new Date(post.updated_at),
|
||||
updated_by: post.updated_by,
|
||||
published_at: new Date(post.published_at),
|
||||
published_by: post.published_by,
|
||||
tags: post.tags,
|
||||
author: post.author,
|
||||
image: post.image,
|
||||
images: post.images,
|
||||
markdown: post.markdown
|
||||
}
|
||||
})
|
||||
return postsWithMappedFields
|
||||
}
|
||||
|
||||
// fetch ghost posts
|
||||
const getPosts = async config => {
|
||||
const loadPosts = () => {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
const token = await getToken(config)
|
||||
const postsReqOptions = {
|
||||
host: config.ghost.host,
|
||||
path: `${GLITCH_API_ROOT}posts/?status=all&staticPages=all&include=tags&limit=30`,
|
||||
headers: {
|
||||
'authorization': `Bearer ${token.access_token}`,
|
||||
'accept': 'application/json'}}
|
||||
const data = new Stream()
|
||||
const res = await httpsGetAsync(postsReqOptions)
|
||||
res.on('data', chunk => data.push(chunk))
|
||||
res.on('end', parseJSONData.bind(null, data, resolve, reject))
|
||||
})
|
||||
}
|
||||
const posts = await loadPosts()
|
||||
const images = await downloadImages(posts, config)
|
||||
return mapPostPages(posts, images, config)
|
||||
}
|
||||
|
||||
module.exports.getPosts = getPosts
|
||||
Reference in New Issue
Block a user