0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-10 23:36:14 -05:00

Regenerated HTML for posts containing a product or video card

refs https://github.com/TryGhost/Toolbox/issues/309
refs https://github.com/TryGhost/Ghost/issues/14344

- this migration will regenerate the HTML for posts that contain a
  product or video card as we experiencing a bug in the card generation
- this migration is mostly ripped from c0d82122b0/core/server/data/migrations/versions/4.0/23-regenerate-posts-html.js
This commit is contained in:
Daniel Lockyer 2022-05-10 09:49:38 +01:00
parent ada0e7975b
commit bb9a797283

View file

@ -0,0 +1,70 @@
const logging = require('@tryghost/logging');
const {createIrreversibleMigration} = require('../../utils');
const mobiledocLib = require('../../../../lib/mobiledoc');
const htmlToPlaintext = require('../../../../../shared/html-to-plaintext');
module.exports = createIrreversibleMigration(async (knex) => {
logging.info(`Starting regeneration of posts HTML`);
await knex.transaction(async (trx) => {
// get list of posts ids, use .forUpdate to lock rows until the transaction is finished
const postIdRows = await knex('posts')
.transacting(trx)
.forUpdate()
.select('id')
.where('mobiledoc', 'like', '%["video%')
.orWhere('mobiledoc', 'like', '%["product%');
logging.info(`Updating HTML for ${postIdRows.length} posts`);
// transform each post individually to avoid dumping all posts into memory and
// pushing all queries into the query builder buffer in parallel
// https://stackoverflow.com/questions/54105280/how-to-loop-through-multi-line-sql-query-and-use-them-in-knex-transactions
// eslint-disable-next-line no-restricted-syntax
for (const postIdRow of postIdRows) {
const {id} = postIdRow;
const [post] = await knex('posts')
.transacting(trx)
.where({id})
.select('mobiledoc', 'html', 'plaintext');
let mobiledoc;
try {
mobiledoc = JSON.parse(post.mobiledoc || null);
if (!mobiledoc) {
logging.warn(`No mobiledoc for ${id}. Skipping.`);
continue;
}
} catch (err) {
logging.warn(`Invalid JSON structure for ${id}. Skipping`);
continue;
}
const html = mobiledocLib.mobiledocHtmlRenderer.render(mobiledoc);
const updatedAttrs = {
html
};
if (html !== post.html || !post.plaintext) {
const plaintext = htmlToPlaintext(html);
if (plaintext !== post.plaintext) {
updatedAttrs.plaintext = plaintext;
}
}
await knex('posts')
.transacting(trx)
.where({id})
.update(updatedAttrs);
}
return 'transaction complete';
});
logging.info('Finished regeneration of posts HTML');
});