TrakTheSources

Sources movies and tv episodes for Trakt.tv

目前为 2015-06-24 提交的版本,查看 最新版本

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