osr-mono/packages/osr-discourse/lib/sync/component.js
2025-01-31 14:45:54 +01:00

373 lines
29 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.sync = exports.syncComponent = exports.updatePost = exports.createPost = void 0;
const path = require("path");
const exists_1 = require("@plastichub/fs/exists");
const dir_1 = require("@plastichub/fs/dir");
const write_1 = require("@plastichub/fs/write");
const fs_1 = require("@plastichub/osr-commons");
const bluebird_1 = require("bluebird");
const osrl_1 = require("./osrl");
const YAML = require('json-to-pretty-yaml');
const cheerio = require('cheerio');
const findUp = require('find-up');
const frontMatter = require('front-matter');
const md5 = require('md5');
const download_1 = require("./download");
const markdown_1 = require("../markdown");
const primitives_1 = require("@plastichub/core/primitives");
const _1 = require("./");
const cache_1 = require("../discourse/cache");
const discourse_1 = require("../discourse");
const commons_1 = require("./commons");
const osr_fs_utils_1 = require("@plastichub/osr-fs-utils");
const index_1 = require("../../index");
const osr_cli_commons_1 = require("@plastichub/osr-cli-commons");
const CONTENT_TEST = false;
const SKIP_EXISTING = false;
const createPost = async (discourse, options, content) => {
if (!(0, primitives_1.isNumber)(options.cat)) {
index_1.logger.error(`category not a number! ${options.title} `);
}
let data;
try {
data = await discourse.createPost(options.title, content, options.cat);
}
catch (e) {
debugger;
}
if (data) {
if (data && data.id) {
try {
options.post_id = data.id;
options.topic_id = data.topic_id;
await discourse.changeOwner(options.post_id, options.topic_id, options.user_name);
index_1.logger.debug('created topic : ' + options.title + ' : ' + data.id + ' | topic id :' + data.topic_id);
return true;
}
catch (e) {
index_1.logger.error('changing owner ' + options.title + ' failed!', e);
}
}
else {
index_1.logger.debug('creating ' + options.title + ' failed!', data.errors, data);
if (data.errors) {
if (data.errors[0] && data.errors[0] === 'Title has already been used') {
index_1.logger.error('title already used : ' + options.title);
}
}
}
}
else {
return false;
}
};
exports.createPost = createPost;
const updatePost = async (discourse, options, topic_id, content) => {
let data;
try {
data = await discourse.updatePost(topic_id, content);
index_1.logger.debug('update post : ' + options.title + ' : ' + data.id + ' | topic id ' + data.topic_id);
}
catch (e) {
return false;
}
if (data) {
if (data && data.id) {
try {
// logger.debug('change user to ', options.owner);
options.post_id = data.id;
options.topic_id = data.topic_id;
await new Promise(f => setTimeout(f, 1000));
await discourse.changeOwner(topic_id, topic_id, options.user_name);
return true;
}
catch (e) {
index_1.logger.debug('changing owner ' + options.title + ' failed!');
return false;
}
}
else {
index_1.logger.debug('creating ' + options.title + ' failed!', data.errors);
if (data.errors) {
if (data.errors[0] && data.errors[0] === 'Title has already been used') {
index_1.logger.error('title already used : ' + options.title);
}
return false;
}
}
}
};
exports.updatePost = updatePost;
const uploadImages = async (content, discourse, options) => {
const root = path.resolve((0, fs_1.resolve)(options.root));
if (!(0, exists_1.sync)(root)) {
return false;
}
const track_path = (0, _1.trackingPath)(root);
const track = (0, _1.tracking)(root);
const html = (0, markdown_1.toHTML)(content);
const $ = cheerio.load(html, {
xmlMode: true
});
const images = (0, commons_1.images_urls)(content);
$('img').each(function () {
if ($(this).attr('src') && $(this).attr('src').length > 5) {
images.push($(this).attr('src'));
}
});
for await (const image of Object.entries(images)) {
const url = image[1];
if (url.length < 10) {
continue;
}
if (url.startsWith('upload:')) {
continue;
}
if (options.uploadRemote && url.startsWith('http')) {
const contentHash = md5(content).substring(0, 5);
const cache_path = path.resolve((0, fs_1.resolve)('${OSR_CACHE}/discourse-downloads/' + contentHash));
if (!(0, exists_1.sync)(cache_path)) {
(0, dir_1.sync)(cache_path);
}
const image_name = (0, download_1.imageName)(url);
const image_local = path.join(cache_path, image_name);
if (!(0, exists_1.sync)(image_local)) {
try {
await (0, download_1.downloadFile)(url, cache_path);
}
catch (e) {
continue;
}
}
if (!(0, exists_1.sync)(image_local)) {
continue;
}
if (!track[url]) {
const upped = await discourse.uploadFile(options.owner, image_local);
const data = upped.data;
if (data && data.id) {
track[url] = data;
(0, write_1.sync)(track_path, track);
}
else {
console.error('error uploading image');
}
}
continue;
}
if (options.uploadLocal) {
const image_path = path.join(root, url);
if ((0, exists_1.sync)(image_path) && (!track[url] || options.cache === false)) {
const upped = await discourse.uploadFile(options.owner, image_path);
const data = upped.data;
if (data && data.id) {
track[url] = data;
(0, write_1.sync)(track_path, track);
}
else {
console.error('error uploading image');
}
}
}
}
return track;
};
const syncFile = async (file, options) => {
const discourse = (0, discourse_1.Instance)(null, options.config);
let config = (0, _1.fromJSON)(file, options) || {};
const componentDir = path.parse(file).dir;
// ph3 back sync
const rel = (0, osr_cli_commons_1.forward_slash)(path.relative(options.root, componentDir));
const productConfigPath = path.join(options.product_root, rel, 'config.json');
let body = await (0, osrl_1.createContent)(componentDir, options);
let images_track;
if (options.uploadLocal || options.uploadRemote) {
images_track = await uploadImages(body, discourse, options);
const image_urls = (0, commons_1.images_urls)(body);
image_urls.forEach((i) => {
if (images_track[i]) {
body = body.replace(i, images_track[i].short_url);
}
else {
index_1.logger.warn(`Cant resolve image url : ${i} - ${componentDir} ! Image Upload track invalid`);
}
});
}
index_1.logger.debug(`Processing ${componentDir}`);
const output = path.join(componentDir, '.osr/discourse_raw.md');
let dst = path.resolve((0, fs_1.resolve)(output));
options.debug && index_1.logger.info('Write output to: ', dst);
(0, write_1.sync)(dst, body);
let post_id, topic_id;
let dOpts = {
...options,
cat: config.forumCategory,
id: options.id,
owner: config.forumUserId || 1,
tags: config.forumTags,
title: config.name,
topic_id: config.forumTopicId,
post_id: config.forumPostId
};
options = {
...options,
...dOpts
};
const hash = md5(JSON.stringify({
cat: dOpts.cat,
tags: dOpts.tags,
owner: dOpts.owner,
body,
title: dOpts.title
}, null));
// const cats = await cacheCategories(options, discourse)
// const tags = await cacheTags(options, discourse)
const users = await (0, cache_1.cacheUsers)(options, discourse);
await new Promise(f => setTimeout(f, 1000));
let search = await discourse.search(dOpts.title);
await new Promise(f => setTimeout(f, 2000));
let dTopic;
let dPost;
if (search && search.posts && search.topics) {
search.topics.forEach((t, i) => {
if (t.title === dOpts.title) {
dTopic = t;
dPost = search.posts[i];
topic_id = dTopic.id;
post_id = dPost.id;
}
});
}
if (!dTopic || !dPost) {
console.error('!dTopic || !dPost : cant find ' + dOpts.title);
// return
}
const user = users.find((u) => {
return u.id === dOpts.owner;
});
if (!user) {
index_1.logger.error('Invalid user : ', dOpts.owner);
return false;
}
options.user_name = user.username;
if (SKIP_EXISTING && hash === config.forumPostHash &&
config.forumTopicId && config.forumPostId) {
return;
}
if (CONTENT_TEST) {
return;
}
if (post_id) {
if (await (0, exports.updatePost)(discourse, options, post_id, body)) {
if (topic_id) {
await new Promise(f => setTimeout(f, 2000));
await discourse.updateTopic(topic_id, dOpts.cat, dOpts.title, dOpts.tags ? dOpts.tags.split(',') : []);
}
}
else {
index_1.logger.error(`Error updating post ${dOpts.title}`);
}
}
else {
if (await (0, exports.createPost)(discourse, options, body)) {
await new Promise(f => setTimeout(f, 1000));
await discourse.updateTopic(options.topic_id, dOpts.cat, dOpts.title, dOpts.tags ? dOpts.tags.split(',') : []);
}
else {
index_1.logger.error('Creating post failed !', dOpts.title);
}
}
// const visStatus = await discourse.updateTopicVisibility(topic_id, true)
// re-read without defaults
config = (0, osr_fs_utils_1.readOSRConfig)(file);
config.forumPostHash = hash;
if (dTopic) {
config.forumTopicId = dTopic.id;
}
else if (topic_id) {
config.forumTopicId = topic_id;
}
if (dPost) {
config.forumPostId = dPost.id;
}
else if (post_id) {
config.forumPostId = post_id;
}
(0, write_1.sync)(file, config);
//ph3 products
if ((0, exists_1.sync)(productConfigPath)) {
let pConfig = (0, osr_fs_utils_1.readOSRConfig)(productConfigPath);
index_1.logger.debug(`Updating product config ${productConfigPath}`);
pConfig = {
...config
//...pConfig,
//...
/*
forumTopicId:config.forumTopicId,
forumPostId:config.forumPostId,
forumPostHash: config.forumPostHash
*/
};
(0, write_1.sync)(productConfigPath, pConfig);
}
return body;
};
const syncComponent = async (options) => {
let components = options.srcInfo.FILES.filter(osr_fs_utils_1.isValidLibraryComponent);
//let components = options.srcInfo.FILES.filter((c) => {
//components = components.filter((c) => {
/*
try {
const config = readOSRConfig(c) as IComponentConfig
if (config) {
if (config.forum === false) {
return false
}
// return !config.code && !config.cscartId && !config.steps
return !!config.name
}
return false
} catch (error) {
logger.error(`Invalid config : ${c}`)
}
})*/
const skipExisting = options.skip;
/*
[
"C:/Users/mc007/Desktop/osr/osr-machines/shredder/asterix-pp/config.json",
"C:/Users/mc007/Desktop/osr/osr-machines/shredder/asterix-sm-morren/config.json",
"C:/Users/mc007/Desktop/osr/osr-machines/shredder/bicycle-shredder/config.json",
"C:/Users/mc007/Desktop/osr/osr-machines/shredder/idefix/config.json",
"C:/Users/mc007/Desktop/osr/osr-machines/shredder/obelix/config.json",
"C:/Users/mc007/Desktop/osr/osr-machines/shredder/pp-v3.3/config.json",
"C:/Users/mc007/Desktop/osr/osr-machines/shredder/components/shredder_v21-light-ex/config.json",
"C:/Users/mc007/Desktop/osr/osr-machines/shredder/components/shredder_v31-light/config.json",
]
*/
if (skipExisting) {
components = components.filter((f) => {
const config = (0, osr_fs_utils_1.readOSRConfig)(f);
if (config.forumPostId && config.forumTopicId) {
return false;
}
return true;
});
}
//components = [components[0]]
index_1.logger.info(`Syncing ${components.length} components`, components);
await bluebird_1.Promise.resolve(components).map((f) => {
try {
return syncFile(f, options);
}
catch (error) {
debugger;
}
}, { concurrency: 1 });
};
exports.syncComponent = syncComponent;
const sync = async (options) => {
return (0, exports.syncComponent)(options);
};
exports.sync = sync;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2xpYi9zeW5jL2NvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2QkFBNEI7QUFDNUIsa0RBQXNEO0FBRXRELDRDQUFnRDtBQUNoRCxnREFBb0Q7QUFHcEQsdURBQXdEO0FBRXhELHVDQUE4QztBQUc5QyxpQ0FBc0M7QUFFdEMsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLHFCQUFxQixDQUFDLENBQUE7QUFDM0MsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFBO0FBQ2xDLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQTtBQUNqQyxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUE7QUFDM0MsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFBO0FBRTFCLHlDQUFvRDtBQUVwRCwwQ0FBb0M7QUFDcEMsNERBQXNEO0FBRXRELHlCQUFvRTtBQU9wRSw4Q0FLMkI7QUFHM0IsNENBR3FCO0FBRXJCLHVDQUVrQjtBQVVsQiwyREFBaUY7QUFFakYsdUNBQW9DO0FBQ3BDLGlFQUEyRDtBQUUzRCxNQUFNLFlBQVksR0FBRyxLQUFLLENBQUE7QUFDMUIsTUFBTSxhQUFhLEdBQUcsS0FBSyxDQUFBO0FBRXBCLE1BQU0sVUFBVSxHQUFHLEtBQUssRUFBRSxTQUFxQixFQUFFLE9BQXFCLEVBQUUsT0FBTyxFQUFFLEVBQUU7SUFFdEYsSUFBSSxDQUFDLElBQUEscUJBQVEsRUFBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUU7UUFDeEIsY0FBTSxDQUFDLEtBQUssQ0FBQywwQkFBMEIsT0FBTyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUE7S0FDM0Q7SUFFRCxJQUFJLElBQVMsQ0FBQTtJQUNiLElBQUk7UUFDQSxJQUFJLEdBQUcsTUFBTSxTQUFTLENBQUMsVUFBVSxDQUFD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