Added WebMentions to data generator

closes: https://github.com/TryGhost/Toolbox/issues/509
closes: https://github.com/TryGhost/Toolbox/issues/507
This commit is contained in:
Sam Lord 2023-01-23 12:47:10 +00:00 committed by Sam Lord
parent 90ad60dd85
commit 24bdcf5e9d
4 changed files with 102 additions and 54 deletions

View File

@ -1,5 +1,6 @@
const Command = require('./command');
const DataGenerator = require('@tryghost/data-generator');
const config = require('../shared/config');
module.exports = class REPL extends Command {
setup() {
@ -39,7 +40,8 @@ module.exports = class REPL extends Command {
fatal: this.fatal,
debug: this.debug
},
modelQuantities: {}
modelQuantities: {},
baseUrl: config.getSiteUrl()
});
try {
await dataGenerator.importData();

View File

@ -1,3 +1,4 @@
const tables = require('./tables');
const {
PostsImporter,
NewslettersImporter,
@ -22,8 +23,9 @@ const {
MembersStripeCustomersSubscriptionsImporter,
MembersPaidSubscriptionEventsImporter,
MembersSubscriptionCreatedEventsImporter,
MembersSubscribeEventsImporter
} = require('./tables');
MembersSubscribeEventsImporter,
MentionsImporter
} = tables;
const path = require('path');
const fs = require('fs/promises');
const {faker} = require('@faker-js/faker');
@ -37,6 +39,7 @@ const {getProcessRoot} = require('@tryghost/root-utils');
* @property {Object} schema
* @property {Object} logger
* @property {Object} modelQuantities
* @property {string} baseUrl
*/
const defaultQuantities = {
@ -61,7 +64,8 @@ class DataGenerator {
knex,
schema,
logger,
modelQuantities = {}
modelQuantities = {},
baseUrl
}) {
this.useBaseData = baseDataPack !== '';
this.baseDataPack = baseDataPack;
@ -69,6 +73,7 @@ class DataGenerator {
this.schema = schema;
this.logger = logger;
this.modelQuantities = Object.assign({}, defaultQuantities, modelQuantities);
this.baseUrl = baseUrl;
}
async importData() {
@ -185,7 +190,7 @@ class DataGenerator {
});
posts = await postsImporter.import({
amount: this.modelQuantities.posts,
rows: ['newsletter_id']
rows: ['newsletter_id', 'published_at', 'slug']
});
const tagsImporter = new TagsImporter(transaction, {
@ -317,6 +322,10 @@ class DataGenerator {
const membersSubscriptionCreatedEventsImporter = new MembersSubscriptionCreatedEventsImporter(transaction, {subscriptions});
await membersSubscriptionCreatedEventsImporter.importForEach(membersStripeCustomersSubscriptions, {amount: 1});
const mentionsImporter = new MentionsImporter(transaction, {baseUrl: this.baseUrl});
// Generate up to 4 webmentions per post
await mentionsImporter.importForEach(posts, {amount: 4});
// TODO: Emails! (relies on posts & newsletters)
// TODO: Email clicks - redirect, members_click_events (relies on emails)
@ -331,3 +340,4 @@ class DataGenerator {
}
module.exports = DataGenerator;
module.exports.tables = tables;

View File

@ -1,51 +1,27 @@
const PostsImporter = require('./posts');
const NewslettersImporter = require('./newsletters');
const UsersImporter = require('./users');
const PostsAuthorsImporter = require('./posts-authors');
const TagsImporter = require('./tags');
const PostsTagsImporter = require('./posts-tags');
const ProductsImporter = require('./products');
const MembersImporter = require('./members');
const BenefitsImporter = require('./benefits');
const ProductsBenefitsImporter = require('./products-benefits');
const MembersProductsImporter = require('./members-products');
const PostsProductsImporter = require('./posts-products');
const MembersNewslettersImporter = require('./members-newsletters');
const MembersCreatedEventsImporter = require('./members-created-events');
const MembersLoginEventsImporter = require('./members-login-events');
const MembersStatusEventsImporter = require('./members-status-events');
const StripeProductsImporter = require('./stripe-products');
const StripePricesImporter = require('./stripe-prices');
const SubscriptionsImporter = require('./subscriptions');
const MembersStripeCustomersImporter = require('./members-stripe-customers');
const MembersStripeCustomersSubscriptionsImporter = require('./members-stripe-customers-subscriptions');
const MembersPaidSubscriptionEventsImporter = require('./members-paid-subscription-events');
const MembersSubscriptionCreatedEventsImporter = require('./members-subscription-created-events');
const MembersSubscribeEventsImporter = require('./members-subscribe-events');
module.exports = {
PostsImporter,
NewslettersImporter,
UsersImporter,
PostsAuthorsImporter,
TagsImporter,
PostsTagsImporter,
ProductsImporter,
MembersImporter,
BenefitsImporter,
ProductsBenefitsImporter,
MembersProductsImporter,
PostsProductsImporter,
MembersNewslettersImporter,
MembersCreatedEventsImporter,
MembersLoginEventsImporter,
MembersStatusEventsImporter,
StripeProductsImporter,
StripePricesImporter,
SubscriptionsImporter,
MembersStripeCustomersImporter,
MembersStripeCustomersSubscriptionsImporter,
MembersPaidSubscriptionEventsImporter,
MembersSubscriptionCreatedEventsImporter,
MembersSubscribeEventsImporter
PostsImporter: require('./posts'),
NewslettersImporter: require('./newsletters'),
UsersImporter: require('./users'),
PostsAuthorsImporter: require('./posts-authors'),
TagsImporter: require('./tags'),
PostsTagsImporter: require('./posts-tags'),
ProductsImporter: require('./products'),
MembersImporter: require('./members'),
BenefitsImporter: require('./benefits'),
ProductsBenefitsImporter: require('./products-benefits'),
MembersProductsImporter: require('./members-products'),
PostsProductsImporter: require('./posts-products'),
MembersNewslettersImporter: require('./members-newsletters'),
MembersCreatedEventsImporter: require('./members-created-events'),
MembersLoginEventsImporter: require('./members-login-events'),
MembersStatusEventsImporter: require('./members-status-events'),
StripeProductsImporter: require('./stripe-products'),
StripePricesImporter: require('./stripe-prices'),
SubscriptionsImporter: require('./subscriptions'),
MembersStripeCustomersImporter: require('./members-stripe-customers'),
MembersStripeCustomersSubscriptionsImporter: require('./members-stripe-customers-subscriptions'),
MembersPaidSubscriptionEventsImporter: require('./members-paid-subscription-events'),
MembersSubscriptionCreatedEventsImporter: require('./members-subscription-created-events'),
MembersSubscribeEventsImporter: require('./members-subscribe-events'),
MentionsImporter: require('./mentions')
};

View File

@ -0,0 +1,60 @@
const TableImporter = require('./base');
const {faker} = require('@faker-js/faker');
const generateEvents = require('../utils/event-generator');
const {luck} = require('../utils/random');
const dateToDatabaseString = require('../utils/database-date');
class WebMentionsImporter extends TableImporter {
constructor(knex, {baseUrl}) {
super('mentions', knex);
this.baseUrl = baseUrl;
}
setImportOptions({model, amount}) {
this.model = model;
// Most web mentions published soon after publication date
const startDate = new Date(this.model.published_at);
// End date should be either 1 year after post is published, or current date, whichever is first
const endDate = new Date(Math.min(new Date().valueOf(), new Date(startDate).setFullYear(startDate.getFullYear() + 1)));
this.timestamps = generateEvents({
shape: 'ease-out',
trend: 'negative',
total: amount,
startTime: startDate,
endTime: endDate
}).sort();
}
generate() {
if (luck(50)) {
// 50/50 chance of having a web mention
return null;
}
const id = faker.database.mongodbObjectId();
const timestamp = this.timestamps.shift();
const author = `${faker.name.fullName()}`;
return {
id,
source: `${faker.internet.url()}/${faker.helpers.slugify(`${faker.word.adjective()} ${faker.word.noun()}`).toLowerCase()}`,
source_title: faker.lorem.sentence(5),
source_site_title: `${author}'s ${faker.word.noun()}`,
source_excerpt: faker.lorem.paragraph(),
source_author: author,
source_featured_image: 'https://via.placeholder.com/650x150.png',
source_favicon: 'https://via.placeholder.com/32x32.png',
target: `${this.baseUrl}${this.model.slug}/`,
resource_id: this.model.id,
resource_type: 'post', // TODO: Randomise resource type - should also include pages
created_at: dateToDatabaseString(timestamp),
payload: JSON.stringify({
// TODO: Add some random payload
})
};
}
}
module.exports = WebMentionsImporter;