Page MenuHomec4science

myTpPlugin.js
No OneTemporary

File Metadata

Created
Sun, Dec 22, 10:13

myTpPlugin.js

const { JSDOM } = require("jsdom");
const axios = require("axios");
const fs = require("fs");
const path = require("path");
const mkdirp = require("mkdirp");
const chalk = require("chalk");
const debug = require("debug")("tei-publisher");
const { DateTime } = require("luxon");
const { AssetCache } = require("@11ty/eleventy-fetch");
const { TpPlugin } = require("@teipublisher/pb-eleventy-plugin/plugin");
function log(input, ...messages) {
console.log(`${chalk.cyan('[nietzsche-dm]')} ${input}`, ...messages);
}
function warn(input, ...messages) {
console.warn(`${chalk.red('[tei-publisher]')} ${input}`, ...messages);
}
function computeKey(params) {
const encParams = [];
Object.keys(params).sort().forEach((key) => {
encParams.push(`${key}=${params[key]}`);
});
//log('Compute key %s with params %s', JSON.stringify(encParams), JSON.stringify(params))
return encParams.join('&');
}
function getAttributes(elem, attributes, properties) {
attributes.forEach((attr) => {
if (elem.hasAttribute(attr)) {
if (attr === 'odd') {
properties[attr] = `${elem.getAttribute(attr)}.odd`;
} else {
properties[attr] = elem.getAttribute(attr);
}
}
});
return properties;
}
function getParameters(elem, properties) {
const params = elem.querySelectorAll('pb-param');
params.forEach((param) => {
properties[`user.${param.getAttribute('name')}`] = param.getAttribute('value');
});
return properties;
}
function createOutputDir(context) {
const outputDir = path.dirname(context.outputPath);
if (!fs.existsSync(outputDir)) {
mkdirp.sync(outputDir);
}
return {...context, ...{ outputDir }};
}
class MyPlugin extends TpPlugin {
constructor(config) {
super(config);
}
async post(url, data) {
log(`Posting data %s to %s`, chalk.white(JSON.stringify(data)), chalk.magenta(url))
const response = await this.client.post(url, data, {
headers: {
'Content-Type': 'application/json'
}
}).catch(function (error) {
const err = error.toJSON();
debug('Failed to post data %s from %s: %s', chalk.bgRed(url), err.config.url, err.message);
});
if (!response) {
return `Failed to post ${url}`;
}
return response.data;
}
/**
*
* @param {string} content HTML content as string
* @param {Context} context context of the current request
* @returns
*/
async transform(content, context) {
const dom = JSDOM.fragment(content);
const views = [...dom.querySelectorAll('pb-view')];
if (views.length > 0) {
debug('Found %s views in page %s', chalk.blue(views.length), context.outputPath);
context = createOutputDir(context);
let componentsChanged = false;
const mapping = {};
const mapFile = path.resolve(context.outputDir, 'index.json');
let oldMap = {};
if (fs.existsSync(mapFile)) {
oldMap = JSON.parse(fs.readFileSync(mapFile));
}
for (let i = 0; i < views.length; i++) {
const component = views[i].id || `_v${1 + i}`;
let params = {};
const srcDoc = views[i].getAttribute('src');
let docPath = '';
if (!srcDoc) {
debug('No src attribute set for component %s in %s', chalk.blue(component), chalk.green(context.inputPath));
continue;
}
const doc = dom.getElementById(srcDoc);
docPath = doc.getAttribute('path');
const meta = await this._loadMeta(docPath);
if (!meta) {
throw new Error(`Failed to load metadata for ${docPath}`);
}
const lastModified = DateTime.fromISO(meta.lastModified);
const firstPageData = path.join(context.outputDir, `${component}-1.json`);
if (fs.existsSync(firstPageData)) {
const fileStat = fs.statSync(firstPageData);
if (lastModified < DateTime.fromMillis(fileStat.mtimeMs)) {
debug('Skipping component %s for %s as it is unchanged', chalk.blue(component), chalk.magenta(docPath));
const testRegex = new RegExp(`^${component}-`);
for (const [key, value] of Object.entries(oldMap)) {
if (testRegex.test(value)) {
mapping[key] = value;
}
}
continue;
}
}
if (meta.odd) {
params.odd = meta.odd;
}
if (meta.view) {
params.view = meta.view;
}
getAttributes(doc, ['view', 'map', 'view'], params);
getParameters(views[i], getAttributes(views[i], ['view', 'map', 'xpath'], params));
this._checkCSS(params, context);
log('Retrieving %s for %s', chalk.blue(component), chalk.magenta(docPath));
let next = null;
let counter = 1;
const images = [];
do {
next = await this._retrieve(component, docPath, params, context, mapping, next, counter, images);
counter += 1;
if (this.config.limit && counter > this.config.limit) {
break;
}
} while(next);
await this._loadImages(images, context.outputDir, `${this.config.remote}${docPath}`);
componentsChanged = true;
}
fs.writeFileSync(mapFile, JSON.stringify(mapping, null, 4));
if (componentsChanged) {
this._index(context);
}
}
return content; // no change done.
}
async _checkCSS(params, context) {
let odd = (params['user.odd']) ? params['user.odd'] : params.odd
log('Checking css %s for %s', chalk.blue(odd), chalk.magenta(JSON.stringify(params)));
if (odd) {
if (!fs.existsSync(context.baseDir)) {
mkdirp.sync(context.baseDir)
}
const file = `${odd.substring(0, odd.length - 4)}.css`;
const url = `transform/${file}`;
const outDir = path.resolve(context.baseDir, 'css');
mkdirp.sync(outDir);
const outFile = path.resolve(outDir, file);
if (!fs.existsSync(outFile)) {
this.client.request({
url,
method: 'get'
})
.then((response) => {
fs.writeFileSync(outFile, response.data);
})
.catch(function (error) {
const err = error.toJSON();
debug('Failed to load CSS from %s: %s', chalk.bgRed(err.config.url), err.message);
});
}
}
}
}
module.exports = { MyPlugin };

Event Timeline