Skip to content

Commit

Permalink
Merge pull request #6 from majewan/master
Browse files Browse the repository at this point in the history
Issue #5: added createSitemapIndex
  • Loading branch information
ekalinin committed Oct 22, 2013
2 parents de1bda1 + c41bc20 commit d1b09db
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 3 deletions.
9 changes: 9 additions & 0 deletions lib/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,12 @@ exports.PriorityInvalidError = function (message) {
this.message = message || 'priority is invalid';
}
exports.PriorityInvalidError.prototype = Error.prototype;

/**
* SitemapIndex target Folder does not exists
*/
exports.UndefinedTargetFolder = function (message) {
this.name = 'UndefinedTargetFolder';
this.message = message || 'Target folder must exist';
}
exports.UndefinedTargetFolder.prototype = Error.prototype;
116 changes: 114 additions & 2 deletions lib/sitemap.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ var ut = require('./utils')
exports.Sitemap = Sitemap;
exports.SitemapItem = SitemapItem;
exports.createSitemap = createSitemap;
exports.createSitemapIndex = createSitemapIndex;

/**
* Shortcut for `new Sitemap (...)`.
Expand Down Expand Up @@ -199,7 +200,7 @@ Sitemap.prototype.toString = function () {
smi = {'url': elem};
}
// insert domain name
if ( self.hostname && smi.url.indexOf('http') === -1 ) {
if ( self.hostname && smi.url.indexOf('http:') === -1 ) {
smi.url = self.hostname + smi.url;
}
xml.push( new SitemapItem(smi) );
Expand All @@ -211,9 +212,120 @@ Sitemap.prototype.toString = function () {
return this.cache;
}

/**
* Shortcut for `new Sitemap (...)`.
*
* @param {Object} conf
* @param {String|Array} conf.urls
* @param {String} conf.targetFolder
* @param {String} conf.hostname
* @param {Number} conf.cacheTime
* @param {String} conf.sitemapName
* @param {Number} conf.sitemapSize
* @return {SitemapIndex}
*/
function createSitemapIndex(conf) {
return new SitemapIndex(conf.urls, conf.targetFolder, conf.hostname, conf.cacheTime, conf.sitemapName, conf.sitemapSize, conf.callback);
}

/**
* Sitemap index (for several sitemaps)
* @param {String|Array} urls
* @param {String} targetFolder
* @param {String} hostname optional
* @param {Number} cacheTime optional in milliseconds
* @param {String} sitemapName optionnal
* @param {Number} sitemapSize optionnal
*/
function SitemapIndex() {
function SitemapIndex(urls, targetFolder, hostname, cacheTime, sitemapName, sitemapSize, callback) {

var self = this;

self.fs = require('fs');

// Base domain
self.hostname = hostname;

if(sitemapName === undefined) {
self.sitemapName = 'sitemap';
}
else {
self.sitemapName = sitemapName;
}

// This limit is defined by Google. See:
// http://sitemaps.org/protocol.php#index
self.sitemapSize = sitemapSize;

self.sitemapId = 0;

self.sitemaps = [];

self.targetFolder = '.';

if(!self.fs.existsSync(targetFolder)) {
throw new err.UndefinedTargetFolder();
}

self.targetFolder = targetFolder;

// URL list for sitemap
self.urls = urls || [];
if ( !(this.urls instanceof Array) ) {
this.urls = [ this.urls ]
}

self.chunks = ut.chunkArray(self.urls, self.sitemapSize);

self.callback = callback;

var processesCount = self.chunks.length + 1;

self.chunks.forEach( function (chunk, index) {

var filename = self.sitemapName + '-' + self.sitemapId++ + '.xml';
self.sitemaps.push(filename);

var sitemap = createSitemap ({
hostname: self.hostname,
cacheTime: self.cacheTime, // 600 sec - cache purge period
urls: chunk
});

var stream = self.fs.createWriteStream(targetFolder + '/' + filename);
stream.once('open', function(fd) {
stream.write(sitemap.toString());
stream.end();
processesCount--;
if(processesCount === 0) {
callback(null, true);
}
});

});

var xml = [];

xml.push('<?xml version="1.0" encoding="UTF-8"?>');
xml.push('<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">');

self.sitemaps.forEach( function (sitemap, index) {
xml.push('<sitemap>');
xml.push('<loc>' + hostname + '/' + sitemap + '</loc>');
// xml.push('<lastmod>' + new Date() + '</lastmod>');
xml.push('</sitemap>');
});

xml.push('</sitemapindex>');

var stream = self.fs.createWriteStream(targetFolder + '/' + self.sitemapName + '-index.xml');
stream.once('open', function(fd) {
stream.write(xml.join('\n'));
stream.end();
processesCount--;
if(processesCount === 0) {
callback(null, true);
}
});

}
8 changes: 8 additions & 0 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,11 @@ exports.distinctArray = function (arr) {
}
return res;
}

exports.chunkArray = function(arr, chunkSize) {
return [].concat.apply([],
arr.map(function(elem,i) {
return i%chunkSize ? [] : [arr.slice(i,i+chunkSize)];
})
);
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sitemap",
"version": "0.6.0",
"version": "0.7.0",
"description": "Sitemap-generating framework",
"keywords": ["sitemap", "sitemap.xml"],
"repository": "git://github.com/ekalinin/sitemap.js.git",
Expand Down
37 changes: 37 additions & 0 deletions tests/sitemap.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,43 @@ module.exports = {
'<priority>0.5</priority> '+
'</url>\n'+
'</urlset>');
},
'simple sitemap index': function() {
var url1 = 'http://ya.ru';
var url2 = 'http://ya2.ru';

assert.throws(
function() {
var ssp = new sm.createSitemapIndex({
cacheTime: 600000,
hostname: 'http://www.sitemap.org',
sitemapName: 'sm-test',
sitemapSize: 1,
targetFolder: '/tmp2',
urls: [url1, url2]
});
},
/UndefinedTargetFolder/
);

var ssp = new sm.createSitemapIndex({
cacheTime: 600000,
hostname: 'http://www.sitemap.org',
sitemapName: 'sm-test',
sitemapSize: 1,
targetFolder: '/tmp',
urls: [url1, url2],
callback: function(err, result) {
assert.eql(err, null);
assert.eql(result, true);
assert.eql(require('fs').existsSync('/tmp/sm-test-0.xml'), true);
assert.eql(require('fs').existsSync('/tmp/sm-test-1.xml'), true);
assert.eql(require('fs').existsSync('/tmp/sm-test-index.xml'), true);
}
});



},
'lpad test': function() {
assert.eql(sm.utils.lpad(5, 2), '05');
Expand Down

0 comments on commit d1b09db

Please sign in to comment.