From 1d2ff96f6e7f75071af501621dc112135bf0db80 Mon Sep 17 00:00:00 2001 From: Niels Groot Obbink Date: Tue, 28 Aug 2012 09:43:07 +0200 Subject: [PATCH] for readability and maintainability splitted lsp files --- lsp/functions.js | 372 ++++++++ server.html => lsp/jquery.js | 1667 ---------------------------------- lsp/main.js | 915 +++++++++++++++++++ lsp/md5.js | 2 + lsp/placeholder.js | 8 + lsp/server.html | 49 + lsp/style.css | 375 ++++++++ 7 files changed, 1721 insertions(+), 1667 deletions(-) create mode 100644 lsp/functions.js rename server.html => lsp/jquery.js (63%) create mode 100644 lsp/main.js create mode 100644 lsp/md5.js create mode 100644 lsp/placeholder.js create mode 100644 lsp/server.html create mode 100644 lsp/style.css diff --git a/lsp/functions.js b/lsp/functions.js new file mode 100644 index 00000000..3adf6e31 --- /dev/null +++ b/lsp/functions.js @@ -0,0 +1,372 @@ + + /** + * Show a confirm dialog + * @param question the question displayed + */ + function confirmDelete(question) + { + return confirm(question); + } + + + /** + * Format a date to mm/dd/yyyy hh:mm:ss format + * @param date the date to format (timestamp) + */ + function formatDate(date) + { + var d = new Date(date * 1000); + + return [ + ('00' + d.getMonth()).slice(-2), + ('00' + d.getDate()).slice(-2), + d.getFullYear() + ].join('/') + ' ' + [ + ('00' + d.getHours()).slice(-2), + ('00' + d.getMinutes()).slice(-2), + ('00' + d.getSeconds()).slice(-2) + ].join(':'); + } + + + /** + * Find out what kind of resource an URI is + * @param uri the URI to check. If it start with a protocol (ebut not file://) return 'Live', else 'Recorded' + */ + function TypeofResource(uri) + { + var protocol = /([a-zA-Z]+):\/\//.exec(uri); + + if(protocol === null || (protocol[1] && protocol[1] === 'file')) + { + return 'Recorded'; + }else{ + return 'Live'; + } + } + + + /** + * convert a short limit name to a long one using the table above + * @param name the short name of a limit + */ + function shortToLongLimit(name) + { + var i; + + for(i = 0; i < ltypes.length; i++) + { + if(name == ltypes[i][0]) + { + return ltypes[i][1]; + } + } + + return name; + } + + + /** + * forse the server to save to the config file + * @param callback function to call after the command is send + */ + function forceJSONSave(callback) + { + // build the object to send to the server + var data = + { + 'authorize': + { + 'username': settings.credentials.username, + 'password': (settings.credentials.authstring != "" ? MD5(MD5(settings.credentials.password) + settings.credentials.authstring) : "" ) + }, + 'save': 1 + }; + + // make the XHR call + $.ajax( + { + 'url': settings.server, + 'data': + { + "command": JSON.stringify(data) + }, + 'dataType': 'jsonp', + 'timeout': 10000, + 'error': function(){}, + 'success': function(){} + }); + } + + + /** + * retrieves data from the server ;) + * note: does not authenticate first. Assumes user is logged in. + * @param callback the function to call when the data has been retrieved. This callback has 1 parameter, the data retrieved. + */ + function getData(callback) + { + var data = + { + 'authorize': + { + 'username': settings.credentials.username, + 'password': (settings.credentials.authstring != "" ? MD5(MD5(settings.credentials.password) + settings.credentials.authstring) : "" ) + } + }; + + $.ajax( + { + 'url': settings.server, + 'data': + { + "command": JSON.stringify(data) + }, + 'dataType': 'jsonp', + 'timeout': 10000, + 'error': function(){}, + 'success': function(d) + { + + var ret = $.extend(true, + { + "streams": {}, + "statistics": {} + }, d); + + console.log('[651] RECV', ret); + + if(callback) + { + callback(ret); + } + } + }); + } + + + /** + * retrieved the status and number of viewers from all streams + * @param callback function that is called when the data is collected. Has one parameter, the data retrieved + */ + function getStreamsData(callback) + { + + getData(function(data) + { + var streams = {}; // streamID: [status, numViewers]; + var cnt = 0; + + for(var stream in data.streams) + { + streams[stream] = [data.streams[stream].online, 0]; + cnt++; + } + + if(cnt === 0) + { + return; // if there are no streams, don't collect data and just return + } + + for(stream in data.statistics) + { + if(data.statistics[stream].curr) + { + for(var viewer in data.statistics[stream].curr) + { + streams[stream][1]++; + } + } + } + + callback(streams); + }); + } + + + /** + * parses an url and returns the parts of it. + * @return object containing the parts of the URL: protocol, host and port. + */ + function parseURL(url) + { + var pattern = /(https?)\:\/\/([^:\/]+)\:(\d+)?/; + + var retobj = {protocol: '', host: '', port: ''}; + var results = url.match(pattern); + + if(results != null) + { + retobj.protocol = results[1]; + retobj.host = results[2]; + retobj.port = results[3]; + } + + return retobj; + } + + /** + * go figure. + * @return true if there is a HTTP connector... and false if there isn't. + */ + function isThereAHTTPConnector() + { + var i, + len = (settings.settings.config.protocols ? settings.settings.config.protocols.length : 0); + + for(i = 0; i < len; i++) + { + if(settings.settings.config.protocols[i].connector == 'HTTP') + { + return true; + } + } + + return false; + } + + + /** + * retrieves the stream status (online and total number of streams) and viewer info (total number of viewers). + * @param callback function that is called when data is retrieved. Has one parameter, the retrieved data. + */ + function getStatData(callback) + { + getData(function(data) + { + var svr, viewer, ret, + numstr = 0, + numvwr = 0, + numtotstr = 0; + + for(svr in data.statistics) + { + if(data.statistics[svr].curr) + { + for(viewer in data.statistics[svr].curr) + { + numvwr++; + } + } + } + + for(svr in data.streams) + { + numtotstr++; + + if(data.streams[svr].online && data.streams[svr].online == 1) + { + numstr++; + } + } + + ret = {streams: [numstr, numtotstr], viewers: numvwr}; + callback(ret); + }); + } + + + /** + * Connect to the server and retrieve the data + * @param callback the function to call when connected. Has one parameter, an optional error string. + */ + function loadSettings(callback) + { + // display 'loading, please wait' while retrieving data + $('body').append( $('
').attr('id', 'shield').text('Loading, please wait...') ); + + var errorstr = '', + data = $.extend(settings.settings, + { + 'authorize': + { + 'username': settings.credentials.username, + 'password': (settings.credentials.authstring != "" ? MD5(MD5(settings.credentials.password) + settings.credentials.authstring) : "" ) + } + }); + + delete data.log; // don't send the logs back to the server + delete data.statistics; // same goes for the stats + + console.log('[763] SEND', data); + + $.ajax( + { + 'url': settings.server, + 'data': + { + "command": JSON.stringify(data) + }, + 'dataType': 'jsonp', + + 'timeout': 5000, + + 'error': function() + { + showTab('disconnect'); + $('#shield').remove(); // remove loading display + }, + 'success': function(d) + { + $('#shield').remove(); // remove loading display + + console.log('[785] RECV', d); + + if(d && d['authorize'] && d['authorize']['challenge']) + { + if (settings.credentials.authstring != d['authorize']['challenge']) + { + settings.credentials.authstring = d['authorize']['challenge']; + loadSettings(callback); + return; + }else{ + errorstr = 'wrong credentials'; + } + }else{ + settings.settings = $.extend(true, { + "config": + { + "host": "", + "limits": [], + "name": "", + "protocols": [], + "status": "", + "version": "" + }, + "streams": {}, + "log": {}, + "statistics": {} + }, d); + } + + if(callback) + { + callback(errorstr); + } + } + }); + } + + + /** + * Sets the page's header text (loging in, connected, disconnected), title and pretty colors (!) + * @param state the state of the header. Possible are 'logingin', 'disconnected' or 'connected'. + */ + function setHeaderState(state) + { + var text, cname, title; + + switch(state) + { + case 'logingin': text = 'connecting...'; cname = 'loggingin'; title = 'connecting to ' + settings.server; break; + case 'disconnected': text = 'disconnected'; cname = 'disconnected'; title = 'disconnected'; break; + case 'connected': text = 'connected'; cname = 'connected'; title = 'connected to ' + settings.server; break; + } + + document.title = 'Mistserver Manager - ' + title; + + $('#header-connection').attr('class', cname); + $('#header-connection').text(text); + $('#header-host').text(settings.server.replace('HTTP://', '')); + } + diff --git a/server.html b/lsp/jquery.js similarity index 63% rename from server.html rename to lsp/jquery.js index 6f763d27..674c18e2 100644 --- a/server.html +++ b/lsp/jquery.js @@ -1,1672 +1,5 @@ - - - - - - - - - Mistserver Manager - not connected - - - - - - - - - - - - - - - -
- - - - - - - - diff --git a/lsp/main.js b/lsp/main.js new file mode 100644 index 00000000..7ce9e002 --- /dev/null +++ b/lsp/main.js @@ -0,0 +1,915 @@ + + +/* WERKLOG todolist +// TODO FIXME remove deze comment als het klaar is +settings.settings.statistics[streamID].log (zelfde als curr maar log = gesloten connecties, dus ex-users +TODO als server het stuurt +*/ + + + /** + * Local settings page + * DDVTECH + * for more information, see http://mistserver.org/index.php?title=Stand-alone_Configuration_Page + */ + + + /** + * Store a local copy of the data send by the server. + * server is the URL, credentials hold the username, password and authstring and settings is the local copy. + */ + var settings = + { + server: '', + credentials: + { + username: "", + password: "", + authstring: "" + }, + settings: {} + }; + + + /** + * Table for long/short limit names + */ + var ltypes = + [ + ['kb_total', 'Total bandwidth'], + ['kbps_max', 'Current bandwidth'], + ['users', 'Concurrent users'], + ['streams', 'Cocurrent streams'], + ['geo', 'Geolimited'], + ['host', 'Hostlimited'], + ['time', 'Timelimited'], + ['duration', 'Duration'], + ['str_kbps_min', 'Minimum bitrate'], + ['str_kbps_max', 'Maximum bitrate'] + ]; + + + /** + * When the page loads, fix the menu and show the correct tab + */ + $(document).ready(function() + { + $('#nav').children().each(function() + { + $(this).click(function() + { + // remove currently selected' class + $('#nav').children().each(function() + { + $(this).attr('class', ''); + }); + + // select this one + $(this).attr('class', 'selected'); + + // show correct tab + showTab($(this).text()); + }); + }); + + // show login 'tab' and hide menu + showTab('login'); + $('#nav').css('visibility', 'hidden'); + }); + + + + // used on the overview and streams page. cleared when switching to another 'tab'. + var sinterval = null; + + // what kind of streams should be displayed? Format is [recorded, live]; + var streamsdisplay = [true, true]; + + + + /** + * Display a certain page. It contains a (giant) switch-statement, that builds a page depending on the tab requested + * @param name the name of the tab + * @param streamname only used when editing streams, the name of the edited (or new) stream. Also used with the 'embed' tab + */ + function showTab(name, streamname) + { + // clear page and refresh interval + $('#page').html(''); + clearInterval(sinterval); + + switch(name) + { + case 'login': + + var host = $('').attr('type', 'text').attr('placeholder', 'HTTP://LOCALHOST:4242'); + var user = $('').attr('type', 'text').attr('placeholder', 'USERNAME'); + var pass = $('').attr('type', 'password').attr('placeholder', 'PASSWORD'); + var conn = $('