8db947cd24
refs: 5f90baf6fe
- Ghost has a character limit on post slugs of 191 characters,
- Sometimes, the slug that is generated from the title in Revue content is longer than this, causing the import to fail.
- This PR trims that generated post slug to 190 characters.
129 lines
3.4 KiB
JavaScript
129 lines
3.4 KiB
JavaScript
const debug = require('@tryghost/debug')('importer:revue');
|
|
const {slugify} = require('@tryghost/string');
|
|
const papaparse = require('papaparse');
|
|
const _ = require('lodash');
|
|
|
|
const JSONToHTML = require('../lib/json-to-html');
|
|
|
|
/**
|
|
* Build posts out of the issue and item data
|
|
*
|
|
* @param {Object} revueData
|
|
* @return {Array}
|
|
*/
|
|
const fetchPostsFromData = (revueData) => {
|
|
const itemData = JSON.parse(revueData.items);
|
|
const issueData = papaparse.parse(revueData.issues, {
|
|
header: true,
|
|
skipEmptyLines: true,
|
|
transform(value, header) {
|
|
if (header === 'id') {
|
|
return parseInt(value);
|
|
}
|
|
return value;
|
|
}
|
|
});
|
|
|
|
const posts = [];
|
|
|
|
issueData.data.forEach((postMeta) => {
|
|
// Convert issues to posts
|
|
if (!postMeta.subject) {
|
|
return;
|
|
}
|
|
|
|
const revuePostID = postMeta.id;
|
|
let postHTML = JSONToHTML.cleanCsvHTML(postMeta.description);
|
|
|
|
const postItems = _.filter(itemData, {issue_id: revuePostID});
|
|
const sortedPostItems = _.sortBy(postItems, o => o.order);
|
|
|
|
if (postItems) {
|
|
const convertedItems = JSONToHTML.itemsToHtml(sortedPostItems);
|
|
postHTML = `${postHTML}${convertedItems}`;
|
|
}
|
|
|
|
const postDate = JSONToHTML.getPostDate(postMeta);
|
|
const postSlug = slugify(postMeta.subject).slice(0, 190);
|
|
|
|
posts.push({
|
|
comment_id: revuePostID,
|
|
title: postMeta.subject,
|
|
slug: postSlug,
|
|
status: JSONToHTML.getPostStatus(postMeta),
|
|
visibility: 'public',
|
|
created_at: postDate,
|
|
published_at: postDate,
|
|
updated_at: postDate,
|
|
html: postHTML
|
|
});
|
|
});
|
|
|
|
return posts;
|
|
};
|
|
|
|
/**
|
|
*
|
|
* @param {*} revueData
|
|
*/
|
|
const buildSubscriberList = (revueData) => {
|
|
const subscribers = [];
|
|
|
|
const subscriberData = papaparse.parse(revueData.subscribers, {
|
|
header: true,
|
|
skipEmptyLines: true
|
|
});
|
|
|
|
subscriberData.data.forEach((subscriber) => {
|
|
subscribers.push({
|
|
email: subscriber.email,
|
|
name: `${subscriber.first_name} ${subscriber.last_name}`.trim(),
|
|
created_at: subscriber.created_at,
|
|
subscribed: true
|
|
});
|
|
});
|
|
|
|
return subscribers;
|
|
};
|
|
|
|
const RevueImporter = {
|
|
type: 'revue',
|
|
preProcess: function (importData) {
|
|
debug('preProcess');
|
|
importData.preProcessedByRevue = true;
|
|
|
|
// TODO: this should really be in doImport
|
|
// No posts to prePprocess, return early
|
|
if (!importData?.revue?.revue?.issues) {
|
|
return importData;
|
|
}
|
|
|
|
// This processed data goes to the data importer
|
|
importData.data = {
|
|
meta: {version: '5.0.0'},
|
|
data: {}
|
|
};
|
|
|
|
importData.data.data.posts = this.importPosts(importData.revue.revue);
|
|
|
|
// No subscribers to import, we're done
|
|
if (!importData?.revue?.revue?.subscribers) {
|
|
return importData;
|
|
}
|
|
|
|
importData.data.data.revue_subscribers = this.importSubscribers(importData.revue.revue);
|
|
|
|
return importData;
|
|
},
|
|
doImport: function (importData) {
|
|
debug('doImport');
|
|
|
|
return importData;
|
|
},
|
|
|
|
importPosts: fetchPostsFromData,
|
|
importSubscribers: buildSubscriberList
|
|
};
|
|
|
|
module.exports = RevueImporter;
|