mirror of
				https://github.com/KevinMidboe/zoff.git
				synced 2025-10-29 18:00:23 +00:00 
			
		
		
		
	REST-endpoints and readme
This commit is contained in:
		
							
								
								
									
										219
									
								
								server/README.md
									
									
									
									
									
								
							
							
						
						
									
										219
									
								
								server/README.md
									
									
									
									
									
								
							| @@ -2,57 +2,197 @@ | |||||||
|  |  | ||||||
| Under ``` /server/apps/ ```, there are two files, ``` admin.js ``` and ``` client.js ```.``` admin.js ``` are for the adminpanel, and ``` client.js ``` are for zoff itself. | Under ``` /server/apps/ ```, there are two files, ``` admin.js ``` and ``` client.js ```.``` admin.js ``` are for the adminpanel, and ``` client.js ``` are for zoff itself. | ||||||
|  |  | ||||||
|  | ## REST | ||||||
|  |  | ||||||
|  | Add song | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | POST /api/list/:channel_name/:video_id | ||||||
|  |     { | ||||||
|  |         "title": TITLE, | ||||||
|  |         "duration": END_TIME - START_TIME, | ||||||
|  |         "end_time": END_TIME, | ||||||
|  |         "start_time": START_TIME, | ||||||
|  |         "adminpass": PASSWORD, | ||||||
|  |         "userpass": USER_PASSWORD | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | Returns 403 for bad authentication | ||||||
|  | Returns 409 if the song exists | ||||||
|  | Returns 200 and the added song object if successful | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Delete song | ||||||
|  | ``` | ||||||
|  | DELETE /api/list/:channel_name/:video_id | ||||||
|  |     { | ||||||
|  |         "adminpass": PASSWORD, | ||||||
|  |         "userpass": USER_PASSWORD | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | Returns 403 for bad authentication | ||||||
|  | Returns 404 if the song doesnt exist | ||||||
|  | Returns 200 if successful | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Vote on song | ||||||
|  | ``` | ||||||
|  | PUT /api/list/:channel_name/:video_id | ||||||
|  |     { | ||||||
|  |         "adminpass": PASSWORD, | ||||||
|  |         "userpass": USER_PASSWORD | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | Returns 403 for bad authentication | ||||||
|  | Returns 404 if the song doesnt exist | ||||||
|  | Returns 409 if you've already voted on that song | ||||||
|  | Returns 200 and the added song object if successful | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Change channel configurations | ||||||
|  | ``` | ||||||
|  | PUT /api/conf/:channel_name | ||||||
|  |     { | ||||||
|  |         "userpass": USER_PASSWORD, | ||||||
|  |         "adminpass": PASSWORD, | ||||||
|  |         "voting": BOOLEAN, | ||||||
|  |         "addsongs": BOOLEAN, | ||||||
|  |         "longsongs": BOOLEAN, | ||||||
|  |         "frontpage": BOOLEAN (if you want to set userpassword, this MUST be false for it to work), | ||||||
|  |         "allvideos": BOOLEAN, | ||||||
|  |         "removeplay": BOOLEAN, | ||||||
|  |         "skipping": BOOLEAN, | ||||||
|  |         "shuffling": BOOLEAN, | ||||||
|  |         "userpass_changed": BOOLEAN (this must be true if you want to keep the userpassword you're sending) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | Returns 403 for bad authentication | ||||||
|  | Returns 404 if the list doesn't exist | ||||||
|  | Returns 200 and the newly added configuration if successful | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Still to come: SKIP and SHUFFLE RESTApi calls.. | ||||||
|  |  | ||||||
|  |  | ||||||
| ## Events | ## Events | ||||||
|  |  | ||||||
| ### To server | ### To server | ||||||
| ``` | ``` | ||||||
| //  Tells the server the song is clientside | //  Tells the server the song is over | ||||||
| 'end', {id: video_id, channel: channel_name, pass: channel_pass} | 'end', { | ||||||
|  |     id: video_id, | ||||||
|  |     channel: channel_name, | ||||||
|  |     pass: channel_pass | ||||||
|  | } | ||||||
|  |  | ||||||
| // Asks server where in the song it should be | // Asks server where in the song it should be | ||||||
| 'pos', {channel: channel_name, pass: channel_pass} | 'pos', { | ||||||
|  |     channel: channel_name, | ||||||
|  |     pass: channel_pass | ||||||
|  | } | ||||||
|  |  | ||||||
| // Tells the server the client wants the list | // Tells the server the client wants the list | ||||||
| 'list', {channel: channel_name, pass: channel_pass, version: system_version (now 3)} | 'list', { | ||||||
|  |     channel: channel_name, | ||||||
|  |     pass: channel_pass, | ||||||
|  |     version: system_version (now 3) | ||||||
|  | } | ||||||
|  |  | ||||||
| // Sends info about a song the client wants to add | // Sends info about a song the client wants to add | ||||||
| 'add', {id: VIDEO_ID, title: VIDEO_TITLE, adminpass: sha256(PASSWORD), duration: VIDEO_DURATION, list: channel_name, playlist: true_if_importing_playlist, num: current_number_of_sending_songs, total: total_number_of_sending_songs, pass: channel_pass} | 'add', { | ||||||
|  |     id: VIDEO_ID, | ||||||
|  |     title: VIDEO_TITLE, | ||||||
|  |     adminpass: AES-CBC-Pkcs7 with Base64 IV(PASSWORD), | ||||||
|  |     duration: VIDEO_DURATION, | ||||||
|  |     list: channel_name, | ||||||
|  |     playlist: true_if_importing_playlist, | ||||||
|  |     num: current_number_of_sending_songs, | ||||||
|  |     total: total_number_of_sending_songs, | ||||||
|  |     pass: channel_pass | ||||||
|  | } | ||||||
|  |  | ||||||
| // Tells the server to disconnect the user from the current channel, is used for remote controlling on the host side | // Tells the server to disconnect the user from the current channel, is used for remote controlling on the host side | ||||||
| 'change_channel', {channel: channel_name} | 'change_channel', { | ||||||
|  |     channel: channel_name | ||||||
|  | } | ||||||
|  |  | ||||||
| // Sends chat text to all chat | // Sends chat text to all chat | ||||||
| 'all,chat', {channel: channel_name, data: input} | 'all,chat', { | ||||||
|  |     channel: channel_name, | ||||||
|  |     data: input | ||||||
|  | } | ||||||
|  |  | ||||||
| // Sends chat text to channelchat | // Sends chat text to channelchat | ||||||
| 'chat',{channel: channel_name, data: input, pass: channel_pass} | 'chat',{ | ||||||
|  |     channel: channel_name, | ||||||
|  |     data: input, | ||||||
|  |     pass: channel_pass | ||||||
|  | } | ||||||
|  |  | ||||||
| // Sends info about song the user wants to vote on. If VOTE_TYPE is del, its deleting the song, if its pos, its just voting | // Sends info about song the user wants to vote on. If VOTE_TYPE is del, its deleting the song, if its pos, its just voting | ||||||
| 'vote', {channel: CHANNEL_NAME, id: VIDEO_ID, type: VOTE_TYPE, adminpass: PASSWORD} | 'vote', { | ||||||
|  |     channel: CHANNEL_NAME, | ||||||
|  |     id: VIDEO_ID, | ||||||
|  |     type: VOTE_TYPE, | ||||||
|  |     adminpass: AES-CBC-Pkcs7 with Base64 IV(PASSWORD) | ||||||
|  | } | ||||||
|  |  | ||||||
| // Sends skip message to server | // Sends skip message to server | ||||||
| 'skip', {pass: adminpass, id:video_id, channel: chan, userpass: channel_pass} | 'skip', { | ||||||
|  |     pass: AES-CBC-Pkcs7 with Base64 IV(PASSWORD), | ||||||
|  |     id:video_id, | ||||||
|  |     channel: chan, | ||||||
|  |     userpass: channel_pass | ||||||
|  | } | ||||||
|  |  | ||||||
| // Sends password for instant log in to server | // Sends password for instant log in to server | ||||||
| 'password', {password: PASSWORD, channel: CHANNEL_NAME, oldpass: old_pass_if_changing_password} | 'password', { | ||||||
|  |     password: PASSWORD, | ||||||
|  |     channel: CHANNEL_NAME, | ||||||
|  |     oldpass: old_pass_if_changing_password | ||||||
|  | } | ||||||
|  |  | ||||||
| // Sends message to the host channel for play | // Sends message to the host channel for play | ||||||
| 'id', {id: CHANNEL_ID, type: "play", value: "mock"} | 'id', { | ||||||
|  |     id: CHANNEL_ID, | ||||||
|  |     type: "play", | ||||||
|  |     value: "mock" | ||||||
|  | } | ||||||
|  |  | ||||||
| // Sends message to the host channel for pause | // Sends message to the host channel for pause | ||||||
| 'id', {id: CHANNEL_ID, type: "pause", value: "mock"} | 'id', { | ||||||
|  |     id: CHANNEL_ID, | ||||||
|  |     type: "pause", | ||||||
|  |     value: "mock" | ||||||
|  | } | ||||||
|  |  | ||||||
| // Sends message to the host channel for skip | // Sends message to the host channel for skip | ||||||
| 'id', {id: CHANNEL_ID, type: "skip", value: "mock"} | 'id', { | ||||||
|  |     id: CHANNEL_ID, | ||||||
|  |     type: "skip", | ||||||
|  |     value: "mock" | ||||||
|  | } | ||||||
|  |  | ||||||
| // Sends message to the host channel to change volume | // Sends message to the host channel to change volume | ||||||
| 'id', {id: CHANNEL_ID, type: "volume", value: VALUE} | 'id', { | ||||||
|  |     id: CHANNEL_ID, | ||||||
|  |     type: "volume", | ||||||
|  |     value: VALUE | ||||||
|  | } | ||||||
|  |  | ||||||
| // Sends message to the host channel to change channel | // Sends message to the host channel to change channel | ||||||
| 'id', {id: CHANNEL_ID, type: "channel", value: NEW_CHANNEL_NAME} | 'id', { | ||||||
|  |     id: CHANNEL_ID, | ||||||
|  |     type: "channel", | ||||||
|  |     value: NEW_CHANNEL_NAME | ||||||
|  | } | ||||||
|  |  | ||||||
| // Sends a video that triggered an error | // Sends a video that triggered an error | ||||||
| 'error_video', {channel: CHANNE_NAME, id: VIDEO_ID, title: VIDEO_TITLE} | 'error_video', { | ||||||
|  |     channel: CHANNE_NAME, | ||||||
|  |     id: VIDEO_ID, | ||||||
|  |     title: VIDEO_TITLE | ||||||
|  | } | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| ### From server | ### From server | ||||||
| @@ -60,36 +200,65 @@ Under ``` /server/apps/ ```, there are two files, ``` admin.js ``` and ``` clien | |||||||
| // Receives a string from server for what type of toast to be triggered | // Receives a string from server for what type of toast to be triggered | ||||||
| 'toast', STRING   | 'toast', STRING   | ||||||
|  |  | ||||||
| // Receives the password for the channel if the user sent the right in the first place | // Receives a boolean if the password was correct | ||||||
| 'pw', STRING    | 'pw', BOOLEAN    | ||||||
|  |  | ||||||
| // Receives configuration array from server | // Receives configuration array from server | ||||||
| 'conf', [ARRAY] | 'conf', [ARRAY] | ||||||
|  |  | ||||||
| // Receives chat message from allchat | // Receives chat message from allchat | ||||||
| 'chat.all', {from: name, msg: message, channel: channel, icon: icon_src} | 'chat.all', { | ||||||
|  |     from: name, | ||||||
|  |     msg: message, | ||||||
|  |     channel: channel, | ||||||
|  |     icon: icon_src | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Receives chat-history for all and for current channel | ||||||
|  | 'chat_history', { | ||||||
|  |     all: BOOLEAN (if true, it is for all-chat), | ||||||
|  |     data: CHAT_HISTORY | ||||||
|  | } | ||||||
|  |  | ||||||
| // Receives chat message from channelchat | // Receives chat message from channelchat | ||||||
| 'chat', {from: name, msg: message, icon: icon_src} | 'chat', { | ||||||
|  |     from: name, | ||||||
|  |     msg: message, | ||||||
|  |     icon: icon_src | ||||||
|  | } | ||||||
|  |  | ||||||
| // Receives the ID of the current client, used for remote listening | // Receives the ID of the current client, used for remote listening | ||||||
| 'id', STRING     | 'id', STRING     | ||||||
|  |  | ||||||
| // Receives the messages sent on CHANNEL_ID above | // Receives the messages sent on CHANNEL_ID above | ||||||
| id, {type: STRING, value: VALUE} | id, { | ||||||
|  |     type: STRING, | ||||||
|  |     value: VALUE | ||||||
|  | } | ||||||
|  |  | ||||||
| // Receives updates from channel. type is one of the following: list, added, deleted, vote, song_change, changed_values (see further down for better explanation here) | // Receives updates from channel. type is one of the following: list, added, deleted, vote, song_change, changed_values (see further down for better explanation here) | ||||||
| 'channel', {type: TYPE, value: value, time: time_of_occurence} | 'channel', { | ||||||
|  |     type: TYPE, | ||||||
|  |     value: value, | ||||||
|  |     time: time_of_occurence | ||||||
|  | } | ||||||
|  |  | ||||||
| // Receives message from the server that its ready to send the playlist and info | // Receives message from the server that its ready to send the playlist and info | ||||||
| 'get_list' | 'get_list' | ||||||
|  |  | ||||||
| // Receives array of now playing song. Is triggered on song-change | // Receives array of now playing song. Is triggered on song-change | ||||||
| 'np', {np: NOW_PLAYING, conf: CONFIGURATION, time: SERVER_TIME} | 'np', { | ||||||
|  |     np: NOW_PLAYING, | ||||||
|  |     conf: CONFIGURATION, | ||||||
|  |     time: SERVER_TIME | ||||||
|  | } | ||||||
|  |  | ||||||
| // Receives number of viewers on the current channel | // Receives number of viewers on the current channel | ||||||
| 'viewers', VALUE     | 'viewers', VALUE     | ||||||
|  |  | ||||||
| // Receives a newly updated video, that was checked for errors (song_generated contains .id which is the current id of the video, and a .new_id for the new video to change the video to) | // Receives a newly updated video, that was checked for errors (song_generated contains .id which is the current id of the video, and a .new_id for the new video to change the video to) | ||||||
| 'channel', {type: "changed_values", value: song_generated} | 'channel', { | ||||||
|  |     type: "changed_values", | ||||||
|  |     value: song_generated | ||||||
|  | } | ||||||
| ``` | ``` | ||||||
|   | |||||||
| @@ -10,12 +10,14 @@ function frontpage_lists(msg, socket) { | |||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
| function update_frontpage(coll, id, title) { | function update_frontpage(coll, id, title, callback) { | ||||||
|     db.collection("frontpage_lists").update({_id: coll}, {$set: { |     db.collection("frontpage_lists").update({_id: coll}, {$set: { | ||||||
|         id: id, |         id: id, | ||||||
|         title: title, |         title: title, | ||||||
|         accessed: Functions.get_time()} |         accessed: Functions.get_time()} | ||||||
|     },{upsert: true}, function(err, returnDocs){}); |     },{upsert: true}, function(err, returnDocs){ | ||||||
|  |         if(typeof(callback) == "function") callback(); | ||||||
|  |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports.frontpage_lists = frontpage_lists; | module.exports.frontpage_lists = frontpage_lists; | ||||||
|   | |||||||
| @@ -74,6 +74,7 @@ function list(msg, guid, coll, offline, socket) { | |||||||
|  |  | ||||||
| function skip(list, guid, coll, offline, socket) { | function skip(list, guid, coll, offline, socket) { | ||||||
|     var socketid = socket.zoff_id; |     var socketid = socket.zoff_id; | ||||||
|  |  | ||||||
|     if(list !== undefined && list !== null && list !== "") |     if(list !== undefined && list !== null && list !== "") | ||||||
|     { |     { | ||||||
|  |  | ||||||
| @@ -81,7 +82,11 @@ function skip(list, guid, coll, offline, socket) { | |||||||
|             socket.emit("update_required"); |             socket.emit("update_required"); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |         if(typeof(list.pass) != "string" || typeof(list.id) != "string" || | ||||||
|  |             typeof(list.channel) != "string" || typeof(list.userpass) != "string") { | ||||||
|  |                 socket.emit("toast", "update_required"); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|         db.collection(coll + "_settings").find(function(err, docs){ |         db.collection(coll + "_settings").find(function(err, docs){ | ||||||
|             if(docs.length > 0 && (docs[0].userpass == undefined || docs[0].userpass == "" || (list.hasOwnProperty('userpass') && docs[0].userpass == Functions.decrypt_string(socketid, list.userpass)))) { |             if(docs.length > 0 && (docs[0].userpass == undefined || docs[0].userpass == "" || (list.hasOwnProperty('userpass') && docs[0].userpass == Functions.decrypt_string(socketid, list.userpass)))) { | ||||||
|  |  | ||||||
| @@ -401,6 +406,7 @@ function end(obj, coll, guid, offline, socket) { | |||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|     id = obj.id; |     id = obj.id; | ||||||
|  |  | ||||||
|     if(id !== undefined && id !== null && id !== "") { |     if(id !== undefined && id !== null && id !== "") { | ||||||
|  |  | ||||||
|         if(coll == "" || coll == undefined || coll == null) { |         if(coll == "" || coll == undefined || coll == null) { | ||||||
| @@ -408,6 +414,12 @@ function end(obj, coll, guid, offline, socket) { | |||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         if(typeof(obj.id) != "string" || typeof(obj.channel) != "string" || | ||||||
|  |             typeof(obj.pass) != "string") { | ||||||
|  |                 socket.emit("toast", "update_required"); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |  | ||||||
|         db.collection(coll + "_settings").find(function(err, docs){ |         db.collection(coll + "_settings").find(function(err, docs){ | ||||||
|             if(docs.length > 0 && (docs[0].userpass == undefined || docs[0].userpass == "" || (obj.hasOwnProperty('pass') && docs[0].userpass == Functions.decrypt_string(socketid, obj.pass)))) { |             if(docs.length > 0 && (docs[0].userpass == undefined || docs[0].userpass == "" || (obj.hasOwnProperty('pass') && docs[0].userpass == Functions.decrypt_string(socketid, obj.pass)))) { | ||||||
|  |  | ||||||
| @@ -491,7 +503,7 @@ function sendColor(coll, socket, id) { | |||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
| function getNextSong(coll) { | function getNextSong(coll, callback) { | ||||||
|     db.collection(coll).aggregate([{ |     db.collection(coll).aggregate([{ | ||||||
|         $match:{ |         $match:{ | ||||||
|             views:{ |             views:{ | ||||||
| @@ -514,6 +526,7 @@ function getNextSong(coll) { | |||||||
|         if(doc.length == 1) { |         if(doc.length == 1) { | ||||||
|             io.to(coll).emit("next_song", {videoId: doc[0].id, title: doc[0].title}); |             io.to(coll).emit("next_song", {videoId: doc[0].id, title: doc[0].title}); | ||||||
|         } |         } | ||||||
|  |         if(typeof(callback) == "function") callback(); | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -27,6 +27,17 @@ function add_function(arr, coll, guid, offline, socket) { | |||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         if(typeof(arr.id) != "string" || typeof(arr.start) != "number" || | ||||||
|  |             typeof(arr.end) != "number" || typeof(arr.title) != "string" || | ||||||
|  |             typeof(arr.list) != "string" || typeof(arr.duration) != "number" || | ||||||
|  |             typeof(arr.playlist) != "boolean" || typeof(arr.num) != "number" || | ||||||
|  |             typeof(arr.total) != "number" || typeof(arr.pass) != "string" || | ||||||
|  |             typeof(arr.adminpass) != "string") { | ||||||
|  |                 socket.emit("toast", "update_required"); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |  | ||||||
|         db.collection(coll + "_settings").find(function(err, docs){ |         db.collection(coll + "_settings").find(function(err, docs){ | ||||||
|             if(docs.length > 0 && (docs[0].userpass == undefined || docs[0].userpass == "" || (arr.hasOwnProperty('pass') && docs[0].userpass == Functions.decrypt_string(socketid, arr.pass)))) { |             if(docs.length > 0 && (docs[0].userpass == undefined || docs[0].userpass == "" || (arr.hasOwnProperty('pass') && docs[0].userpass == Functions.decrypt_string(socketid, arr.pass)))) { | ||||||
|  |  | ||||||
| @@ -179,6 +190,13 @@ function voteUndecided(msg, coll, guid, offline, socket) { | |||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         if(typeof(msg.channel) != "string" || typeof(msg.id) != "string" || | ||||||
|  |             typeof(msg.type) != "string" || typeof(msg.adminpass) != "string" || | ||||||
|  |             typeof(msg.pass) != "string") { | ||||||
|  |                 socket.emit("toast", "update_required"); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |  | ||||||
|         db.collection(coll + "_settings").find(function(err, docs){ |         db.collection(coll + "_settings").find(function(err, docs){ | ||||||
|             if(docs.length > 0 && (docs[0].userpass == undefined || docs[0].userpass == "" || (msg.hasOwnProperty('pass') && docs[0].userpass == Functions.decrypt_string(socketid, msg.pass)))) { |             if(docs.length > 0 && (docs[0].userpass == undefined || docs[0].userpass == "" || (msg.hasOwnProperty('pass') && docs[0].userpass == Functions.decrypt_string(socketid, msg.pass)))) { | ||||||
|  |  | ||||||
| @@ -218,6 +236,12 @@ function shuffle(msg, coll, guid, offline, socket) { | |||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         if(typeof(msg.adminpass) != "string" || typeof(msg.channel) != "string" || | ||||||
|  |             typeof(msg.pass) != "string") { | ||||||
|  |                 socket.emit("toast", "update_required"); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |  | ||||||
|         Functions.check_inlist(coll, guid, socket, offline); |         Functions.check_inlist(coll, guid, socket, offline); | ||||||
|         var hash; |         var hash; | ||||||
|         if(msg.adminpass === "") hash = msg.adminpass; |         if(msg.adminpass === "") hash = msg.adminpass; | ||||||
| @@ -290,6 +314,11 @@ function delete_all(msg, coll, guid, offline, socket) { | |||||||
|         var hash = Functions.hash_pass(Functions.decrypt_string(socketid, msg.adminpass)); |         var hash = Functions.hash_pass(Functions.decrypt_string(socketid, msg.adminpass)); | ||||||
|         var hash_userpass = Functions.decrypt_string(socketid, msg.pass); |         var hash_userpass = Functions.decrypt_string(socketid, msg.pass); | ||||||
|  |  | ||||||
|  |         if(typeof(msg.channel) != "string" || typeof(msg.adminpass) != "string" || | ||||||
|  |             typeof(msg.pass) != "string") { | ||||||
|  |                 socket.emit("toast", "update_required"); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|         db.collection(coll + "_settings").find(function(err, conf) { |         db.collection(coll + "_settings").find(function(err, conf) { | ||||||
|             if(conf.length == 1 && conf) { |             if(conf.length == 1 && conf) { | ||||||
|                 conf = conf[0]; |                 conf = conf[0]; | ||||||
|   | |||||||
| @@ -21,7 +21,6 @@ function password(inp, coll, guid, offline, socket) { | |||||||
|  |  | ||||||
|         uncrypted = pw; |         uncrypted = pw; | ||||||
|         pw = Functions.decrypt_string(socket.zoff_id, pw); |         pw = Functions.decrypt_string(socket.zoff_id, pw); | ||||||
|  |  | ||||||
|         Functions.check_inlist(coll, guid, socket, offline); |         Functions.check_inlist(coll, guid, socket, offline); | ||||||
|  |  | ||||||
|         if(inp.oldpass) |         if(inp.oldpass) | ||||||
| @@ -44,6 +43,7 @@ function password(inp, coll, guid, offline, socket) { | |||||||
|                     }); |                     }); | ||||||
|                 }else |                 }else | ||||||
|                 socket.emit("toast", "wrongpass"); |                 socket.emit("toast", "wrongpass"); | ||||||
|  |                 socket.emit("pw", false); | ||||||
|             } |             } | ||||||
|         }); |         }); | ||||||
|     } else { |     } else { | ||||||
| @@ -94,6 +94,15 @@ function conf_function(params, coll, guid, offline, socket) { | |||||||
|         var skipping = params.skipping; |         var skipping = params.skipping; | ||||||
|         var shuffling = params.shuffling; |         var shuffling = params.shuffling; | ||||||
|         var userpass = Functions.decrypt_string(socket.zoff_id, params.userpass); |         var userpass = Functions.decrypt_string(socket.zoff_id, params.userpass); | ||||||
|  |         if(typeof(userpass) != "string" || typeof(adminpass) != "string" || | ||||||
|  |             typeof(voting) != "boolean" || typeof(addsongs) != "boolean" || | ||||||
|  |             typeof(longsongs) != "boolean" || typeof(frontpage) != "boolean" || | ||||||
|  |             typeof(allvideos) != "boolean" || typeof(removeplay) != "boolean" || | ||||||
|  |             typeof(skipping) != "boolean" || typeof(shuffling) != "boolean" || | ||||||
|  |             typeof(params.userpass_changed) != "boolean") { | ||||||
|  |                 socket.emit("toast", "wrongpass"); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |  | ||||||
|         if((!params.userpass_changed && frontpage) || (params.userpass_changed && userpass == "")) { |         if((!params.userpass_changed && frontpage) || (params.userpass_changed && userpass == "")) { | ||||||
|             userpass = ""; |             userpass = ""; | ||||||
|   | |||||||
| @@ -1,5 +1,10 @@ | |||||||
| function thumbnail(msg, coll, guid, offline, socket) { | function thumbnail(msg, coll, guid, offline, socket) { | ||||||
|     if(msg.thumbnail && msg.channel && msg.adminpass && msg.thumbnail.indexOf("i.imgur.com") > -1){ |     if(msg.thumbnail && msg.channel && msg.adminpass && msg.thumbnail.indexOf("i.imgur.com") > -1){ | ||||||
|  |         if(typeof(msg.channel) != "string" || typeof(msg.thumbnail) != "string" || | ||||||
|  |             typeof(msg.adminpass) != "string" || typeof(msg.pass) != "string") { | ||||||
|  |                 socket.emit("toast", "update_required"); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|         msg.thumbnail = msg.thumbnail.replace(/^https?\:\/\//i, ""); |         msg.thumbnail = msg.thumbnail.replace(/^https?\:\/\//i, ""); | ||||||
|         if(msg.thumbnail.substring(0,2) != "//") msg.thumbnail = "//" + msg.thumbnail; |         if(msg.thumbnail.substring(0,2) != "//") msg.thumbnail = "//" + msg.thumbnail; | ||||||
|         var channel = msg.channel.toLowerCase(); |         var channel = msg.channel.toLowerCase(); | ||||||
| @@ -23,6 +28,11 @@ function thumbnail(msg, coll, guid, offline, socket) { | |||||||
|  |  | ||||||
| function description(msg, coll, guid, offline, socket) { | function description(msg, coll, guid, offline, socket) { | ||||||
|     if(msg.description && msg.channel && msg.adminpass && msg.description.length < 100){ |     if(msg.description && msg.channel && msg.adminpass && msg.description.length < 100){ | ||||||
|  |         if(typeof(msg.channel) != "string" || typeof(msg.description) != "string" || | ||||||
|  |             typeof(msg.adminpass) != "string" || typeof(msg.pass) != "string") { | ||||||
|  |                 socket.emit("toast", "update_required"); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|         var channel = msg.channel.toLowerCase(); |         var channel = msg.channel.toLowerCase(); | ||||||
|         var hash = Functions.hash_pass(Functions.decrypt_string(socket.zoff_id, msg.adminpass)); |         var hash = Functions.hash_pass(Functions.decrypt_string(socket.zoff_id, msg.adminpass)); | ||||||
|         db.collection(channel + "_settings").update({views: {$exists: true}}, function(err, docs){ |         db.collection(channel + "_settings").update({views: {$exists: true}}, function(err, docs){ | ||||||
|   | |||||||
| @@ -19,6 +19,332 @@ router.route('/api/generate_name').get(function(req, res) { | |||||||
|     Functions.generate_channel_name(res); |     Functions.generate_channel_name(res); | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | router.route('/api/list/:channel_name/:video_id').delete(function(req, res) { | ||||||
|  |     res.header("Access-Control-Allow-Origin", "*"); | ||||||
|  |     res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); | ||||||
|  |     if(!req.body.hasOwnProperty('adminpass') || !req.body.hasOwnProperty('userpass') || | ||||||
|  |         !req.params.hasOwnProperty('channel_name') || !req.params.hasOwnProperty('video_id')) { | ||||||
|  |         res.sendStatus(400); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |     try { | ||||||
|  |         var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress; | ||||||
|  |         var guid = Functions.hash_pass(req.get('User-Agent') + ip + req.headers["accept-language"]); | ||||||
|  |         var adminpass = req.body.adminpass == "" ? "" : Functions.hash_pass(crypto.createHash('sha256').update(req.body.adminpass, 'utf8').digest("hex")); | ||||||
|  |         req.body.userpass = crypto.createHash('sha256').update(req.body.userpass, 'utf8').digest("hex"); | ||||||
|  |         var userpass = req.body.userpass; | ||||||
|  |         var channel_name = cleanChannelName(req.params.channel_name); | ||||||
|  |         var video_id = req.params.video_id; | ||||||
|  |         if(typeof(userpass) != "string" || typeof(adminpass) != "string") { | ||||||
|  |                 throw "Wrong format"; | ||||||
|  |             } | ||||||
|  |     } catch(e) { | ||||||
|  |         res.sendStatus(400); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     validateLogin(adminpass, userpass, channel_name, "delete", res, function(exists) { | ||||||
|  |         if(!exists) { | ||||||
|  |             res.sendStatus(404); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         db.collection(channel_name).find({id:video_id, now_playing: false}, function(err, docs){ | ||||||
|  |             if(docs.length == 0) { | ||||||
|  |                 res.sendStatus(404); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |             dont_increment = true; | ||||||
|  |             if(docs[0]){ | ||||||
|  |                 if(docs[0].type == "suggested"){ | ||||||
|  |                     dont_increment = false; | ||||||
|  |                 } | ||||||
|  |                 db.collection(channel_name).remove({id:video_id}, function(err, docs){ | ||||||
|  |                     io.to(channel_name).emit("channel", {type:"deleted", value: video_id}); | ||||||
|  |                     if(dont_increment) { | ||||||
|  |                         db.collection("frontpage_lists").update({_id: channel_name, count: {$gt: 0}}, {$inc: {count: -1}, $set:{accessed: Functions.get_time()}}, {upsert: true}, function(err, docs){ | ||||||
|  |                             res.sendStatus(200); | ||||||
|  |                             return; | ||||||
|  |                         }); | ||||||
|  |                     } else { | ||||||
|  |                         res.sendStatus(200); | ||||||
|  |                         return; | ||||||
|  |                     } | ||||||
|  |                 }); | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |     }); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | function cleanChannelName(channel_name) { | ||||||
|  |     var coll = emojiStrip(channel_name).toLowerCase(); | ||||||
|  |     coll = coll.replace("_", ""); | ||||||
|  |     coll = encodeURIComponent(coll).replace(/\W/g, ''); | ||||||
|  |     coll = filter.clean(coll); | ||||||
|  |     return coll; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function validateLogin(adminpass, userpass, channel_name, type, res, callback) { | ||||||
|  |     db.collection(channel_name + "_settings").find({views: {$exists: true}}, function(err, conf) { | ||||||
|  |         var exists = false; | ||||||
|  |         if(conf.length > 0 && ((conf[0].userpass == undefined || conf[0].userpass == "" || conf[0].userpass == userpass))) { | ||||||
|  |             exists = true; | ||||||
|  |         } else if(conf.length > 0) { | ||||||
|  |             res.sendStatus(403); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         if( | ||||||
|  |             (type == "add" && ((conf[0].addsongs && (conf[0].adminpass == "" || conf[0].adminpass == undefined || conf[0].adminpass == adminpass)) || !conf[0].addsongs)) || | ||||||
|  |             (type == "delete" && (conf[0].adminpass == "" || conf[0].adminpass == undefined || conf[0].adminpass == adminpass)) || | ||||||
|  |             (type == "vote" && ((conf[0].vote && (conf[0].adminpass == "" || conf[0].adminpass == undefined || conf[0].adminpass == adminpass)) || !conf[0].vote)) || | ||||||
|  |             (type == "config" && (conf[0].adminpass == "" || conf[0].adminpass == undefined || conf[0].adminpass == adminpass)) | ||||||
|  |         ) { | ||||||
|  |             callback(exists); | ||||||
|  |         } else { | ||||||
|  |             res.sendStatus(403); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | router.route('/api/conf/:channel_name').put(function(req, res) { | ||||||
|  |     res.header("Access-Control-Allow-Origin", "*"); | ||||||
|  |     res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); | ||||||
|  |     if(!req.body.hasOwnProperty('adminpass') || !req.body.hasOwnProperty('userpass') || | ||||||
|  |         !req.params.hasOwnProperty('channel_name') || !req.body.hasOwnProperty('voting') || | ||||||
|  |         !req.body.hasOwnProperty('addsongs') || !req.body.hasOwnProperty('longsongs') || | ||||||
|  |         !req.body.hasOwnProperty('frontpage') || !req.body.hasOwnProperty('allvideos') || | ||||||
|  |         !req.body.hasOwnProperty('skipping') || !req.body.hasOwnProperty('shuffling') || | ||||||
|  |         !req.body.hasOwnProperty('userpass_changed')) { | ||||||
|  |         res.sendStatus(400); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |     try { | ||||||
|  |         var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress; | ||||||
|  |         var guid = Functions.hash_pass(req.get('User-Agent') + ip + req.headers["accept-language"]); | ||||||
|  |         var adminpass = req.body.adminpass == "" ? "" : Functions.hash_pass(crypto.createHash('sha256').update(req.body.adminpass, 'utf8').digest("hex")); | ||||||
|  |         req.body.userpass = crypto.createHash('sha256').update(req.body.userpass, 'utf8').digest("hex"); | ||||||
|  |         var userpass = req.body.userpass; | ||||||
|  |         var voting = req.body.voting; | ||||||
|  |         var addsongs = req.body.addsongs; | ||||||
|  |         var longsongs = req.body.longsongs; | ||||||
|  |         var frontpage = req.body.frontpage; | ||||||
|  |         var allvideos = req.body.allvideos; | ||||||
|  |         var removeplay = req.body.removeplay; | ||||||
|  |         var skipping = req.body.skipping; | ||||||
|  |         var shuffling = req.body.shuffling; | ||||||
|  |         var userpass_changed = req.body.userpass_changed; | ||||||
|  |         var channel_name = cleanChannelName(req.params.channel_name); | ||||||
|  |         if(typeof(userpass) != "string" || typeof(adminpass) != "string" || | ||||||
|  |             typeof(voting) != "boolean" || typeof(addsongs) != "boolean" || | ||||||
|  |             typeof(longsongs) != "boolean" || typeof(frontpage) != "boolean" || | ||||||
|  |             typeof(allvideos) != "boolean" || typeof(removeplay) != "boolean" || | ||||||
|  |             typeof(skipping) != "boolean" || typeof(shuffling) != "boolean" || | ||||||
|  |             typeof(userpass_changed) != "boolean") { | ||||||
|  |                 throw "Wrong format"; | ||||||
|  |             } | ||||||
|  |     } catch(e) { | ||||||
|  |         res.send(e); | ||||||
|  |         res.sendStatus(400); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     validateLogin(adminpass, userpass, channel_name, "config", res, function(exists) { | ||||||
|  |         if(!exists) { | ||||||
|  |             res.sendStatus(404); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if((!userpass_changed && frontpage) || (userpass_changed && userpass == "")) { | ||||||
|  |             userpass = ""; | ||||||
|  |         } else if(userpass_changed && userpass != "") { | ||||||
|  |             frontpage = false; | ||||||
|  |         } | ||||||
|  |         var description = ""; | ||||||
|  |  | ||||||
|  |         var obj = { | ||||||
|  |             addsongs:addsongs, | ||||||
|  |             allvideos:allvideos, | ||||||
|  |             frontpage:frontpage, | ||||||
|  |             skip:skipping, | ||||||
|  |             vote:voting, | ||||||
|  |             removeplay:removeplay, | ||||||
|  |             shuffle:shuffling, | ||||||
|  |             longsongs:longsongs, | ||||||
|  |             adminpass:adminpass, | ||||||
|  |             desc: description, | ||||||
|  |         }; | ||||||
|  |         if(userpass_changed) { | ||||||
|  |             obj["userpass"] = userpass; | ||||||
|  |         } else if (frontpage) { | ||||||
|  |             obj["userpass"] = ""; | ||||||
|  |         } | ||||||
|  |         db.collection(channel_name + "_settings").update({views:{$exists:true}}, { | ||||||
|  |             $set:obj | ||||||
|  |         }, function(err, docs){ | ||||||
|  |  | ||||||
|  |             if(obj.adminpass !== "") obj.adminpass = true; | ||||||
|  |             if(obj.hasOwnProperty("userpass") && obj.userpass != "") obj.userpass = true; | ||||||
|  |             else obj.userpass = false; | ||||||
|  |             io.to(channel_name).emit("conf", [obj]); | ||||||
|  |  | ||||||
|  |             db.collection("frontpage_lists").update({_id: channel_name}, {$set:{ | ||||||
|  |                 frontpage:frontpage, accessed: Functions.get_time()} | ||||||
|  |             }, | ||||||
|  |             {upsert:true}, function(err, docs){ | ||||||
|  |                 res.header({'Content-Type': 'application/json'}); | ||||||
|  |                 res.status(200).send(JSON.stringify(obj)); | ||||||
|  |             }); | ||||||
|  |         }); | ||||||
|  |     }); | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | router.route('/api/list/:channel_name/:video_id').put(function(req,res) { | ||||||
|  |     res.header("Access-Control-Allow-Origin", "*"); | ||||||
|  |     res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); | ||||||
|  |     if(!req.body.hasOwnProperty('adminpass') || !req.body.hasOwnProperty('userpass') || | ||||||
|  |         !req.params.hasOwnProperty('channel_name') || !req.params.hasOwnProperty('video_id')) { | ||||||
|  |         res.sendStatus(400); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |     try { | ||||||
|  |         var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress; | ||||||
|  |         var guid = Functions.hash_pass(req.get('User-Agent') + ip + req.headers["accept-language"]); | ||||||
|  |         var adminpass = req.body.adminpass == "" ? "" : Functions.hash_pass(crypto.createHash('sha256').update(req.body.adminpass, 'utf8').digest("hex")); | ||||||
|  |         req.body.userpass = crypto.createHash('sha256').update(req.body.userpass, 'utf8').digest("hex"); | ||||||
|  |         var userpass = req.body.userpass; | ||||||
|  |         var channel_name = cleanChannelName(req.params.channel_name); | ||||||
|  |         var video_id = req.params.video_id; | ||||||
|  |         if(typeof(userpass) != "string" || typeof(adminpass) != "string") { | ||||||
|  |                 throw "Wrong format"; | ||||||
|  |             } | ||||||
|  |     } catch(e) { | ||||||
|  |         res.send(e); | ||||||
|  |         res.sendStatus(400); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     validateLogin(adminpass, userpass, channel_name, "vote", res, function(exists) { | ||||||
|  |         if(!exists) { | ||||||
|  |             res.sendStatus(404); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         db.collection(channel_name).find({id: video_id, now_playing: false}, function(err, song) { | ||||||
|  |             if(song.length == 0) { | ||||||
|  |                 res.sendStatus(404); | ||||||
|  |                 return; | ||||||
|  |             } else if(song[0].guids.indexOf(guid) > -1) { | ||||||
|  |                 res.sendStatus(409); | ||||||
|  |                 return; | ||||||
|  |             } else { | ||||||
|  |                 song[0].votes += 1; | ||||||
|  |                 song[0].guids.push(guid); | ||||||
|  |                 db.collection(channel_name).update({id: video_id}, {$inc:{votes:1}, $set:{added:Functions.get_time()}, $push :{guids: guid}}, function(err, success) { | ||||||
|  |                     io.to(channel_name).emit("channel", {type: "vote", value: video_id, time: Functions.get_time()}); | ||||||
|  |                     List.getNextSong(channel_name, function() { | ||||||
|  |                         res.header({'Content-Type': 'application/json'}); | ||||||
|  |                         res.status(200).send(JSON.stringify(song[0])); | ||||||
|  |                         return; | ||||||
|  |                     }); | ||||||
|  |                 }); | ||||||
|  |             } | ||||||
|  |         }) | ||||||
|  |     }); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | router.route('/api/list/:channel_name/:video_id').post(function(req,res) { | ||||||
|  |     res.header("Access-Control-Allow-Origin", "*"); | ||||||
|  |     res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); | ||||||
|  |     if(!req.body.hasOwnProperty('adminpass') || !req.body.hasOwnProperty('userpass') || | ||||||
|  |         !req.params.hasOwnProperty('channel_name') || !req.params.hasOwnProperty('video_id') || | ||||||
|  |         !req.body.hasOwnProperty('duration') || !req.body.hasOwnProperty('start_time') || | ||||||
|  |         !req.body.hasOwnProperty('end_time') || !req.body.hasOwnProperty('title')) { | ||||||
|  |         res.sendStatus(400); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |     try { | ||||||
|  |         var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress; | ||||||
|  |         var guid = Functions.hash_pass(req.get('User-Agent') + ip + req.headers["accept-language"]); | ||||||
|  |         var adminpass = req.body.adminpass == "" ? "" : Functions.hash_pass(crypto.createHash('sha256').update(req.body.adminpass, 'utf8').digest("hex")); | ||||||
|  |         req.body.userpass = crypto.createHash('sha256').update(req.body.userpass, 'utf8').digest("hex"); | ||||||
|  |         var userpass = req.body.userpass; | ||||||
|  |         var channel_name = cleanChannelName(req.params.channel_name); | ||||||
|  |         var video_id = req.params.video_id; | ||||||
|  |         var duration = parseInt(req.body.duration); | ||||||
|  |         var start_time = parseInt(req.body.start_time); | ||||||
|  |         var end_time = parseInt(req.body.end_time); | ||||||
|  |         if(duration != end_time - start_time) duration = end_time - start_time; | ||||||
|  |         var title = req.body.title; | ||||||
|  |         if(typeof(userpass) != "string" || typeof(adminpass) != "string" || | ||||||
|  |             typeof(title) != "string") { | ||||||
|  |                 throw "Wrong format"; | ||||||
|  |             } | ||||||
|  |     } catch(e) { | ||||||
|  |         res.send(e); | ||||||
|  |         res.sendStatus(400); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     validateLogin(adminpass, userpass, channel_name, "add", res, function(exists) { | ||||||
|  |         db.collection(channel_name).find({id: video_id}, function(err, result) { | ||||||
|  |             if(result.length == 0) { | ||||||
|  |                 db.collection(channel_name).find({now_playing: true}, function(err, now_playing) { | ||||||
|  |                     var set_np = false; | ||||||
|  |                     if(now_playing.length == 0) { | ||||||
|  |                         set_np = true; | ||||||
|  |                     } | ||||||
|  |                     var new_song = {"added": Functions.get_time(),"guids":[guid],"id":video_id,"now_playing":set_np,"title":title,"votes":1, "duration":duration, "start": parseInt(start_time), "end": parseInt(end_time)}; | ||||||
|  |                     db.collection("frontpage_lists").find({"_id": channel_name}, function(err, count) { | ||||||
|  |                         var create_frontpage_lists = false; | ||||||
|  |                         if(count.length == 0) { | ||||||
|  |                             create_frontpage_lists = true; | ||||||
|  |                         } | ||||||
|  |                         if(!exists) { | ||||||
|  |                             var configs = {"addsongs":false, "adminpass":"", "allvideos":true, "frontpage":true, "longsongs":false, "removeplay": false, "shuffle": true, "skip": false, "skips": [], "startTime":Functions.get_time(), "views": [], "vote": false, "desc": ""}; | ||||||
|  |                             db.collection(channel_name + "_settings").insert(configs, function(err, docs){ | ||||||
|  |                                 io.to(channel_name).emit("conf", configs); | ||||||
|  |                             }); | ||||||
|  |                         } | ||||||
|  |                         db.collection(channel_name).insert(new_song, function(err, success) { | ||||||
|  |                             if(create_frontpage_lists) { | ||||||
|  |                                 db.collection("frontpage_lists").insert({"_id": channel_name, "count" : 1, "frontpage": true, "accessed": Functions.get_time(), "viewers": 1}, function(err, docs) { | ||||||
|  |                                     io.to(channel_name).emit("conf", configs); | ||||||
|  |                                     io.to(channel_name).emit("channel", {type: "added", value: new_song}); | ||||||
|  |                                     List.getNextSong(channel_name, function() { | ||||||
|  |                                         res.header({'Content-Type': 'application/json'}); | ||||||
|  |                                         res.status(200).send(JSON.stringify(new_song)); | ||||||
|  |                                         return; | ||||||
|  |                                     }); | ||||||
|  |                                 }); | ||||||
|  |                             } else if(set_np) { | ||||||
|  |                                 Frontpage.update_frontpage(channel_name, video_id, title, function() { | ||||||
|  |                                     io.to(channel_name).emit("np", new_song); | ||||||
|  |                                     List.getNextSong(channel_name, function() { | ||||||
|  |                                         res.header({'Content-Type': 'application/json'}); | ||||||
|  |                                         res.status(200).send(JSON.stringify(new_song)); | ||||||
|  |                                         return; | ||||||
|  |                                     }); | ||||||
|  |                                 }); | ||||||
|  |                             } else { | ||||||
|  |                                 db.collection("frontpage_lists").update({"_id": channel_name}, {$inc: {count: 1}}, function(err, docs) { | ||||||
|  |                                     io.to(channel_name).emit("channel", {type: "added", value: new_song}); | ||||||
|  |                                     List.getNextSong(channel_name, function() { | ||||||
|  |                                         res.header({'Content-Type': 'application/json'}); | ||||||
|  |                                         res.status(200).send(JSON.stringify(new_song)); | ||||||
|  |                                         return; | ||||||
|  |                                     }); | ||||||
|  |                                 }); | ||||||
|  |                             } | ||||||
|  |                         }); | ||||||
|  |                     }) | ||||||
|  |                 }) | ||||||
|  |             } else { | ||||||
|  |                 res.sendStatus(409); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |     }); | ||||||
|  | }); | ||||||
|  |  | ||||||
| router.route('/api/list/:channel_name').get(function(req, res) { | router.route('/api/list/:channel_name').get(function(req, res) { | ||||||
|     res.header("Access-Control-Allow-Origin", "*"); |     res.header("Access-Control-Allow-Origin", "*"); | ||||||
|     res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); |     res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user