TrakTheSources

Sources movies and tv episodes for Trakt.tv

  1. // ==UserScript==
  2. // @name TrakTheSources
  3. // @namespace http://tribuadore.github.io/TrakTheSources
  4. // @version 0.5.1
  5. // @author Tribuadore
  6. // @description Sources movies and tv episodes for Trakt.tv
  7. // @domain trakt.tv
  8. // @domain raw.github.com
  9. // @include http://trakt.tv/*
  10. // @include https://trakt.tv/*
  11. // @grant GM_xmlhttpRequest
  12. // @run-at document-end
  13. // @noframes
  14. // @license MIT License
  15. // ==/UserScript==
  16.  
  17. var aggregators = {};
  18.  
  19. aggregators.Primewire = {
  20.  
  21. URL: 'https://www.primewire.ag',
  22.  
  23. search: function (media) {
  24.  
  25. httpGet(aggregators.Primewire.URL + '/index.php?search_keywords=' + media.title, aggregators.Primewire.index, media);
  26.  
  27. },
  28.  
  29. index: function (doc, media) {
  30.  
  31. var pages = doc.evaluate('//div[contains(@class, "index_item")]/a[starts-with(@title, "Watch ' + media.title + '")]', doc.body, null, XPathResult.ANY_TYPE);
  32. var matches = 0;
  33.  
  34. for (var page = pages.iterateNext(); page; page = pages.iterateNext()) {
  35.  
  36. if ((new RegExp(' \\(' + media.year + '\\)$')).test(page.getAttribute('title'))) {
  37.  
  38. ++matches;
  39. httpGet(aggregators.Primewire.URL + page.getAttribute('href'), media.isEpisode ? aggregators.Primewire.episodes : aggregators.Primewire.sources, media);
  40.  
  41. }
  42.  
  43. }
  44.  
  45. if (matches === 0) {
  46. return actions.searchShortendTitle(aggregators.Primewire.search, media);
  47. }
  48.  
  49. },
  50.  
  51. episodes: function (doc, media) {
  52.  
  53. var episodes = document.evaluate('//div[@class="tv_episode_item"]/a', doc.body, null, XPathResult.ANY_TYPE);
  54. var seasonNo = parseInt(media.seasonNo, 10);
  55. var episodeNo = parseInt(media.episodeNo, 10);
  56.  
  57. for (var episode = episodes.iterateNext(); episode; episode = episodes.iterateNext()) {
  58.  
  59. var href = episode.getAttribute('href');
  60.  
  61. if ((new RegExp('/[^/]+/season-' + seasonNo + '-episode-' + episodeNo)).test(href)) {
  62.  
  63. return httpGet(aggregators.Primewire.URL + href, aggregators.Primewire.sources, media);
  64.  
  65. }
  66.  
  67. }
  68.  
  69. return actions.searchShortendTitle(aggregators.Primewire.search, media);
  70.  
  71. },
  72.  
  73. sources: function (doc, media) {
  74.  
  75. var links = document.evaluate('//table[@class="movie_version"]', doc.body, null, XPathResult.ANY_TYPE);
  76.  
  77. for (var link = links.iterateNext(); link; link = links.iterateNext()) {
  78.  
  79. var quality = document.evaluate('.//td[1]/span/@class', link, null, XPathResult.STRING_TYPE).stringValue;
  80.  
  81. if (quality === 'quality_dvd') {
  82.  
  83. if (document.evaluate('.//td[3]/span/script/text()', link, null, XPathResult.STRING_TYPE).stringValue !== 'Promo Host') {
  84.  
  85. return actions.showExternalLink(doc.url, 'PRIMEWIRE');
  86.  
  87. }
  88.  
  89. }
  90.  
  91. }
  92.  
  93. }
  94.  
  95. };
  96.  
  97.  
  98. aggregators.Icefilms = {
  99.  
  100. URL: 'https://www.icefilms.info',
  101.  
  102. search: function (media) {
  103.  
  104. var letter = media.title.toLowerCase().replace('the ', '').replace('a ', '').replace(' ', '')[0].toUpperCase();
  105.  
  106. httpGet(aggregators.Icefilms.URL + '/' + (media.isMovie ? 'movies' : 'tv') + '/a-z/' + letter, aggregators.Icefilms.index, media);
  107.  
  108. },
  109.  
  110. index: function (doc, media) {
  111.  
  112. var pages = doc.evaluate('//a[starts-with(text(), "' + media.title + '")]', doc.body, null, XPathResult.ANY_TYPE);
  113. var matches = 0;
  114. for (var page = pages.iterateNext(); page; page = pages.iterateNext()) {
  115.  
  116. if ((new RegExp(' \\(' + media.year + '\\)$')).test(page.textContent)) {
  117.  
  118. ++matches;
  119. httpGet(aggregators.Icefilms.URL + page.getAttribute('href'), media.isEpisode ? aggregators.Icefilms.episodes : aggregators.Icefilms.sources, media);
  120.  
  121. }
  122.  
  123. }
  124.  
  125. if (matches === 0) {
  126. return actions.searchShortendTitle(aggregators.Icefilms.search, media);
  127. }
  128.  
  129. },
  130.  
  131. episodes: function (doc, media) {
  132.  
  133. var episodes = document.evaluate('//a[starts-with(@href, "/ip\.php\?v=")]', doc.body, null, XPathResult.ANY_TYPE);
  134.  
  135. for (var episode = episodes.iterateNext(); episode; episode = episodes.iterateNext()) {
  136. if ((new RegExp('^' + media.seasonNo + 'x' + media.episodeNo + ' ')).test(episode.textContent)) {
  137.  
  138. return httpGet(aggregators.Icefilms.URL + episode.getAttribute('href'), aggregators.Icefilms.sources, media);
  139.  
  140. }
  141.  
  142. }
  143.  
  144. },
  145.  
  146. sources: function (doc, media) {
  147.  
  148. if (doc.getElementById('videoframe')) {
  149. actions.showExternalLink(doc.url, 'ICEFILMS');
  150. }
  151.  
  152. }
  153.  
  154. };
  155.  
  156.  
  157. var actions = {};
  158.  
  159. actions.showExternalLink = function (url, label) {
  160.  
  161. var nav = document.evaluate('//section[@id="info-wrapper"]/div[@class="container"]/div[1]/div[1]/div[1]/ul[@class="external"]', document.body, null, XPathResult.FIRST_ORDERED_NODE_TYPE).singleNodeValue;
  162. var li = document.createElement('li');
  163. li.innerHTML = '<a href="' + url + '" target="_blank">' + label + '<div class="fa fa-external-link"></div></a>';
  164. nav.appendChild(li);
  165.  
  166. };
  167.  
  168.  
  169. actions.searchShortendTitle = function (search, media) {
  170.  
  171. var words = media.title.split(' ');
  172.  
  173. if (words.length > 1) {
  174. words.splice(0, 1);
  175. media.title = words.join(' ');
  176. search(media);
  177. }
  178.  
  179. };
  180.  
  181.  
  182. var httpGet = function (url, onload, data) {
  183.  
  184. GM_xmlhttpRequest({
  185. method: 'GET',
  186. url: url,
  187. onload: function (response) {
  188. if (response.status === 200) {
  189. var doc = document.implementation.createHTMLDocument();
  190. doc.documentElement.innerHTML = response.responseText;
  191. doc.url = url;
  192. onload(doc, data);
  193. }
  194. }
  195. });
  196.  
  197. };
  198.  
  199.  
  200. var traktUrl;
  201.  
  202. var trakTheSources = function () {
  203. // If URL hasn't change since last check, don't check again
  204. if (traktUrl === window.location.href) return;
  205.  
  206. traktUrl = window.location.href;
  207. // Remove none VIP Ads
  208. document.querySelector('[id="huckster-desktop-wrapper"]').style.display = 'none';
  209. document.querySelector('[id="huckster-desktop-bottom"]').style.display = 'none';
  210.  
  211. var media = {
  212. isMovie: /^https?:\/\/trakt\.tv\/movies\//.test(traktUrl),
  213. isEpisode: /^https?:\/\/trakt\.tv\/shows\//.test(traktUrl)
  214. };
  215.  
  216. if (media.isMovie) {
  217.  
  218. var title = /^(.*) \((\d+)\)/.exec(document.title);
  219.  
  220. media.title = title[1];
  221. media.year = title[2];
  222.  
  223. } else if (media.isEpisode) {
  224.  
  225. var title = /^(.*) (\d+)x(\d+) (&quot;|")(.*)(&quot;|")/.exec(document.title);
  226.  
  227. media.title = title[1];
  228. media.year = '\\d+';
  229. media.seasonNo = title[2];
  230. media.episodeNo = title[3];
  231. media.episodeName = title[5];
  232.  
  233. } else {
  234.  
  235. return;
  236.  
  237. }
  238.  
  239. var aggregatorNames = Object.getOwnPropertyNames(aggregators);
  240.  
  241. for (var nameIndex in aggregatorNames) {
  242.  
  243. aggregators[aggregatorNames[nameIndex]].search(JSON.parse(JSON.stringify(media)));
  244.  
  245. }
  246.  
  247. };
  248.  
  249. setInterval(trakTheSources, 1000);