UNPKG

8.17 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.Sitemap = undefined;
7
8var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
9
10var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
11
12var _sitemapFile = require('./sitemapFile');
13
14var _config = require('./config');
15
16function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
17
18function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
19
20function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
21
22var Writable = require('stream').Writable;
23
24var DEFAULTS = {
25 maxUrlsPerFile: 50000
26};
27
28var Sitemap = exports.Sitemap = function (_Writable) {
29 _inherits(Sitemap, _Writable);
30
31 function Sitemap(_ref) {
32 var source = _ref.source;
33 var sitemapConfig = _ref.sitemapConfig;
34
35 _classCallCheck(this, Sitemap);
36
37 var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(Sitemap).call(this, { objectMode: true }));
38
39 _this.source = source;
40 _this.source.on("error", function (err) {
41 _this.emit("error", err);
42 });
43 _this.sitemapConfig = sitemapConfig;
44 _this.baseUrl = '' + sitemapConfig.sitemapRootUrl + sitemapConfig.sitemapFileDirectory;
45 _this.directory = sitemapConfig.targetDirectory;
46 _this.urlCount = {};
47 _this.maxPerFile = _this.sitemapConfig.maxUrlsPerFile || DEFAULTS.maxUrlsPerFile;
48 _this.files = {};
49 _this.pipeline = source.pipe(_this);
50 _this.finished = false;
51 _this.on('finish', function () {
52 _this.finished = true;
53 _config.config.log.trace('Pushed all urls for ' + _this.source.name);
54 });
55 return _this;
56 }
57
58 _createClass(Sitemap, [{
59 key: 'open',
60 value: function open() {
61 this.source.open();
62 }
63 }, {
64 key: 'isFinished',
65 value: function isFinished() {
66 var _this2 = this;
67
68 // Hasn't started yet
69 if (!this.finished && Object.keys(this.files).length == 0) {
70 return false;
71 }
72 if (Object.keys(this.files).length == 0 && this.finished) {
73 // All urls filtered?
74 return true;
75 }
76 return Object.keys(this.files).every(function (channel) {
77 var channelFiles = _this2.filesForChannel(channel) || [];
78 return channelFiles.every(function (file) {
79 var drained = file.isDrained();
80 if (drained) {
81 file.end();
82 }
83 return drained;
84 });
85 });
86 }
87 }, {
88 key: 'allFiles',
89 value: function allFiles() {
90 var _this3 = this;
91
92 return Object.keys(this.files).reduce(function (memo, channel) {
93 return memo.concat(_this3.files[channel]);
94 }, []);
95 }
96 }, {
97 key: 'filesForChannel',
98 value: function filesForChannel(channel) {
99 var channelFiles = this.files[channel];
100 if (channelFiles === undefined) {
101 channelFiles = this.files[channel] = [];
102 }
103 return channelFiles;
104 }
105 }, {
106 key: 'currentSitemapFile',
107 value: function currentSitemapFile(channel) {
108 var _this4 = this;
109
110 if (this.urlCount[channel] === undefined) {
111 this.urlCount[channel] = 0;
112 }
113 var fileIndex = Math.floor(this.urlCount[channel] / this.maxPerFile);
114 var channelFiles = this.filesForChannel(channel);
115 var file = channelFiles[fileIndex];
116 var previousFile = null;
117 if (!file) {
118 if (fileIndex > 0) {
119 // close out the old one
120 previousFile = channelFiles[fileIndex - 1];
121 _config.config.log.trace('Closing ' + previousFile.fileName);
122 previousFile.close();
123 }
124 var fileName = '' + channel + fileIndex + '.xml.gz';
125 file = channelFiles[fileIndex] = new _sitemapFile.SitemapFile({ location: this.baseUrl + '/' + fileName,
126 fileName: this.directory + '/' + fileName });
127 file.on('error', function (err) {
128 _this4.emit("error", err);
129 });
130 file.open();
131 }
132 return [file, previousFile];
133 }
134 }, {
135 key: 'totalUrls',
136 value: function totalUrls() {
137 var _this5 = this;
138
139 var pushed = 0;
140 Object.keys(this.urlCount).forEach(function (channel) {
141 pushed += _this5.urlCount[channel];
142 });
143 var drained = 0;
144 Object.keys(this.files).forEach(function (channel) {
145 _this5.files[channel].forEach(function (file) {
146 drained += file.urlCount;
147 });
148 });
149 return [pushed, drained];
150 }
151 }, {
152 key: 'closeRemaining',
153 value: function closeRemaining() {
154 var _this6 = this;
155
156 Object.keys(this.files).forEach(function (channel) {
157 var channelFiles = _this6.filesForChannel(channel);
158 if (channelFiles.length > 0) {
159 var lastFileInChannel = channelFiles[channelFiles.length - 1];
160 _config.config.log.trace('Closing ' + lastFileInChannel.fileName);
161 lastFileInChannel.close();
162 }
163 });
164 }
165 }, {
166 key: '_write',
167 value: function _write(url, encoding, callback) {
168 // Just pass the url through to the currently active SitemapFile
169 var channel = this.source.channelForUrl(url);
170 if (!channel) {
171 var util = require('util');
172 _config.config.log.error(new Error('url ' + util.inspect(url) + ' of source ' + this.source.name + ' has no channel: ' + util.inspect(channel)));
173 throw new Error('url ' + util.inspect(url) + ' has no channel: ' + util.inspect(channel));
174 }
175
176 var _currentSitemapFile = this.currentSitemapFile(channel);
177
178 var _currentSitemapFile2 = _slicedToArray(_currentSitemapFile, 2);
179
180 var file = _currentSitemapFile2[0];
181 var previousFile = _currentSitemapFile2[1];
182 // If there is a previousFile, wait for it to drain before writing url
183
184 if (previousFile) {
185 (function () {
186 var waiting = function waiting() {
187 if (previousFile.isDrained()) {
188 _config.config.log.trace(previousFile.fileName + ' is drained, saved ' + previousFile.urlCount + ' URLS');
189 callback();
190 } else {
191 //config.log.trace(`${previousFile.fileName} is not drained, waiting`);
192 setTimeout(waiting, 100);
193 }
194 };
195 setTimeout(waiting, 100);
196 })();
197 } else {
198 file.write(url);
199 this.urlCount[channel] += 1;
200 callback();
201 }
202 }
203 }]);
204
205 return Sitemap;
206}(Writable);
\No newline at end of file