PTH Preview Tracks

Embed youtube clips for the tracks of a torrent group

  1. // ==UserScript==
  2. // @name PTH Preview Tracks
  3. // @version 3.0
  4. // @description Embed youtube clips for the tracks of a torrent group
  5. // @author Chameleon
  6. // @include http*://redacted.ch/torrents.php?*id=*
  7. // @include http*://redacted.ch/index.php
  8. // @include http*://redacted.ch/*threadid=1837*
  9. // @grant GM_xmlhttpRequest
  10. // @connect youtube.com
  11. // @namespace https://greasyfork.org/users/87476
  12. // ==/UserScript==
  13.  
  14. (function() {
  15. 'use strict';
  16.  
  17. if(!document.hidden)
  18. run();
  19. else
  20. document.addEventListener('visibilitychange', visibilityChanged);
  21. }());
  22.  
  23. var scriptLoaded=false;
  24.  
  25. function visibilityChanged()
  26. {
  27. if(!document.hidden && !scriptLoaded)
  28. {
  29. run();
  30. scriptLoaded=true;
  31. }
  32. }
  33.  
  34. function run()
  35. {
  36. //console.log(document.hidden);
  37. var settings=getSettings();
  38.  
  39. if(settings.useYoutubeAPI)
  40. {
  41. // include youtube's elephant of an API
  42. var tag = document.createElement('script');
  43.  
  44. tag.src = "https://www.youtube.com/iframe_api";
  45. var firstScriptTag = document.getElementsByTagName('script')[0];
  46. firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
  47. // stop including
  48. }
  49.  
  50. var wH=window.location.href;
  51. if(wH.indexOf('index.php') != -1 && settings.useYoutubeAPI && settings.masterPlayer)
  52. {
  53. loadPlayer();
  54. }
  55. else if(wH.indexOf('torrents.php') != -1)
  56. loadTorrent();
  57. else if(wH.indexOf('threadid=1837') != -1)
  58. showSettings();
  59. }
  60.  
  61. function showSettings()
  62. {
  63. var div=document.getElementById('ChameleonSettings');
  64. if(!div)
  65. {
  66. var before = document.getElementsByClassName('forum_post')[0];
  67. div = document.createElement('div');
  68. div.setAttribute('id', 'ChameleonSettings');
  69. before.parentNode.insertBefore(div, before);
  70. div.setAttribute('style', 'width: 100%; text-align: center; padding-bottom: 10px;');
  71. div.setAttribute('class', 'box');
  72. }
  73. div.innerHTML = '<h2>Preview Tracks Settings</h2><br />';
  74. var settings = getSettings();
  75.  
  76. var a=document.createElement('a');
  77. a.href='javascript:void(0);';
  78. a.innerHTML = 'Master player on /index.php: '+(settings.masterPlayer ? 'On':'Off');
  79. a.addEventListener('click', changeSettings.bind(undefined, a, div), false);
  80. div.appendChild(a);
  81. div.appendChild(document.createElement('br'));
  82.  
  83. var a=document.createElement('a');
  84. a.href='javascript:void(0);';
  85. a.innerHTML = 'Youtube API: '+(settings.useYoutubeAPI ? 'On':'Off');
  86. a.addEventListener('click', changeSettings.bind(undefined, a, div), false);
  87. div.appendChild(a);
  88. div.appendChild(document.createElement('br'));
  89.  
  90. var a=document.createElement('a');
  91. a.href='javascript:void(0);';
  92. a.innerHTML = 'Minimize Track Preview: '+(settings.hideTrackPreview ? 'On':'Off');
  93. a.addEventListener('click', changeSettings.bind(undefined, a, div), false);
  94. div.appendChild(a);
  95. div.appendChild(document.createElement('br'));
  96.  
  97. var a=document.createElement('a');
  98. a.href='javascript:void(0);';
  99. a.innerHTML = 'Force show separate preview area: '+(settings.alwaysShowExtraBox ? 'On':'Off');
  100. a.addEventListener('click', changeSettings.bind(undefined, a, div), false);
  101. div.appendChild(a);
  102. div.appendChild(document.createElement('br'));
  103.  
  104. var input=document.createElement('input');
  105. input.placeholder = 'Youtube quality';
  106. input.value=settings.quality ? settings.quality:'';
  107. input.addEventListener('change', changeSettings.bind(undefined, undefined, div), false);
  108. div.appendChild(input);
  109. div.appendChild(document.createElement('br'));
  110.  
  111. var input=document.createElement('input');
  112. input.placeholder = 'Youtube volume';
  113. input.type='number';
  114. input.value=settings.volume ? settings.volume:'';
  115. input.addEventListener('change', changeSettings.bind(undefined, undefined, div), false);
  116. div.appendChild(input);
  117. div.appendChild(document.createElement('br'));
  118.  
  119. var input=document.createElement('input');
  120. input.placeholder = 'API Key';
  121. input.value=settings.apiKey ? settings.apiKey:'AIzaSyBkMKh0dR1lWSrr2Bia_JdRc1kv7Nue8H8';
  122. input.addEventListener('change', changeSettings.bind(undefined, undefined, div), false);
  123. div.appendChild(input);
  124. div.appendChild(document.createElement('br'));
  125.  
  126. var a=document.createElement('a');
  127. div.appendChild(a);
  128. a.href='javascript:void(0);';
  129. a.innerHTML = 'Save';
  130. }
  131.  
  132. function changeSettings(a, div)
  133. {
  134. var settings=getSettings();
  135. var as=div.getElementsByTagName('a');
  136.  
  137. if(a == as[0])
  138. {
  139. if(as[0].innerHTML.indexOf('Off') != -1)
  140. {
  141. settings.masterPlayer = true;
  142. }
  143. else
  144. settings.masterPlayer = false;
  145. }
  146.  
  147. if(a == as[1])
  148. {
  149. if(as[1].innerHTML.indexOf('Off') != -1)
  150. {
  151. settings.useYoutubeAPI = true;
  152. }
  153. else
  154. settings.useYoutubeAPI = false;
  155. }
  156.  
  157. if(a == as[2])
  158. {
  159. if(as[2].innerHTML.indexOf('Off') != -1)
  160. {
  161. settings.hideTrackPreview = true;
  162. }
  163. else
  164. settings.hideTrackPreview = false;
  165. }
  166.  
  167. if(a == as[3])
  168. {
  169. if(as[3].innerHTML.indexOf('Off') != -1)
  170. {
  171. settings.alwaysShowExtraBox = true;
  172. }
  173. else
  174. settings.alwaysShowExtraBox = false;
  175. }
  176.  
  177. var inputs=div.getElementsByTagName('input');
  178. settings.quality=inputs[0].value;
  179. settings.volume=inputs[1].value;
  180. settings.apiKey=inputs[2].value;
  181.  
  182. window.localStorage.previewTracksSettings = JSON.stringify(settings);
  183. showSettings();
  184. }
  185.  
  186. function getSettings()
  187. {
  188. var settings = window.localStorage.previewTracksSettings;
  189. if(!settings)
  190. {
  191. settings = {masterPlayer:false, useYoutubeAPI:true, alwaysShowExtraBox:false};
  192. }
  193. else
  194. settings = JSON.parse(settings);
  195. if(settings.useYoutubeAPI !== false)
  196. settings.useYoutubeAPI=true;
  197. return settings;
  198. }
  199.  
  200. function waitForYT(messageDiv)
  201. {
  202. messageDiv.innerHTML = 'Waiting on Youtube API to load';
  203. window.setTimeout(loadPlayer.bind(undefined, messageDiv), 1000);
  204. }
  205.  
  206. function loadPlayer(messageDiv)
  207. {
  208. var div=document.getElementById('youtubePlayerDiv');
  209. var thin=document.getElementsByClassName('thin')[0];
  210. if(!div)
  211. {
  212. div=document.createElement('div');
  213. div.setAttribute('id', 'youtubePlayerDiv');
  214. div.setAttribute('style', 'background: rgba(0,0,200,0.5); text-align: center; border-radius: 20px; padding-bottom: 10px;');
  215. thin.insertBefore(div, thin.firstElementChild);
  216.  
  217. var messageDiv=document.createElement('div');
  218. div.appendChild(messageDiv);
  219. }
  220.  
  221. if(typeof(YT) == "undefined")
  222. {
  223. waitForYT(messageDiv);
  224. return;
  225. }
  226. messageDiv.innerHTML = '';
  227.  
  228. var header=document.createElement('div');
  229. div.appendChild(header);
  230.  
  231. var youtubeDiv=document.createElement('div');
  232. youtubeDiv.setAttribute('id', 'playlistPlayer');
  233. div.appendChild(youtubeDiv);
  234.  
  235. var playlist=getPlaylist();
  236. var youtube;
  237. if(playlist.length === 0)
  238. {
  239. messageDiv.innerHTML = 'no videos to play ';
  240. var a=document.createElement('a');
  241. messageDiv.appendChild(a);
  242. a.innerHTML = 'Reload playlist';
  243. a.href='javascript:void(0);';
  244. a.addEventListener('click', loadPlayer.bind(undefined, messageDiv), false);
  245. return;
  246. }
  247. else if(!playlist[0].track)
  248. {
  249. messageDiv.innerHTML = 'Old playlist, ';
  250. var a=document.createElement('a');
  251. messageDiv.appendChild(a);
  252. a.innerHTML = 'clear it and rebuild';
  253. a.href='javascript:void(0);';
  254. a.addEventListener('click', clearAndLoadPlayer.bind(undefined, messageDiv), false);
  255. return;
  256. }
  257. else
  258. {
  259.  
  260. /*var width = thin.clientWidth-20;
  261. var height = Math.round(width/(16/9));
  262. youtube=new YT.Player('playlistPlayer', {
  263. height: height,
  264. width: width,
  265. events: {'onReady': playerReady, 'onStateChange': playerStateChanged.bind(undefined, messageDiv)}});*/
  266.  
  267. playPlaylistVideo(messageDiv, youtube);
  268. }
  269.  
  270. var a=document.createElement('a');
  271. a.innerHTML = 'Go to start of playlist';
  272. a.href='javascript:void(0);';
  273. header.appendChild(a);
  274. a.addEventListener('click', playlistResetIndex.bind(undefined, messageDiv, youtube), false);
  275.  
  276. header.appendChild(document.createTextNode(' | '));
  277. var a=document.createElement('a');
  278. a.innerHTML = 'Clear playlist';
  279. a.href='javascript:void(0);';
  280. header.appendChild(a);
  281. a.addEventListener('click', playlistReset.bind(undefined, messageDiv, youtube), false);
  282.  
  283. header.appendChild(document.createTextNode(' | '));
  284. var a=document.createElement('a');
  285. a.innerHTML = 'Play';
  286. a.href='javascript:void(0);';
  287. header.appendChild(a);
  288. a.addEventListener('click', playPlaylistVideo.bind(undefined, messageDiv, youtube), false);
  289.  
  290. header.appendChild(document.createTextNode(' | '));
  291. var a=document.createElement('a');
  292. a.innerHTML = 'Next';
  293. a.href='javascript:void(0);';
  294. header.appendChild(a);
  295. a.addEventListener('click', playNextPlaylistVideo.bind(undefined, messageDiv, youtube), false);
  296.  
  297. header.appendChild(document.createTextNode(' | '));
  298. var a=document.createElement('a');
  299. a.innerHTML = 'Previous';
  300. a.href='javascript:void(0);';
  301. header.appendChild(a);
  302. a.addEventListener('click', playPrevPlaylistVideo.bind(undefined, messageDiv, youtube), false);
  303.  
  304. header.appendChild(document.createTextNode(' | '));
  305. var a=document.createElement('a');
  306. a.innerHTML = 'Show playlist';
  307. a.href='javascript:void(0);';
  308. header.appendChild(a);
  309. a.addEventListener('click', showPlaylist.bind(undefined, messageDiv), false);
  310. }
  311.  
  312. function showPlaylist(messageDiv, onlyifopen)
  313. {
  314. var div=document.getElementById('playlistDiv');
  315. if(!div && onlyifopen=="yes")
  316. {
  317. div=document.createElement('div');
  318. div.setAttribute('id', 'playlistDiv');
  319. div.setAttribute('style', 'margin: 10px; background: rgba(0,0,0,0.6); padding: 10px; border-radius: 10px;');
  320. var thin=document.getElementsByClassName('thin')[0];
  321. thin.insertBefore(div, thin.firstElementChild.nextElementSibling);
  322. }
  323. div.innerHTML = '';
  324. var headers=["", "", "Track", "Artist", "Album"];
  325. var baseHeaderStyle="display: inline-block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;";
  326. var headersStyle=["width: 80px;", "width: 30px;", "width: 300px;", "width: 200px; text-align: center;", "width:200px; text-align: center;"];
  327. var hStyle="text-align: center;";
  328. var header=document.createElement('div');
  329. div.appendChild(header);
  330. for(var i=0; i<headers.length; i++)
  331. {
  332. var span=document.createElement('span');
  333. header.appendChild(span);
  334. span.innerHTML=headers[i];
  335. span.setAttribute('style', baseHeaderStyle+headersStyle[i]+hStyle);
  336. }
  337. var playlist=getPlaylist();
  338. var playlistIndex=getPlaylistIndex();
  339. for(var i=0; i<playlist.length; i++)
  340. {
  341. var p=playlist[i];
  342.  
  343. var pDiv=document.createElement('div');
  344. pDiv.setAttribute('playlistItem', JSON.stringify(p));
  345. if(i===parseInt(playlistIndex))
  346. {
  347. pDiv.setAttribute('style', 'background: rgba(0,128,128,0.5);');
  348. }
  349. div.appendChild(pDiv);
  350.  
  351. var span=document.createElement('span');
  352. span.setAttribute('style', baseHeaderStyle+headersStyle[0]);
  353. pDiv.appendChild(span);
  354. //span.innerHTML = "Up / Down";
  355. var a=document.createElement('a');
  356. span.appendChild(a);
  357. a.innerHTML = '-';
  358. a.href='javascript:void(0);';
  359. a.addEventListener('click', removePlaylist.bind(undefined, messageDiv, i), false);
  360. span.appendChild(document.createTextNode(' / '));
  361. var a=document.createElement('a');
  362. span.appendChild(a);
  363. a.innerHTML = 'Up';
  364. a.href='javascript:void(0);';
  365. a.addEventListener('click', movePlaylistUp.bind(undefined, messageDiv, i), false);
  366. span.appendChild(document.createTextNode(' / '));
  367. var a=document.createElement('a');
  368. span.appendChild(a);
  369. a.innerHTML = 'Down';
  370. a.href='javascript:void(0);';
  371. a.addEventListener('click', movePlaylistDown.bind(undefined, messageDiv, i), false);
  372.  
  373. var span=document.createElement('span');
  374. span.setAttribute('style', baseHeaderStyle+headersStyle[1]);
  375. pDiv.appendChild(span);
  376. span.innerHTML = i+1;
  377.  
  378. var span=document.createElement('a');
  379. span.setAttribute('style', baseHeaderStyle+headersStyle[2]);
  380. pDiv.appendChild(span);
  381. span.innerHTML = p.track;
  382. span.href='javascript:void(0);';
  383. span.addEventListener('click', playIndex.bind(undefined, messageDiv, i), false);
  384.  
  385. var span=document.createElement('span');
  386. span.setAttribute('style', baseHeaderStyle+headersStyle[3]);
  387. pDiv.appendChild(span);
  388. span.innerHTML = p.artist === '' ? '<Unknown>':p.artist;
  389.  
  390. var span=document.createElement('span');
  391. span.setAttribute('style', baseHeaderStyle+headersStyle[4]);
  392. pDiv.appendChild(span);
  393. span.innerHTML = p.album;
  394. }
  395. }
  396.  
  397. function removePlaylist(messageDiv, index)
  398. {
  399. var playlist=getPlaylist();
  400. playlist.splice(index, 1);
  401. savePlaylist(playlist);
  402. showPlaylist(messageDiv);
  403. }
  404.  
  405. function movePlaylistUp(messageDiv, index)
  406. {
  407. if(index === 0)
  408. return;
  409.  
  410. var playlist=getPlaylist();
  411. playlist.splice(index-1, 0, playlist.splice(index, 1)[0]);
  412. if(index === parseInt(getPlaylistIndex()))
  413. setPlaylistIndex(index-1);
  414. savePlaylist(playlist);
  415. showPlaylist(messageDiv);
  416. }
  417.  
  418. function movePlaylistDown(messageDiv, index)
  419. {
  420. var playlist=getPlaylist();
  421. if(index > playlist.length-2)
  422. return;
  423.  
  424. playlist.splice(index+1, 0, playlist.splice(index, 1)[0]);
  425. if(index === parseInt(getPlaylistIndex()))
  426. setPlaylistIndex(index+1);
  427. savePlaylist(playlist);
  428. showPlaylist(messageDiv);
  429. }
  430.  
  431. function playIndex(messageDiv, index)
  432. {
  433. setPlaylistIndex(index);
  434. playPlaylistVideo(messageDiv);
  435. }
  436.  
  437. function clearAndLoadPlayer(messageDiv)
  438. {
  439. playlistReset(messageDiv);
  440. loadPlayer(messageDiv);
  441. }
  442.  
  443. function playNextPlaylistVideo(messageDiv)
  444. {
  445. setPlaylistIndex(parseInt(getPlaylistIndex())+1);
  446. playPlaylistVideo(messageDiv);
  447. }
  448.  
  449. function playPrevPlaylistVideo(messageDiv)
  450. {
  451. var index=parseInt(getPlaylistIndex())-1;
  452. if(index<0)
  453. index=0;
  454. setPlaylistIndex(index);
  455. playPlaylistVideo(messageDiv);
  456. }
  457.  
  458. function playlistReset(messageDiv)
  459. {
  460. savePlaylist([]);
  461. setPlaylistIndex(0);
  462. }
  463.  
  464. function playlistResetIndex(messageDiv)
  465. {
  466. setPlaylistIndex(0);
  467. playPlaylistVideo(messageDiv);
  468. }
  469.  
  470. function playPlaylistVideo(messageDiv)
  471. {
  472. messageDiv.innerHTML = 'loading video';
  473. var index=getPlaylistIndex();
  474. var playlist=getPlaylist();
  475. if(index >= playlist.length)
  476. {
  477. messageDiv.innerHTML = 'Finished playlist';
  478. return;
  479. }
  480. showPlaylist(messageDiv, "yes");
  481. var settings=getSettings();
  482. var search=encodeURIComponent((playlist[index].artist+' '+playlist[index].track).trim());
  483. var xhr = new XMLHttpRequest();
  484. var apikey=settings.apiKey?settings.apiKey:'AIzaSyBkMKh0dR1lWSrr2Bia_JdRc1kv7Nue8H8';
  485. xhr.open('GET', "https://www.googleapis.com/youtube/v3/search?part=snippet&order=relevance&type=video&key="+apikey+"&q="+search);
  486. xhr.onreadystatechange = xhr_func.bind(undefined, messageDiv, xhr, playPlayer.bind(undefined, messageDiv), playPlaylistVideo.bind(undefined, messageDiv));
  487. xhr.send();
  488. }
  489.  
  490. function playPlayer(messageDiv, response)
  491. {
  492. messageDiv.innerHTML = 'Got videos';
  493. /*if(typeof(youtube.loadVideoById) == "undefined")
  494. {
  495. window.setTimeout(playPlayer.bind(undefined, messageDiv, youtube, response), 500);
  496. return;
  497. }*/
  498. var data=JSON.parse(response);
  499. if(data.items.length === 0)
  500. {
  501. messageDiv.innerHTML = "Couldn't find any videos :(";
  502. window.setTimeout(clear.bind(undefined, messageDiv), 5000);
  503. setPlaylistIndex(parseInt(getPlaylistIndex())+1);
  504. return;
  505. }
  506.  
  507. var videoId=data.items[0].id.videoId;
  508.  
  509. var iframe = document.getElementById('playlistPlayer');
  510. var t=iframe.parentNode;
  511. var prev=document.getElementById('playlistPlayer');
  512. if(prev)
  513. prev.parentNode.removeChild(prev);
  514. iframe=document.createElement('div');
  515. iframe.setAttribute('id', 'playlistPlayer');
  516. t.appendChild(iframe);
  517. var width = iframe.parentNode.clientWidth-20;
  518. var height = Math.round(width/(16/9));
  519. console.log(videoId);
  520. console.log(YT);
  521. new YT.Player('playlistPlayer', {
  522. height: height,
  523. width: width,
  524. videoId: videoId,
  525. events: {'onReady': playerReady, 'onStateChange': playerStateChanged.bind(undefined, messageDiv)}});
  526. }
  527.  
  528. function playerReady(event)
  529. {
  530. event.target.playVideo();
  531. var settings=getSettings();
  532. if(settings.quality && settings.quality.length > '')
  533. event.target.setPlaybackQuality(settings.quality);
  534. }
  535.  
  536. function playerStateChanged(messageDiv, event)
  537. {
  538. if(event.target.getPlayerState() === 0)
  539. {
  540. setPlaylistIndex(parseInt(getPlaylistIndex())+1);
  541. playPlaylistVideo(messageDiv);
  542. }
  543. if(event.data == YT.PlayerState.BUFFERING)
  544. {
  545. var settings=getSettings();
  546. if(settings.quality && settings.quality.length > '')
  547. event.target.setPlaybackQuality(settings.quality);
  548. if(settings.volume)
  549. event.target.setVolume(settings.volume);
  550. }
  551. }
  552.  
  553. function getPlaylistIndex()
  554. {
  555. var playlistIndex=window.localStorage.youtubeIndex;
  556. if(!playlistIndex)
  557. playlistIndex=0;
  558. return playlistIndex;
  559. }
  560.  
  561. function setPlaylistIndex(index)
  562. {
  563. window.localStorage.youtubeIndex=index;
  564. }
  565.  
  566. function getPlaylist()
  567. {
  568. var playlist=window.localStorage.youtubePlaylist;
  569. if(!playlist)
  570. playlist=[];
  571. else
  572. playlist=JSON.parse(playlist);
  573. return playlist;
  574. }
  575.  
  576. function savePlaylist(playlist)
  577. {
  578. window.localStorage.youtubePlaylist = JSON.stringify(playlist);
  579. }
  580.  
  581. function loadTorrent()
  582. {
  583. var settings=getSettings();
  584. var h2 = document.getElementsByTagName('h2')[0];
  585. var artist = h2.getElementsByTagName('a');
  586. if(artist.length > 0)
  587. artist = artist[0].innerHTML;
  588. else
  589. artist = '';
  590. var tracks = document.getElementsByClassName('torrent_description')[0].getElementsByClassName('postlist');
  591. var tD=document.getElementsByClassName('torrent_description')[0].textContent;
  592. if(tD.indexOf('discogs.com') != -1 && tD.indexOf('/release/') != -1)
  593. {
  594. var discogs_release=parseInt(tD.split('/release/')[1]);
  595. doDiscogs(discogs_release);
  596. }
  597. else if(tracks.length > 0 && !settings.alwaysShowExtraBox)
  598. {
  599. var s=document.createElement('span');
  600. var a=document.createElement('a');
  601. s.appendChild(a);
  602. a.innerHTML = 'Close Videos';
  603. a.href='javascript:void(0);';
  604. a.addEventListener('click', closeIframes, false);
  605. tracks[0].parentNode.insertBefore(s, tracks[0]);
  606. tracks=tracks[0].getElementsByTagName('li');
  607.  
  608. if(settings.useYoutubeAPI)
  609. {
  610. var a=document.createElement('a');
  611. s.appendChild(document.createTextNode(' '));
  612. s.appendChild(a);
  613. a.innerHTML = '(enqueue all)';
  614. a.href='javascript:void(0);';
  615. var album=h2.getElementsByTagName('span')[0].textContent;
  616. a.addEventListener('click', enqueueTracks.bind(undefined, a, tracks, artist, album), false);
  617. }
  618. doTracks(artist, tracks);
  619. }
  620. else
  621. {
  622. tracks=makePreview(getTracks);
  623. doTracks(artist, tracks);
  624. }
  625. }
  626.  
  627. function doDiscogs(id)
  628. {
  629. var messageDiv=document.getElementById('previewTracksMessages');
  630. if(!messageDiv)
  631. {
  632. messageDiv=document.createElement('div');
  633. messageDiv.setAttribute('style', 'position: fixed; background: rgba(0,0,0,0.7); top: 50px; margin: auto; left: 0; right: 0; text-align: center; font-size: 2em;');
  634. messageDiv.setAttribute('id', 'previewTracksMessages');
  635. document.body.appendChild(messageDiv);
  636. }
  637. messageDiv.innerHTML = 'Getting tracklist from discogs.com';
  638.  
  639. var xhr = new XMLHttpRequest();
  640. xhr.open('GET', "https://api.discogs.com/releases/"+id);
  641. xhr.onreadystatechange = xhr_func.bind(undefined, messageDiv, xhr, gotDiscogs.bind(undefined, messageDiv), doDiscogs.bind(undefined, id));
  642. xhr.send();
  643. }
  644.  
  645. function gotDiscogs(messageDiv, response)
  646. {
  647. messageDiv.innerHTML = '';
  648. var r=JSON.parse(response);
  649. console.log(r.tracklist);
  650.  
  651. var tracks=makePreview(getDiscogTracks.bind(undefined, r.tracklist));
  652.  
  653. doTracks(r.artists[0].name.split('(')[0], tracks);
  654. }
  655.  
  656. function getDiscogTracks(tracks)
  657. {
  658. var result=[];
  659. for(var i=0; i<tracks.length; i++)
  660. {
  661. if(tracks[i].title.length > 0)
  662. result.push(tracks[i].title);
  663. }
  664. return result;
  665. }
  666.  
  667. function doTracks(artist, tracks)
  668. {
  669. var settings=getSettings();
  670. for(var i=0; i<tracks.length; i++)
  671. {
  672. var input=document.createElement('input');
  673. var t=tracks[i];
  674. var track=t.textContent;
  675. input.value=(artist+' '+track).trim();
  676. t.innerHTML = '';
  677. var span=document.createElement('span');
  678. var a=document.createElement('a');
  679. a.href='javascript:void(0);';
  680. a.setAttribute('class', 'previewLinks');
  681. a.innerHTML = track;
  682. a.addEventListener('click', preview.bind(undefined, a, t, span, artist, track, i, input), false);
  683. t.appendChild(a);
  684. t.appendChild(document.createTextNode(' '));
  685. if(settings.useYoutubeAPI)
  686. {
  687. var a=document.createElement('a');
  688. a.href='javascript:void(0);';
  689. a.innerHTML = '(enqueue)';
  690. var album=document.getElementsByTagName('h2')[0].getElementsByTagName('span')[0].textContent;
  691. a.addEventListener('click', enqueueTrack.bind(undefined, a, artist, track, album), false);
  692. t.appendChild(a);
  693. t.appendChild(document.createTextNode(' '));
  694. }
  695. var a=document.createElement('a');
  696. a.href='javascript:void(0);';
  697. a.innerHTML = '(show search)';
  698. a.addEventListener('click', toggleShow.bind(undefined, input, a), false);
  699. t.appendChild(a);
  700. t.appendChild(document.createTextNode(' '));
  701. t.appendChild(input);
  702. input.style.display='none';
  703. t.appendChild(span);
  704. }
  705. }
  706.  
  707. function toggleShow(el, link)
  708. {
  709. if(el.style.display=='none')
  710. {
  711. link.innerHTML=link.innerHTML.replace(/show/, 'hide');
  712. el.style.display='';
  713. }
  714. else
  715. {
  716. link.innerHTML=link.innerHTML.replace(/hide/, 'show');
  717. el.style.display='none';
  718. }
  719. }
  720.  
  721. function enqueueTrack(a, artist, track, album)
  722. {
  723. var playlist=getPlaylist();
  724. playlist.push({artist:artist, album:album, track:track});
  725. savePlaylist(playlist);
  726. a.innerHTML = '(enqueued)';
  727. }
  728.  
  729. function enqueueTracks(a, trackLis, artist, album)
  730. {
  731. var playlist=getPlaylist();
  732. for(var i=0; i<trackLis.length; i++)
  733. {
  734. playlist.push({artist:artist, album:album, track:trackLis[i].getElementsByTagName('a')[0].textContent.trim()});
  735. }
  736. savePlaylist(playlist);
  737. a.innerHTML='(enqueued all)';
  738. }
  739.  
  740. function closeIframes()
  741. {
  742. var prev=document.getElementById('previewIframe');
  743. if(prev)
  744. prev.parentNode.removeChild(prev);
  745. }
  746.  
  747. function toggle(div)
  748. {
  749. if(div.style.display == 'none')
  750. div.style.display = 'initial';
  751. else
  752. div.style.display = 'none';
  753. }
  754.  
  755. function makePreview(getTracksFunc)
  756. {
  757. var settings=getSettings();
  758. var div=document.createElement('div');
  759. div.setAttribute('class', 'box torrent_description');
  760. var before=document.getElementsByClassName('torrent_description')[0];
  761. before.parentNode.insertBefore(div, before);
  762. var clone=before.getElementsByClassName('head')[0].cloneNode(true);
  763. div.appendChild(clone);
  764. clone.getElementsByTagName('strong')[0].innerHTML = 'Track Preview';
  765. var body=document.createElement('div');
  766. if(settings.hideTrackPreview)
  767. body.style.display='none';
  768. var a=document.createElement('a');
  769. a.href='javascript:void(0);';
  770. a.innerHTML = '(toggle)';
  771. clone.appendChild(document.createTextNode(' '));
  772. clone.appendChild(a);
  773. a.addEventListener('click', toggle.bind(undefined, body), false);
  774. var a=document.createElement('a');
  775. a.setAttribute('style', 'float: right;');
  776. a.innerHTML='Settings';
  777. a.href='/forums.php?action=viewthread&threadid=1837';
  778. clone.appendChild(a);
  779. div.appendChild(body);
  780. body.setAttribute('class', 'body');
  781. body.innerHTML = 'Track List:<br />';
  782. var a=document.createElement('a');
  783. a.innerHTML = 'Close Videos';
  784. a.href='javascript:void(0);';
  785. a.addEventListener('click', closeIframes, false);
  786. body.appendChild(a);
  787. var tracks=getTracksFunc();
  788.  
  789. if(settings.useYoutubeAPI)
  790. {
  791. var a=document.createElement('a');
  792. body.appendChild(document.createTextNode(' '));
  793. body.appendChild(a);
  794. a.innerHTML = '(enqueue all)';
  795. a.href='javascript:void(0);';
  796. }
  797.  
  798. var ol=document.createElement('ol');
  799. ol.setAttribute('class', 'postlist');
  800. body.appendChild(ol);
  801. var result = [];
  802. for(var i=0; i<tracks.length; i++)
  803. {
  804. var li=document.createElement('li');
  805. li.innerHTML = tracks[i];
  806. ol.appendChild(li);
  807. result.push(li);
  808. }
  809.  
  810. if(settings.useYoutubeAPI)
  811. {
  812. var h2 = document.getElementsByTagName('h2')[0];
  813. var artist = h2.getElementsByTagName('a');
  814. if(artist.length > 0)
  815. artist = artist[0].innerHTML;
  816. else
  817. artist = '';
  818. var album=h2.getElementsByTagName('span')[0].textContent;
  819. a.addEventListener('click', enqueueTracks.bind(undefined, a, result, artist, album), false);
  820. }
  821.  
  822. return result;
  823. }
  824.  
  825. function getTracks(offset)
  826. {
  827. if(!offset)
  828. offset=0;
  829. var torrent_row = document.getElementsByClassName('torrent_row')[offset];
  830. var type = torrent_row.getElementsByTagName('a');
  831. type = type[type.length-1].innerHTML.split(' / ')[0].toLowerCase();
  832. var filelist = document.getElementsByClassName('filelist_table')[offset].getElementsByTagName('tr');
  833. var files=[];
  834. for(var i=1; i<filelist.length; i++)
  835. {
  836. var f=filelist[i].getElementsByTagName('td')[0].innerHTML;
  837. if(f.indexOf(type) != f.length-type.length)
  838. continue;
  839. var f1 = f.split('/');
  840. if(f1.length > 1)
  841. f=f1[f1.length-1];
  842. f1 = f.split(f.match(/\d+/));
  843. if(f1.length > 1)
  844. f=f1[1];
  845. f = f.replace(/^[0-9]+\.?/, '').replace(/ - /g, ' ').replace(new RegExp("."+type), '').replace(/_/g, ' ').replace(/-/g, ' ');
  846. var artist = document.getElementsByTagName('h2')[0].getElementsByTagName('a');
  847. if(artist.length > 0)
  848. artist = artist[0].innerHTML;
  849. else
  850. artist='';
  851. var l=f.toLowerCase().indexOf(artist.toLowerCase());
  852. if( l != -1)
  853. f=f.substr(0, l)+f.substr(l+artist.length);
  854. //f = f.split('(')[0];
  855. files.push(f);
  856. }
  857. if(files.length === 0)
  858. return getTracks(offset+1);
  859. return files;
  860. }
  861.  
  862. function preview(a, t, span, artist, track, index1, input)
  863. {
  864. var existingSearch=a.getAttribute('search');
  865. if(existingSearch == input.value)
  866. {
  867. var videoIds = t.getAttribute('videoIds');
  868. if(videoIds)
  869. {
  870. var index = parseInt(t.getAttribute('index'));
  871. videoIds = JSON.parse(videoIds);
  872. if(index >= videoIds.length)
  873. {
  874. span.innerHTML = 'Already on last video';
  875. window.setTimeout(clear.bind(undefined, span), 5000);
  876. return;
  877. }
  878. addEmbed(t, span, videoIds[index]);
  879. t.setAttribute('index', index+1);
  880. return;
  881. }
  882. }
  883. a.setAttribute('search', input.value);
  884. t.parentNode.setAttribute('index', index1);
  885. span.innerHTML = 'Getting videos';
  886. //track = track.split('(')[0];
  887. var xhr = new XMLHttpRequest();
  888. var settings=getSettings();
  889. var apikey=settings.apiKey?settings.apiKey:'AIzaSyBkMKh0dR1lWSrr2Bia_JdRc1kv7Nue8H8';
  890. var search=input.value.trim();
  891. //xhr.open('GET', "https://gdata.youtube.com/feeds/api/videos?v=2&alt=json&orderby=relevance&q="+encodeURIComponent(artist+' '+track));
  892. //xhr.open('GET', "https://www.googleapis.com/youtube/v3/search?part=snippet&order=relevance&type=video&key="+apikey+"&q="+encodeURIComponent(search));
  893. /*console.log('https://www.youtube.com/results?search_query='+encodeURIComponent(search));
  894. return;
  895. xhr.open('GET', 'https://www.youtube.com/results?search_query='+encodeURIComponent(search));
  896. xhr.onreadystatechange = xhr_func.bind(undefined, span, xhr, previewing.bind(undefined, t, span), preview.bind(undefined, a, t, span, artist, track, input));
  897. xhr.send();
  898. */
  899. GM_xmlhttpRequest({
  900. method:'GET',
  901. url:'https://www.youtube.com/results?search_query='+encodeURIComponent(search),
  902. onload:function(xhr)
  903. {
  904. if(xhr.readyState == 4 && xhr.status==200)
  905. {
  906. previewing(t, span, xhr);
  907. }
  908. }
  909. });
  910. }
  911.  
  912. function previewing(t, span, response)
  913. {
  914. span.innerHTML = 'Got videos';
  915. /*
  916. var data=JSON.parse(response);
  917. if(data.items.length === 0)
  918. {
  919. span.innerHTML = "Couldn't find any videos :(";
  920. window.setTimeout(clear.bind(undefined, span), 5000);
  921. return;
  922. }
  923. var videoIds = [];
  924. for(var i=0; i<data.items.length; i++)
  925. {
  926. videoIds.push(data.items[i].id.videoId);
  927. }
  928. */
  929. var videoIds=[];
  930. /*var newDoc=document.implementation.createHTMLDocument();
  931. newDoc.body.innerHTML=response.responseText;
  932. var as=newDoc.querySelectorAll('a.ytd-thumbnail');
  933. console.log(response.responseText);
  934. for(var i=0; i<as.length; i++)
  935. {
  936. var a=as[i];
  937. if(a.href.indexOf('watch?v=')==-1)
  938. continue;
  939. videoIds.push(a.href.split('watch?v=')[1]);
  940. }
  941. */
  942. var splits=response.responseText.split('"videoId":"');
  943. for(var i=1; i<splits.length-1; i++)
  944. {
  945. videoIds.push(splits[i].split('"')[0]);
  946. }
  947. if(videoIds.length === 0)
  948. {
  949. span.innerHTML = "Couldn't find any videos :(";
  950. window.setTimeout(clear.bind(undefined, span), 5000);
  951. return;
  952. }
  953. t.setAttribute('videoIds', JSON.stringify(videoIds));
  954. t.setAttribute('index', 1);
  955.  
  956. addEmbed(t, span, videoIds[0]);
  957. }
  958.  
  959. function addEmbed(t, span, videoId)
  960. {
  961. var settings=getSettings();
  962. var iframe = t.getElementsByTagName('iframe');
  963. if(iframe.length === 0)
  964. {
  965. var prev=document.getElementById('previewIframe');
  966. if(prev)
  967. prev.parentNode.removeChild(prev);
  968. if(settings.useYoutubeAPI)
  969. {
  970. iframe=document.createElement('div');
  971. iframe.setAttribute('id', 'previewIframe');
  972. t.appendChild(iframe);
  973. var width = t.parentNode.clientWidth-20;
  974. var height = Math.round(width/(16/9));
  975. new YT.Player('previewIframe', {
  976. height: height,
  977. width: width,
  978. videoId: videoId,
  979. events: {'onReady': previewReady, 'onStateChange': previewStateChanged}});
  980. }
  981. else
  982. {
  983. iframe = document.createElement('iframe');
  984. iframe.setAttribute('id', 'previewIframe');
  985. t.appendChild(iframe);
  986. iframe.width = t.parentNode.clientWidth-20;
  987. iframe.height = iframe.width/(16/9);
  988. iframe.setAttribute('allowfullscreen', 'true');
  989. iframe.frameBorder='0';
  990. }
  991. }
  992. else
  993. iframe = iframe[0];
  994. iframe.src='https://www.youtube.com/embed/'+videoId+'?autoplay=1';
  995. //iframe.setAttribute('autoplay', true);
  996. span.innerHTML = ' Added youtube embed';
  997. var link=document.getElementById('youtubeLink');
  998. if(link)
  999. link.parentNode.removeChild(link);
  1000. link=document.createElement('a');
  1001. span.parentNode.insertBefore(link, span);
  1002. link.href='https://youtu.be/'+videoId;
  1003. link.innerHTML='(Link)';
  1004. link.id='youtubeLink';
  1005. window.setTimeout(clear.bind(undefined, span), 5000);
  1006. }
  1007.  
  1008. function previewReady(event)
  1009. {
  1010. event.target.playVideo();
  1011. var settings=getSettings();
  1012. if(settings.quality && settings.quality.length > '')
  1013. event.target.setPlaybackQuality(settings.quality);
  1014. }
  1015.  
  1016. function previewStateChanged(event)
  1017. {
  1018. if(event.target.getPlayerState() === 0)
  1019. {
  1020. //console.log('ended');
  1021. var as=document.getElementsByClassName('previewLinks');
  1022. var index=parseInt(as[0].parentNode.parentNode.getAttribute('index'))+1;
  1023. if(index < as.length)
  1024. as[index].click();
  1025. }
  1026. if(event.data == YT.PlayerState.BUFFERING)
  1027. {
  1028. var settings=getSettings();
  1029. if(settings.quality && settings.quality.length > '')
  1030. event.target.setPlaybackQuality(settings.quality);
  1031. if(settings.volume)
  1032. event.target.setVolume(settings.volume);
  1033. }
  1034. }
  1035.  
  1036. function clear(span)
  1037. {
  1038. span.innerHTML = '';
  1039. }
  1040.  
  1041. function xhr_func(messageDiv, xhr, func, repeatFunc)
  1042. {
  1043. if(xhr.readyState == 4)
  1044. {
  1045. if(xhr.status == 200)
  1046. func(xhr.responseText);
  1047. else
  1048. {
  1049. messageDiv.innerHTML = 'Error: '+xhr.status+'<br />retrying in 1 second';
  1050. window.setTimeout(repeatFunc, 1000);
  1051. }
  1052. }
  1053. }