diff --git a/.gitignore b/.gitignore index 5148e52..d35d381 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,6 @@ jspm_packages # Optional REPL history .node_repl_history + +# vscode +.vscode diff --git a/lib/overwatch.js b/lib/overwatch.js index c8f54ff..dbcb57a 100644 --- a/lib/overwatch.js +++ b/lib/overwatch.js @@ -16,19 +16,19 @@ const searchUrl = 'https://playoverwatch.com/en-us/search/account-by-name/'; const GAMETYPES = ['competitive', 'quickplay']; const PLATFORMS = { - XboxLive : "xbl", - Playstation : "psn", - PC : "pc" + XboxLive: "xbl", + Playstation: "psn", + PC: "pc" } -let OverwatchProvider = function() { +let OverwatchProvider = function () { var self = this; - String.prototype.sanitize = function() { + String.prototype.sanitize = function () { return this.trim().replace(" - ", "_").replace(/\s/g, "_").toLowerCase(); } - String.prototype.toTimestamp = function() { + String.prototype.toTimestamp = function () { if (this.indexOf(':') > 0) { let intervals = this.split(':').reverse(); intervals.at0 = (idx) => intervals[idx] || 0; @@ -40,32 +40,31 @@ let OverwatchProvider = function() { if (swap.endsWith('s')) swap = this.substr(0, this.length - 1); // remove trailing s if (swap.endsWith("second")) return parseInt(swap) * 1000; if (swap.endsWith("minute")) return parseInt(swap) * 60000; - if (swap.endsWith("hour")) return parseInt(swap) * 3600000; - if (swap.endsWith("day")) return parseInt(swap) * 86400000; + if (swap.endsWith("hour")) return parseInt(swap) * 3600000; + if (swap.endsWith("day")) return parseInt(swap) * 86400000; return parseInt(swap); } - String.prototype.cast = function() { + String.prototype.cast = function () { if (this.indexOf('.') > 0) return parseFloat(this); if (this.indexOf(':') > 0 || this.split(' ').length > 1) return this.toTimestamp(); - return parseInt(this.replace(/,/g,'')); + return parseInt(this.replace(/,/g, '')); } let getUrl = (platform, region, tag) => { - switch(platform) - { - case PLATFORMS.PC : + switch (platform) { + case PLATFORMS.PC: region = "/" + region break; - case PLATFORMS.Playstation : - case PLATFORMS.XboxLive : - default : + case PLATFORMS.Playstation: + case PLATFORMS.XboxLive: + default: //// No region must be specified region = ""; break; - } + } return url + `${platform}${region}/${tag}`; }; @@ -81,9 +80,9 @@ let OverwatchProvider = function() { stats.avatar = $('.player-portrait').attr('src'); stats.rank = parseInt($('div.competitive-rank > div').first().text()); - if(stats.rank) + if (stats.rank) stats.rankPicture = $('div.competitive-rank > img').attr('src'); - + stats.platform = $('#profile-platforms > a').text(); return stats; @@ -103,9 +102,9 @@ let OverwatchProvider = function() { var heroesMap = []; var stats = {}; _.each($(`#${gametype} > .career-stats-section option`), (item) => { - heroesMap.push({ name : item.attribs['option-id'].toLowerCase().sanitize(), value : item.attribs['value'] }); + heroesMap.push({ name: item.attribs['option-id'].toLowerCase().sanitize(), value: item.attribs['value'] }); - if(overallOnly) + if (overallOnly) return false; }); @@ -120,23 +119,42 @@ let OverwatchProvider = function() { }); }); - if(overallOnly) + if (overallOnly) return false; }); return stats; } + let parseAchievements = ($) => { + var categories = []; + var stats = {}; + _.each($(`select[data-group-id="achievements"] option`), (item) => { + categories.push({ name: item.attribs['option-id'].toLowerCase(), value: item.attribs['value'] }); + }); + + // Seeking achievements stats + return _.map(categories, (category) => { + var ctn = $(`[data-category-id="${category.value}"]`); + return { + acquired : ctn.find('.achievement-card').attr('class').indexOf('m-disabled') < 0, + thumbnail : ctn.find('.media-card-fill').attr('src'), + title : ctn.find('.tooltip-tip > .h5').text(), + description : ctn.find('.tooltip-tip > .h6').text() + } + }); + } + let handle = (err) => { console.log(err); switch (err.response.statusCode) { - case 404 : - throw new Error('PROFILE_NOT_FOUND'); + case 404: + throw new Error('PROFILE_NOT_FOUND'); break; - case 500 : - throw new Error('TECHNICAL_EXCEPTION_HTML_STRUCTURE_MAY_HAVE_CHANGED') + case 500: + throw new Error('TECHNICAL_EXCEPTION_HTML_STRUCTURE_MAY_HAVE_CHANGED') break; - default : + default: throw new Error('TECHNICAL_EXCEPTION_NOT_IDENTIFIED') break; } @@ -177,17 +195,22 @@ let OverwatchProvider = function() { promises.push(p); }); + promises.push(new Promise((resolve, reject) => { + result.achievements = parseAchievements($); + resolve(result); + })); + return Promise.all(promises).then(() => { return result; }); }) - .catch(handle); + .catch(handle); }; self.search = (username) => { var options = { uri: getSearchUrl(username), - json: true + json: true }; return rp(options).then((datas) => { @@ -201,7 +224,7 @@ let OverwatchProvider = function() { return datas; }) - .catch(handle); + .catch(handle); } };