Skip to content

Commit

Permalink
Added option to rewrite a specified RSS file
Browse files Browse the repository at this point in the history
  • Loading branch information
NJKode committed Nov 29, 2022
1 parent 0461f3a commit bdd23d9
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 31 deletions.
2 changes: 2 additions & 0 deletions cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ module.exports = {
const destination = flags.dest.replace(/^\/|\/$/g, '');
const baseurl = flags.baseurl.replace(/^\/|\/$/g, '');
const sitemap = (flags.sitemap || 'sitemap.xml').replace(/^\/|\/$/g, '');
const rss = (flags.rss || '').replace(/^\/|\/$/g, '');

const port = this.checkPortNumber(flags.port) || defaultPort;
const split = flags.split || 1;
Expand All @@ -112,6 +113,7 @@ module.exports = {
dest: destination,
baseurl: baseurl,
sitemap: sitemap,
rss: rss,
fullPathToSource: path.resolve(cwd, source),
fullPathToDest: path.resolve(cwd, destination, baseurl)
},
Expand Down
9 changes: 7 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Commands:
clone-assets Clones non CSS and HTML files from src to dest
rewrite-css Clones CSS files from src to dest and rewrites urls to include baseurl
rewrite-html Clones HTML files from src to dest and rewrites attributes to include baseurl
rewrite-sitemap Finds all sitemap files based on index sitemap, and rewrites links to include baseurl
rewrite-sitemap Finds all sitemap files based on index sitemap, and rewrites links to include baseurl
serve Runs 'build' then a local webserver on the dest folder
watch Watches the src folder and triggers builds
Expand All @@ -24,7 +24,8 @@ Options:
-b | --baseurl The base-URL to prepend to the files once copied
-p | --port The portnumber to serve the cloned site on
-e | --extrasrc A list of extra src attributes to be rewritten
-m | --sitemap A path to a valid sitemap file
-m | --sitemap A path to a valid sitemap or sitemapindex file
-r | --rss A path to a valid RSS file
-o | --overwrite When cleaning --dest, don't prompt for confirmation
--split The number of partitions to divide files into
--partition The partition number to process
Expand Down Expand Up @@ -59,6 +60,10 @@ const inputs = meow(
alias: 'e',
isMultiple: true
},
rss: {
type: 'string',
alias: 'r'
},
sitemap: {
type: 'string',
alias: 'm'
Expand Down
21 changes: 16 additions & 5 deletions lib/processors/sitemap.js → lib/processors/xml.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,32 @@ function rewriteXML(xml, baseurl) {
}
});

$('xhtml\\:link').each(function () {
$('link').each(function () {
const $el = $(this);
const originalValue = $el.attr('href');
const originalValue = $el.text();
const updated = rewritePath(baseurl, originalValue);
$el.attr('href', updated);
$el.text(updated);
});

$('[href]').each(function () {
const $el = $(this);
const href = $el.attr('href');
const updated = rewritePath(baseurl, href);

if (updated !== href) {
$el.attr('href', updated);
}
});

return $.xml();
}

module.exports = {
rewrite: rewriteXML,

/** Handles rewriting urls in sitemap(s)
/** Handles rewriting urls in xml(s)
*
* @param {string} file the absolute path to the sitemap file.
* @param {string} file the absolute path to the xml file.
* @param {string} destination the absolute path to the destination directory.
* @param {string} baseurl the baseurl to prepend to the source files.
*/
Expand Down
58 changes: 46 additions & 12 deletions lib/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const { URL } = require('url');

const cssRewrite = require('./processors/css').plugin;
const htmlRewrite = require('./processors/html').plugin;
const sitemapRewrite = require('./processors/sitemap').plugin;
const xmlRewrite = require('./processors/xml').plugin;

const regex = {
css: /\.s?css$/i,
Expand Down Expand Up @@ -88,7 +88,7 @@ module.exports = {
filesByType.css.push(file);
} else if (regex.html.test(ext)) {
filesByType.html.push(file);
} else if (!regex.css.test(ext) && !regex.html.test(ext)) {
} else {
filesByType.other.push(file);
}
});
Expand Down Expand Up @@ -183,14 +183,25 @@ module.exports = {
return 1;
}

const otherFiles = await this.clone_assets(options, sourceFiles.other);
const cloneExitCode = await this.clone_assets(options, sourceFiles.other);
const cssExitCode = await this.rewrite_css(options, sourceFiles.css);
const htmlExitCode = await this.rewrite_html(options, sourceFiles.html);
const sitemapExitCode = await this.rewrite_sitemap(options);

if (!otherFiles || cssExitCode > 1 || htmlExitCode > 1 || sitemapExitCode > 1) {
const rssExitCode = options.paths.rss ? await this.rewrite_rss(options) : 0;

const processExitCode = Math.max(
cloneExitCode || 0,
cssExitCode || 0,
htmlExitCode || 0,
sitemapExitCode || 0,
rssExitCode || 0
);

// Exit code 1 in the function calls above means that there were no files
// of that type to process, so ignorable (i.e. shouldn't halt process).
if (processExitCode > 1) {
log.error('There was an error building your site 😓');
return otherFiles ? Math.max(cssExitCode || 0, htmlExitCode || 0, sitemapExitCode || 0) : 1;
return processExitCode;
}
return 0;
},
Expand All @@ -201,8 +212,7 @@ module.exports = {
*/
clean: async function (options) {
if (!options.flags.overwrite && fs.pathExistsSync(options.paths.dest)) {
const question = `Warning: The destination ${options.paths.dest} already exists.`
+ 'Continuing will delete this folder and everything in it. Do you wish to continue? (Y or N): ';
const question = `Warning: The destination ${options.paths.dest} already exists.\nContinuing will delete this folder and everything in it.\nDo you wish to continue? (Y or N): `;
const isYes = await this._askYesNo(question);
if (!isYes) return 1;
}
Expand All @@ -228,7 +238,7 @@ module.exports = {
const { split, partition } = flags;
files = await getFiles(options.paths.fullPathToSource, {
partition: { split: split, partition: partition },
ignorePatterns: ['/**/*.htm?', '/**/*.css']
ignorePatterns: ['/**/*.htm', '/**/*.html', '/**/*.css', '/**/*.scss']
});
if (!files || !files.length) return 1;
}
Expand All @@ -239,7 +249,7 @@ module.exports = {
return 4;
}

return otherFiles;
return 0;
},

/**
Expand Down Expand Up @@ -356,13 +366,13 @@ module.exports = {

if (options.fromIndex) {
copiedFiles.forEach((file) => {
const exit = sitemapRewrite(file, options.paths.fullPathToDest, options.paths.baseurl);
const exit = xmlRewrite(file, options.paths.fullPathToDest, options.paths.baseurl);
if (exit > 0) return exit; // if error
});
} else {
log('rewriting sitemap...');
const file = copiedFiles[0];
const exit = sitemapRewrite(file, options.paths.fullPathToDest, options.paths.baseurl);
const exit = xmlRewrite(file, options.paths.fullPathToDest, options.paths.baseurl);
if (Array.isArray(exit) && !options.fromIndex) {
options.fromIndex = true;

Expand All @@ -384,6 +394,30 @@ module.exports = {
return 0;
},

/**
* Rewrites <link>s in an RSS file to include baseurl.
*
* @param {Object} options The options object.
* @returns {[String]} The copied files (TODO).
*/
rewrite_rss: async function (options) {
const files = await getFiles(options.paths.fullPathToSource,
{ globPattern: options.paths.rss });
if (!files || !files.length) {
return 1;
}

const copiedFiles = await this._copyFiles(files, options);
if (!copiedFiles) {
return 4;
}

log('rewriting rss feed...');
const file = copiedFiles[0];
const exit = xmlRewrite(file, options.paths.fullPathToDest, options.paths.baseurl);
return exit;
},

/**
* Serves the files on a local webserver, so that they may be viewed on a browser.
*
Expand Down
58 changes: 53 additions & 5 deletions test/runner.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,14 +235,14 @@ describe('build', function () {
before(function () {
cleanStub.returns([]);
fetchStub.returns([]);
cloneAssetsStub.returns();
cloneAssetsStub.returns(2);
rewriteCssStub.returns(0);
rewriteHtmlStub.returns(0);
});

it('should return with exit code 1', async function () {
const result = await runner.build(testOp);
expect(result).to.equal(1);
expect(result).to.equal(2);
});
});

Expand Down Expand Up @@ -372,9 +372,9 @@ describe('clone-assets', function () {
});

context('Cloning from a valid directory', function () {
it('should return the cloned files', async function () {
const results = await runner.clone_assets(testOp);
expect(results.length).to.equal(2);
it('should return exit code 0', async function () {
const result = await runner.clone_assets(testOp);
expect(result).to.equal(0);
});
});

Expand Down Expand Up @@ -604,6 +604,54 @@ describe('rewrite_sitemap()', function () {
});
});

describe('rewrite_rss()', function () {
context('no rss feed', function () {
it('should return error exit code (1)', async function () {
const results = await runner.rewrite_rss(testOp);
expect(results).to.equal(1);
});
});

context('Uses rss file', function () {
before(function () {
mock({
'test/src': {
'index.xml': `<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Site title</title>
<link>http://example.org/testBaseurl/</link>
<description>Site description</description>
<generator>Generator</generator>
<language>en-us</language>
<lastBuildDate>Fri, 12 Aug 2016 00:00:00 +0000</lastBuildDate><atom:link href="http://example.org/testBaseurl/index.xml" rel="self" type="application/rss+xml"/>
<item>
<title>Advice</title>
<link>http://example.org/testBaseurl/advice/</link>
<pubDate>Fri, 12 Aug 2016 00:00:00 +0000</pubDate>
<guid>http://example.org/advice/</guid>
<description>Advice</description>
</item>
</channel>
</rss>`
}
});
});

it('should return exit code 0', async function () {
const options = cloneObject(testOp);
options.paths.rss = 'index.xml';
const results = await runner.rewrite_sitemap(options);
expect(results).to.equal(0);
});

after(function () {
mock.restore();
});
});
});

describe('serve', function () {

});
Expand Down
59 changes: 52 additions & 7 deletions test/xml.test.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
/* eslint-disable prefer-arrow-callback */
const { expect } = require('chai');
const mock = require('mock-fs');
const xmlRewrite = require('../lib/processors/sitemap');
const xmlRewrite = require('../lib/processors/xml');

describe('rewrite xml', function () {
context('elements with some src attribute', function () {
it('should rewrite the url in each loc node', function () {
context('sitemap with "xhtml:link" and "loc" nodes', function () {
it('should rewrite the url in each node', function () {
const xmlString = `<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">
<url>
<loc>http://example.org/advice/</loc>
<lastmod>2016-11-11T00:00:00+13:00</lastmod>
<xhtml:link rel="alternate" hreflang="gr" href="https://www.example.com/advice/"/>
<xhtml:link rel="alternate" hreflang="en" href="https://www.example.com/advice/"/>
<xhtml:link rel="alternate" hreflang="gr" href="https://www.example.org/advice/"/>
<xhtml:link rel="alternate" hreflang="en" href="https://www.example.org/advice/"/>
</url>
<url>
Expand All @@ -27,8 +27,8 @@ describe('rewrite xml', function () {
<url>
<loc>http://example.org/testBaseurl/advice/</loc>
<lastmod>2016-11-11T00:00:00+13:00</lastmod>
<xhtml:link rel="alternate" hreflang="gr" href="https://www.example.com/testBaseurl/advice/"/>
<xhtml:link rel="alternate" hreflang="en" href="https://www.example.com/testBaseurl/advice/"/>
<xhtml:link rel="alternate" hreflang="gr" href="https://www.example.org/testBaseurl/advice/"/>
<xhtml:link rel="alternate" hreflang="en" href="https://www.example.org/testBaseurl/advice/"/>
</url>
<url>
Expand All @@ -40,6 +40,51 @@ describe('rewrite xml', function () {
expect(rewrittenElement).to.equal(expectedXmlString);
});
});

context('rss feed with "link" nodes', function () {
it('should rewrite the url in each node', function () {
const xmlString = `<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Site title</title>
<link>http://example.org/</link>
<description>Site description</description>
<generator>Generator</generator>
<language>en-us</language>
<lastBuildDate>Fri, 12 Aug 2016 00:00:00 +0000</lastBuildDate><atom:link href="http://example.org/index.xml" rel="self" type="application/rss+xml"/>
<item>
<title>Advice</title>
<link>http://example.org/advice/</link>
<pubDate>Fri, 12 Aug 2016 00:00:00 +0000</pubDate>
<guid>http://example.org/advice/</guid>
<description>Advice</description>
</item>
</channel>
</rss>`;
const expectedXmlString = `<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Site title</title>
<link>http://example.org/testBaseurl/</link>
<description>Site description</description>
<generator>Generator</generator>
<language>en-us</language>
<lastBuildDate>Fri, 12 Aug 2016 00:00:00 +0000</lastBuildDate><atom:link href="http://example.org/testBaseurl/index.xml" rel="self" type="application/rss+xml"/>
<item>
<title>Advice</title>
<link>http://example.org/testBaseurl/advice/</link>
<pubDate>Fri, 12 Aug 2016 00:00:00 +0000</pubDate>
<guid>http://example.org/advice/</guid>
<description>Advice</description>
</item>
</channel>
</rss>`;
const rewrittenElement = xmlRewrite.rewrite(xmlString, 'testBaseurl');
expect(rewrittenElement).to.equal(expectedXmlString);
});
});
});

describe('plugin', function () {
Expand Down

0 comments on commit bdd23d9

Please sign in to comment.