UNPKG

@dsottimano/trendspy-js

Version:

ALPHA VERSION: JavaScript port of trendspy - A library for analyzing Google Trends data

220 lines (212 loc) 10.3 kB
"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 };