IGDB List Extra Info

Adds additional information (genre, rating, keywords)to igdb.com lists. They can be loaded witha button // click. Needs an IGDB api key.

当前为 2017-11-18 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name IGDB List Extra Info
  3. // @namespace https://greasyfork.org/de/users/155913-nkay08
  4. // @description Adds additional information (genre, rating, keywords)to igdb.com lists. They can be loaded witha button // click. Needs an IGDB api key.
  5. // @author NKay
  6. // @include http*://www.igdb.com/*
  7. // @grant none
  8. // @require http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
  9. // @version 0.0.1.20171118155105
  10. // ==/UserScript==
  11.  
  12.  
  13. //insert your API-KEY here
  14. var apikey = '';
  15.  
  16. var gametextarray = [];
  17. var gameidarray = [];
  18. var genresnodearray = [];
  19. var keywordsnodearray = [];
  20. var ratingnodearray = [];
  21.  
  22.  
  23. function addAdditionalInfo(jnode) {
  24. 'use strict';
  25. // Your code here...
  26. console.log('Adding button and placeholders for extra info');
  27. //api urls
  28. var apiurl = 'https://api-2445582011268.apicast.io';
  29. var req = '/games/?search=';
  30. var reqid = '/games/1942?fields=*';
  31. var corsproxy = 'https://cors-anywhere.herokuapp.com/';
  32. var fields = '?fields=*';
  33.  
  34. var sidebar = document.getElementsByClassName("nopad");
  35. var sidebarchild = sidebar[0].childNodes[0];
  36. if (sidebar && sidebarchild) {
  37.  
  38.  
  39. }
  40.  
  41.  
  42. // btn.appendChild(btntext);
  43. // sidebar[0].appendChild(btn);
  44.  
  45.  
  46. var pageDivs = document.getElementsByClassName("media-body");
  47.  
  48. var promises = [];
  49. var sequence = Promise.resolve();
  50. //set header for apikey and json
  51. var myheaders = new Headers();
  52. myheaders.append('user-key', apikey);
  53. //myheaders.append('Accept', 'application/json');
  54.  
  55. //for every element "media-body" do
  56. for (var i = 0; i < pageDivs.length; i++)
  57. //for (var i = 0; i < 1; i++)
  58. {
  59.  
  60. // get sibling. sibling has game id
  61. var sib = pageDivs[i].nextSibling;
  62. var gameid = sib.getAttribute("data-game");
  63. //set some elements
  64. // var filler = document.createTextNode(' | ');
  65. var genrestext = document.createTextNode('Genres: ');
  66. var genresspan = document.createElement('span');
  67. genresspan.style.fontSize = 'medium';
  68. genresspan.style.textDecoration = 'underline';
  69. genresspan.appendChild(genrestext);
  70. pageDivs[i].appendChild(genresspan);
  71. var genresnode = document.createElement('span');
  72. genresnode.setAttribute("id", "usgenre" + i.toString());
  73. pageDivs[i].appendChild(genresnode);
  74. genresnodearray.push(genresnode);
  75. pageDivs[i].appendChild(document.createTextNode(' | '));
  76. var keywordstext = document.createTextNode('Keywords: ');
  77. var kwspan = document.createElement('span');
  78. kwspan.style.fontSize = 'medium';
  79. kwspan.style.textDecoration = "underline";
  80. kwspan.appendChild(keywordstext);
  81. pageDivs[i].appendChild(kwspan);
  82. var keywordsnode = document.createElement('span');
  83. keywordsnode.setAttribute("id", "uskw" + i.toString());
  84. pageDivs[i].appendChild(keywordsnode);
  85. keywordsnodearray.push(keywordsnode);
  86. pageDivs[i].appendChild(document.createTextNode(' | '));
  87. var ratingtext = document.createTextNode('Rating: ');
  88. var rtspan = document.createElement('span');
  89. rtspan.style.fontSize = 'medium';
  90. rtspan.style.textDecoration = "underline";
  91. rtspan.appendChild(ratingtext);
  92. pageDivs[i].appendChild(rtspan);
  93. var ratingnode = document.createTextNode('');
  94. pageDivs[i].appendChild(ratingnode);
  95. ratingnodearray.push(ratingnode);
  96.  
  97.  
  98. //get the game name
  99. var span1 = pageDivs[i].getElementsByTagName('span');
  100. gameidarray.push(corsproxy + apiurl + '/games/' + gameid + fields);
  101.  
  102. // var ref = pageDivs[i].getElementsByClassName("link-dark");
  103. // text = document.createTextNode(ref[0].href);
  104. }
  105.  
  106. var btn = document.createElement("button");
  107. var btntext = document.createTextNode('Load additional info');
  108. btn.appendChild(btntext);
  109. var firstbtn = document.getElementsByClassName("btn btn-primary btn-block mar-md-bottom");
  110. firstbtn[0].parentNode.insertBefore(document.createElement('hr'), firstbtn[0]);
  111. firstbtn[0].parentNode.insertBefore(btn, firstbtn[0]);
  112. firstbtn[0].parentNode.insertBefore(document.createElement('hr'), firstbtn[0]);
  113. btn.addEventListener("click", load, false);
  114.  
  115. function load() {
  116. genresnodearray.forEach(element => element.innerHTML = 'loading..');
  117. keywordsnodearray.forEach(element => element.innerHTML = 'loading..');
  118. ratingnodearray.forEach(element => element.nodeValue = 'loading..');
  119.  
  120. //execute multiple fetch promises
  121. // first fetch rating for each id
  122. Promise.all(
  123. gameidarray.map(
  124. (url, index) => fetch(url, {
  125. headers: myheaders
  126. })
  127. .then(res2 => res2.json())
  128. .then(data2 => {
  129. if (data2) {
  130. var ratingstr = '';
  131. ratingstr = ratingstr.concat('User: ');
  132. if (data2[0].rating) {
  133. ratingstr = ratingstr.concat(Math.round(data2[0].rating).toString());
  134. ratingstr = ratingstr.concat(' (' + data2[0].rating_count.toString() + ')');
  135. } else {
  136. ratingstr = ratingstr.concat('/');
  137. }
  138. ratingstr = ratingstr.concat(', ');
  139. ratingstr = ratingstr.concat('Critics: ');
  140. if (data2[0].aggregated_rating) {
  141. ratingstr = ratingstr.concat(Math.round(data2[0].aggregated_rating).toString());
  142. ratingstr = ratingstr.concat(' (' + data2[0].aggregated_rating_count.toString() + ')');
  143. } else {
  144. ratingstr = ratingstr.concat('/');
  145. }
  146. ratingstr = ratingstr.concat(', ');
  147. ratingstr = ratingstr.concat('Total: ');
  148. if (data2[0].total_rating) {
  149. ratingstr = ratingstr.concat(Math.round(data2[0].total_rating).toString());
  150. ratingstr = ratingstr.concat(' (' + data2[0].total_rating_count.toString() + ')');
  151. } else {
  152. ratingstr = ratingstr.concat('/');
  153. }
  154. ratingnodearray[index].nodeValue = ratingstr;
  155.  
  156.  
  157.  
  158.  
  159. //concat all genrenames. fetch for all genre-ids at once
  160. if (data2[0].genres) {
  161. var genresid = data2[0].genres;
  162. var genresurl = corsproxy + apiurl + '/genres/' + data2[0].genres.toString();
  163. fetch(genresurl, {
  164. headers: myheaders
  165. })
  166. .then(resgenre => resgenre.json())
  167. .then(datagenre => {
  168. var newgenres = '';
  169. genresnodearray[index].innerHTML = '';
  170. datagenre.forEach((tgenre, genreindex) => {
  171. var newgenre = document.createElement('a');
  172. newgenre.setAttribute("href", tgenre.url);
  173. var comma = ', ';
  174. if (genreindex == datagenre.length) {
  175. comma = '';
  176. }
  177. newgenre.appendChild(document.createTextNode(tgenre.name + comma));
  178. genresnodearray[index].appendChild(newgenre);
  179.  
  180. });
  181. });
  182. }
  183.  
  184. //concat all keywords. fetch for all keyword-ids at once
  185. if (data2[0].keywords) {
  186. var keywordsid = data2[0].keywords;
  187. var keywordsurl = corsproxy + apiurl + '/keywords/' + data2[0].keywords.toString();
  188. fetch(keywordsurl, {
  189. headers: myheaders
  190. })
  191. .then(reskey => reskey.json())
  192. .then(datakey => {
  193. keywordsnodearray[index].innerHTML = '';
  194. datakey.forEach((tkey, keyindex) => {
  195. var newkey = document.createElement('a');
  196. newkey.setAttribute('href', tkey.url);
  197. var comma = ', ';
  198. if (keyindex == datakey.length) {
  199. comma = '';
  200. }
  201. newkey.appendChild(document.createTextNode(tkey.name + comma));
  202. keywordsnodearray[index].appendChild(newkey);
  203. });
  204.  
  205.  
  206. });
  207.  
  208. }
  209.  
  210. }
  211. })
  212. )
  213. );
  214.  
  215. }
  216. }
  217.  
  218. //only execute function if this element is loaded via ajax
  219. waitForKeyElements("#content-page > div > div.content-left.col-md-pull-10.col-md-2 > div > a:nth-child(3)", addAdditionalInfo, true);
  220.  
  221. /*--- waitForKeyElements(): A utility function, for Greasemonkey scripts,
  222. that detects and handles AJAXed content.
  223.  
  224. Usage example:
  225.  
  226. waitForKeyElements (
  227. "div.comments"
  228. , commentCallbackFunction
  229. );
  230.  
  231. //--- Page-specific function to do what we want when the node is found.
  232. function commentCallbackFunction (jNode) {
  233. jNode.text ("This comment changed by waitForKeyElements().");
  234. }
  235.  
  236. IMPORTANT: This function requires your script to have loaded jQuery.
  237. */
  238. function waitForKeyElements (
  239. selectorTxt, /* Required: The jQuery selector string that
  240. specifies the desired element(s).
  241. */
  242. actionFunction, /* Required: The code to run when elements are
  243. found. It is passed a jNode to the matched
  244. element.
  245. */
  246. bWaitOnce, /* Optional: If false, will continue to scan for
  247. new elements even after the first match is
  248. found.
  249. */
  250. iframeSelector /* Optional: If set, identifies the iframe to
  251. search.
  252. */
  253. ) {
  254. var targetNodes, btargetsFound;
  255.  
  256. if (typeof iframeSelector == "undefined")
  257. targetNodes = $(selectorTxt);
  258. else
  259. targetNodes = $(iframeSelector).contents ()
  260. .find (selectorTxt);
  261.  
  262. if (targetNodes && targetNodes.length > 0) {
  263. btargetsFound = true;
  264. /*--- Found target node(s). Go through each and act if they
  265. are new.
  266. */
  267. targetNodes.each ( function () {
  268. var jThis = $(this);
  269. var alreadyFound = jThis.data ('alreadyFound') || false;
  270.  
  271. if (!alreadyFound) {
  272. //--- Call the payload function.
  273. var cancelFound = actionFunction (jThis);
  274. if (cancelFound)
  275. btargetsFound = false;
  276. else
  277. jThis.data ('alreadyFound', true);
  278. }
  279. } );
  280. }
  281. else {
  282. btargetsFound = false;
  283. }
  284.  
  285. //--- Get the timer-control variable for this selector.
  286. var controlObj = waitForKeyElements.controlObj || {};
  287. var controlKey = selectorTxt.replace (/[^\w]/g, "_");
  288. var timeControl = controlObj [controlKey];
  289.  
  290. //--- Now set or clear the timer as appropriate.
  291. if (btargetsFound && bWaitOnce && timeControl) {
  292. //--- The only condition where we need to clear the timer.
  293. clearInterval (timeControl);
  294. delete controlObj [controlKey];
  295. }
  296. else {
  297. //--- Set a timer, if needed.
  298. if ( ! timeControl) {
  299. timeControl = setInterval ( function () {
  300. waitForKeyElements ( selectorTxt,
  301. actionFunction,
  302. bWaitOnce,
  303. iframeSelector
  304. );
  305. },
  306. 300
  307. );
  308. controlObj [controlKey] = timeControl;
  309. }
  310. }
  311. waitForKeyElements.controlObj = controlObj;
  312. }