app.js 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775
  1. History = new Mongo.Collection("history");
  2. Playlists = new Mongo.Collection("playlists");
  3. Rooms = new Mongo.Collection("rooms");
  4. if (Meteor.isClient) {
  5. Meteor.startup(function() {
  6. reCAPTCHA.config({
  7. publickey: '6LcVxg0TAAAAAE18vBiH00UAyaJggsmLm890SjZl'
  8. });
  9. });
  10. var hpSound = undefined;
  11. var songsArr = [];
  12. var ytArr = [];
  13. var _sound = undefined;
  14. var parts = location.href.split('/');
  15. var id = parts.pop();
  16. var type = id.toLowerCase();
  17. function getSpotifyInfo(title, cb) {
  18. $.ajax({
  19. type: "GET",
  20. url: 'https://api.spotify.com/v1/search?q=' + encodeURIComponent(title.toLowerCase()) + '&type=track',
  21. applicationType: "application/json",
  22. contentType: "json",
  23. success: function (data) {
  24. cb(data);
  25. }
  26. });
  27. }
  28. function getSpotifyArtist(data) {
  29. var temp = "";
  30. var artist;
  31. if(data.artists.length >= 2){
  32. for(var k in data.artists){
  33. temp = temp + data.artists[k].name + ", ";
  34. }
  35. } else{
  36. for(var k in data.artists){
  37. temp = temp + data.artists[k].name;
  38. }
  39. }
  40. if(temp[temp.length-2] === ","){
  41. artist = temp.substr(0,temp.length-2);
  42. } else{
  43. artist = temp;
  44. }
  45. return artist;
  46. }
  47. Template.register.events({
  48. "submit form": function(e){
  49. e.preventDefault();
  50. var username = e.target.registerUsername.value;
  51. var email = e.target.registerEmail.value;
  52. var password = e.target.registerPassword.value;
  53. var captchaData = grecaptcha.getResponse();
  54. Meteor.call("createUserMethod", {username: username, email: email, password: password}, captchaData, function(err, res) {
  55. grecaptcha.reset();
  56. if (err) {
  57. console.log(err);
  58. } else {
  59. Meteor.loginWithPassword(username, password);
  60. }
  61. });
  62. },
  63. "click #facebook-login": function(){
  64. Meteor.loginWithFacebook()
  65. },
  66. "click #github-login": function(){
  67. Meteor.loginWithGithub()
  68. },
  69. "click #login": function(){
  70. $("#register-view").hide();
  71. $("#login-view").show();
  72. }
  73. });
  74. Template.login.events({
  75. "submit form": function(e){
  76. e.preventDefault();
  77. var username = e.target.loginUsername.value;
  78. var password = e.target.loginPassword.value;
  79. Meteor.loginWithPassword(username, password);
  80. Accounts.onLoginFailure(function(){
  81. $("input").css("background-color","indianred").addClass("animated shake");
  82. $("input").on("click",function(){
  83. $("input").css({
  84. "background-color": "transparent",
  85. "width": "250px"
  86. });
  87. })
  88. });
  89. },
  90. "click #facebook-login": function(){
  91. Meteor.loginWithFacebook()
  92. },
  93. "click #github-login": function(){
  94. Meteor.loginWithGithub()
  95. },
  96. "click #register": function(){
  97. $("#login-view").hide();
  98. $("#register-view").show();
  99. }
  100. });
  101. Template.dashboard.events({
  102. "click .logout": function(e){
  103. e.preventDefault();
  104. Meteor.logout();
  105. if (hpSound !== undefined) {
  106. hpSound.stop();
  107. }
  108. },
  109. "click #croom_create": function() {
  110. Meteor.call("createRoom", $("#croom").val(), function (err, res) {
  111. if (err) {
  112. alert("Error " + err.error + ": " + err.reason);
  113. } else {
  114. window.location = "/" + $("#croom").val();
  115. }
  116. });
  117. }
  118. });
  119. Template.dashboard.helpers({
  120. rooms: function() {
  121. return Rooms.find({});
  122. }
  123. })
  124. Template.room.events({
  125. "click #add-song-button": function(e){
  126. e.preventDefault();
  127. parts = location.href.split('/');
  128. id = parts.pop();
  129. var genre = id.toLowerCase();
  130. var type = $("#type").val();
  131. id = $("#id").val();
  132. var title = $("#title").val();
  133. var artist = $("#artist").val();
  134. var songData = {type: type, id: id, title: title, artist: artist};
  135. console.log(songData);
  136. Meteor.call("addPlaylistSong", genre, songData, function(err, res) {
  137. console.log(err, res);
  138. });
  139. },
  140. "click #search-song": function(){
  141. $("#song-results").empty()
  142. $.ajax({
  143. type: "GET",
  144. url: "https://www.googleapis.com/youtube/v3/search?part=snippet&q=" + $("#song-input").val() + "&key=AIzaSyAgBdacEWrHCHVPPM4k-AFM7uXg-Q__YXY",
  145. applicationType: "application/json",
  146. contentType: "json",
  147. success: function(data){
  148. console.log(data);
  149. for(var i in data.items){
  150. $("#song-results").append("<p>" + data.items[i].snippet.title + "</p>");
  151. ytArr.push({title: data.items[i].snippet.title, id: data.items[i].id.videoId});
  152. }
  153. console.log(ytArr);
  154. $("#song-results p").click(function(){
  155. var title = $(this).text();
  156. for(var i in ytArr){
  157. if(ytArr[i].title === title){
  158. var songObj = {
  159. id: ytArr[i].id,
  160. title: ytArr[i].title,
  161. type: "youtube"
  162. };
  163. console.log(ytArr[i].title);
  164. console.log(ytArr[i].id);
  165. // Set title field
  166. $("#title").val(songObj.title);
  167. // Set ID field
  168. $("#id").val(songObj.id);
  169. getSpotifyInfo(songObj.title.replace(/\[.*\]/g, ""), function(data) {
  170. console.log(data);
  171. if (data.tracks.items.length > 0) {
  172. $("#title").val(data.tracks.items[0].name);
  173. var artists = [];
  174. data.tracks.items[0].artists.forEach(function(artist) {
  175. artists.push(artist.name);
  176. });
  177. console.log(artists);
  178. console.log(artists.join(", "));
  179. $("#artist").val(artists.join(", "));
  180. }
  181. // Set title field again if possible
  182. // Set artist if possible
  183. });
  184. }
  185. }
  186. })
  187. }
  188. })
  189. // SC.get('/tracks', { q: $("#song-input").val()}, function(tracks) {
  190. // console.log(tracks);
  191. // for(var i in tracks){
  192. // $("#song-results").append("<p>" + tracks[i].title + "</p>")
  193. // songsArr.push({title: tracks[i].title, id: tracks[i].id, duration: tracks[i].duration / 1000});
  194. // }
  195. // $("#song-results p").click(function(){
  196. // var title = $(this).text();
  197. // for(var i in songsArr){
  198. // if(songsArr[i].title === title){
  199. // var id = songsArr[i].id;
  200. // var duration = songsArr[i].duration;
  201. // var songObj = {
  202. // title: songsArr[i].title,
  203. // id: id,
  204. // duration: duration,
  205. // type: "soundcloud"
  206. // }
  207. // }
  208. // }
  209. // console.log(id);
  210. // })
  211. // });
  212. },
  213. "click #add-songs": function(){
  214. $("#add-songs-modal").show();
  215. }
  216. });
  217. Template.room.helpers({
  218. type: function() {
  219. var parts = location.href.split('/');
  220. var id = parts.pop();
  221. return id.toUpperCase();
  222. },
  223. title: function(){
  224. return Session.get("title");
  225. },
  226. artist: function(){
  227. return Session.get("artist");
  228. },
  229. title_next: function(){
  230. return Session.get("title_next");
  231. },
  232. artist_next: function(){
  233. return Session.get("artist_next");
  234. },
  235. title_after: function(){
  236. return Session.get("title_after");
  237. },
  238. artist_after: function(){
  239. return Session.get("artist_after");
  240. },
  241. loaded: function() {
  242. return Session.get("loaded");
  243. }
  244. });
  245. Template.admin.helpers({
  246. rooms: function() {
  247. return Rooms.find({});
  248. }
  249. });
  250. Template.playlist.helpers({
  251. playlist_songs: function() {
  252. var data = Playlists.find({type: type}).fetch();
  253. if (data !== undefined && data.length > 0) {
  254. return data[0].songs;
  255. } else {
  256. return [];
  257. }
  258. }
  259. });
  260. Meteor.subscribe("rooms");
  261. Template.room.onCreated(function () {
  262. var tag = document.createElement("script");
  263. tag.src = "https://www.youtube.com/iframe_api";
  264. var firstScriptTag = document.getElementsByTagName('script')[0];
  265. firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
  266. var currentSong = undefined;
  267. var nextSong = undefined;
  268. var afterSong = undefined;
  269. var _sound = undefined;
  270. var yt_player = undefined;
  271. var size = 0;
  272. var artistStr;
  273. var temp = "";
  274. var currentArt;
  275. function getTimeElapsed() {
  276. if (currentSong !== undefined) {
  277. return Date.now() - currentSong.started;
  278. }
  279. return 0;
  280. }
  281. function getSongInfo(query, platform){
  282. var search = query;
  283. var titles = [];
  284. getSpotifyInfo(query, function(data) {
  285. console.log(data);
  286. for(var i in data){
  287. for(var j in data[i].items){
  288. if(search.indexOf(data[i].items[j].name) !== -1){
  289. console.log(data[i].items[j].name);
  290. var info = data[i].items[j];
  291. Session.set("title", data[i].items[j].name);
  292. console.log("Info: " + info);
  293. if(platform === "youtube"){
  294. Session.set("duration", data[i].items[j].duration_ms / 1000)
  295. console.log(Session.get("duration"));
  296. }
  297. var artist = getSpotifyArtist(data[i].items[j]);
  298. Session.set("artist", artist);
  299. $("#song-img").attr("src", data[i].items[j].album.images[1].url);
  300. return true;
  301. }
  302. }
  303. //---------------------------------------------------------------//
  304. }
  305. });
  306. }
  307. function getNextSongInfo(query, platform){
  308. var search = query;
  309. var titles = [];
  310. getSpotifyInfo(query, function(data) {
  311. console.log(data);
  312. for(var i in data){
  313. for(var j in data[i].items){
  314. if(search.indexOf(data[i].items[j].name) !== -1){
  315. console.log(data[i].items[j].name);
  316. var info = data[i].items[j];
  317. Session.set("title_next", data[i].items[j].name);
  318. var artist = getSpotifyArtist(data[i].items[j]);
  319. Session.set("artist_next", artist);
  320. $("#song-img-next").attr("src", data[i].items[j].album.images[1].url);
  321. return true;
  322. }
  323. }
  324. //---------------------------------------------------------------//
  325. }
  326. });
  327. }
  328. function getAfterSongInfo(query, platform){
  329. var search = query;
  330. var titles = [];
  331. getSpotifyInfo(query, function(data) {
  332. console.log(data);
  333. for(var i in data){
  334. for(var j in data[i].items){
  335. if(search.indexOf(data[i].items[j].name) !== -1){
  336. console.log(data[i].items[j].name);
  337. var info = data[i].items[j];
  338. Session.set("title_after", data[i].items[j].name);
  339. var artist = getSpotifyArtist(data[i].items[j]);
  340. Session.set("artist_after", artist);
  341. $("#song-img-after").attr("src", data[i].items[j].album.images[1].url);
  342. return true;
  343. }
  344. }
  345. //---------------------------------------------------------------//
  346. }
  347. });
  348. }
  349. function resizeSeekerbar() {
  350. $("#seeker-bar").width(((getTimeElapsed() / 1000) / Session.get("duration") * 100) + "%");
  351. }
  352. function startSong() {
  353. if (currentSong !== undefined) {
  354. if (_sound !== undefined) _sound.stop();
  355. if (yt_player !== undefined && yt_player.stopVideo !== undefined) yt_player.stopVideo();
  356. if (currentSong.song.type === "soundcloud") {
  357. $("#player").attr("src", "")
  358. getSongInfo(currentSong.song.title, "soundcloud");
  359. SC.stream("/tracks/" + currentSong.song.id + "#t=20s", function(sound){
  360. console.log(sound);
  361. _sound = sound;
  362. sound._player._volume = 0.3;
  363. sound.play();
  364. console.log(getTimeElapsed());
  365. var interval = setInterval(function() {
  366. if (sound.getState() === "playing") {
  367. sound.seek(getTimeElapsed());
  368. window.clearInterval(interval);
  369. }
  370. }, 200);
  371. // Session.set("title", currentSong.song.title || "Title");
  372. // Session.set("artist", currentSong.song.artist || "Artist");
  373. Session.set("duration", currentSong.song.duration);
  374. resizeSeekerbar();
  375. });
  376. } else {
  377. if (yt_player === undefined) {
  378. yt_player = new YT.Player("player", {
  379. height: 540,
  380. width: 960,
  381. videoId: currentSong.song.id,
  382. events: {
  383. 'onReady': function(event) {
  384. event.target.seekTo(getTimeElapsed() / 1000);
  385. event.target.playVideo();
  386. resizeSeekerbar();
  387. },
  388. 'onStateChange': function(event){
  389. if (event.data == YT.PlayerState.PAUSED) {
  390. event.target.seekTo(getTimeElapsed() / 1000);
  391. event.target.playVideo();
  392. }
  393. }
  394. }
  395. });
  396. } else {
  397. yt_player.loadVideoById(currentSong.song.id);
  398. }
  399. // Session.set("title", currentSong.song.title || "Title");
  400. // Session.set("artist", currentSong.song.artist || "Artist");
  401. getSongInfo(currentSong.song.title, "youtube");
  402. //Session.set("duration", currentSong.song.duration);
  403. }
  404. }
  405. }
  406. Meteor.subscribe("history");
  407. Meteor.subscribe("playlists");
  408. Session.set("loaded", false);
  409. Meteor.subscribe("rooms", function() {
  410. var parts = location.href.split('/');
  411. var id = parts.pop();
  412. var type = id.toLowerCase();
  413. //console.log(Rooms.find({type: type}).fetch().length);
  414. if (Rooms.find({type: type}).count() !== 1) {
  415. window.location = "/";
  416. } else {
  417. Session.set("loaded", true);
  418. Meteor.setInterval(function () {
  419. var data = undefined;
  420. var dataCursorH = History.find({type: type});
  421. var dataCursorP = Playlists.find({type: type});
  422. dataCursorH.forEach(function (doc) {
  423. if (data === undefined) {
  424. data = doc;
  425. }
  426. });
  427. if (data !== undefined && data.history.length > size) {
  428. currentSong = data.history[data.history.length - 1];
  429. var songs = dataCursorP.fetch()[0].songs;
  430. console.log(currentSong, " 555");
  431. songs.forEach(function(song, index) {
  432. if (currentSong.song.title === song.title) {
  433. console.log(index);
  434. console.log(song);
  435. if (index + 1 < songs.length) {
  436. // INDEX+1
  437. nextSong = songs[index + 1];
  438. } else {
  439. // 0
  440. nextSong = songs[0];
  441. }
  442. console.log(nextSong, 5555);
  443. getNextSongInfo(nextSong.title, nextSong.type);
  444. if (index + 2 < songs.length) {
  445. console.log("OOO 1");
  446. afterSong = songs[index + 2];
  447. } else if (songs.length === index + 1) {
  448. afterSong = songs[1];
  449. } else {
  450. afterSong = songs[0];
  451. }
  452. getAfterSongInfo(afterSong.title, afterSong.type);
  453. }
  454. });
  455. size = data.history.length;
  456. startSong();
  457. }
  458. }, 1000);
  459. Meteor.setInterval(function () {
  460. resizeSeekerbar();
  461. }, 50);
  462. }
  463. });
  464. });
  465. }
  466. if (Meteor.isServer) {
  467. Meteor.startup(function() {
  468. reCAPTCHA.config({
  469. privatekey: '6LcVxg0TAAAAAI2fgIEEWHFxwNXeVIs8mzq5cfRM'
  470. });
  471. });
  472. Meteor.users.deny({update: function () { return true; }});
  473. Meteor.users.deny({insert: function () { return true; }});
  474. Meteor.users.deny({remove: function () { return true; }});
  475. function getSongDuration(query){
  476. var duration;
  477. var search = query;
  478. query = query.toLowerCase().split(" ").join("%20");
  479. var res = Meteor.http.get('https://api.spotify.com/v1/search?q=' + query + '&type=track');
  480. for(var i in res.data){
  481. for(var j in res.data[i].items){
  482. if(search.indexOf(res.data[i].items[j].name) !== -1){
  483. duration = res.data[i].items[j].duration_ms / 1000;
  484. console.log(duration);
  485. return duration;
  486. }
  487. }
  488. }
  489. }
  490. function getSongAlbumArt(query){
  491. var albumart;
  492. var search = query;
  493. query = query.toLowerCase().split(" ").join("%20");
  494. var res = Meteor.http.get('https://api.spotify.com/v1/search?q=' + query + '&type=track');
  495. for(var i in res.data){
  496. for(var j in res.data[i].items){
  497. if(search.indexOf(res.data[i].items[j].name) !== -1){
  498. albumart = res.data[i].items[j].album.images[1].url
  499. return albumart;
  500. }
  501. }
  502. }
  503. }
  504. //var room_types = ["edm", "nightcore"];
  505. var songsArr = [];
  506. function getSongsByType(type) {
  507. if (type === "edm") {
  508. return [
  509. {id: "aE2GCa-_nyU", title: "Radioactive - Lindsey Stirling and Pentatonix", duration: getSongDuration("Radioactive - Lindsey Stirling and Pentatonix"), albumart: getSongAlbumArt("Radioactive - Lindsey Stirling and Pentatonix"), type: "youtube"},
  510. {id: "aHjpOzsQ9YI", title: "Crystallize", artist: "Linsdey Stirling", duration: getSongDuration("Crystallize"), albumart: getSongAlbumArt("Crystallize"), type: "youtube"}
  511. ];
  512. } else if (type === "nightcore") {
  513. return [{id: "f7RKOP87tt4", title: "Monster (DotEXE Remix)", duration: getSongDuration("Monster (DotEXE Remix)"), albumart: getSongAlbumArt("Monster (DotEXE Remix)"), type: "youtube"}];
  514. } else {
  515. return [{id: "dQw4w9WgXcQ", title: "Never Gonna Give You Up", duration: getSongDuration("Never Gonna Give You Up"), albumart: getSongAlbumArt("Never Gonna Give You Up"), type: "youtube"}];
  516. }
  517. }
  518. Rooms.find({}).fetch().forEach(function(room) {
  519. var type = room.type;
  520. if (Playlists.find({type: type}).count() === 0) {
  521. if (type === "edm") {
  522. Playlists.insert({type: type, songs: getSongsByType(type)});
  523. } else if (type === "nightcore") {
  524. Playlists.insert({type: type, songs: getSongsByType(type)});
  525. } else {
  526. Playlists.insert({type: type, songs: getSongsByType(type)});
  527. }
  528. }
  529. if (History.find({type: type}).count() === 0) {
  530. History.insert({type: type, history: []});
  531. }
  532. if (Playlists.find({type: type}).fetch()[0].songs.length === 0) {
  533. // Add a global video to Playlist so it can proceed
  534. } else {
  535. var startedAt = Date.now();
  536. var songs = Playlists.find({type: type}).fetch()[0].songs;
  537. var currentSong = 0;
  538. addToHistory(songs[currentSong], startedAt);
  539. function addToHistory(song, startedAt) {
  540. History.update({type: type}, {$push: {history: {song: song, started: startedAt}}});
  541. }
  542. function skipSong() {
  543. songs = Playlists.find({type: type}).fetch()[0].songs;
  544. if (currentSong < (songs.length - 1)) {
  545. currentSong++;
  546. } else currentSong = 0;
  547. songTimer();
  548. addToHistory(songs[currentSong], startedAt);
  549. }
  550. function songTimer() {
  551. startedAt = Date.now();
  552. Meteor.setTimeout(function() {
  553. skipSong();
  554. }, songs[currentSong].duration * 1000);
  555. }
  556. songTimer();
  557. }
  558. });
  559. ServiceConfiguration.configurations.remove({
  560. service: "facebook"
  561. });
  562. ServiceConfiguration.configurations.insert({
  563. service: "facebook",
  564. appId: "1496014310695890",
  565. secret: "9a039f254a08a1488c08bb0737dbd2a6"
  566. });
  567. ServiceConfiguration.configurations.remove({
  568. service: "github"
  569. });
  570. ServiceConfiguration.configurations.insert({
  571. service: "github",
  572. clientId: "dcecd720f47c0e4001f7",
  573. secret: "375939d001ef1a0ca67c11dbf8fb9aeaa551e01b"
  574. });
  575. Meteor.publish("history", function() {
  576. return History.find({})
  577. });
  578. Meteor.publish("playlists", function() {
  579. return Playlists.find({})
  580. });
  581. Meteor.publish("rooms", function() {
  582. return Rooms.find()
  583. });
  584. Meteor.methods({
  585. createUserMethod: function(formData, captchaData) {
  586. var verifyCaptchaResponse = reCAPTCHA.verifyCaptcha(this.connection.clientAddress, captchaData);
  587. if (!verifyCaptchaResponse.success) {
  588. console.log('reCAPTCHA check failed!', verifyCaptchaResponse);
  589. throw new Meteor.Error(422, 'reCAPTCHA Failed: ' + verifyCaptchaResponse.error);
  590. } else {
  591. console.log('reCAPTCHA verification passed!');
  592. Accounts.createUser({
  593. username: formData.username,
  594. email: formData.email,
  595. password: formData.password
  596. });
  597. }
  598. return true;
  599. },
  600. addPlaylistSong: function(type, songData) {
  601. type = type.toLowerCase();
  602. if (Rooms.find({type: type}).count() === 1) {
  603. console.log(songData);
  604. if (songData !== undefined && Object.keys(songData).length === 4 && songData.type !== undefined && songData.title !== undefined && songData.title !== undefined && songData.artist !== undefined) {
  605. songData.duration = getSongDuration(songData.title);
  606. Playlists.update({type: type}, {$push: {songs: {id: songData.id, title: songData.title, artist: songData.artist, duration: songData.duration, type: songData.type}}});
  607. return true;
  608. } else {
  609. throw new Meteor.error(403, "Invalid data.");
  610. }
  611. } else {
  612. throw new Meteor.error(403, "Invalid genre.");
  613. }
  614. },
  615. createRoom: function(type) {
  616. if (Rooms.find({type: type}).count() === 0) {
  617. Rooms.insert({type: type}, function(err) {
  618. if (err) {
  619. throw err;
  620. } else {
  621. if (Playlists.find({type: type}).count() === 1) {
  622. if (History.find({type: type}).count() === 0) {
  623. History.insert({type: type, history: []}, function(err3) {
  624. if (err3) {
  625. throw err3;
  626. } else {
  627. startStation();
  628. return true;
  629. }
  630. });
  631. } else {
  632. startStation();
  633. return true;
  634. }
  635. } else {
  636. Playlists.insert({type: type, songs: getSongsByType(type)}, function (err2) {
  637. if (err2) {
  638. throw err2;
  639. } else {
  640. if (History.find({type: type}).count() === 0) {
  641. History.insert({type: type, history: []}, function(err3) {
  642. if (err3) {
  643. throw err3;
  644. } else {
  645. startStation();
  646. return true;
  647. }
  648. });
  649. } else {
  650. startStation();
  651. return true;
  652. }
  653. }
  654. });
  655. }
  656. }
  657. });
  658. } else {
  659. throw "Room already exists";
  660. }
  661. function startStation() {
  662. var startedAt = Date.now();
  663. var songs = Playlists.find({type: type}).fetch()[0].songs;
  664. var currentSong = 0;
  665. addToHistory(songs[currentSong], startedAt);
  666. function addToHistory(song, startedAt) {
  667. History.update({type: type}, {$push: {history: {song: song, started: startedAt}}});
  668. }
  669. function skipSong() {
  670. songs = Playlists.find({type: type}).fetch()[0].songs;
  671. if (currentSong < (songs.length - 1)) {
  672. currentSong++;
  673. } else currentSong = 0;
  674. songTimer();
  675. addToHistory(songs[currentSong], startedAt);
  676. }
  677. function songTimer() {
  678. startedAt = Date.now();
  679. Meteor.setTimeout(function() {
  680. skipSong();
  681. }, songs[currentSong].duration * 1000);
  682. }
  683. songTimer();
  684. }
  685. }
  686. });
  687. }
  688. Router.route("/", {
  689. template: "home"
  690. });
  691. Router.route("/terms", {
  692. template: "terms"
  693. });
  694. Router.route("/privacy", {
  695. template: "privacy"
  696. });
  697. Router.route("/admin", {
  698. template: "admin"
  699. });
  700. Router.route("/:type", {
  701. template: "room"
  702. });