@dsottimano/trendspy-js
Version:
ALPHA VERSION: JavaScript port of trendspy - A library for analyzing Google Trends data
220 lines (212 loc) • 10.3 kB
JavaScript
"use strict";
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
var _require = require('luxon'),
DateTime = _require.DateTime;
var _require2 = require('./utils'),
ensureList = _require2.ensureList,
truncateString = _require2.truncateString;
var _require3 = require('./news_article'),
NewsArticle = _require3.NewsArticle;
/**
* Represents a trending search term with associated metadata.
*/
var TrendKeyword = /*#__PURE__*/function () {
/**
* @param {Array} item - Raw data array from API
*/
function TrendKeyword(item) {
_classCallCheck(this, TrendKeyword);
var _item = _slicedToArray(item, 13);
this.keyword = _item[0];
this.news = _item[1];
this.geo = _item[2];
this.startedTimestamp = _item[3];
this.endedTimestamp = _item[4];
this._unk2 = _item[5];
this.volume = _item[6];
this._unk3 = _item[7];
this.volumeGrowthPct = _item[8];
this.trendKeywords = _item[9];
this.topics = _item[10];
this.newsTokens = _item[11];
this.normalizedKeyword = _item[12];
if (this.news) {
this.news = this.news.map(function (n) {
return NewsArticle.fromApi(n);
});
}
}
/**
* Converts time in seconds to a DateTime object with UTC timezone
* @private
* @param {number} rawTime - Raw timestamp
* @returns {DateTime|null}
*/
return _createClass(TrendKeyword, [{
key: "_convertToDatetime",
value: function _convertToDatetime(rawTime) {
return rawTime ? DateTime.fromSeconds(rawTime).setZone('utc') : null;
}
/**
* Checks if the trend is finished
* @returns {boolean}
*/
}, {
key: "isTrendFinished",
get: function get() {
return this.endedTimestamp !== null;
}
/**
* Returns the number of hours elapsed since the trend started
* @returns {number}
*/
}, {
key: "hoursSinceStarted",
value: function hoursSinceStarted() {
if (!this.startedTimestamp) {
return 0;
}
var start = DateTime.fromSeconds(this.startedTimestamp[0]).setZone('utc');
var now = DateTime.now().setZone('utc');
return now.diff(start, 'hours').hours;
}
/**
* String representation of the trend
* @returns {string}
*/
}, {
key: "toString",
value: function toString() {
var startTime = DateTime.fromSeconds(this.startedTimestamp[0]).toFormat('yyyy-MM-dd HH:mm:ss');
var timeframe = startTime;
if (this.isTrendFinished) {
timeframe += ' - ' + DateTime.fromSeconds(this.endedTimestamp[0]).toFormat('yyyy-MM-dd HH:mm:ss');
} else {
timeframe += ' - now';
}
var s = "Keyword : ".concat(this.keyword);
s += "\nGeo : ".concat(this.geo);
s += "\nVolume : ".concat(this.volume, " (").concat(this.volumeGrowthPct, "%)");
s += "\nTimeframe : ".concat(timeframe);
s += "\nTrend keywords : ".concat(this.trendKeywords.length, " keywords (").concat(truncateString(this.trendKeywords.join(','), 50), ")");
s += "\nNews tokens : ".concat(this.newsTokens.length, " tokens");
return s;
}
}]);
}();
/**
* A lightweight version of TrendKeyword for simple trend representation.
*/
var TrendKeywordLite = /*#__PURE__*/function () {
/**
* @param {string} keyword - The trending search term
* @param {string} volume - Approximate search volume
* @param {Array} trendKeywords - Related keywords
* @param {string} link - URL to more information
* @param {string} started - Start timestamp
* @param {string} picture - URL to related image
* @param {string} pictureSource - Source of the picture
* @param {Array} news - Related news articles
*/
function TrendKeywordLite(keyword, volume, trendKeywords, link, started, picture, pictureSource, news) {
_classCallCheck(this, TrendKeywordLite);
this.keyword = keyword;
this.volume = volume;
this.trendKeywords = trendKeywords;
this.link = link;
this.started = null;
this.picture = picture;
this.pictureSource = pictureSource;
this.news = news;
if (started) {
this.started = this._parsePubDate(started);
} else if (news && news.length > 0) {
this.started = Math.min.apply(Math, _toConsumableArray(news.map(function (item) {
return item.time;
})));
}
}
/**
* Parse publication date string
* @private
* @param {string} pubDate - Publication date string
* @returns {number} Unix timestamp
*/
return _createClass(TrendKeywordLite, [{
key: "toString",
value:
/**
* String representation of the trend
* @returns {string}
*/
function toString() {
var s = "Keyword : ".concat(this.keyword);
if (this.volume) s += "\nVolume : ".concat(this.volume);
if (this.started) {
s += "\nStarted : ".concat(DateTime.fromSeconds(this.started).toFormat('yyyy-MM-dd HH:mm:ss'));
}
if (this.trendKeywords) {
s += "\nTrend keywords : ".concat(this.trendKeywords.length, " keywords (").concat(truncateString(this.trendKeywords.join(','), 50), ")");
}
if (this.news) s += "\nNews : ".concat(this.news.length, " news");
return s;
}
}], [{
key: "_parsePubDate",
value: function _parsePubDate(pubDate) {
return DateTime.fromFormat(pubDate, 'EEE, dd MMM yyyy HH:mm:ss ZZZ', {
zone: 'utc'
}).toSeconds();
}
/**
* Create instance from API data
* @param {Object} data - Raw API data
* @returns {TrendKeywordLite}
*/
}, {
key: "fromApi",
value: function fromApi(data) {
var _data$relatedQueries, _data$image, _data$image2;
var title = _typeof(data.title) === 'object' ? data.title.query : data.title;
var volume = data.formattedTraffic || data.approx_traffic;
var trendKeywords = (_data$relatedQueries = data.relatedQueries) === null || _data$relatedQueries === void 0 ? void 0 : _data$relatedQueries.map(function (item) {
return item.query;
});
if (!trendKeywords && data.description) {
trendKeywords = data.description.split(', ');
}
if (!trendKeywords && data.idsForDedup) {
trendKeywords = Array.from(new Set(data.idsForDedup.flatMap(function (item) {
return item.split(' ');
})));
}
var link = data.shareUrl || data.link;
var started = data.pubDate;
var picture = data.picture || ((_data$image = data.image) === null || _data$image === void 0 ? void 0 : _data$image.imageUrl);
var pictureSource = data.picture_source || ((_data$image2 = data.image) === null || _data$image2 === void 0 ? void 0 : _data$image2.source);
var articles = data.articles || data.news_item || [];
return new TrendKeywordLite(title, volume, trendKeywords, link, started, picture, pictureSource, ensureList(articles).map(function (item) {
return NewsArticle.fromApi(item);
}));
}
}]);
}();
module.exports = {
TrendKeyword: TrendKeyword,
TrendKeywordLite: TrendKeywordLite
};