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