IMDb Scout

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

目前為 2015-01-15 提交的版本,檢視 最新版本

  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.3.2/jquery.min.js
  9. //
  10. // @version 2.31.1
  11. // @include http://*.imdb.com/title/tt*
  12. // @include http://*.imdb.de/title/tt*
  13. // @include http://*.imdb.es/title/tt*
  14. // @include http://*.imdb.fr/title/tt*
  15. // @include http://*.imdb.it/title/tt*
  16. // @include http://*.imdb.pt/title/tt*
  17. // @include http://*.imdb.com/search/title*
  18. // @include http://*.imdb.de/search/title*
  19. // @include http://*.imdb.es/search/title*
  20. // @include http://*.imdb.fr/search/title*
  21. // @include http://*.imdb.it/search/title*
  22. // @include http://*.imdb.pt/search/title*
  23. //
  24. // @grant GM_log
  25. // @grant GM_getValue
  26. // @grant GM_setValue
  27. // @grant GM_addStyle
  28. // @grant GM_openInTab
  29. // @grant GM_xmlhttpRequest
  30. // @grant GM_registerMenuCommand
  31. //
  32. // ==/UserScript==
  33. /*---------------------Version History--------------------
  34. 1.00 - Initial public release, everything works on barebones greasemonkey
  35.  
  36. 1.50 - Added the ability to select which sites to load from the GM script commands
  37. - Moved the required method to userscripts
  38. - Removed FH, NZB, Avax
  39.  
  40. 1.60 - Added style elements and shading to display on imdb
  41.  
  42. 1.62 - Fixed bug:SCC-ARC not removing when unchecked
  43. - Alphabetized list
  44.  
  45. 1.70 - Cleaned up code
  46. - Added option to not run script on page load
  47.  
  48. 1.71 - Deprecated action-box field
  49.  
  50. 1.80 - Added icons that link to OpenSubs, Criticker, RT, YT
  51.  
  52. 1.81 - Added support for tv, only displays on shows listed as 'tv series'
  53. - Added support for icheckmovies at top bar.
  54.  
  55. 1.82 - Fixed title parsing for tv shows.
  56.  
  57. 1.83 - Fixed dhive not working properly
  58.  
  59. 1.90 - Set height of preference window to 450px, added scroll bar
  60.  
  61. 1.91 - Added another 11 torrent sites
  62.  
  63. 2.00 - Added auto updater
  64.  
  65. 2.01 - Added TC, FreshOn, TVT, STF, CC
  66. - Cleaned up code (tabbing)
  67. - Removed THR
  68. - Added TV-Rage to top bar
  69.  
  70. 2.02 - Added PS, THC, HH, HDStar
  71. - Fixed CC false positive
  72.  
  73. 2.03 - TehC now uses tt
  74. - Added Raymoz mod for AT
  75.  
  76. 2.04 - Added HDbits
  77. - Added TL
  78.  
  79. 2.10 - Added genre page search functionality
  80.  
  81. 2.11 - Fixed ICM because Nuked was whining
  82.  
  83. 2.12 - Removed tvrage
  84. - Fixed iCM (added tt)
  85. - Added HDVNbits
  86. - Changed RevTT to .me
  87. - Added HDT
  88. - removed autoupdate
  89.  
  90. 2.13 - removed xvidme
  91. - reinstated autoupdate
  92. - removed google chrome code
  93. - fixed hdvn and hdt issues
  94.  
  95. 2.14 - Added @grant entries for API access
  96. - Fixed tt parser to work on imdb pages with referral info in url
  97.  
  98. 2.2 - Switch preferences window to use GM_config
  99. - Consolidate icon & site lists
  100. - Added IPT, KASS, sHD, and HDW
  101. - Fix "Open All" link
  102. - Add option for strikethroughs on search page
  103. - Removed arrays from search URLs
  104. - Spring cleaning
  105.  
  106. 2.21 - Added SSL to TVT, HDME, TC, AHD, IPT, SCC
  107. - Added SSL option for CG
  108. - Added GFT, GFT-Gems, GFT-TV
  109. - Fixed SCC, SCC-ARC search URL
  110. - Removed TheBox, TheDVDClub
  111. - Added more comments, cleaned up some more stuff
  112.  
  113. 2.22 - Fixed TehC, BTN, BTN-Req, THC
  114. - Added a bunch of TV sites, courtesy of seedless
  115. - Added "both" option for sites, and made changes
  116. to allow coexistence of movie and TV sites with
  117. the same name
  118. - Code re-organization, documentation
  119. - Re-added code to allow an array for searchUrl
  120.  
  121. 2.22.1 - Minor fixes
  122.  
  123. 2.23 - Fixed THC, BTN
  124. - Distinguish between movies and TV on search page
  125.  
  126. 2.24 - Separate load_on_start option for search page
  127. - Fix search_string on search page
  128.  
  129. 2.25 - Added some helpful text when no sites have been enabled
  130.  
  131. 2.26 - Added code to show links when on pages besides just the "front" one
  132. (e.g. http://www.imdb.com/title/tt2310332/reference)
  133.  
  134. 2.26.1 - Correctly detect TV shows when on aforementioned pages.
  135.  
  136. 2.3 - Incorporate a bunch of changes courtesy of Inguin:
  137. - Added SSL to AT, TE, D-noid, TG, YT, RT
  138. - Changed tracker short titles to canonical form ADC, KG
  139. - Updated D-noid from .me to .pw
  140. - Fixed broken AT search; also updated to use .me so avoids redirect
  141. - Added BitHQ, ET (eutorrents)
  142. - Removed two broken THC; replaced with one fixed
  143. - Removed iplay, horrorhaven, hdstar, scandbits, leecherslair
  144. - Removed needless CG http/https duplication - plenty of listed sites self-sign
  145. - A-Z sites list for readability
  146. - Cleanup YT search string
  147. - Copyedits
  148. - Clean up code (tabs, trailing spaces)
  149. - Use consistent naming style
  150. - Added Letterboxd, Subscene to icons
  151. - Added options for showing icons
  152.  
  153. 2.31 - Added preliminary check for TSH
  154. - Change all SCC links to .org
  155.  
  156. 2.31.1 - Typo fix
  157.  
  158.  
  159. --------------------------------------------------------*/
  160.  
  161. if (window.top != window.self) //don't run on frames or iframes
  162. {
  163. //Optional: GM_log ('In frame');
  164. return;
  165. }
  166.  
  167. //------------------------------------------------------
  168. // A list of all the sites, and the data necessary to
  169. // check IMDb against them.
  170. // Each site is a dictionary with the following attributes:
  171. // - name: The site name, abbreviated
  172. // - searchUrl: The URL to perform the search against, see below for how
  173. // to tailor the string to a site
  174. // - matchRegex: The string which appears if
  175. // the searchUrl DOESN'T return a result
  176. // - TV (optional): If true, it means that this site will only
  177. // show up on TV pages. By default, sites only show up on movie pages
  178. // - both (optional): Means that the site will show up
  179. // on both movie and TV pages
  180. // To create a search URL, there are three parameters
  181. // you can use inside the URL:
  182. // - %tt%: The IMDb id with the tt prefix
  183. // - %nott%: The IMDb id without the tt prefix
  184. // - %search_string%: The movie title
  185. // See below for examples
  186. //------------------------------------------------------
  187.  
  188. var sites = [
  189. { 'name': 'ADC',
  190. 'searchUrl': 'https://asiandvdclub.org/browse.php?descr=1&btnSubmit=Submit&search=%tt%',
  191. 'matchRegex': /Your search returned zero results|<h1>You need cookies enabled to log in.<\/h1>/,
  192. 'both': true},
  193. { 'name': 'AHD',
  194. 'searchUrl': 'https://awesome-hd.net/torrents.php?searchstr=%search_string%',
  195. 'matchRegex': /<h2>Error 404<\/h2>/,
  196. 'TV': true},
  197. { 'name': 'AHD',
  198. 'searchUrl': 'https://awesome-hd.net/torrents.php?id=%tt%',
  199. 'matchRegex': /<h2>Error 404<\/h2>/},
  200. { 'name': 'AT',
  201. 'searchUrl': 'https://www.asiatorrents.me/index.php?page=torrents&options=3&search=%tt%',
  202. 'matchRegex': /discount=0&amp;order=9&amp|You&rsquo;re not authorized to view/,
  203. 'both': true},
  204. { 'name': 'BitHD',
  205. 'searchUrl': 'http://www.bit-hdtv.com/torrents.php?cat=0&description_search=1&search=%tt%',
  206. 'matchRegex': /<h2>No match!<\/h2>/},
  207. { 'name': 'BitHQ',
  208. 'searchUrl': 'https://www.bithq.org/search.php?search=%search_string%&options=AND&in=original&incldead=1',
  209. 'matchRegex': /Try again with a refined search string|<h1>Not logged in!<\/h1>/},
  210. { 'name': 'BMTV',
  211. 'searchUrl': 'https://www.bitmetv.org/browse.php?search=%search_string%',
  212. 'matchRegex': /Nothing found!<\/h2>/,
  213. 'TV': true},
  214. { 'name': 'BTN',
  215. 'searchUrl': 'https://broadcasthe.net/torrents.php?imdb=%tt%',
  216. 'matchRegex': /Error 404|Lost your password\?/,
  217. 'TV': true},
  218. { 'name': 'BTN-Req',
  219. 'searchUrl': 'https://broadcasthe.net/requests.php?search=%search_string%',
  220. 'matchRegex': /Nothing found|Lost your password\?/,
  221. 'TV': true},
  222. { 'name': 'CC',
  223. 'searchUrl': 'http://www.cine-clasico.com/foros/search.php?terms=any&author=&sc=1&sf=all&sr=posts&sk=t&sd=d&st=0&ch=300&t=0&submit=Search&keywords=%tt%',
  224. 'matchRegex': /You will be banned for 6 hours after your login attempts run out.|You must specify at least one word to search for. Each word must consist of at least 3 characters and must not contain more than 14 characters excluding wildcards.|Disculpe/},
  225. { 'name': 'CG',
  226. 'searchUrl': 'https://cinemageddon.net/browse.php?search=%tt%',
  227. 'matchRegex': /<h2>Nothing found!<\/h2>|<h1>Not logged in!<\/h1>/},
  228. { 'name': 'CHD',
  229. 'searchUrl': 'http://chdbits.org/torrents.php?incldead=1&spstate=0&inclbookmarked=0&search_area=4&search_mode=0&search=%tt%',
  230. 'matchRegex': /Nothing found! Try again with a refined search string.|<h1>You need cookies enabled to log in or switch language.<\/h1>/},
  231. { 'name': 'D-noid',
  232. 'searchUrl': 'http://www.demonoid.pw/files/?query=%tt%',
  233. 'matchRegex': /<b>No torrents found<\/b>|We are currently performing the daily site maintenance.<br>/,
  234. 'both': true},
  235. { 'name': 'DHive',
  236. 'searchUrl': 'https://gks.gs/sphinx/?category=0&prez=&sort=normal&order=desc&q=%tt%',
  237. 'matchRegex': /Votre Recherche aucun|<h1>Mot de passe<\/h1>/},
  238. { 'name': 'eThor',
  239. '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%',
  240. 'matchRegex': /Try again with a refined search string.|<h1>Note: Vous devez activer vos 'cookies' pour pouvoir vous identifier.<\/h1>/},
  241. { 'name': 'ET',
  242. 'searchUrl': 'http://eutorrents.ph/index.php?page=torrents&options=3&active=0&search=%tt%',
  243. 'matchRegex': /discount=0&amp;order=9&amp|You&rsquo;re not authorized to view/},
  244. { 'name': 'Fresh',
  245. 'searchUrl': 'http://freshon.tv/browse.php?search=%search_string%',
  246. 'matchRegex': /Nothing found!<\/h2>/,
  247. 'TV': true},
  248. { 'name': 'FSS',
  249. 'searchUrl': 'http://fss.omnilounge.co.uk/browse.php?blah=2&cat=0&incldead=1&search=%tt%',
  250. 'matchRegex': /Try again with a different search string?|<h1>You need cookies enabled to log in.<\/h1>/},
  251. { 'name': 'FY',
  252. 'searchUrl': 'https://fuckyeahtorrents.com/browse.php?_by=2&cat=0&search=%tt%',
  253. 'matchRegex': /Try again with a refined search string|<h1>You need cookies enabled to log in.<\/h1>/},
  254. { 'name': 'GFT',
  255. 'searchUrl': 'https://www.thegft.org/browse.php?view=0&search=%search_string%',
  256. 'matchRegex': /Nothing found!<\/h2>/,
  257. 'TV': true},
  258. { 'name': 'GFT',
  259. 'searchUrl': 'https://www.thegft.org/browse.php?view=0&c2=1&c1=1&c9=1&c11=1&c48=1&c8=1&c18=1&c49=1&c7=1&c38=1&c46=1&c5=1&c13=1&c26=1&c37=1&c19=1&c47=1&c17=1&c4=1&c22=1&c25=1&c20=1&c3=1&search=%tt%&searchtype=0',
  260. 'matchRegex': /Nothing found!<\/h2>/},
  261. { 'name': 'GFT-Gems',
  262. 'searchUrl': 'https://www.thegft.org/browse.php?view=1&search=%tt%&searchtype=0',
  263. 'matchRegex': /Nothing found!<\/h2>/},
  264. { 'name': 'Goem',
  265. 'searchUrl': 'http://goem.org/browse.php?s_type=2&cat=0&search=%tt%',
  266. 'matchRegex': /Try again with a refined searchstring|<h1>Note: You need cookies enabled to log in.<\/h1>/,
  267. 'both': true},
  268. { 'name': 'HDb',
  269. 'searchUrl': 'http://hdbits.org/browse2.php#film/dir=null&searchtype=film&actorfilm=film&search=%tt%',
  270. 'matchRegex': /<p>Note: You need cookies enabled to log in.<\/p>/},
  271. { 'name': 'HDME',
  272. 'searchUrl': 'https://hdme.eu/browse.php?search=%search_string%&blah=0&cat=0&incldead=1',
  273. 'matchRegex': /Try again with a refined search string.|<h1>You need cookies enabled to log in.<\/h1>/,
  274. 'TV': true},
  275. { 'name': 'HDME',
  276. 'searchUrl': 'https://hdme.eu/browse.php?blah=2&cat=0&incldead=1&search=%tt%',
  277. 'matchRegex': /Try again with a refined search string.|<h1>You need cookies enabled to log in.<\/h1>/},
  278. { 'name': 'HDT',
  279. 'searchUrl': 'http://hd-torrents.org/torrents.php?active=0&options=2&search=%tt%',
  280. 'matchRegex': /No torrents here.../},
  281. { 'name': 'HDVN',
  282. 'searchUrl': 'http://hdvnbits.org/torrents.php?search=%tt%&search_area=4&search_mode=0',
  283. 'matchRegex': /Nothing found! Try again with a refined search string/},
  284. { 'name': 'HDW',
  285. 'searchUrl': 'http://hdwing.com/browse.php?search=%search_string%',
  286. 'matchRegex': /<h2>没找到任何内容!|对不起<\/h2>/,
  287. 'both': true},
  288. { 'name': 'ILC',
  289. 'searchUrl': 'http://www.iloveclassics.com/browse.php?incldead=1&searchin=2&search=%tt%',
  290. 'matchRegex': /Try again with a refined search string|<h1>Not logged in!<\/h1>/},
  291. { 'name': 'IPT',
  292. 'searchUrl': 'https://www.iptorrents.com/torrents/?q=%tt%',
  293. 'matchRegex': /<h2>Nothing found!<\/h2>|( 0 torrents )/},
  294. { 'name': 'IPT',
  295. 'searchUrl': 'https://www.iptorrents.com/torrents/?q=%search_string%',
  296. 'matchRegex': /<h2>Nothing found!<\/h2>|( 0 torrents )/,
  297. 'TV': true},
  298. { 'name': 'KASS',
  299. 'searchUrl': 'https://kickass.to/usearch/%search_string%',
  300. 'matchRegex': /<h2>Nothing found!<\/h2>/,
  301. 'TV': true},
  302. { 'name': 'KASS',
  303. 'searchUrl': 'https://kickass.to/usearch/imdb%3A%nott%',
  304. 'matchRegex': /<h2>Nothing found!<\/h2>/},
  305. { 'name': 'KG',
  306. 'searchUrl': 'https://www.karagarga.net/browse.php?search_type=imdb&search=%nott%',
  307. 'matchRegex': /<h2>No torrents found<\/h2>|<h1>If you want the love<\/h1>/},
  308. { 'name': 'MT',
  309. 'searchUrl': 'http://www.maroctorrent.net/torrents-search.php?cat=42&incldead=1&search=%tt%',
  310. 'matchRegex': /Aucun torrent|<h1>Les Cookies DOIVENT<\/h1>/},
  311. { 'name': 'PS',
  312. 'searchUrl': 'http://polishsource.org/browse.php?incldead=0&scene=0&pl=0&sub=&search_in=both&free=0&search=%tt%',
  313. 'matchRegex': /Nic nie znaleziono|Musisz|login/},
  314. { 'name': 'PTP',
  315. 'searchUrl': 'https://tls.passthepopcorn.me/torrents.php?imdb=%tt%',
  316. 'matchRegex': /<h2>Your search did not match anything.<\/h2>/},
  317. { 'name': 'PTP-Req',
  318. 'searchUrl': 'https://tls.passthepopcorn.me/requests.php?submit=true&search=%tt%',
  319. 'matchRegex': /Nothing found!|<h1>Keep me logged in.<\/h1>/},
  320. { 'name': 'RevTT',
  321. 'searchUrl': 'https://www.revolutiontt.me/browse.php?search=%search_string%&cat=0&incldead=1&titleonly=1',
  322. 'matchRegex': /<h2>Nothing found!<\/h2>/,
  323. 'TV': true},
  324. { 'name': 'RevTT',
  325. 'searchUrl': 'https://www.revolutiontt.me/browse.php?search=%tt%',
  326. 'matchRegex': /<h2>Nothing found!<\/h2>/},
  327. { 'name': 'SCC',
  328. 'searchUrl': 'https://sceneaccess.org/browse?search=%search_string%&method=2',
  329. 'matchRegex': /Try again with a refined search string.|<h1>Note: Three (3) failed login attempts will result in a temporary security lockout.<\/h1>/,
  330. 'TV': true},
  331. { 'name': 'SCC',
  332. 'searchUrl': 'https://sceneaccess.org/browse?method=3&search=%tt%',
  333. 'matchRegex': /Try again with a refined search string.|<h1>Note: Three (3) failed login attempts will result in a temporary security lockout.<\/h1>/},
  334. { 'name': 'SCC-ARC',
  335. 'searchUrl': 'https://sceneaccess.org/archive?=&method=3&search=%tt%',
  336. 'matchRegex': /Try again with a refined search string.|<h1>Note: Three (3) failed login attempts will result in a temporary security lockout.<\/h1>/},
  337. { 'name': 'SCC-ARC',
  338. 'searchUrl': 'https://sceneaccess.org/archive?search=%search_string%&method=1',
  339. 'matchRegex': /Try again with a refined search string.|<h1>Note: Three (3) failed login attempts will result in a temporary security lockout.<\/h1>/,
  340. 'TV': true},
  341. { 'name': 'SCC-NS',
  342. 'searchUrl': 'https://sceneaccess.org/nonscene?search=%search_string%&method=2',
  343. 'matchRegex': /Try again with a refined search string.|<h1>Note: Three (3) failed login attempts will result in a temporary security lockout.<\/h1>/,
  344. 'TV': true},
  345. { 'name': 'SCC-NS',
  346. 'searchUrl': 'https://sceneaccess.org/nonscene?=&method=3&search=%tt%',
  347. 'matchRegex': /Try again with a refined search string.|<h1>Note: Three (3) failed login attempts will result in a temporary security lockout.<\/h1>/},
  348. { 'name': 'SDBits',
  349. 'searchUrl': 'http://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%',
  350. 'matchRegex': /Nothing found!|<h1>You need cookies enabled to log in.<\/h1>/},
  351. { 'name': 'sHD',
  352. 'searchUrl': 'https://scenehd.org/browse.php?options&unpack&incldead&search=%search_string%',
  353. 'matchRegex': /<h2>No torrents found!<\/h2>/},
  354. { 'name': 'SM',
  355. 'searchUrl': 'http://www.surrealmoviez.info/advanced_search.php?simdb=%tt%',
  356. 'matchRegex': /0 Movies found matching search criteria|You need to be logged in to view this page/},
  357. { 'name': 'TE',
  358. 'searchUrl': 'https://theempire.bz/browse.php?incldead=0&country=&nonboolean=1&search=%tt%',
  359. 'matchRegex': /Try again with a refined search string|<h1>You need cookies enabled to log in.<\/h1>/,
  360. 'both': true},
  361. { 'name': 'TehC',
  362. 'searchUrl': 'https://tehconnection.eu/torrents.php?searchstr=%tt%',
  363. 'matchRegex': /You will be banned for 6 hours after your login attempts run out.|<h2>No Search Results, try reducing your search options./},
  364. { 'name': 'TG',
  365. 'searchUrl': 'https://thegeeks.bz/browse.php?incldead=0&country=&nonboolean=1&search=%tt%',
  366. 'matchRegex': /Try again with a refined search string|<h1>You need cookies enabled to log in.<\/h1>/,
  367. 'both': true},
  368. { 'name': 'THC',
  369. 'searchUrl': 'https://horrorcharnel.kicks-ass.org/more_details.php?mid=%nott%',
  370. 'matchRegex': /<h1>Not logged in!<\/h1>|not currently on <span style="font-weight: bold;">The Horror Charnel<\/span>\./},
  371. { 'name': 'Tik',
  372. 'searchUrl': 'http://cinematik.net/browse.php?srchdtls=1&incldead=1&search=%tt%',
  373. 'matchRegex': /The page you tried to view can only be used when you're logged in|<h2>Nothing found!<\/h2>/},
  374. { 'name': 'TL',
  375. 'searchUrl': 'http://www.torrentleech.org/torrents/browse/index/query/%search_string%&/categories/2,26,27,32',
  376. 'matchRegex': /Signup With Invite|Please refine your search./,
  377. 'TV': true},
  378. { 'name': 'TL',
  379. 'searchUrl': 'http://www.torrentleech.org/torrents/browse/index/query/%search_string%&/categories/1,8,9,10,11,12,13,14,15,29',
  380. 'matchRegex': /Signup With Invite|Please refine your search./},
  381. { 'name': 'TPB',
  382. 'searchUrl': 'https://thepiratebay.org/search/%tt%',
  383. 'matchRegex': /No hits. Try adding an asterisk in you search phrase.<\/h2>/,
  384. 'both': true},
  385. { 'name': 'TSH',
  386. 'searchUrl': 'https://torrentshack.eu/torrents.php?searchstr=%search_string%&action=advanced&torrentname=&description=&filelist=&extrainfo=&hasnfo=&nuked=&nukedtext=&release_type=both&searchtags=&tags_type=0&order_by=s3&order_way=desc&torrent_preset=all&filter_cat%5B960%5D=1&filter_cat%5B300%5D=1&filter_cat%5B320%5D=1&filter_cat%5B400%5D=1&filter_cat%5B970%5D=1&filter_cat%5B350%5D=1&filter_cat%5B982%5D=1&filter_cat%5B983%5D=1',
  387. 'matchRegex': /Your search did not match anything./},
  388. { 'name': 'TvT',
  389. 'searchUrl': 'https://www.tvtorrents.com/loggedin/search.do?search=%search_string%',
  390. 'matchRegex': /Nothing found!<\/h2>/,
  391. 'TV': true},
  392. { 'name': 'TVV',
  393. 'searchUrl': 'http://tv-vault.me/torrents.php?searchstr=%search_string%',
  394. 'matchRegex': /Nothing found<\/h2>/,
  395. 'TV': true},
  396. { 'name': 'x264',
  397. 'searchUrl': 'http://x264.me/browse.php?incldead=0&xtype=0&stype=3&search=%tt%',
  398. 'matchRegex': /Try again with a refined search string.|<h1>Forgot your password?<\/h1>/},
  399. ];
  400.  
  401. icon_sites = [
  402. { 'name': 'OpenSubtitles',
  403. 'icon': 'http://www.opensubtitles.org/favicon.ico',
  404. 'searchUrl': "http://www.opensubtitles.org/en/search/imdbid-%tt%"},
  405. { 'name': 'YouTube',
  406. 'icon': 'https://www.youtube.com/favicon.ico',
  407. 'searchUrl': 'https://www.youtube.com/results?search_query="%search_string%'},
  408. { 'name': 'Rotten Tomatoes',
  409. 'icon': "https://www.rottentomatoes.com/favicon.ico",
  410. 'searchUrl': "https://www.rottentomatoes.com/alias?type=imdbid&s=%nott%"},
  411. { 'name': 'Criticker',
  412. 'icon': 'http://www.criticker.com/favicon.ico',
  413. 'searchUrl': 'http://www.criticker.com/?st=movies&h=%search_string%&g=Go'},
  414. { 'name': 'iCheckMovies',
  415. 'icon': 'https://www.icheckmovies.com/favicon.ico',
  416. 'searchUrl': 'https://www.icheckmovies.com/search/movies/?query=%tt%'},
  417. { 'name': 'Letterboxd',
  418. 'icon': 'http://letterboxd.com/favicon.ico',
  419. 'searchUrl': 'http://letterboxd.com/imdb/%nott%'},
  420. { 'name': 'Subscene',
  421. 'icon': 'http://subscene.com/favicon.ico',
  422. 'searchUrl': 'http://subscene.com/subtitles/title?q=%search_string%'},
  423. ];
  424.  
  425. function replaceSearchUrlParams(search_url, movie_id, movie_title) {
  426. var search_string = movie_title.replace(/ +\(.*/, '').replace(/[^a-zA-Z0-9]/g, ' ').replace(/ +/g, '+');
  427. // If an array, do a little bit of recursion
  428. if ($.isArray(search_url)) {
  429. search_array = [];
  430. $.each(search_url, function(index, url) {
  431. search_array[index] = replaceSearchUrlParams(url, movie_id, movie_title);
  432. });
  433. return search_array;
  434. }
  435. return search_url.replace('%tt%', 'tt'+movie_id)
  436. .replace('%nott%', movie_id)
  437. .replace('%search_string%', search_string);
  438. }
  439.  
  440. // Adds search links to an element
  441. function addLink(elem, search_url, link_text, strikeout) {
  442. var a = $('<a />').attr('href',search_url).attr('target','_blank');
  443.  
  444. if (strikeout) {
  445. a.append($('<s />').append(link_text));
  446. } else {
  447. a.append(link_text);
  448. }
  449.  
  450. if (!onSearchPage) {
  451. // A little bit of trickery to make matches appear first in a list
  452. if (strikeout) {
  453. $('#imdbscout_header').append(a).append(' ');
  454. } else {
  455. $('#imdbscout_found').append(a).append(' ');
  456. }
  457. } else {
  458. var result_box = $(elem).find('td.result_box');
  459. if (result_box.length > 0) {
  460. $(result_box).append(a);
  461. } else {
  462. $(elem).append($('<td />').append(a).addClass('result_box'));
  463. }
  464. }
  465. }
  466.  
  467. // Performs an ajax request to determine whether or not a url should be displayed
  468. function maybeAddLink(elem, link_text, search_url, search_fail_match, success_match) {
  469. if (typeof(success_match) === 'undefined') success_match = false;
  470. // If the search URL is an array, recurse briefly on the elements.
  471. if ($.isArray(search_url)) {
  472. $.each(search_url, function(index, url) {
  473. maybeAddLink(elem, link_text+'_'+(index+1).toString(), url, search_fail_match, success_match);
  474. });
  475. return;
  476. }
  477. GM_xmlhttpRequest({
  478. method: 'GET',
  479. url: search_url,
  480. onload: function (response_details) {
  481. if (String(response_details.responseText).match(search_fail_match) ? !(success_match) : success_match) {
  482. if (onSearchPage ? GM_config.get('strikeout_links_search') : GM_config.get('strikeout_links_movie')) {
  483. addLink(elem, search_url, link_text, true);
  484. }
  485. // If we're on the search page and it isn't found on PTP
  486. if (onSearchPage && link_text == 'PTP') {
  487. var box = $(elem).find('td.result_box');
  488. if (box.length > 0) {
  489. box.css('background-color','green');
  490. } else {
  491. $(elem).append($('<td />').css('background-color','green').addClass('result_box'));
  492. }
  493. }
  494. } else {
  495. addLink(elem, search_url, link_text, false);
  496. }
  497. }
  498. });
  499. }
  500.  
  501. // Run code to create fields and display sites
  502. function perform(elem, movie_id, movie_title, is_tv) {
  503. site_shown = false;
  504. $.each(sites, function(index, site) {
  505. if (site['show']) {
  506. site_shown = true;
  507. // If we're on a TV page, only show TV links.
  508. if (Boolean(site['TV']) == is_tv || Boolean(site['both'])) {
  509. searchUrl = replaceSearchUrlParams(site['searchUrl'], movie_id, movie_title);
  510. maybeAddLink(elem, site['name'], searchUrl, site['matchRegex']);
  511. }
  512. }
  513. });
  514. if (!site_shown) {
  515. $(elem).append("No sites enabled! You can change this via the Greasemonkey option \"IMDb Scout Preferences\".");
  516. }
  517. }
  518.  
  519. //------------------------------------------------------
  520. // Button Code
  521. //------------------------------------------------------
  522.  
  523. function displayButton() {
  524. var p = $('<p />').attr('id', 'imdbscout_button');
  525. p.append($('<button>Load IMDb Scout</button>').click(function() {
  526. $('#imdbscout_button').remove();
  527. if (onSearchPage) {
  528. performSearch();
  529. } else {
  530. performPage();
  531. }
  532. }));
  533. if (onSearchPage) {
  534. $('#sidebar').append(p);
  535. } else {
  536. $('h1.header:first').parent().append(p);
  537. }
  538. }
  539.  
  540. //------------------------------------------------------
  541. // Icons at top bar
  542. //------------------------------------------------------
  543.  
  544. // Adds a dictionary of icons to the top of the page.
  545. // Unlike the other URLs, they aren't checked to see if the movie exists.
  546. function addIconBar(movie_id, movie_title) {
  547. if ($('h1.header:first').length) {
  548. var iconbar = $('h1.header:first');
  549. } else {
  550. var iconbar = $('#tn15title .title-extra');
  551. }
  552. $.each(icon_sites, function(index, site) {
  553. if (site['show']) {
  554. var search_url = replaceSearchUrlParams(site['searchUrl'], movie_id, movie_title);
  555. var image = $('<img />').attr({'style': '-moz-opacity: 0.4;',
  556. 'width': '16',
  557. 'border': '0',
  558. 'src': site['icon'],
  559. 'title': site['name']});
  560. var html = $('<span />').append($('<a />').attr('href', search_url).addClass('iconbar_icon').append(image));
  561. iconbar.append(html).append(' ');
  562. }
  563. });
  564. //If we have access to the openInTab function, add an Open All feature
  565. if (GM_openInTab) {
  566. var aopenall = $("<a />").text("Open All")
  567. .attr("href", "javascript:;")
  568. .attr('style', 'font-weight:bold;font-size:10px;font-family: Calibri, Verdana, Arial, Helvetica, sans-serif;');
  569. aopenall.click( function () {
  570. $('.iconbar_icon').each(function () {
  571. GM_openInTab($(this).attr('href'));
  572. });
  573. }, false);
  574. iconbar.append(aopenall);
  575. }
  576. }
  577.  
  578. //------------------------------------------------------
  579. // Search page code
  580. //------------------------------------------------------
  581.  
  582. function performSearch(){
  583. //Add css for the new table cells we're going to add
  584. var styles = '.result_box {width: 335px} .result_box a { margin-right: 5px; color: #444;} ';
  585. styles += ' .result_box a:visited { color: red;}';
  586. styles += ' #content-2-wide #main, #content-2-wide .maindetails_center {margin-left: 5px; width: 1001px;} ';
  587. GM_addStyle(styles);
  588.  
  589. //Loop through each result row
  590. $('div#main table.results tr.detailed').each(function(){
  591. var link = $(this).find('.title>a');
  592. var is_tv = Boolean($(this).find('.year_type').html().match('TV Series'));
  593. movie_title = link.html();
  594. movie_id = link.attr('href').match(/tt([0-9]*)\/?$/)[1];
  595.  
  596. $(this).find('span.genre a').each(function(){
  597. if($(this).html() == "Adult") {
  598. $(this).parent().parent().parent().css('background-color','red');
  599. }
  600. });
  601. perform($(this), movie_id, movie_title, is_tv);
  602. });
  603. }
  604.  
  605. //------------------------------------------------------
  606. // TV/movie page code
  607. //------------------------------------------------------
  608.  
  609. function performPage() {
  610. var movie_title = $("title").text().match(/^(.*?) \(/)[1];
  611. var movie_id = document.URL.match(/\/tt([0-9]+)\//)[1].trim('tt');
  612. var is_tv_page = Boolean($("title").text().match("TV Series")) || Boolean($('.tv-extra').length);
  613. //Create area to put links in
  614. var p = $('<p />').append(GM_config.get('imdbscout_header_text')).attr('id', 'imdbscout_header').attr('style', 'font-weight:bold; color:black; background-color: lightgray;');
  615. p.append($('<span />').attr('id', 'imdbscout_found'));
  616. if ( $('h1.header:first').length) {
  617. $('h1.header:first').parent().append(p);
  618. } else {
  619. $('#tn15rating').before(p);
  620. }
  621. perform($('#imdbscout_header'), movie_id, movie_title, is_tv_page);
  622. addIconBar(movie_id, movie_title);
  623. }
  624.  
  625. //------------------------------------------------------
  626. // Code being run (main)
  627. //------------------------------------------------------
  628.  
  629. // Get everything configured
  630.  
  631. // Create the non-site dictionary for GM_config
  632. var config_fields = {
  633. 'imdbscout_header_text': {
  634. 'label': 'Header text:',
  635. 'type': 'text',
  636. 'default': 'Pirate this film: '
  637. },
  638. 'load_on_start': {
  639. 'label': 'Load on start?',
  640. 'type': 'checkbox',
  641. 'default': true
  642. },
  643. 'load_on_start_search': {
  644. 'label': 'Load on start on search page?',
  645. 'type': 'checkbox',
  646. 'default': true
  647. },
  648. 'strikeout_links_search': {
  649. 'label': 'Strike out links on search page?',
  650. 'type': 'checkbox',
  651. 'default': true
  652. },
  653. 'strikeout_links_movie': {
  654. 'label': 'Strike out links on movie page?',
  655. 'type': 'checkbox',
  656. 'default': true
  657. },
  658. };
  659.  
  660. // Sort the sites into a consistent pattern
  661. sites.sort(function (a, b) {
  662. return a['name'].toLowerCase() > b['name'].toLowerCase();
  663. });
  664.  
  665. // Add each site to a GM_config dictionary schema
  666. // The GM_config default for checkboxes is false
  667. $.each(sites, function(index, site) {
  668. config_fields['show_'+site['name']+(site['TV']?"_TV":"")] = {
  669. 'label': 'Show '+site['name']+(site['TV']?" (TV)":"")+'?',
  670. 'type': 'checkbox'
  671. }
  672. });
  673.  
  674. // Icon sites should be shown by default though, since they barely use any resources.
  675. $.each(icon_sites, function(index, icon_site) {
  676. config_fields['show_icon_'+icon_site['name']] = {
  677. 'label': 'Show '+icon_site['name']+' icon?',
  678. 'type': 'checkbox',
  679. 'default': true
  680. }
  681. });
  682.  
  683. // Initialize and register GM_config
  684. GM_config.init({
  685. 'id': 'imbd_scout',
  686. 'title': 'IMDb Scout Preferences',
  687. 'fields': config_fields
  688. });
  689. GM_registerMenuCommand('IMDb Scout Preferences', function() {GM_config.open()});
  690.  
  691. // Fetch per-site values from GM_config
  692. $.each(sites, function(index, site) {
  693. site['show'] = GM_config.get('show_'+site['name']+(site['TV']?"_TV":""));
  694. });
  695.  
  696. $.each(icon_sites, function(index, icon_site) {
  697. icon_site['show'] = GM_config.get('show_icon_'+icon_site['name']);
  698. });
  699.  
  700. // Are we on a search page?
  701. // This variable is camelCased to show it's global
  702. // Hopefully it can be factored out of the global scope in the future
  703. var onSearchPage = Boolean(location.href.match('search'));
  704.  
  705. $('title').ready(function() {
  706. if (!onSearchPage && GM_config.get('load_on_start')) {
  707. performPage();
  708. } else if (onSearchPage && GM_config.get('load_on_start_search')) {
  709. performSearch();
  710. } else {
  711. displayButton();
  712. }
  713. });