IMDb Scout

Add links from IMDb pages to torrent sites -- easy downloading from IMDb

当前为 2019-02-17 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name IMDb Scout
  3. // @namespace https://greasyfork.org/users/1057-kannibalox
  4. // @description Add links from IMDb pages to torrent sites -- easy downloading from IMDb
  5. //
  6. // Preference window for userscripts, hosted by greasyfork:
  7. // @require https://greasyfork.org/libraries/GM_config/20131122/GM_config.js
  8. // @require http://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js
  9. //
  10. // @version 4.11.0
  11. // @include http*://*.imdb.tld/title/tt*
  12. // @include http*://*.imdb.tld/search/title*
  13. // @include http*://*.imdb.tld/user/*/watchlist*
  14. // @include http*://*.imdb.com/title/tt*
  15. // @include http*://*.imdb.com/search/title*
  16. // @include http*://*.imdb.com/user/*/watchlist*
  17. //
  18. // @connect *
  19. // @grant GM_log
  20. // @grant GM_getValue
  21. // @grant GM_setValue
  22. // @grant GM_addStyle
  23. // @grant GM_openInTab
  24. // @grant GM_xmlhttpRequest
  25. // @grant GM_registerMenuCommand
  26. //
  27. // ==/UserScript==
  28. /*---------------------Version History--------------------
  29. 1.00 - Initial public release, everything works on barebones greasemonkey
  30.  
  31. 1.50 - Added the ability to select which sites to load from the GM script commands
  32. - Moved the required method to userscripts
  33. - Removed FH, NZB, Avax
  34.  
  35. 1.60 - Added style elements and shading to display on imdb
  36.  
  37. 1.62 - Fixed bug:SCC-ARC not removing when unchecked
  38. - Alphabetized list
  39.  
  40. 1.70 - Cleaned up code
  41. - Added option to not run script on page load
  42.  
  43. 1.71 - Deprecated action-box field
  44.  
  45. 1.80 - Added icons that link to OpenSubs, Criticker, RT, YT
  46.  
  47. 1.81 - Added support for tv, only displays on shows listed as 'tv series'
  48. - Added support for icheckmovies at top bar.
  49.  
  50. 1.82 - Fixed title parsing for tv shows.
  51.  
  52. 1.83 - Fixed dhive not working properly
  53.  
  54. 1.90 - Set height of preference window to 450px, added scroll bar
  55.  
  56. 1.91 - Added another 11 torrent sites
  57.  
  58. 2.00 - Added auto updater
  59.  
  60. 2.01 - Added TC, FreshOn, TVT, STF, CC
  61. - Cleaned up code (tabbing)
  62. - Removed THR
  63. - Added TV-Rage to top bar
  64.  
  65. 2.02 - Added PS, THC, HH, HDStar
  66. - Fixed CC false positive
  67.  
  68. 2.03 - TehC now uses tt
  69. - Added Raymoz mod for AT
  70.  
  71. 2.04 - Added HDbits
  72. - Added TL
  73.  
  74. 2.10 - Added genre page search functionality
  75.  
  76. 2.11 - Fixed ICM because Nuked was whining
  77.  
  78. 2.12 - Removed tvrage
  79. - Fixed iCM (added tt)
  80. - Added HDVNbits
  81. - Changed RevTT to .me
  82. - Added HDT
  83. - removed autoupdate
  84.  
  85. 2.13 - removed xvidme
  86. - reinstated autoupdate
  87. - removed google chrome code
  88. - fixed hdvn and hdt issues
  89.  
  90. 2.14 - Added @grant entries for API access
  91. - Fixed tt parser to work on imdb pages with referral info in url
  92.  
  93. 2.2 - Switch preferences window to use GM_config
  94. - Consolidate icon & site lists
  95. - Added IPT, KASS, sHD, and HDW
  96. - Fix "Open All" link
  97. - Add option for strikethroughs on search page
  98. - Removed arrays from search URLs
  99. - Spring cleaning
  100.  
  101. 2.21 - Added SSL to TVT, HDME, TC, AHD, IPT, SCC
  102. - Added SSL option for CG
  103. - Added GFT, GFT-Gems, GFT-TV
  104. - Fixed SCC, SCC-ARC search URL
  105. - Removed TheBox, TheDVDClub
  106. - Added more comments, cleaned up some more stuff
  107.  
  108. 2.22 - Fixed TehC, BTN, BTN-Req, THC
  109. - Added a bunch of TV sites, courtesy of seedless
  110. - Added "both" option for sites, and made changes
  111. to allow coexistence of movie and TV sites with
  112. the same name
  113. - Code re-organization, documentation
  114. - Re-added code to allow an array for searchUrl
  115.  
  116. 2.22.1 - Minor fixes
  117.  
  118. 2.23 - Fixed THC, BTN
  119. - Distinguish between movies and TV on search page
  120.  
  121. 2.24 - Separate load_on_start option for search page
  122. - Fix search_string on search page
  123.  
  124. 2.25 - Added some helpful text when no sites have been enabled
  125.  
  126. 2.26 - Added code to show links when on pages besides just the "front" one
  127. (e.g. http://www.imdb.com/title/tt2310332/reference)
  128.  
  129. 2.26.1 - Correctly detect TV shows when on aforementioned pages.
  130.  
  131. 2.3 - Incorporate a bunch of changes courtesy of Inguin:
  132. - Added SSL to AT, TE, D-noid, TG, YT, RT
  133. - Changed tracker short titles to canonical form ADC, KG
  134. - Updated D-noid from .me to .pw
  135. - Fixed broken AT search; also updated to use .me so avoids redirect
  136. - Added BitHQ, ET (eutorrents)
  137. - Removed two broken THC; replaced with one fixed
  138. - Removed iplay, horrorhaven, hdstar, scandbits, leecherslair
  139. - Removed needless CG http/https duplication - plenty of listed sites self-sign
  140. - A-Z sites list for readability
  141. - Cleanup YT search string
  142. - Copyedits
  143. - Clean up code (tabs, trailing spaces)
  144. - Use consistent naming style
  145. - Added Letterboxd, Subscene to icons
  146. - Added options for showing icons
  147.  
  148. 2.31 - Added preliminary check for TSH
  149. - Change all SCC links to .org
  150.  
  151. 2.31.1 - Typo fix
  152.  
  153. 2.32 - On uncertain pages, display both movie and TV sites
  154.  
  155. 2.33 - Add year to possible search params
  156. - Add rutorrent
  157.  
  158. 2.33.1 - Change KG to .in
  159.  
  160. 2.33.2 - Change TSH to .me
  161.  
  162. 2.34 - Updated AT, TPB
  163. - Removed HDWing, TVT and CHDBits
  164. - Added RARBG
  165. - Re-added reverse match checking to support rarbg
  166.  
  167. 2.35 - Fixed YouTube icon, add SubtitleSeeker icon
  168. - Added FL.ro, bB, BHD, HDS
  169. - Fixed TL, TehC, HDb, HDVN, AHD, KG
  170. - Renamed reverseMatch to positiveMatch
  171.  
  172. 2.36 - Added Wikipedia to icon sites
  173.  
  174. 2.36.1 - Typo fix
  175.  
  176. 2.37 - Add PxHD
  177.  
  178. 2.38 - Fix subtitle seeker
  179. - Added CG-c
  180. - Added FilmAffinity
  181. - Added option to skip http check entirely
  182.  
  183. 2.38.1 - Typo fix
  184.  
  185. 2.38.2 - Global replace parameters
  186.  
  187. 2.38.3 - Typo fix
  188.  
  189. 3.00 - Clean up some formatting
  190. - Add support for new IMDb page format
  191. - Update jquery
  192.  
  193. 3.0.1 - Added Classix
  194.  
  195. 3.0.2 - Updated documentation/comments
  196.  
  197. 3.0.3 - Removed GOEM, FY, PS, MT
  198. - Added Metacritic, CanIStream.It?, AllMovie, Facebook, Amazon, Cartoon Chaos, MySpleen, Secret Cinema
  199. - Fixed Wikipedia icon
  200.  
  201. 3.1 - Handle HTTP failures less silently
  202.  
  203. 3.1.1 - Fix KASS
  204.  
  205. 3.1.2 - Fix TPB, TE, HDT
  206. - Add MTV, DVDSeed
  207.  
  208. 3.1.3 - Add M-T, UHDB, HDC, Blu-ray.com
  209. - Fix scenehd, RT
  210.  
  211. 3.1.4 - Add HDClub
  212.  
  213. 3.2 - Fix the button on new-style pages
  214.  
  215. 3.2.1 - Fix AHD
  216.  
  217. 3.3 - Be less obnoxious about failed calls
  218.  
  219. 3.4 - Add Netflix icon
  220. - Remove a default parameter to satisfy Chrome
  221.  
  222. 3.5 - Add KZ, NNM, BB-HD, t411, TD, Rutor
  223. - Fix HDClub
  224. - Fix preferences in Chrome, sort sites properly
  225.  
  226. 3.5.1 - Remove DHive, Fix AHD
  227.  
  228. 4.0 - Bring in UI changes courtesy of janot
  229. - Add spaceEncode and goToUrl to site options
  230. - Add option to show results as links instead of text
  231. - Differentiate between missing and logged out
  232. - General refactoring
  233.  
  234. 4.1 - Add RARAT
  235.  
  236. 4.2 - Fix t411
  237. - Use magic .tld domain in @include
  238.  
  239. 4.3 - Set @connect in metadata block
  240.  
  241. 4.3.1 - Fix THC
  242.  
  243. 4.3.2 - Add AR, TtN
  244. - Add year and "trailer" to youtube search
  245. - Fix M-team
  246.  
  247. 4.3.3 - Fix BitHQ, PTP-Req, SCC
  248.  
  249. 4.3.4 - Fix M-team, myspleen, avistaz, eutorrents
  250. - Removed KAT
  251.  
  252. 4.3.5 - Fix IPT, Freshon
  253. - Add ExtraTorrent
  254.  
  255. 4.3.6 - Fix Demonoid, EuTorrents (now CinemaZ)
  256. - Fix "Actually search for torrents" option
  257. - Add PrivateHD for movies and tv
  258.  
  259. 4.3.7 - Apply CinemaZ fixes to AvistaZ as well
  260.  
  261. 4.3.8 - Fix SurrealMoviez and MySpleen, switch to new PTP url
  262.  
  263. 4.3.9 - Fix criticker, add CN
  264.  
  265. 4.3.10 - Fix Netflix, MTV
  266.  
  267. 4.3.11 - Add CHD back
  268.  
  269. 4.3.12 - Fix typo
  270.  
  271. 4.4 - Fix BeyondHD
  272. - Allow unicode when searching by name
  273.  
  274. 4.4.1 - Add trakt.tv
  275.  
  276. 4.4.2 - Added XS, HD-S, PTN, TBD, Blutopia
  277. - Removed Freshon, CN, ExT, t411, SCC
  278. - Fixed SC, TE, TG, Tik
  279. - Add .com for script runners that don't support .tld
  280.  
  281. 4.5 - (Chameleon)
  282. - Added an option to run on ILC request pages
  283. - Fixed running on reference pages (new imdb style)
  284. - Added a delay of 1 second between loading the same site (by domain) - no more popcorn quota timeouts
  285. - Fixed running on search pages
  286.  
  287. 4.5.1 - Removed (dead): BitHQ, TehC, FSS, ExtraTorrent, Cine-Clasico, and Secret-Cinema
  288. - Fixed the hack on goToUrl
  289.  
  290. 4.5.2 - Fixed filelist.ro, Tik, TD
  291. - Added HDHome, HDU, OurBits
  292.  
  293. 4.5.3 - Fixed TG, TE, HDSpace
  294. - Added XS
  295.  
  296. 4.5.4 - Fixed HDU
  297.  
  298. 4.5.5 - Fixed BHD
  299.  
  300. 4.6 - Option to highlight if the movie is missing from PTP
  301.  
  302. 4.7 - Added option to ignore the movie/tv distinction
  303.  
  304. 4.7.1 - Fix blutopia, hdchina, indenting
  305.  
  306. 4.7.2 - Fix SDBits, M-T
  307. - Add TTGg
  308.  
  309. 4.7.3 - Enable on https versions of imdb sites
  310. - Add TTG
  311.  
  312. 4.8.0 - Add FinVip, JoyHD, TO, TP, TS, TVCK
  313. - Fix TE, HDH, CZ, Subscene
  314. - Remove SubtitleSeeker
  315. - Rip out all site-specific code
  316. - Fix up minor code smells
  317. - Allow config name to be different from site name
  318.  
  319. 4.8.1 - Add SP
  320.  
  321. 4.8.2 - Add TMDB
  322.  
  323. 4.8.3 - Add TGx
  324. - Fix TTG, JoyHD, HDH
  325. - Remove duplicate TMDB
  326.  
  327. 4.9.0 - Add support for a user's watchlist
  328.  
  329. 4.10.0 - Add support for icon sites on the reference view
  330. - Add HTTPS for icon sites that support it
  331.  
  332. 4.11.0 - Fix search_string
  333.  
  334. -------------------------------------------------------*/
  335.  
  336. if (window.top != window.self) // Don't run on frames or iframes
  337. {
  338. return;
  339. }
  340.  
  341. //------------------------------------------------------
  342. // A list of all the sites, and the data necessary to
  343. // check IMDb against them.
  344. // Each site is a dictionary with the following attributes:
  345. // - name:
  346. // The site name, abbreviated
  347. // - searchUrl:
  348. // The URL to perform the search against, see below for how
  349. // to tailor the string to a site
  350. // - matchRegex:
  351. // The string which appears if the searchUrl *doesn't* return a result
  352. // - postiveMatch (optional):
  353. // Changes the test to return true if the searchUrl *does* return
  354. // a result that matches matchRegex
  355. // - TV (optional):
  356. // If true, it means that this site will only show up on TV pages.
  357. // By default, sites only show up on movie pages.
  358. // - both (optional):
  359. // Means that the site will show up on both movie and TV pages
  360. // - spaceEncode (optional):
  361. // Changes the character used to encode spaces in movie titles
  362. // The default is '+'.
  363. // - goToUrl (optional):
  364. // Most of the time the same URLs that are used for checking are
  365. // the ones that are used to actually get to the movie,
  366. // but this allows overriding that.
  367. // - loggedOutRegex (optional):
  368. // If any text on the page matches this regex, the site is treated
  369. // as being logged out, rather than mising the movie. This option is
  370. // not effected by postiveMatch.
  371. // - configName (optional):
  372. // Use this to allow changing names without breaking existing users.
  373. // To create a search URL, there are four parameters
  374. // you can use inside the URL:
  375. // - %tt%:
  376. // The IMDb id with the tt prefix (e.g. tt0055630)
  377. // - %nott%:
  378. // The IMDb id without the tt prefix (e.g. 0055630)
  379. // - %search_string%:
  380. // The movie title (e.g. Yojimbo)
  381. // - %year%:
  382. // The movie year (e.g. 1961)
  383. // See below for examples
  384. //------------------------------------------------------
  385.  
  386. var sites = [
  387. { 'name': 'ADC',
  388. 'searchUrl': 'https://asiandvdclub.org/browse.php?descr=1&btnSubmit=Submit&search=%tt%',
  389. 'matchRegex': /Your search returned zero results|<h1>You need cookies enabled to log in.<\/h1>/,
  390. 'both': true},
  391. { 'name': 'AHD',
  392. 'searchUrl': 'https://awesome-hd.me/torrents.php?id=%tt%',
  393. 'matchRegex': /Your search did not match anything.|<h2>Error 404<\/h2>/,
  394. 'both': true},
  395. { 'name': 'ANT',
  396. 'searchUrl': 'https://anthelion.me/torrents.php?searchstr=%search_string%&order_by=time&order_way=desc&group_results=1&action=basic&searchsubmit=1',
  397. 'matchRegex': /Your search did not match anything/},
  398. { 'name': 'AR',
  399. 'searchUrl': 'https://alpharatio.cc/torrents.php?searchstr=%search_string%+%year%&filter_cat[6]=1&filter_cat[7]=1&filter_cat[8]=1&filter_cat[9]=1',
  400. 'matchRegex': /Your search did not match anything/},
  401. { 'name': 'AR',
  402. 'searchUrl': 'https://alpharatio.cc/torrents.php?searchstr=%search_string%&filter_cat[1]=1&filter_cat[2]=1&filter_cat[3]=1&filter_cat[4]=1&filter_cat[5]=1',
  403. 'matchRegex': /Your search did not match anything/,
  404. 'TV': true},
  405. { 'name': 'AT',
  406. 'searchUrl': 'https://avistaz.to/movies?search=&imdb=%tt%',
  407. 'matchRegex': /class="overlay-container"/,
  408. 'positiveMatch': true},
  409. { 'name': 'AT',
  410. 'searchUrl': 'https://avistaz.to/tv-shows?search=&imdb=%tt%',
  411. 'matchRegex': /class="overlay-container"/,
  412. 'positiveMatch': true,
  413. 'TV': true},
  414. { 'name': 'Blutopia',
  415. 'searchUrl': 'https://blutopia.xyz/search??imdb=%nott%',
  416. 'both': true},
  417. { 'name': 'bB',
  418. 'searchUrl': 'https://baconbits.org/torrents.php?action=basic&filter_cat[9]=1&searchstr=%search_string%+%year%',
  419. 'matchRegex': /Your search was way too l33t|You will be banned for 6 hours after your login attempts run out/},
  420. { 'name': 'bB',
  421. 'searchUrl': 'https://baconbits.org/torrents.php?action=basic&filter_cat[8]=1&filter_cat[10]=1&searchstr=%search_string%',
  422. 'matchRegex': /Your search was way too l33t|You will be banned for 6 hours after your login attempts run out/,
  423. 'TV': true},
  424. { 'name': 'BB-HD',
  425. 'searchUrl': 'https://bluebird-hd.org/browse.php?search=&incldead=0&cat=0&dsearch=%tt%&stype=or',
  426. 'matchRegex': /Nothing found|Ничего не найдено/,
  427. 'both': true},
  428. { 'name': 'BHD',
  429. 'searchUrl': 'https://beyond-hd.me/browse.php?search=%tt%&searchin=title&incldead=1',
  430. 'matchRegex': /Nothing found!|Please login or Register a personal account to access our user area and great community/},
  431. { 'name': 'BHD',
  432. 'searchUrl': 'https://beyond-hd.me/browse.php?c40=1&c44=1&c48=1&c89=1&c46=1&c45=1&search=%search_string%&searchin=title&incldead=0',
  433. 'matchRegex': /Nothing found!|Please login or Register a personal account to access our user area and great community/,
  434. 'TV': true},
  435. { 'name': 'BitHD',
  436. 'searchUrl': 'http://www.bit-hdtv.com/torrents.php?cat=0&search=%tt%',
  437. 'matchRegex': /<h2>No match!<\/h2>/},
  438. { 'name': 'BTN',
  439. 'searchUrl': 'https://broadcasthe.net/torrents.php?imdb=%tt%',
  440. 'matchRegex': /Error 404|Lost your password\?/,
  441. 'TV': true},
  442. { 'name': 'BTN-Req',
  443. 'searchUrl': 'https://broadcasthe.net/requests.php?search=%search_string%',
  444. 'matchRegex': /Nothing found|Lost your password\?/,
  445. 'TV': true},
  446. { 'name': 'CaCh',
  447. 'searchUrl': 'http://www.cartoonchaos.org/index.php?page=torrents&search=%search_string%&category=0&options=0&active=0',
  448. 'matchRegex': />Av.<\/td>\s*<\/tr>\s*<\/table>|not authorized to view the Torrents/,
  449. 'both': true},
  450. { 'name': 'CG',
  451. 'searchUrl': 'https://cinemageddon.net/browse.php?search=%tt%',
  452. 'matchRegex': /<h2>Nothing found!<\/h2>/,
  453. 'loggedOutRegex': 'Not logged in!'},
  454. { 'name': 'CG-c',
  455. 'searchUrl': 'https://cinemageddon.net/cocks/endoscope.php?what=imdb&q=%tt%',
  456. 'matchRegex': /<h2>Nothing found!<\/h2>/,
  457. 'loggedOutRegex': 'Not logged in!'},
  458. { 'name': 'CHD',
  459. 'searchUrl': 'https://chdbits.co/torrents.php?incldead=1&spstate=0&inclbookmarked=0&search_area=4&search_mode=0&search=%tt%',
  460. 'matchRegex': /Nothing found/},
  461. { 'name': 'Classix',
  462. 'searchUrl': 'http://classix-unlimited.co.uk/torrents-search.php?search=%search_string%',
  463. 'matchRegex': /Nothing Found<\/div>/},
  464. { 'name': 'CZ',
  465. 'configName': 'ET',
  466. 'searchUrl': 'https://cinemaz.to/movies?search=&imdb=%tt%',
  467. 'matchRegex': /class="overlay-container"/,
  468. 'positiveMatch': true},
  469. { 'name': 'CZ',
  470. 'configName': 'ET',
  471. 'searchUrl': 'https://cinemaz.to/tv-shows?search=&imdb=%tt%',
  472. 'matchRegex': /class="overlay-container"/,
  473. 'positiveMatch': true,
  474. 'TV': true},
  475. { 'name': 'Demnoid',
  476. 'searchUrl': 'http://www.demonoid.pw/files/?query=%tt%',
  477. 'matchRegex': /<b>No torrents found<\/b>|We are currently performing the daily site maintenance.<br>/,
  478. 'both': true},
  479. { 'name': 'DVDSeed',
  480. 'searchUrl': 'http://www.dvdseed.eu/browse2.php?search=%tt%&wheresearch=2&incldead=1&polish=0&nuke=0&rodzaj=0',
  481. 'matchRegex': /Nic tutaj nie ma!<\/h2>/},
  482. { 'name': 'eThor',
  483. 'searchUrl': 'http://ethor.net/browse.php?stype=b&c23=1&c20=1&c42=1&c5=1&c19=1&c25=1&c6=1&c37=1&c43=1&c7=1&c9=1&advcat=0&incldead=0&includedesc=1&search=%tt%',
  484. 'matchRegex': /Try again with a refined search string.|<h1>Note: Vous devez activer vos 'cookies' pour pouvoir vous identifier.<\/h1>/},
  485. { 'name': 'FL',
  486. 'searchUrl': 'https://filelist.ro/browse.php?search=%nott%',
  487. 'matchRegex': /<h2>Nu s-a găsit nimic!<\/h2>/,
  488. 'both': true},
  489. { 'name': 'FinVip',
  490. 'searchUrl': 'https://finvip.org/index.php?page=torrents&search=%tt%&options=1',
  491. 'matchRegex': /<td colspan="2" align="center"> <\/td>/},
  492. { 'name': 'HD',
  493. 'searchUrl': 'http://hounddawgs.org/torrents.php?type=&userid=&searchstr=&searchimdb=%tt%&searchlang=&searchtags=&order_by=s3&order_way=desc&showOnly=#results',
  494. 'matchRegex': /<h2>Din søgning gav intet resultat.<\/h2>/,
  495. 'both': true},
  496. { 'name': 'HDb',
  497. 'searchUrl': 'https://hdbits.org/browse.php?c3=1&c1=1&c4=1&c2=1&imdb=%tt%',
  498. 'matchRegex': /Nothing here!|You need cookies enabled to log in/,
  499. 'both': true},
  500. { 'name': 'HDC',
  501. 'searchUrl': 'https://hdchina.org/torrents.php?incldead=0&spstate=0&inclbookmarked=0&boardid=0&seeders=&search=%tt%&search_area=4&search_mode=2',
  502. 'matchRegex': /Nothing found! Try again with a refined search string./},
  503. { 'name': 'HDH',
  504. 'configName': 'HDHome',
  505. 'searchUrl': 'https://hdhome.org/torrents.php?search_area=4&search=%tt%',
  506. 'matchRegex': /Nothing found! Try again with a refined search string/},
  507. { 'name': 'HDME',
  508. 'searchUrl': 'https://hdme.eu/browse.php?blah=2&cat=0&incldead=1&search=%tt%',
  509. 'matchRegex': /Try again with a refined search string.|<h1>You need cookies enabled to log in.<\/h1>/},
  510. { 'name': 'HDME',
  511. 'searchUrl': 'https://hdme.eu/browse.php?search=%search_string%&blah=0&cat=0&incldead=1',
  512. 'matchRegex': /Try again with a refined search string.|<h1>You need cookies enabled to log in.<\/h1>/,
  513. 'TV': true},
  514. { 'name': 'HDS',
  515. 'searchUrl': 'https://hdsky.me/torrents.php?incldead=1&search=%tt%&search_area=4&search_mode=0',
  516. 'matchRegex': /Nothing found! Try again with a refined search string|Email:hdsky.me@gmail.com/},
  517. { 'name': 'HDS',
  518. 'searchUrl': 'https://hdsky.me/torrents.php?cat402=1&cat403=1&incldead=1&search=%search_string%&search_area=0&search_mode=0',
  519. 'matchRegex': /Nothing found! Try again with a refined search string|Email:hdsky.me@gmail.com/,
  520. 'TV': true},
  521. { 'name': 'HDSpace',
  522. 'icon': 'http://www.favicon.by/ico/5991df36e3635.ico',
  523. 'searchUrl': 'https://hd-space.org/index.php?page=torrents&active=0&options=2&search=%nott%',
  524. 'matchRegex': /<td colspan="2" align="center"> <\/td>|You’re not authorized to view the Torrents!<br \/>/,
  525. 'both': true},
  526. { 'name': 'HDT',
  527. 'icon': 'https://hdts.ru/favicon.ico',
  528. 'searchUrl': 'http://hd-torrents.org/torrents.php?active=0&options=2&search=%tt%',
  529. 'matchRegex': /No torrents here.../,
  530. 'both': true},
  531. { 'name': 'HDU',
  532. 'searchUrl': 'https://pt.upxin.net/torrents.php?search_area=4&search=%tt%',
  533. 'matchRegex': /Nothing found! Try again with a refined search string/},
  534. { 'name': 'HDVN',
  535. 'searchUrl': 'http://torviet.com/torrents.php?search=%tt%&search_area=4&search_mode=0',
  536. 'matchRegex': /Nothing found! Try again with a refined search string|You need cookies enabled to log in or switch language/,
  537. 'both': true},
  538. { 'name': 'ILC',
  539. 'searchUrl': 'http://www.iloveclassics.com/browse.php?incldead=1&searchin=2&search=%tt%',
  540. 'matchRegex': /Try again with a refined search string|<h1>Not logged in!<\/h1>/},
  541. { 'name': 'IPT',
  542. 'searchUrl': 'https://www.iptorrents.com/torrents/?q=%tt%',
  543. 'matchRegex': /<h1 style="color:yellow">No Torrents Found!/},
  544. { 'name': 'IPT',
  545. 'searchUrl': 'https://www.iptorrents.com/torrents/?q=%search_string%',
  546. 'matchRegex': /<h1 style="color:yellow">No Torrents Found!/,
  547. 'TV': true},
  548. { 'name': 'JoyHD',
  549. 'searchUrl': 'https://www.joyhd.net/torrents.php?search_area=4&search=%tt%',
  550. 'matchRegex': /Nothing found! Try again with a refined search string/},
  551. { 'name': 'KG',
  552. 'searchUrl': 'https://www.karagarga.in/browse.php?search_type=imdb&search=%nott%',
  553. 'matchRegex': /<h2>No torrents found|<h1>If you want the love<\/h1>/},
  554. { 'name': 'KZ',
  555. 'searchUrl': 'http://kinozal.tv/browse.php?s=%search_string%+%year%&g=0&c=1002&v=0&d=0&w=0&t=0&f=0',
  556. 'matchRegex': 'Нет активных раздач, приносим извинения. Пожалуйста, уточните параметры поиска'},
  557. { 'name': 'KZ',
  558. 'searchUrl': 'http://kinozal.tv/browse.php?s=%search_string%+%year%&g=0&c=1001&v=0&d=0&w=0&t=0&f=0',
  559. 'matchRegex': 'Нет активных раздач, приносим извинения. Пожалуйста, уточните параметры поиска',
  560. 'TV': true},
  561. { 'name': 'M-T',
  562. 'searchUrl': 'https://tp.m-team.cc/torrents.php?incldead=1&spstate=0&inclbookmarked=0&search=%tt%&search_area=4&search_mode=0',
  563. 'matchRegex': /Nothing here!|Try again with a refined search string./,
  564. 'both': true},
  565. { 'name': 'MS',
  566. 'searchUrl': 'http://www.myspleen.org/browse.php?search=%search_string%&title=0&cat=0',
  567. 'matchRegex': /<strong>Nothing found!<\/strong>|<title>MySpleen :: Login<\/title>/,
  568. 'both': true},
  569. { 'name': 'MTV',
  570. 'searchUrl': 'https://www.morethan.tv/torrents.php?searchstr=%search_string%+%year%&tags_type=1&order_by=time&order_way=desc&group_results=1&filter_cat%5B1%5D=1&action=basic&searchsubmit=1',
  571. 'matchRegex': /<h2>Your search did not match anything.<\/h2>/},
  572. { 'name': 'MTV',
  573. 'searchUrl': 'https://www.morethan.tv/torrents.php?searchstr=%search_string%&tags_type=1&order_by=time&order_way=desc&group_results=1&filter_cat%5B2%5D=1&action=basic&searchsubmit=1',
  574. 'matchRegex': /<h2>Your search did not match anything.<\/h2>/,
  575. 'TV': true},
  576. { 'name': 'NNM',
  577. 'searchUrl': 'https://nnm-club.me/forum/tracker.php?nm=%search_string%+%year%',
  578. 'matchRegex': 'Не найдено',
  579. 'both': true},
  580. { 'name': 'NB',
  581. 'searchUrl': 'https://norbits.net/browse.php?incldead=1&fullsearch=0&scenerelease=0&imdbsearch=%tt%&imdb_from=0&imdb_to=0&search=',
  582. 'matchRegex': /<h3>Ingenting her!<\/h3>/,
  583. 'both': true},
  584. { 'name': 'NBL',
  585. 'searchUrl': 'https://nebulance.io/torrents.php?order_by=time&order_way=desc&searchtext=%search_string%&search_type=0&taglist=&tags_type=0',
  586. 'matchRegex': /Your search did not match anything/,
  587. 'TV': true},
  588. { 'name': 'OurBits',
  589. 'searchUrl': 'https://ourbits.club/torrents.php?search_area=4&search=%tt%',
  590. 'matchRegex': /Nothing found! Try again with a refined search string/},
  591. { 'name': 'PHD',
  592. 'searchUrl': 'https://privatehd.to/movies?search=&imdb=%tt%',
  593. 'matchRegex': /class="overlay-container"/,
  594. 'positiveMatch': true},
  595. { 'name': 'PHD',
  596. 'searchUrl': 'https://privatehd.to/tv-shows?search=&imdb=%tt%',
  597. 'matchRegex': /class="overlay-container"/,
  598. 'positiveMatch': true,
  599. 'TV': true},
  600. { 'name': 'PTF',
  601. 'searchUrl': 'https://ptfiles.net/browse.php?search=%search_string%&incldead=0&title=0',
  602. 'matchRegex': /<h2>Nothing found!<\/h2>/},
  603. { 'name': 'PTN',
  604. 'icon': 'https://piratethenet.org/pic/favicon.ico',
  605. 'searchUrl': 'https://piratethenet.org/browseold.php?incldead=1&_by=3&search=%tt%',
  606. 'matchRegex': /Nothing found!/,
  607. 'both': true},
  608. { 'name': 'PTP',
  609. 'searchUrl': 'https://passthepopcorn.me/torrents.php?imdb=%tt%',
  610. 'matchRegex': /<h2>Your search did not match anything.<\/h2>/},
  611. { 'name': 'PTP-Req',
  612. 'searchUrl': 'https://passthepopcorn.me/requests.php?submit=true&search=%tt%',
  613. 'matchRegex': /Your search did not match anything.|<h1>Keep me logged in.<\/h1>/},
  614. { 'name': 'PxHD',
  615. 'searchUrl': 'https://pixelhd.me/torrents.php?groupname=&year=&tmdbover=&tmdbunder=&tmdbid=&imdbover=&imdbunder=&imdbid=%tt%&order_by=time&order_way=desc&taglist=&tags_type=1&filterTorrentsButton=Filter+Torrents',
  616. 'matchRegex': /<h2>Your search did not match anything.<\/h2>/},
  617. { 'name': 'RARAT',
  618. 'searchUrl': 'https://rarat.org/api/v1/torrents?extendedSearch=false&hideOld=false&index=0&limit=15&order=asc&page=search&searchText=%tt%&sort=n#https://rarat.org/search?search=%tt%',
  619. 'goToUrl': 'https://rarat.org/search?search=%tt%',
  620. 'matchRegex': /^$/,
  621. 'both': true},
  622. { 'name': 'RARBG',
  623. 'searchUrl': 'https://rarbg.to/torrents.php?imdb=%tt%',
  624. 'matchRegex': '//dyncdn.me/static/20/images/imdb_thumb.gif',
  625. 'positiveMatch': true,
  626. 'both': true},
  627. { 'name': 'RevTT',
  628. 'searchUrl': 'https://www.revolutiontt.me/browse.php?search=%tt%',
  629. 'matchRegex': /<h2>Nothing found!<\/h2>/},
  630. { 'name': 'RevTT',
  631. 'searchUrl': 'https://www.revolutiontt.me/browse.php?search=%search_string%&cat=0&incldead=1&titleonly=1',
  632. 'matchRegex': /<h2>Nothing found!<\/h2>/,
  633. 'TV': true},
  634. { 'name': 'RuT',
  635. 'searchUrl': 'https://rutracker.org/forum/tracker.php?nm=%search_string%',
  636. 'matchRegex': 'Не найдено',
  637. 'both': true},
  638. { 'name': 'Rutor',
  639. 'searchUrl': 'http://rutor.info/search/0/0/010/0/%tt%',
  640. 'matchRegex': 'Результатов поиска 0',
  641. 'both': true},
  642. { 'name': 'SC',
  643. 'searchUrl': 'https://secret-cinema.pw/torrents.php?action=advanced&searchsubmit=1&filter_cat=1&cataloguenumber=%tt%&order_by=time&order_way=desc&tags_type=0',
  644. 'matchRegex': /Your search did not match anything./},
  645. { 'name': 'SDBits',
  646. 'searchUrl': 'https://sdbits.org/browse.php?c6=1&c3=1&c1=1&c4=1&c5=1&c2=1&m1=1&incldead=0&from=&to=&imdbgt=0&imdblt=10&uppedby=&imdb=&search=%tt%',
  647. 'matchRegex': /Nothing found!|<h1>You need cookies enabled to log in.<\/h1>/},
  648. { 'name': 'sHD',
  649. 'searchUrl': 'https://scenehd.org/browse.php?search=%tt%',
  650. 'matchRegex': /<h2>No torrents found!<\/h2>/},
  651. { 'name': 'SM',
  652. 'searchUrl': 'https://surrealmoviez.info/search.php?stext=%tt%',
  653. 'matchRegex': /0 Movies found matching search criteria|You need to be logged in to view this page/},
  654. { 'name': 'SP',
  655. 'searchUrl': 'http://www.scenepalace.info/browse.php?search=%nott%&cat=0&incldead=1',
  656. 'matchRegex': /<h1>Not logged in!<\/h1>|<h2>Nothing found!<\/h2>/,
  657. 'both': true},
  658. { 'name': 'TBD',
  659. 'icon': 'https://1.bp.blogspot.com/-F2JeKtPCJYI/VgjpVxwMO4I/AAAAAAAAADg/VyNyp-yW9Ac/s1600/TBD.ico',
  660. 'searchUrl': 'http://www.torrentbd.com/torrent/torrents-search.php?search=%search_string%',
  661. 'matchRegex': /No torrents were found based on your search criteria./,
  662. 'both': true},
  663. { 'name': 'TD',
  664. 'searchUrl': 'https://www.torrentday.com/t?q=%tt%',
  665. 'matchRegex': /No Torrents Found!/,
  666. 'both': true},
  667. { 'name': 'TE',
  668. 'searchUrl': 'https://theempire.click/browse.php?incldead=0&country=&nonboolean=1&search=%tt%',
  669. 'matchRegex': /Try again with a refined search string|<h1>You need cookies enabled to log in.<\/h1>/,
  670. 'both': true},
  671. { 'name': 'TG',
  672. 'searchUrl': 'https://thegeeks.click/browse.php?incldead=0&country=&nonboolean=1&search=%tt%',
  673. 'matchRegex': /Try again with a refined search string|<h1>You need cookies enabled to log in.<\/h1>/,
  674. 'both': true},
  675. { 'name': 'TO',
  676. 'searchUrl': 'https://theoccult.click/browse.php?incldead=0&country=&nonboolean=1&search=%tt%',
  677. 'matchRegex': /Try again with a refined search string|<h1>You need cookies enabled to log in.<\/h1>/,
  678. 'both': true},
  679. { 'name': 'TP',
  680. 'searchUrl': 'https://theplace.click/browse.php?incldead=0&country=&nonboolean=1&search=%tt%',
  681. 'matchRegex': /Try again with a refined search string|<h1>You need cookies enabled to log in.<\/h1>/,
  682. 'both': true},
  683. { 'name': 'TS',
  684. 'searchUrl': 'https://theshow.click/browse.php?incldead=0&country=&nonboolean=1&search=%tt%',
  685. 'matchRegex': /Try again with a refined search string|<h1>You need cookies enabled to log in.<\/h1>/,
  686. 'both': true},
  687. { 'name': 'THC',
  688. 'searchUrl': 'https://horrorcharnel.org/browse.php?search=%nott%&cat=0&incldead=1',
  689. 'matchRegex': /<h1>Not logged in!<\/h1>|<h2>Nothing found!<\/h2>/},
  690. { 'name': 'Tik',
  691. 'searchUrl': 'https://www.cinematik.net/browse.php?&cat=0&incldead=1&sort=1&type=asc&srchdtls=1&search=%tt%',
  692. 'matchRegex': /The page you tried to view can only be used when you're logged in|Nothing found!/},
  693. { 'name': 'TL',
  694. 'searchUrl': 'http://www.torrentleech.org/torrents/browse/index/query/%search_string%+%year%/categories/1,8,9,10,11,12,13,14,15,29',
  695. 'matchRegex': /Signup With Invite|Please refine your search./},
  696. { 'name': 'TL',
  697. 'searchUrl': 'http://www.torrentleech.org/torrents/browse/index/query/%search_string%/categories/2,26,27,32',
  698. 'matchRegex': /Signup With Invite|Please refine your search./,
  699. 'TV': true},
  700. { 'name': 'TPB',
  701. 'searchUrl': 'https://thepiratebay.org/search/%tt%',
  702. 'matchRegex': /No hits. Try adding an asterisk in you search phrase.<\/h2>/,
  703. 'both': true},
  704. { 'name': 'TTG',
  705. 'searchUrl': 'https://totheglory.im/browse.php?c=M&search_field=imdb%nott%+%2Bincdead',
  706. 'matchRegex': /Didn't match any titles/},
  707. { 'name': 'TGx',
  708. 'searchUrl': 'https://torrentgalaxy.org/torrents.php?search=%tt%',
  709. 'matchRegex': /No results found/},
  710. { 'name': 'TVCK',
  711. 'searchUrl': 'https://www.tvchaosuk.com/browse.php?do=search&search_type=t_name&keywords=%search_string%',
  712. 'matchRegex': /<b>Nothing Found<\/b>/},
  713. { 'name': 'TVV',
  714. 'searchUrl': 'https://tv-vault.me/torrents.php?action=advanced&imdbid=%tt%&order_by=s3&order_way=desc',
  715. 'matchRegex': /Nothing found<\/h2>/,
  716. 'TV': true},
  717. { 'name': 'UHDB',
  718. 'searchUrl': 'https://uhdbits.org/torrents.php?action=advanced&groupname=%tt%',
  719. 'matchRegex': /Your search did not match anything./},
  720. { 'name': 'XS',
  721. 'searchUrl': 'https://www.xspeeds.eu/browse.php?do=search&keywords=%search_string%&search_type=t_name&category=0&include_dead_torrents=yes',
  722. 'matchRegex': /<b>Nothing Found<\/b>/}
  723. ];
  724.  
  725. var icon_sites = [
  726. { 'name': 'Google',
  727. 'searchUrl': 'https://www.google.com/search?q=%search_string%'},
  728. { 'name': 'TMDB',
  729. 'searchUrl': 'https://www.themoviedb.org/search?query=%search_string%'},
  730. { 'name': 'TVDB',
  731. 'searchUrl': 'https://www.thetvdb.com/search?q=%search_string%'},
  732. { 'name': 'BCDB',
  733. 'searchUrl': 'https://www.bcdb.com/bcdb/search.cgi?query=%search_string%'},
  734. { 'name': 'OpenSubtitles',
  735. 'searchUrl': 'https://www.opensubtitles.org/en/search/imdbid-%tt%'},
  736. { 'name': 'YouTube.com',
  737. 'searchUrl': 'https://www.youtube.com/results?search_query="%search_string%"+%year%+trailer'},
  738. { 'name': 'Rotten Tomatoes',
  739. 'searchUrl': 'https://www.rottentomatoes.com/search/?search=%search_string%'},
  740. { 'name': 'Criticker',
  741. 'searchUrl': 'https://www.criticker.com/?search=%search_string%&type=films'},
  742. { 'name': 'iCheckMovies',
  743. 'searchUrl': 'https://www.icheckmovies.com/search/movies/?query=%tt%'},
  744. { 'name': 'Letterboxd',
  745. 'searchUrl': 'https://letterboxd.com/imdb/%nott%'},
  746. { 'name': 'Subscene',
  747. 'icon': 'https://subscene.com/favicon.ico',
  748. 'searchUrl': 'https://subscene.com/subtitles/title?q=%search_string%'},
  749. { 'name': 'Wikipedia',
  750. 'searchUrl': 'https://en.wikipedia.org/w/index.php?search=%search_string%&go=Go'},
  751. { 'name': 'FilmAffinity',
  752. 'searchUrl': 'https://www.filmaffinity.com/en/advsearch.php?stext=%search_string%&stype[]=title&fromyear=%year%&toyear=%year%',
  753. 'showByDefault': false},
  754. { 'name': 'Metacritic',
  755. 'searchUrl': 'https://www.metacritic.com/search/all/%search_string%/results?cats[movie]=1&cats[tv]=1&search_type=advanced&sort=relevancy',
  756. 'showByDefault': false},
  757. { 'name': 'Can I Stream.It? (Movie)',
  758. 'searchUrl': 'http://www.canistream.it/search/movie/%search_string%',
  759. 'showByDefault': false},
  760. { 'name': 'Can I Stream.It? (TV)',
  761. 'searchUrl': 'http://www.canistream.it/search/tv/%search_string%',
  762. 'showByDefault': false},
  763. { 'name': 'AllMovie',
  764. 'searchUrl': 'https://www.allmovie.com/search/movies/%search_string%',
  765. 'showByDefault': false},
  766. { 'name': 'Facebook',
  767. 'searchUrl': 'https://www.facebook.com/search/str/%search_string%/keywords_pages',
  768. 'showByDefault': false},
  769. { 'name': 'Amazon',
  770. 'searchUrl': 'https://www.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Dmovies-tv&field-keywords=%search_string%',
  771. 'showByDefault': false},
  772. { 'name': 'Netflix',
  773. 'searchUrl': 'https://www.netflix.com/search/%search_string%',
  774. 'showByDefault': false},
  775. { 'name': 'Blu-ray.com',
  776. 'searchUrl': 'https://www.blu-ray.com/search/?quicksearch=1&quicksearch_country=all&quicksearch_keyword=%search_string%+&section=bluraymovies',
  777. 'showByDefault': false},
  778. { 'name': 'trakt.tv',
  779. 'icon': 'https://walter.trakt.tv/hotlink-ok/public/favicon.ico',
  780. 'searchUrl': 'https://trakt.tv/search?query=%search_string%',
  781. 'showByDefault': false}
  782. ];
  783.  
  784. // For internal use (order matters)
  785. var valid_states = [
  786. 'found',
  787. 'missing',
  788. 'logged_out',
  789. 'error'
  790. ];
  791.  
  792. function replaceSearchUrlParams(site, movie_id, movie_title) {
  793. var search_url = site['searchUrl'];
  794. // If an array, do a little bit of recursion
  795. if ($.isArray(search_url)) {
  796. var search_array = [];
  797. $.each(search_url, function(index, url) {
  798. search_array[index] = replaceSearchUrlParams(url, movie_id, movie_title);
  799. });
  800. return search_array;
  801. }
  802. var space_replace = ('spaceEncode' in site) ? site['spaceEncode'] : '+';
  803. var search_string = movie_title.trim().replace(/ +\(.*/, '').replace(/\s+/g, space_replace);
  804. var movie_year = document.title.replace(/^(.+) \((.*)([0-9]{4})(.*)$/gi, '$3');
  805. var s = search_url.replace(/%tt%/g, 'tt' + movie_id)
  806. .replace(/%nott%/g, movie_id)
  807. .replace(/%search_string%/g, search_string)
  808. .replace(/%year%/g, movie_year);
  809. return s;
  810. }
  811.  
  812. function getPageSetting(key) {
  813. return (onSearchPage ? GM_config.get(key + '_search') : GM_config.get(key + '_movie'));
  814. }
  815.  
  816. // Small utility function to return a site's icon
  817. function getFavicon(site, hide_on_err) {
  818. if (typeof(hide_on_err) === 'undefined') { hide_on_err = false };
  819. if ('icon' in site) {
  820. var favicon = site['icon'];
  821. } else {
  822. var url = new URL(site['searchUrl']);
  823. var favicon = url.origin + '\/favicon.ico';
  824. }
  825. var img = $('<img />').attr({'style': '-moz-opacity: 0.4; border: 0; vertical-align: text-top',
  826. 'width': '16',
  827. 'src': favicon,
  828. 'title': site['name'],
  829. 'alt': site['name']});
  830. if (hide_on_err) { img.attr('onerror', "this.style.display='none';") };
  831. return img;
  832. }
  833.  
  834. // Adds search links to an element
  835. // state should always be one of the values defined in valid_states
  836. function addLink(elem, link_text, target, site, state) {
  837. var link = $('<a />').attr('href', target).attr('target', '_blank');
  838. if ($.inArray(state, valid_states) < 0) {
  839. console.log("Unknown state " + state);
  840. }
  841. if (getPageSetting('use_icons')) {
  842. var icon = getFavicon(site);
  843. icon.css({'border-width': '3px', 'border-style': 'solid', 'border-radius': '2px'});
  844. if (state == 'error' || state == 'logged_out') {
  845. icon.css('border-color', 'red');
  846. } else if (state == 'missing') {
  847. icon.css('border-color', 'yellow');
  848. } else {
  849. icon.css('border-color', 'green');
  850. }
  851. link.append(icon);
  852. } else {
  853. if (state == 'missing' || state == 'error' || state == 'logged_out') {
  854. link.append($('<s />').append(link_text));
  855. } else {
  856. link.append(link_text);
  857. }
  858. if (state == 'error' || state == 'logged_out') {
  859. link.css('color', 'red');
  860. }
  861. }
  862.  
  863. if (!onSearchPage) {
  864. $('#imdbscout_' + state).append(link).append(' ');
  865. } else {
  866. var result_box = $(elem).find('td.result_box');
  867. if (result_box.length > 0) {
  868. $(result_box).append(link);
  869. } else {
  870. $(elem).append($('<td />').append(link).addClass('result_box'));
  871. }
  872. }
  873. }
  874.  
  875. // Performs an ajax request to determine
  876. // whether or not a url should be displayed
  877. function maybeAddLink(elem, link_text, search_url, site) {
  878. // If the search URL is an array, recurse briefly on the elements.
  879. if ($.isArray(search_url)) {
  880. $.each(search_url, function(index, url) {
  881. maybeAddLink(elem, link_text + '_' + (index + 1).toString(), url, site);
  882. });
  883. return;
  884. }
  885.  
  886. var domain = search_url.split('/')[2];
  887. var now = (new Date())*1;
  888. var lastLoaded = window.localStorage[domain+'_lastLoaded'];
  889. if (!lastLoaded) {
  890. lastLoaded = now - 5000;
  891. } else {
  892. lastLoaded = parseInt(lastLoaded);
  893. }
  894. if (now-lastLoaded < 1000) {
  895. window.setTimeout(maybeAddLink.bind(undefined, elem, site['name'], search_url, site), 1000);
  896. return;
  897. }
  898. else
  899. {
  900. window.localStorage[domain+'_lastLoaded']=(new Date())*1;
  901. }
  902.  
  903. var target = search_url;
  904. if (site.goToUrl) {
  905. target = site.goToUrl;
  906. }
  907. var success_match = ('positiveMatch' in site) ? site['positiveMatch'] : false;
  908. GM_xmlhttpRequest({
  909. method: 'GET',
  910. url: search_url,
  911. onload: function(response_details) {
  912. if (String(response_details.responseText).match(site['matchRegex']) ? !(success_match) : success_match) {
  913. if (getPageSetting('highlight_missing').split(',').includes(site['name'])) {
  914. if (elem.style) {
  915. elem.parentNode.style.background = 'rgba(255,104,104,0.7)';
  916. } else {
  917. document.querySelector('#imdbscout_missing').style.background = 'rgba(255,104,104,0.7)';
  918. }
  919. }
  920. if (!getPageSetting('hide_missing')) {
  921. addLink(elem, link_text, target, site, 'missing');
  922. }
  923. } else if (site['loggedOutRegex'] && String(response_details.responseText).match(site['loggedOutRegex'])) {
  924. addLink(elem, link_text, target, site, 'logged_out');
  925. } else {
  926. addLink(elem, link_text, target, site, 'found');
  927. }
  928. },
  929. onerror: function(response) {
  930. addLink(elem, link_text, target, site, 'error');
  931. },
  932. onabort: function(response) {
  933. addLink(elem, link_text, target, site, 'error');
  934. }
  935. });
  936. }
  937.  
  938. // Run code to create fields and display sites
  939. function perform(elem, movie_id, movie_title, is_tv, is_movie) {
  940. var site_shown = false;
  941. $.each(sites, function(index, site) {
  942. if (site['show']) {
  943. site_shown = true;
  944. // If we're on a TV page, only show TV links.
  945. if ((Boolean(site['TV']) == is_tv ||
  946. Boolean(site['both'])) ||
  947. (!is_tv && !is_movie) || getPageSetting('ignore_type')) {
  948. searchUrl = replaceSearchUrlParams(site, movie_id, movie_title);
  949. if (site.goToUrl)
  950. site.goToUrl = replaceSearchUrlParams({
  951. 'searchUrl': site['goToUrl'],
  952. 'spaceEncode': ('spaceEncode' in site) ? site['spaceEncode'] : '+'
  953. }, movie_id, movie_title);
  954. if (getPageSetting('call_http')) {
  955. maybeAddLink(elem, site['name'], searchUrl, site);
  956. } else {
  957. addLink(elem, site['name'], searchUrl, site, 'found');
  958. }
  959. }
  960. }
  961. });
  962. if (!site_shown) {
  963. $(elem).append('No sites enabled! You can change this via the Greasemonkey option "IMDb Scout Preferences".');
  964. }
  965. }
  966.  
  967. //------------------------------------------------------
  968. // Button Code
  969. //------------------------------------------------------
  970.  
  971. function displayButton() {
  972. var p = $('<p />').attr('id', 'imdbscout_button');
  973. p.append($('<button>Load IMDb Scout</button>').click(function() {
  974. $('#imdbscout_button').remove();
  975. if (onSearchPage) {
  976. performSearch();
  977. } else {
  978. performPage();
  979. }
  980. }));
  981. if (onSearchPage) {
  982. $('#sidebar').append(p);
  983. } else if ($('h1.header:first').length) {
  984. $('h1.header:first').parent().append(p);
  985. } else {
  986. $('#title-overview-widget').parent().append(p);
  987. }
  988. }
  989.  
  990. //------------------------------------------------------
  991. // Icons at top bar
  992. //------------------------------------------------------
  993.  
  994. // Adds a dictionary of icons to the top of the page.
  995. // Unlike the other URLs, they aren't checked to see if the movie exists.
  996. function addIconBar(movie_id, movie_title) {
  997. if ($('h1.header:first').length) {
  998. var iconbar = $('h1.header:first').append($('<br/>'));
  999. } else if ($('.title_wrapper h1').length) {
  1000. var iconbar = $('.title_wrapper h1').append($('<br/>'));
  1001. } else if ($('h3[itemprop="name"]').length) {
  1002. var iconbar = $('h3[itemprop="name"]').append($('<br/>'));
  1003. } else {
  1004. var iconbar = $('#tn15title .title-extra');
  1005. }
  1006. $.each(icon_sites, function(index, site) {
  1007. if (site['show']) {
  1008. var search_url = replaceSearchUrlParams(site, movie_id, movie_title);
  1009. var image = getFavicon(site);
  1010. var html = $('<span />').append("&nbsp;").attr('style', 'font-size: 11px;').append(
  1011. $('<a />').attr('href', search_url)
  1012. .addClass('iconbar_icon').append(image));
  1013. iconbar.append(html).append();
  1014. }
  1015. });
  1016. //If we have access to the openInTab function, add an Open All feature
  1017. if (GM_openInTab) {
  1018. var aopenall = $('<a />').text('Open All')
  1019. .prepend("&nbsp;")
  1020. .attr('href', 'javascript:;')
  1021. .attr('style', 'font-weight:bold;font-size:11px;font-family: Calibri, Verdana, Arial, Helvetica, sans-serif;');
  1022. aopenall.click(function() {
  1023. $('.iconbar_icon').each(function() {
  1024. GM_openInTab($(this).attr('href'));
  1025. });
  1026. }, false);
  1027. iconbar.append(aopenall);
  1028. }
  1029. }
  1030.  
  1031. //------------------------------------------------------
  1032. // Search page code
  1033. //------------------------------------------------------
  1034.  
  1035. function performSearch() {
  1036. //Add css for the new table cells we're going to add
  1037. var styles = '.result_box {width: 335px}';
  1038. styles += ' .result_box a { margin-right: 5px; color: #444;} ';
  1039. styles += ' .result_box a:visited { color: #551A8B; }';
  1040. styles += ' #content-2-wide #main, #content-2-wide';
  1041. styles += ' .maindetails_center {margin-left: 5px; width: 1001px;} ';
  1042. GM_addStyle(styles);
  1043.  
  1044. if($('div#main table.results tr.detailed').length !== 0) {
  1045. //Loop through each result row
  1046. $('div#main table.results tr.detailed').each(function() {
  1047. var link = $(this).find('.title>a');
  1048. var is_tv = Boolean($(this).find('.year_type').html()
  1049. .match('TV Series'));
  1050. var is_movie = Boolean($(this).find('.year_type').html()
  1051. .match(/\(([0-9]*)\)/));
  1052. var movie_title = link.html();
  1053. var movie_id = link.attr('href').match(/tt([0-9]*)\/?$/)[1];
  1054.  
  1055. $(this).find('span.genre a').each(function() {
  1056. if ($(this).html() == 'Adult') {
  1057. $(this).parent().parent().parent()
  1058. .css('background-color', 'red');
  1059. }
  1060. });
  1061. perform($(this), movie_id, movie_title, is_tv, is_movie);
  1062. });
  1063. } else {
  1064. // Chameleon code, in a different style
  1065. var titleDivs = document.getElementsByClassName('col-title');
  1066. var compact = true;
  1067. if(titleDivs.length === 0)
  1068. {
  1069. titleDivs=document.getElementsByClassName('lister-item-header');
  1070. compact=false;
  1071. }
  1072. for(var i=0; i<titleDivs.length; i++)
  1073. {
  1074. var t = titleDivs[i];
  1075. var link = t.getElementsByTagName('a')[0];
  1076. var is_tv = link.nextElementSibling.textContent.indexOf('-')!==-1;
  1077. var is_movie = !is_tv;
  1078. var movie_title = link.textContent;
  1079. var movie_id = link.href.split("/title/tt")[1].split("/")[0];
  1080.  
  1081. var elem = t.parentNode.parentNode;
  1082. if(!compact)
  1083. elem = t.parentNode;
  1084. perform(elem, movie_id, movie_title, is_tv, is_movie);
  1085. }
  1086. }
  1087. }
  1088.  
  1089. //------------------------------------------------------
  1090. // Watchlist page code
  1091. //------------------------------------------------------
  1092.  
  1093. function performWatchlist() {
  1094. //Add css for the new table cells we're going to add
  1095. var styles = '.result_box {width: 335px}';
  1096. styles += ' .result_box a { margin-right: 5px; color: #444;} ';
  1097. styles += ' .result_box a:visited { color: #551A8B; }';
  1098. styles += ' #content-2-wide #main, #content-2-wide';
  1099. styles += ' .maindetails_center {margin-left: 5px; width: 1001px;} ';
  1100. GM_addStyle(styles);
  1101. if($('div .lister-list.mode-detail').children().length !== 0) {
  1102. $('div .lister-list.mode-detail').children().each(function() {
  1103. var link = $(this).find('.lister-item-header>a');
  1104. var is_tv = Boolean($(this).find('.lister-item-details').html()
  1105. .match('TV Series'));
  1106. var is_movie = Boolean($(this).find('.lister-item-year').html()
  1107. .match(/^([0-9]*)$/));
  1108. var movie_title = link.html();
  1109. var movie_id = link.attr('href').match(/tt([0-9]*)\/?.*/)[1];
  1110. perform($(this), movie_id, movie_title, is_tv, is_movie);
  1111. });
  1112. }
  1113. }
  1114.  
  1115. //------------------------------------------------------
  1116. // TV/movie page code
  1117. //------------------------------------------------------
  1118.  
  1119. function performPage() {
  1120. var movie_title = $('.title_wrapper>h1').clone().children().remove().end().text();
  1121. if (movie_title === "") {
  1122. movie_title = $('h3[itemprop="name"]').text().trim();
  1123. }
  1124. var movie_id = document.URL.match(/\/tt([0-9]+)\//)[1].trim('tt');
  1125. var is_tv_page = Boolean($('title').text().match('TV Series')) ||
  1126. Boolean($('.tv-extra').length);
  1127. var is_movie_page = Boolean($('title').text().match(/.*? \(([0-9]*)\)/));
  1128. //Create area to put links in
  1129. perform(getLinkArea(), movie_id, movie_title,
  1130. is_tv_page, is_movie_page);
  1131. addIconBar(movie_id, movie_title);
  1132. }
  1133.  
  1134. //------------------------------------------------------
  1135. // Find/create elements
  1136. //------------------------------------------------------
  1137.  
  1138. function getLinkArea() {
  1139. // If it already exists, just return it
  1140. if ($('#imdbscout_header').length) {
  1141. return $('#imdbscout_header');
  1142. }
  1143. var p = $('<p />').append('<h2>' + GM_config.get('imdbscout_header_text') + '</h2>').attr('id', 'imdbscout_header').css({
  1144. 'padding': '0px 20px',
  1145. 'font-weight': 'bold'
  1146. });
  1147. $.each(valid_states, function(i, name) {
  1148. if (GM_config.get('one_line')) {
  1149. p.append($('<span />').attr('id', 'imdbscout_' + name));
  1150. } else {
  1151. var title = $('<span>' + name.replace('_', ' ') + ': </span>').css({
  1152. 'textTransform': 'capitalize',
  1153. 'min-width': '100px',
  1154. 'display': 'inline-block'
  1155. });
  1156. p.append($('<div />').attr('id', 'imdbscout_' + name).append(title));
  1157. }
  1158. });
  1159. if ($('h1.header:first').length) {
  1160. $('h1.header:first').parent().append(p);
  1161. } else if ($('#title-overview-widget').length) {
  1162. $('#title-overview-widget').parent().append(p);
  1163. } else if ($('.titlereference-header').length) {
  1164. $('.titlereference-header').append(p);
  1165. } else {
  1166. $('#tn15rating').before(p);
  1167. }
  1168. return $('#imdbscout_header');
  1169. }
  1170.  
  1171. //------------------------------------------------------
  1172. // Create the config name
  1173. //------------------------------------------------------
  1174.  
  1175. function configName(site) {
  1176. if ('configName' in site) {
  1177. return 'show_' + site['configName'] + (site['TV'] ? '_TV' : '');
  1178. } else {
  1179. return 'show_' + site['name'] + (site['TV'] ? '_TV' : '');
  1180. }
  1181. }
  1182. //------------------------------------------------------
  1183. // Code being run (main)
  1184. //------------------------------------------------------
  1185.  
  1186. // Get everything configured
  1187.  
  1188. // Create the non-site dictionary for GM_config
  1189. var config_fields = {
  1190. 'imdbscout_header_text': {
  1191. 'label': 'Header text:',
  1192. 'type': 'text',
  1193. 'default': 'Pirate this film: '
  1194. },
  1195. 'call_http_movie': {
  1196. 'section': 'Movie Page:',
  1197. 'type': 'checkbox',
  1198. 'label': 'Actually check for torrents?',
  1199. 'default': true
  1200. },
  1201. 'load_on_start_movie': {
  1202. 'type': 'checkbox',
  1203. 'label': 'Load on start?',
  1204. 'default': true
  1205. },
  1206. 'hide_missing_movie': {
  1207. 'type': 'checkbox',
  1208. 'label': 'Hide missing links?',
  1209. 'default': false
  1210. },
  1211. 'use_icons_movie': {
  1212. 'type': 'checkbox',
  1213. 'label': 'Use icons instead of text?',
  1214. 'default': false
  1215. },
  1216. 'one_line': {
  1217. 'type': 'checkbox',
  1218. 'label': 'Show results on one line?',
  1219. 'default': true
  1220. },
  1221. 'ignore_type_movie': {
  1222. 'type': 'checkbox',
  1223. 'label': 'Search all sites, ignoring movie/tv distinction?',
  1224. 'default': false
  1225. },
  1226. 'highlight_missing_movie': {
  1227. 'label': 'Highlight when not on:',
  1228. 'type': 'text',
  1229. 'default': ''
  1230. },
  1231. 'call_http_search': {
  1232. 'section': 'Search Page:',
  1233. 'type': 'checkbox',
  1234. 'label': 'Actually check for torrents?',
  1235. 'default': true
  1236. },
  1237. 'load_on_start_search': {
  1238. 'type': 'checkbox',
  1239. 'label': 'Load on start?',
  1240. 'default': true
  1241. },
  1242. 'hide_missing_search': {
  1243. 'type': 'checkbox',
  1244. 'label': 'Hide missing links?',
  1245. 'default': false
  1246. },
  1247. 'use_icons_search': {
  1248. 'type': 'checkbox',
  1249. 'label': 'Use icons instead of text?',
  1250. 'default': false
  1251. },
  1252. 'ignore_type_search': {
  1253. 'type': 'checkbox',
  1254. 'label': 'Search all sites, ignoring movie/tv distinction?',
  1255. 'default': false
  1256. },
  1257. 'watchlist_as_search': {
  1258. 'type': 'checkbox',
  1259. 'label': 'Treat the watchlist a a search page?',
  1260. 'default': false
  1261. },
  1262. 'highlight_missing_search': {
  1263. 'label': 'Highlight when not on:',
  1264. 'type': 'text',
  1265. 'default': ''
  1266. }
  1267. };
  1268.  
  1269. // Add each site to a GM_config dictionary schema
  1270. // The GM_config default for checkboxes is false
  1271. $.each(sites, function(index, site) {
  1272. config_fields[configName(site)] = {
  1273. 'section': (index == 0) ? ['Torrents:'] : '',
  1274. 'type': 'checkbox',
  1275. 'label': ' ' + site['name'] + (site['TV'] ? ' (TV)' : '')
  1276. };
  1277. });
  1278.  
  1279. // Icon sites should be shown by default though,
  1280. // since they barely use any resources.
  1281. $.each(icon_sites, function(index, icon_site) {
  1282. config_fields['show_icon_' + icon_site['name']] = {
  1283. 'section': (index == 0) ? ['Other sites:'] : '',
  1284. 'type': 'checkbox',
  1285. 'label': ' ' + icon_site['name'],
  1286. 'default': ('showByDefault' in icon_site) ?
  1287. icon_site['showByDefault'] : true
  1288. };
  1289. });
  1290.  
  1291. // Initialize and register GM_config
  1292. GM_config.init({
  1293. 'id': 'imdb_scout',
  1294. 'title': 'IMDb Scout Preferences',
  1295. 'fields': config_fields,
  1296. 'css': '.section_header { \
  1297. background: white !important; \
  1298. color: black !important; \
  1299. border: 0px !important; \
  1300. text-align: left !important;} \
  1301. .field_label { \
  1302. font-weight: normal !important;}',
  1303. 'events':
  1304. {
  1305. 'open': function() {
  1306. $('#imdb_scout').contents().find('#imdb_scout_section_2').find('.field_label').each(function(index, label) {
  1307. url = new URL(sites[index].searchUrl);
  1308. $(label).append(' ' + '<a class="grey_link" target="_blank" style="color: gray; text-decoration : none" href="' + url.origin + '">'
  1309. + (/www./.test(url.hostname) ? url.hostname.match(/www.(.*)/)[1] : url.hostname) + '</a>');
  1310. $(label).prepend(getFavicon(sites[index], true));
  1311. });
  1312. $('#imdb_scout').contents().find('#imdb_scout_section_3').find('.field_label').each(function(index, label) {
  1313. $(label).prepend(getFavicon(icon_sites[index], true));
  1314. });
  1315. }
  1316. }
  1317. });
  1318.  
  1319. GM_registerMenuCommand('IMDb Scout Preferences', function() {GM_config.open()});
  1320.  
  1321. // Fetch per-site values from GM_config
  1322. $.each(sites, function(index, site) {
  1323. site['show'] = GM_config.get(configName(site));
  1324. });
  1325.  
  1326. $.each(icon_sites, function(index, icon_site) {
  1327. icon_site['show'] = GM_config.get('show_icon_' + icon_site['name']);
  1328. });
  1329.  
  1330. // Are we on a search page?
  1331. // This variable is camelCased to show it's global
  1332. // Hopefully it can be factored out of the global scope in the future
  1333. var onSearchPage = Boolean(location.href.match('search')) || Boolean(location.href.match('watchlist'));
  1334.  
  1335. $('title').ready(function() {
  1336. if (!onSearchPage && GM_config.get('load_on_start_movie')) {
  1337. performPage();
  1338. } else if (onSearchPage && GM_config.get('load_on_start_search')) {
  1339. if (Boolean(location.href.match('watchlist')) && GM_config.get('watchlist_as_search')) {
  1340. performWatchlist();
  1341. } else {
  1342. performSearch();
  1343. }
  1344.  
  1345. } else {
  1346. displayButton();
  1347. }
  1348. });
  1349.