PSA.pm TVmaze API

TVmaze API (https://www.tvmaze.com/api), Icons created by Flat Icons - Flaticon (https://www.flaticon.com/)

  1. // ==UserScript==
  2. // @name PSA.pm TVmaze API
  3. // @namespace tuktuk3103@gmail.com
  4. // @description TVmaze API (https://www.tvmaze.com/api), Icons created by Flat Icons - Flaticon (https://www.flaticon.com/)
  5. // @license CC BY-SA 4.0
  6. // @include *://psa.*/tv-show/*
  7. // @include *://psarips.com/tv-show/*
  8. // @version 1.13
  9. // @grant GM.openInTab
  10. // @grant GM.xmlHttpRequest
  11. // @icon https://psa.re/wp-content/uploads/2021/10/cropped-PS-ICO-192x192.png
  12. // ==/UserScript==
  13.  
  14.  
  15. //Removing duplicate episodes since it breaks script, sorry if you wanted other variants.
  16.  
  17. window.addEventListener("DOMContentLoaded", function() {
  18. var var0 = document.querySelectorAll('.sp-head');
  19. var regex = /(S\d{2}E\d{2}).*\.720p/;
  20. for(var x = var0.length; x--; x>-1) {
  21. var check1 = regex.exec(var0[x].textContent);
  22. var check2 = regex.exec(var0[x-1].textContent);
  23. if (check1[1] === check2[1]) var0[x].remove();
  24. }
  25. });
  26.  
  27. //Adding style
  28.  
  29. let head = document.getElementsByTagName('head')[0];
  30. if (head) {
  31. let style = document.createElement('style');
  32. style.setAttribute('type', 'text/css');
  33. style.textContent = "#FemaleCast, #MaleCast, #Year {font-family: Verdana, sans-serif; font-size: 1.6em; font-variant: small-caps;}";
  34. head.appendChild(style);
  35. }
  36.  
  37. document.querySelectorAll("img.size-full")[0].setAttribute('width', '');
  38. document.querySelectorAll("img.size-full")[0].setAttribute('height', '');
  39.  
  40. //XHR
  41.  
  42. var id = document.querySelector("h1.entry-title").textContent.replace(/\s\(TV show\)/i,'').replace(/\s\(\d+\)/,'').replace('Law & Order SVU','Law & Order: Special Victims Unit').replace('Marvel’s ','').replace(/Season\s\d+/,'');
  43. var tvmazeAPI = "https://api.tvmaze.com/singlesearch/shows?q=" + encodeURIComponent(id) + "&embed[]=cast&embed[]=episodes";
  44. GM.xmlHttpRequest ({
  45. method: 'GET',
  46. url: tvmazeAPI,
  47. responseType: "json",
  48. onload: function (response) {
  49.  
  50. console.log (
  51. "GM.xmlHttpRequest() response is:\n",
  52. response.response
  53. );
  54.  
  55. //Adding containers for the response data
  56.  
  57. document.querySelector("h1.entry-title").insertAdjacentHTML('afterbegin', '<a id="dayLink" href="" target="_blank"><img id="dayImg" style="max-height:51.2px; margin-right:20px;" src=""></a><a id="showLink" href="" target="_blank"><img id="showImg" style="max-height:40px; margin-right:20px;" src="https://static.tvmaze.com/images/tvm-header-logo.png"></a>');
  58. document.querySelector("h1.entry-title").insertAdjacentHTML('afterend', '<span id="Year"></span><br><br><span id="FemaleCast"></span><br><br><span id="MaleCast"></span>');
  59.  
  60. switch (response.response.schedule.days[0]) { //Get the day and set the icon
  61. case "Sunday":
  62. document.getElementById("dayLink").setAttribute("href", "https://www.flaticon.com/free-icons/sunday");
  63. document.getElementById("dayImg").setAttribute("src", "https://cdn-icons-png.flaticon.com/512/5776/5776782.png");
  64. break;
  65. case "Monday":
  66. document.getElementById("dayLink").setAttribute("href", "https://www.flaticon.com/free-icons/monday");
  67. document.getElementById("dayImg").setAttribute("src", "https://cdn-icons-png.flaticon.com/512/5776/5776609.png");
  68. break;
  69. case "Tuesday":
  70. document.getElementById("dayLink").setAttribute("href", "https://www.flaticon.com/free-icons/tuesday");
  71. document.getElementById("dayImg").setAttribute("src", "https://cdn-icons-png.flaticon.com/512/5776/5776837.png");
  72. break;
  73. case "Wednesday":
  74. document.getElementById("dayLink").setAttribute("href", "https://www.flaticon.com/free-icons/wednesday");
  75. document.getElementById("dayImg").setAttribute("src", "https://cdn-icons-png.flaticon.com/512/5776/5776852.png");
  76. break;
  77. case "Thursday":
  78. document.getElementById("dayLink").setAttribute("href", "https://www.flaticon.com/free-icons/thursday");
  79. document.getElementById("dayImg").setAttribute("src", "https://cdn-icons-png.flaticon.com/512/5776/5776798.png");
  80. break;
  81. case "Friday":
  82. document.getElementById("dayLink").setAttribute("href", "https://www.flaticon.com/free-icons/friday");
  83. document.getElementById("dayImg").setAttribute("src", "https://cdn-icons-png.flaticon.com/512/5776/5776451.png");
  84. break;
  85. case "Saturday":
  86. document.getElementById("dayLink").setAttribute("href", "https://www.flaticon.com/free-icons/saturday");
  87. document.getElementById("dayImg").setAttribute("src", "https://cdn-icons-png.flaticon.com/512/5776/5776750.png");
  88. break;
  89. default:
  90. document.getElementById("dayLink").setAttribute("href", "");
  91. document.getElementById("dayImg").setAttribute("src", "");
  92. }
  93.  
  94. document.getElementById("showLink").setAttribute("href", response.response.url);
  95.  
  96. document.getElementById("Year").innerHTML += "Premiere Year: " + response.response.premiered.slice(0, 4); //Adding premiere year
  97.  
  98. if (response.response.status === "Ended") document.getElementById("Year").innerHTML += ", End Year: " + response.response.ended.slice(0, 4); //Adding end year
  99.  
  100. document.getElementById("wpd-post-rating").insertAdjacentHTML('afterend', response.response.summary); //Adding show summary
  101.  
  102. var varO = document.querySelectorAll('.sp-head');
  103. var regex2 = /E(\d{2}).*/;
  104. var order = true;
  105. var t=0, f=0;
  106. for(var m = varO.length; m--; m>-1) {
  107. try{ var check1 = regex2.exec(varO[m].textContent); } catch{}
  108. try{ var check2 = regex2.exec(varO[m-1].textContent); } catch{}
  109. try{ if (parseInt(check1[1], 10) < parseInt(check2[1], 10)) t++; else if (parseInt(check1[1], 10) > parseInt(check2[1], 10)) f++; } catch{}
  110. }
  111. if (t<f) order = false;
  112.  
  113. if (order) {
  114. var var1 = document.querySelectorAll('.sp-head');
  115. var j = 0;
  116. for(var i = var1.length; i--; i>-1) { //Adding episode names and summaries
  117. if (/E\d{2}.*\.720p(\.10bit|)\.WEBRip\.2CH\.x265\.HEVC-PSA/.test(var1[i].textContent)) { //Ignores TV-PACKS
  118. var s = /S(\d{2})/.exec(var1[i].textContent); //Gets the season number
  119. if (parseInt(s[1], 10) === response.response._embedded.episodes[j].season) { //Checks if the season number matches
  120. if (/E\d{2}E\d{2}/.test(var1[i].textContent)) { //Double episodes
  121. var1[i].insertAdjacentHTML('beforeend', '<br>' + response.response._embedded.episodes[j].name + ': ' + response.response._embedded.episodes[j].summary + '<br>' + response.response._embedded.episodes[j+1].name + ': ' + response.response._embedded.episodes[j+1].summary);
  122. j = j+2;
  123. } else {
  124. if ( (/E00.*\.720p/.test(var1[i].textContent)) || (/(REPACK|INTERNAL)\.720p/.test(var1[i].textContent)) ) { } //Skips E00 because the API doesn't have any info about it and repacks/internals
  125. else {
  126. var1[i].insertAdjacentHTML('beforeend', '<br>' + response.response._embedded.episodes[j].name + ': ' + response.response._embedded.episodes[j].summary);
  127. j++;
  128. }
  129. }
  130. } else { if ( (/E00.*\.720p/.test(var1[i].textContent)) || (/(REPACK|INTERNAL)\.720p/.test(var1[i].textContent)) ) { } else { j++; i++; } }
  131. }
  132. }
  133. } else {
  134. var var1 = document.querySelectorAll('.sp-head');
  135. var j = response.response._embedded.episodes.length-1;
  136. for(var i = var1.length; i--; i>-1) { //Adding episode names and summaries
  137. if (/E\d{2}.*\.720p(\.10bit|)\.WEBRip\.2CH\.x265\.HEVC-PSA/.test(var1[i].textContent)) { //Ignores TV-PACKS
  138. var s = /S(\d{2})/.exec(var1[i].textContent); //Gets the season number
  139. if (parseInt(s[1], 10) === response.response._embedded.episodes[j].season) { //Checks if the season number matches
  140. if (/E\d{2}E\d{2}/.test(var1[i].textContent)) { //Double episodes
  141. var1[i].insertAdjacentHTML('beforeend', '<br>' + response.response._embedded.episodes[j].name + ': ' + response.response._embedded.episodes[j].summary + '<br>' + response.response._embedded.episodes[j-1].name + ': ' + response.response._embedded.episodes[j-1].summary);
  142. j = j-2;
  143. } else {
  144. if ( (/E00.*\.720p/.test(var1[i].textContent)) || (/(REPACK|INTERNAL)\.720p/.test(var1[i].textContent)) ) { } //Skips E00 because the API doesn't have any info about it and repacks/internals
  145. else {
  146. var1[i].insertAdjacentHTML('beforeend', '<br>' + response.response._embedded.episodes[j].name + ': ' + response.response._embedded.episodes[j].summary);
  147. j--;
  148. }
  149. }
  150. } else { if ( (/E00.*\.720p/.test(var1[i].textContent)) || (/(REPACK|INTERNAL)\.720p/.test(var1[i].textContent)) ) { } else { j--; i++; } }
  151. }
  152. }
  153. }
  154.  
  155. //Segregate by gender
  156.  
  157. let date = new Date().getFullYear();
  158.  
  159. const Female = response.response._embedded.cast.filter(actress => actress.person.gender === "Female"); //Ladies first! (*^_^*)
  160.  
  161. try {
  162. if (Female[0].person.birthday) var bDay = Female[0].person.birthday.slice(0, 4); else var bDay = date;
  163. var age = parseInt(date, 10) - parseInt(bDay, 10);
  164. try {var country1 = "<img title='" + Female[0].person.country.name + "' style='margin-bottom:-8px;' src='https://flagsapi.com/" + Female[0].person.country.code + "/flat/32.png'>&nbsp;";} catch {var country1 = ""; Female[0].person.name = "\u2620&nbsp;" + Female[0].person.name;}
  165. document.getElementById("FemaleCast").innerHTML += "Female Cast: " + "<a href='" + Female[0].person.url + "' target='_blank'>" + country1 + Female[0].person.name + " (" + age + "yo)" + "</a>" + ".";}
  166. catch {document.getElementById("FemaleCast").innerHTML += "Female Cast: Not Found.";}
  167.  
  168. try {if (Female[1]) document.getElementById("FemaleCast").innerHTML = document.getElementById("FemaleCast").innerHTML.slice(0, document.getElementById("FemaleCast").innerHTML.length-1);
  169. if (Female[1].person.birthday) var bDay = Female[1].person.birthday.slice(0, 4); else var bDay = date;
  170. var age = parseInt(date, 10) - parseInt(bDay, 10);
  171. try {var country2 = "<img title='" + Female[1].person.country.name + "' style='margin-bottom:-8px;' src='https://flagsapi.com/" + Female[1].person.country.code + "/flat/32.png'>&nbsp;";} catch {var country2 = ""; Female[1].person.name = "\u2620&nbsp;" + Female[1].person.name;}
  172. document.getElementById("FemaleCast").innerHTML += ", " + "<a href='" + Female[1].person.url + "' target='_blank'>" + country2 + Female[1].person.name + " (" + age + "yo)" + "</a>" + ".";}
  173. catch {}
  174.  
  175. try {if (Female[2]) document.getElementById("FemaleCast").innerHTML = document.getElementById("FemaleCast").innerHTML.slice(0, document.getElementById("FemaleCast").innerHTML.length-1);
  176. if (Female[2].person.birthday) var bDay = Female[2].person.birthday.slice(0, 4); else var bDay = date;
  177. var age = parseInt(date, 10) - parseInt(bDay, 10);
  178. try {var country3 = "<img title='" + Female[2].person.country.name + "' style='margin-bottom:-8px;' src='https://flagsapi.com/" + Female[2].person.country.code + "/flat/32.png'>&nbsp;";} catch {var country3 = ""; Female[2].person.name = "\u2620&nbsp;" + Female[2].person.name;}
  179. document.getElementById("FemaleCast").innerHTML += ", " + "<a href='" + Female[2].person.url + "' target='_blank'>" + country3 + Female[2].person.name + " (" + age + "yo)" + "</a>" + ".";}
  180. catch {}
  181.  
  182. try {if (Female[0].person.image.medium) document.getElementById("FemaleCast").getElementsByTagName('a')[0].addEventListener('mouseover', function() { document.querySelectorAll("img.size-full")[0].setAttribute('src', Female[0].person.image.medium); }, false);} catch {}
  183. try {if (Female[1].person.image.medium) document.getElementById("FemaleCast").getElementsByTagName('a')[1].addEventListener('mouseover', function() { document.querySelectorAll("img.size-full")[0].setAttribute('src', Female[1].person.image.medium); }, false);} catch {}
  184. try {if (Female[2].person.image.medium) document.getElementById("FemaleCast").getElementsByTagName('a')[2].addEventListener('mouseover', function() { document.querySelectorAll("img.size-full")[0].setAttribute('src', Female[2].person.image.medium); }, false);} catch {}
  185.  
  186. const Male = response.response._embedded.cast.filter(actor => actor.person.gender === "Male");
  187.  
  188. try {
  189. if (Male[0].person.birthday) var bDay = Male[0].person.birthday.slice(0, 4); else var bDay = date;
  190. var age = parseInt(date, 10) - parseInt(bDay, 10);
  191. try {var country4 = "<img title='" + Male[0].person.country.name + "' style='margin-bottom:-8px;' src='https://flagsapi.com/" + Male[0].person.country.code + "/flat/32.png'>&nbsp;";} catch {var country4 = ""; Male[0].person.name = "\u2620&nbsp;" + Male[0].person.name;}
  192. document.getElementById("MaleCast").innerHTML += "Male Cast: " + "<a href='" + Male[0].person.url + "' target='_blank'>" + country4 + Male[0].person.name + " (" + age + "yo)" + "</a>" + ".";}
  193. catch {document.getElementById("MaleCast").innerHTML += "Male Cast: Not Found.";}
  194.  
  195. try {if (Male[1]) document.getElementById("MaleCast").innerHTML = document.getElementById("MaleCast").innerHTML.slice(0, document.getElementById("MaleCast").innerHTML.length-1);
  196. if (Male[1].person.birthday) var bDay = Male[1].person.birthday.slice(0, 4); else var bDay = date;
  197. var age = parseInt(date, 10) - parseInt(bDay, 10);
  198. try {var country5 = "<img title='" + Male[1].person.country.name + "' style='margin-bottom:-8px;' src='https://flagsapi.com/" + Male[1].person.country.code + "/flat/32.png'>&nbsp;";} catch {var country5 = ""; Male[1].person.name = "\u2620&nbsp;" + Male[1].person.name;}
  199. document.getElementById("MaleCast").innerHTML += ", " + "<a href='" + Male[1].person.url + "' target='_blank'>" + country5 + Male[1].person.name + " (" + age + "yo)" + "</a>" + ".";}
  200. catch {}
  201.  
  202. try {if (Male[2]) document.getElementById("MaleCast").innerHTML = document.getElementById("MaleCast").innerHTML.slice(0, document.getElementById("MaleCast").innerHTML.length-1);
  203. if (Male[2].person.birthday) var bDay = Male[2].person.birthday.slice(0, 4); else var bDay = date;
  204. var age = parseInt(date, 10) - parseInt(bDay, 10);
  205. try {var country6 = "<img title='" + Male[2].person.country.name + "' style='margin-bottom:-8px;' src='https://flagsapi.com/" + Male[2].person.country.code + "/flat/32.png'>&nbsp;";} catch {var country6 = ""; Male[2].person.name = "\u2620&nbsp;" + Male[2].person.name;}
  206. document.getElementById("MaleCast").innerHTML += ", " + "<a href='" + Male[2].person.url + "' target='_blank'>" + country6 + Male[2].person.name + " (" + age + "yo)" + "</a>" + ".";}
  207. catch {}
  208.  
  209. try {if (Male[0].person.image.medium) document.getElementById("MaleCast").getElementsByTagName('a')[0].addEventListener('mouseover', function() { document.querySelectorAll("img.size-full")[0].setAttribute('src', Male[0].person.image.medium); }, false);} catch {}
  210. try {if (Male[1].person.image.medium) document.getElementById("MaleCast").getElementsByTagName('a')[1].addEventListener('mouseover', function() { document.querySelectorAll("img.size-full")[0].setAttribute('src', Male[1].person.image.medium); }, false);} catch {}
  211. try {if (Male[2].person.image.medium) document.getElementById("MaleCast").getElementsByTagName('a')[2].addEventListener('mouseover', function() { document.querySelectorAll("img.size-full")[0].setAttribute('src', Male[2].person.image.medium); }, false);} catch {}
  212.  
  213. }
  214. });
  215.  
  216. // TVmaze API Button
  217.  
  218. var node1 = document.createElement("div");
  219. node1.setAttribute("style","position: fixed;" +
  220. "bottom: 0;" +
  221. "left: 28px;" +
  222. "cursor: pointer;" +
  223. "border: 1px solid #313131;" +
  224. "border-top-left-radius: 5px;" +
  225. "background: #101000;" +
  226. "padding: 7px 15px;" +
  227. "z-index: 999999;");
  228. node1.setAttribute("title", "Click here to open API");
  229. node1.innerHTML = "<img src='https://static.tvmaze.com/images/api/tvm_api.png' style='max-height:4vh;'><img src='https://licensebuttons.net/l/by-sa/4.0/80x15.png' style='display: block;margin-left: auto;margin-right: auto;'>";
  230. node1.id = "api";
  231. document.body.appendChild(node1);
  232.  
  233. document.getElementById("api").addEventListener('click', function() { GM.openInTab("https://www.tvmaze.com/api#licensing", false); }, false);