mirror of
https://gitlab.com/octtspacc/sitoctt
synced 2025-06-05 22:09:20 +02:00
Nuovo post: 🎄 Distrazioni di Natale: l'albero Padoru; Agg vari
This commit is contained in:
@ -1,20 +1,18 @@
|
||||
#!/usr/bin/env -S node --experimental-fetch
|
||||
const fs = require('fs');
|
||||
const JSDOM = require('jsdom').JSDOM;
|
||||
const ConfigParser = require("./Lib/config-ini-parser").ConfigIniParser;
|
||||
const ConfigParser = require('./Lib/config-ini-parser').ConfigIniParser;
|
||||
|
||||
const BlogURL = 'https://listed.to/@u8'; // Full base URL of the Listed blog (any server)
|
||||
const SiteName = 'sitoctt';
|
||||
//const DefaultMode = 'Include' // 'Include' or 'Exclude' | Not implemented
|
||||
const PostsFileDate = true; // Append dates (YYYY-MM-DD) to posts file names
|
||||
const Replacements = { // Format: { ReplaceWithString: [ToFindString] }
|
||||
"## [:HNotesRefsHTML:]": "<h2>🏷️ Note e Riferimenti</h2>",
|
||||
"<h2>[:HNotesRefsHTML:]</h2>": "<h2>🏷️ Note e Riferimenti</h2>",
|
||||
'<div class="footnotes">': ['<div class="footnotes"><hr>', '<div class="footnotes">\n<hr>'],
|
||||
"<a href=\"[staticoso:CustomPath:Assets]/": "<a href=\"https://sitoctt-assets.octt.eu.org/",
|
||||
"<img src=\"[staticoso:CustomPath:Assets]/": "<img src=\"https://sitoctt-assets.octt.eu.org/",
|
||||
// TODO: Fix anchor rels
|
||||
"# ": "<h1>", "## ": "<h2>", "### ": "<h3>", "#### ": "<h4>", "##### ": "<h5>", "###### ": "<h6>",
|
||||
"": ["</h1>", "</h2>", "</h3>", "</h4>", "</h5>", "</h6>"],
|
||||
// staticoso TODO: Fix the handling of headings to remove this crap above...
|
||||
};
|
||||
|
||||
const MetadataBlockSelect = '.MetadataBlock, .MetadataBlock + :Where(Div, Pre, Code)';
|
||||
@ -25,6 +23,7 @@ const TryReadFileSync = Path => {
|
||||
return fs.readFileSync(Path, 'utf8');
|
||||
};
|
||||
};
|
||||
|
||||
const TryMkdirSync = Path => {
|
||||
if (!fs.existsSync(Path)) {
|
||||
return fs.mkdirSync(Path, {recursive: true});
|
||||
@ -41,26 +40,28 @@ const GetPath = URL => {
|
||||
const GetFragHTML = Frag => {
|
||||
let Dom = new JSDOM('<body></body>');
|
||||
Dom.window.document.body.appendChild(Frag);
|
||||
return Dom.window.document.body.innerHTML;
|
||||
return Dom.window.document.body.innerHTML.trim();
|
||||
};
|
||||
|
||||
const CheckDoDownsync = File => {
|
||||
let DoDownsync = true;
|
||||
const TryFile = TryReadFileSync(File);
|
||||
if (TryFile) {
|
||||
const Lines = TryFile.trim().toLowerCase().split('\n');
|
||||
const CheckDownsync = Body => {
|
||||
if (Body) {
|
||||
const Lines = Body.trim().toLowerCase().split('\n');
|
||||
for (let i=0; i<Lines.length; i++) {
|
||||
const Line = Lines[i].trim().replaceAll(' ', ' ').replaceAll(':', ' : ').replaceAll('=', ' = ');
|
||||
if (Line.startsWith('// ')) {
|
||||
const Tokens = Line.split(' ').filter(i => {return i != ''});
|
||||
if (Tokens[1] == '%' && Tokens[2] == 'downsync' && [':', '='].includes(Tokens[3]) && ['false', 'disabled', 'off', 'no'].includes(Tokens[4])) {
|
||||
DoDownsync = false;
|
||||
break;
|
||||
const Line = Lines[i].trim()
|
||||
const CheckLine = Line.replaceAll(' ', ' ').replaceAll(':', ' : ').replaceAll('=', ' = ');
|
||||
if (CheckLine.startsWith('// ')) {
|
||||
const Tokens = CheckLine.split(' ').filter(i => {return i != ''});
|
||||
if (Tokens[1] == '%' && Tokens[2] == 'downsync' && [':', '='].includes(Tokens[3])) {
|
||||
if (['false', 'disabled', 'off', 'no'].includes(Tokens[4])) {
|
||||
return false;
|
||||
} else if (Tokens[4].startsWith('/')) {
|
||||
return Line.substring(Line.indexOf('/', 2));
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
return DoDownsync;
|
||||
return true;
|
||||
};
|
||||
|
||||
const GetLinkElem = Dom => {
|
||||
@ -73,8 +74,8 @@ const GetLinkElem = Dom => {
|
||||
};
|
||||
|
||||
const ParseMeta = Raw => {
|
||||
let Mid = {"Meta": "", "Macros": ""};
|
||||
let Data = {"Meta": {}, "Macros": {}};
|
||||
let Mid = {'Meta': '', 'Macros': ''};
|
||||
let Data = {'Meta': {}, 'Macros': {}};
|
||||
const Lines = Raw.trim().split('\n');
|
||||
for (let i=0; i<Lines.length; i++) {
|
||||
let Type;
|
||||
@ -123,8 +124,8 @@ const MakeMetaStr = Post => {
|
||||
};
|
||||
|
||||
const HandlePost = PostSrc => {
|
||||
let LinkElem, ContentDom;
|
||||
let Post = {"Meta": {}, "Macros": {}};
|
||||
let ContentDom, LinkPath;
|
||||
let Post = {'Meta': {}, 'Macros': {}};
|
||||
|
||||
Post.Meta.Title = PostSrc.title;
|
||||
Post.Meta.CreatedOn = PostSrc.created_at.split('T')[0];
|
||||
@ -133,29 +134,46 @@ const HandlePost = PostSrc => {
|
||||
|
||||
ContentDom = JSDOM.fragment(Post.Content);
|
||||
|
||||
LinkElem = GetLinkElem(ContentDom);
|
||||
if (!LinkElem) { // Post content has no mirror-flagging element, skip it
|
||||
// TODO: Exclusion mode instead of inclusion? Aka automatically handle posts without the element
|
||||
// TODO: Check flagging via MetadataBlock?
|
||||
console.log(`[I] : No mirror flag in source body; Skipping!`);
|
||||
return;
|
||||
// Handle MetadataBlock elements
|
||||
let MetadataBlocks = ContentDom.querySelectorAll(MetadataBlockSelect);
|
||||
for (let i=0; i<MetadataBlocks.length; i++) {
|
||||
const Elem = MetadataBlocks[i];
|
||||
if (Elem.textContent) {
|
||||
const Meta = ParseMeta(Elem.textContent);
|
||||
Post.Meta = Object.assign(Post.Meta, Meta.Meta);
|
||||
Post.Macros = Object.assign(Post.Macros, Meta.Macros);
|
||||
};
|
||||
MetadataBlocks[i].outerHTML = '';
|
||||
};
|
||||
const LinkPath = GetPath(JSDOM.fragment(LinkElem.outerHTML).querySelector('[href]').href);
|
||||
// NOTE: Maybe would be better to first do string replacements?
|
||||
|
||||
/*
|
||||
// Get post categories
|
||||
Post.Categories = '';
|
||||
const Classes = LinkElem.classList;
|
||||
for (let i=0; i<Classes.length; i++) {
|
||||
const Class = Classes[i];
|
||||
const Key = `Mirror-${SiteName}-Categories-`;
|
||||
if (Class.startsWith(Key)) {
|
||||
Post['Categories'] = '// % Categories = ' + Class.substring(Key.length).replaceAll('|', ' ');
|
||||
let LinkElem = GetLinkElem(ContentDom);
|
||||
if (LinkElem) {
|
||||
LinkPath = GetPath(JSDOM.fragment(LinkElem.outerHTML).querySelector('[href]').href);
|
||||
LinkElem.outerHTML = '';
|
||||
} else {
|
||||
let Check = Post.Meta.Downsync;
|
||||
if (typeof(Check) == 'string' && Check.startsWith('/')) {
|
||||
LinkPath = Check.substring(1);
|
||||
} else {
|
||||
console.log(`[I] : No Downsync flag set with URL in source body; Skipping!`);
|
||||
return;
|
||||
};
|
||||
};
|
||||
*/
|
||||
|
||||
Post.Content = GetFragHTML(ContentDom);
|
||||
|
||||
const PathFile = LinkPath.split('/').slice(-1)[0];
|
||||
const PathDir = LinkPath.split('/').slice(0, (LinkPath.split('/').length - 1)).join('/');
|
||||
const DatePrefix = PostsFileDate ? Post.Meta.CreatedOn + '-' : '';
|
||||
const FinalFilePath = `${PathDir}/${DatePrefix}${PathFile.substring(0, (PathFile.length - 4))}md`;
|
||||
if (!CheckDownsync(TryReadFileSync(FinalFilePath))) {
|
||||
console.log(`[I] : Downsync disabled in destination body; Skipping!`);
|
||||
return;
|
||||
};
|
||||
|
||||
// Do string replacements
|
||||
// TODO: Replacements written in post body?
|
||||
const ReplacementsKeys = Object.keys(Replacements);
|
||||
for (let i=0; i<ReplacementsKeys.length; i++) {
|
||||
const To = ReplacementsKeys[i];
|
||||
@ -170,22 +188,8 @@ const HandlePost = PostSrc => {
|
||||
|
||||
ContentDom = JSDOM.fragment(Post.Content);
|
||||
|
||||
LinkElem = GetLinkElem(ContentDom);
|
||||
LinkElem.outerHTML = '';
|
||||
|
||||
// Handle MetadataBlock elements
|
||||
let MetadataBlocks = ContentDom.querySelectorAll(MetadataBlockSelect);
|
||||
for (let i=0; i<MetadataBlocks.length; i++) {
|
||||
const Elem = MetadataBlocks[i];
|
||||
if (Elem.textContent) {
|
||||
const Meta = ParseMeta(Elem.textContent);
|
||||
Post.Meta = Object.assign(Post.Meta, Meta.Meta);
|
||||
Post.Macros = Object.assign(Post.Macros, Meta.Macros);
|
||||
};
|
||||
MetadataBlocks[i].outerHTML = '';
|
||||
};
|
||||
|
||||
// Handle ExtractCodeBlock elements
|
||||
// TODO: Opposite of extract blocks? (Allowing some HTML to remain on Listed but get deleted from here)
|
||||
let ExtCodeBlocks = ContentDom.querySelectorAll(ExtractCodeBlockSelect);
|
||||
for (let i=0; i<ExtCodeBlocks.length; i++) {
|
||||
const Elem = ExtCodeBlocks[i];
|
||||
@ -197,21 +201,12 @@ const HandlePost = PostSrc => {
|
||||
};
|
||||
};
|
||||
|
||||
Post.Content = GetFragHTML(ContentDom).trim();
|
||||
|
||||
const PathFile = LinkPath.split('/').slice(-1)[0];
|
||||
const PathDir = LinkPath.split('/').slice(0, (LinkPath.split('/').length - 1)).join('/');
|
||||
const FinalFilePath = `${PathDir}/${PostsFileDate ? Post.Meta.CreatedOn + '-' : ''}${PathFile.substring(0, (PathFile.length - 4))}md`;
|
||||
|
||||
if (!CheckDoDownsync(FinalFilePath)) {
|
||||
console.log(`[I] : Downsync disabled in destination body; Skipping!`);
|
||||
return;
|
||||
};
|
||||
Post.Content = GetFragHTML(ContentDom);
|
||||
|
||||
TryMkdirSync(PathDir);
|
||||
fs.writeFileSync(FinalFilePath, `\
|
||||
${MakeMetaStr(Post)}
|
||||
# ${Post.Meta.HTMLTitle ? Post.Meta.HTMLTitle : Post.Meta.Title}
|
||||
<h1>${Post.Meta.HTMLTitle ? Post.Meta.HTMLTitle : Post.Meta.Title}</h1>
|
||||
|
||||
${Post.Content}
|
||||
`);
|
||||
|
Reference in New Issue
Block a user