Merge branch 'testing-version-005' of github.com:lfzawacki/bigbluebutton into testing-version-005

Conflicts:
	labs/meteor-client/app/.meteor/packages
	labs/meteor-client/app/smart.json
	labs/meteor-client/app/smart.lock
This commit is contained in:
Anton Georgiev 2014-11-12 13:14:21 -05:00
commit 2b819c2499
20 changed files with 116 additions and 11893 deletions

View File

@ -16,4 +16,6 @@ nemo64:bootstrap
less
francocatena:status
mrt:external-file-loader@0.1.4
winston
winston-client

View File

@ -64,3 +64,5 @@ underscore@1.0.1
url@1.0.1
webapp-hashing@1.0.1
webapp@1.1.3
winston-client@0.0.0
winston@0.0.0

View File

@ -1,347 +0,0 @@
var presenterUserID = "";
var registerListeners = function() {
console.log("Listening for events.");
BBB.listen("QueryPresentationsReplyEvent", function(bbbEvent) {
console.log("Number of presentations [" + bbbEvent.presentations.length + "]. First presentation [" + bbbEvent.presentations[0] + "].");
});
BBB.listen("OpenExternalFileUploadWindowEvent", function(bbbEvent) {
console.log("Open file upload dialog. Max file size is [" + bbbEvent.maxFileSize + "].");
});
BBB.listen("UserKickedOutEvent", function(bbbEvent) {
console.log("User has been kicked [" + bbbEvent.userID + "].");
});
BBB.listen("SwitchedLayoutEvent", function(bbbEvent) {
console.log("New Layout [" + bbbEvent.layoutID + "].");
});
BBB.listen("NewRoleEvent", function(bbbEvent) {
console.log("New Role Event [amIPresenter=" + bbbEvent.amIPresenter + ",role=" + bbbEvent.role + ",newPresenterUserID=" + bbbEvent.newPresenterUserID + "].");
});
BBB.listen("SwitchedPresenterEvent", function(bbbEvent) {
console.log("Switched Presenter [amIPresenter=" + bbbEvent.amIPresenter + ",role=" + bbbEvent.role + ",newPresenterUserID=" + bbbEvent.newPresenterUserID + "].");
presenterUserID = bbbEvent.newPresenterUserID;
if (bbbEvent.amIPresenter) {
console.log("*** I am presenter. Am I publishing webcam?");
BBB.listen("AmISharingCamQueryResponse", function(bbbEvent2) {
console.log("AmISharingCamQueryResponse [isPublishing=" + bbbEvent2.isPublishing + ",camIndex=" + bbbEvent2.camIndex + "]");
});
BBB.amISharingWebcam();
BBB.amISharingWebcam(function(bbbEvent3) {
console.log("amISharingWebcam [isPublishing=" + bbbEvent3.isPublishing
+ ",camIndex=" + bbbEvent3.camIndex
+ ",camWidth=" + bbbEvent3.camWidth
+ ",camHeight=" + bbbEvent3.camHeight
+ ",camKeyFrameInterval=" + bbbEvent3.camKeyFrameInterval
+ ",camModeFps=" + bbbEvent3.camModeFps
+ ",camQualityBandwidth=" + bbbEvent3.camQualityBandwidth
+ ",camQualityPicture=" + bbbEvent3.camQualityPicture
+ "]");
if (bbbEvent3.isPublishing) {
CAM_PREVIEW.stopPreviewCamera(bbbEvent3.avatarURL);
CAM_PREVIEW.previewCamera(bbbEvent3.camIndex, bbbEvent3.camWidth, bbbEvent3.camHeight, bbbEvent3.camKeyFrameInterval,
bbbEvent3.camModeFps, bbbEvent3.camQualityBandwidth, bbbEvent3.camQualityPicture, bbbEvent3.avatarURL);
}
});
} else {
console.log("*** I am NOT presenter. Is new presenter publishing webcam?");
BBB.listen("IsUserPublishingCamResponse", function(bbbEvent4) {
console.log("IsUserPublishingCamResponse [isUserPublishing=" + bbbEvent4.isUserPublishing
+ ",uri=" + bbbEvent4.uri
+ ",streamName=" + bbbEvent4.streamName + "]");
});
BBB.isUserSharingWebcam(bbbEvent.newPresenterUserID);
BBB.isUserSharingWebcam(bbbEvent.newPresenterUserID, function(bbbEvent5) {
console.log("isUserSharingWebcam [isUserPublishing=" + bbbEvent5.isUserPublishing
+ ",uri=" + bbbEvent5.uri
+ ",streamName=" + bbbEvent5.streamName + "]");
if (presenterUserID == bbbEvent.userID) {
CAM_VIEW.stopViewWebcamStream(bbbEvent.avatarURL);
CAM_VIEW.viewWebcamStream(bbbEvent.uri, bbbEvent.streamName, bbbEvent5.avatarURL);
}
});
CAM_PREVIEW.stopPreviewCamera(bbbEvent.avatarURL);
}
});
BBB.listen("UserLeftEvent", function(bbbEvent) {
console.log("User [" + bbbEvent.userID + "] has left.");
});
BBB.listen("UserJoinedEvent", function(bbbEvent) {
console.log("User [" + bbbEvent.userID + ", [" + bbbEvent.userName + "] has joined.");
});
BBB.listen("NewPublicChatEvent", function(bbbEvent) {
console.log("Received NewPublicChatEvent [" + bbbEvent.message + "]");
});
BBB.listen("NewPrivateChatEvent", function(bbbEvent) {
console.log("Received NewPrivateChatEvent event");
});
BBB.listen("UserJoinedVoiceEvent", function(bbbEvent) {
console.log("User [" + bbbEvent.userID + "] had joined the voice conference.");
});
BBB.listen("UserLeftVoiceEvent", function(bbbEvent) {
console.log("User [" + bbbEvent.userID + "has left the voice conference.");
});
BBB.listen("UserVoiceMutedEvent", function(bbbEvent) {
console.log("User [" + bbbEvent.userID + "] is muted [" + bbbEvent.muted + "]");
});
BBB.listen("UserLockedVoiceEvent", function(bbbEvent) {
console.log("User [" + bbbEvent.userID + "] is locked [" + bbbEvent.locked + "]");
});
BBB.listen("CamStreamSharedEvent", function(bbbEvent) {
console.log("User CamStreamSharedEvent [" + bbbEvent.uri + "," + bbbEvent.streamName + "]");
if (presenterUserID == bbbEvent.userID) {
CAM_VIEW.stopViewWebcamStream(bbbEvent.avatarURL);
CAM_VIEW.viewWebcamStream(bbbEvent.uri, bbbEvent.streamName, bbbEvent.avatarURL);
}
});
BBB.listen("BroadcastingCameraStartedEvent", function(bbbEvent) {
console.log("User BroadcastingCameraStartedEvent [" + bbbEvent.camIndex + "] [" + bbbEvent.camWidth + "]");
if (bbbEvent.isPresenter) {
CAM_PREVIEW.stopPreviewCamera(bbbEvent.avatarURL);
CAM_PREVIEW.previewCamera(bbbEvent.camIndex, bbbEvent.camWidth, bbbEvent.camHeight, bbbEvent.camKeyFrameInterval,
bbbEvent.camModeFps, bbbEvent.camQualityBandwidth, bbbEvent.camQualityPicture, bbbEvent.avatarURL);
}
});
BBB.listen("BroadcastingCameraStoppedEvent", function(bbbEvent) {
console.log("User BroadcastingCameraStoppedEvent ]");
CAM_PREVIEW.stopPreviewCamera(bbbEvent.avatarURL);
});
console.log("Listen Presentation Updates");
BBB.listen("OfficeDocConversionSuccessEvent", function(bbbEvent) {
console.log("Successfully converted Office document. : " + JSON.stringify(bbbEvent));
});
BBB.listen("OfficeDocConversionFailedEvent", function(bbbEvent) {
console.log("Failed to convert Office document. : " + JSON.stringify(bbbEvent));
});
BBB.listen("SupportedDocEvent", function(bbbEvent) {
console.log("Uploaded presentation file type is supported. : " + JSON.stringify(bbbEvent));
});
BBB.listen("UnsupportedDocEvent", function(bbbEvent) {
console.log("Uploaded presentation file type is unsupported. : " + JSON.stringify(bbbEvent));
});
BBB.listen("PageCountFailedEvent", function(bbbEvent) {
console.log("Failed to determine number of pages for the uploaded presentation. : " + JSON.stringify(bbbEvent));
});
BBB.listen("ThumbnailsUpdateEvent", function(bbbEvent) {
console.log("Generating thumbnails for uploaded presentation. : " + JSON.stringify(bbbEvent));
});
BBB.listen("PageCountExceededEvent", function(bbbEvent) {
console.log("Uploaded presentation had exceeded max number of pages. : " + JSON.stringify(bbbEvent));
});
BBB.listen("ConversionSuccessEvent", function(bbbEvent) {
console.log("Successfully converted uploaded presentation. : " + JSON.stringify(bbbEvent));
});
BBB.listen("ConversionProgressEvent", function(bbbEvent) {
console.log("Progress update on conversion process. : " + JSON.stringify(bbbEvent));
});
}
var leaveVoiceConference2 = function () {
BBB.leaveVoiceConference();
}
var joinVoiceConference2 = function () {
BBB.joinVoiceConference();
}
var amIPresenterAsync = function() {
BBB.listen("AmIPresenterQueryResponse", function(bbbEvent) {
console.log("Received AmIPresenterQueryResponse event [" + bbbEvent.amIPresenter + "]");
});
BBB.amIPresenter();
}
var amIPresenterSync = function() {
BBB.amIPresenter(function(amIPresenter) {
console.log("Am I Presenter = " + amIPresenter);
});
}
var getMyUserInfoAsynch = function() {
BBB.listen("GetMyUserInfoResponse", function(bbbEvent) {
console.log("User info response [myUserID=" + bbbEvent.myUserID
+ ",myUsername=" + bbbEvent.myUsername + ",myAvatarURL=" + bbbEvent.myAvatarURL
+ ",myRole=" + bbbEvent.myRole + ",amIPresenter=" + bbbEvent.amIPresenter
+ ",dialNumber=" + bbbEvent.dialNumber + ",voiceBridge=" + bbbEvent.voiceBridge + "].");
for(var key in bbbEvent.customdata){
console.log(key + " " + bbbEvent.customdata[key]);
}
});
BBB.getMyUserInfo();
}
var getMyUserInfoSynch = function() {
BBB.getMyUserInfo(function(userInfo) {
console.log("User info callback [myUserID=" + userInfo.myUserID
+ ",myUsername=" + userInfo.myUsername + ",myAvatarURL=" + userInfo.myAvatarURL
+ ",myRole=" + userInfo.myRole + ",amIPresenter=" + userInfo.amIPresenter
+ ",dialNumber=" + userInfo.dialNumber + ",voiceBridge=" + userInfo.voiceBridge + "].");
for(var key in userInfo.customdata){
console.log(key + " " + userInfo.customdata[key]);
}
});
}
var getMyRoleAsynch = function() {
BBB.listen("GetMyRoleResponse", function(bbbEvent) {
console.log("Received GetMyRoleResponse event [" + bbbEvent.myRole + "]");
});
BBB.getMyRole();
}
var getMyRoleSynch = function() {
BBB.getMyRole(function(myRole) {
console.log("My role = " + myRole);
});
}
var getMyUserID = function() {
BBB.getMyUserID(function(userID) {
console.log("My user ID = [" + userID + "]");
});
}
var getMeetingID = function() {
BBB.getMeetingID(function(meetingID) {
console.log("Meeting ID = [" + meetingID + "]");
});
}
var raiseHand = function(raiseHand) {
BBB.raiseHand(raiseHand);
}
var muteMe = function() {
BBB.muteMe();
}
var unmuteMe = function() {
BBB.unmuteMe();
}
var muteAll = function() {
BBB.muteAll();
}
var unmuteAll = function() {
BBB.unmuteAll();
}
var switchLayout = function(newLayout) {
BBB.switchLayout(newLayout);
}
var lockLayout = function(lock) {
BBB.lockLayout(lock);
}
var queryListOfPresentations = function() {
BBB.queryListOfPresentations();
}
var displayPresentation = function(presentationID) {
BBB.displayPresentation(presentationID);
}
var deletePresentation = function(presentationID) {
BBB.deletePresentation(presentationID);
}
var sendPublicChat = function () {
var message = "Hello from the Javascript API";
BBB.sendPublicChatMessage('0x7A7A7A', "en", message);
}
var sendPrivateChat = function () {
var message = "ECHO: " + bbbEvent.message;
BBB.sendPrivateChatMessage(bbbEvent.fromColor, bbbEvent.fromLang, message, bbbEvent.fromUserID);
}
var webcamViewStandaloneAppReady = function() {
console.log("WebcamViewStandalone App is ready.");
BBB.getPresenterUserID(function(puid) {
if (puid == "") {
console.log("There is no presenter in the meeting");
} else {
console.log("The presenter user id is [" + puid + "]");
// Is presenter sharing webcam? If so, get the webcam stream and display.
}
});
}
var webcamPreviewStandaloneAppReady = function() {
console.log("WebcamPreviewStandalone App is ready.");
BBB.getPresenterUserID(function(puid) {
if (puid == "") {
console.log("There is no presenter in the meeting");
} else {
console.log("The presenter user id is [" + puid + "]");
}
});
// Am I presenter? If so, am I publishing my camera? If so, display my camera.
}
var uploadPresentation = function() {
console.log("uploadPresentation");
BBB.getInternalMeetingID(function(meetingID) {
var formData = new FormData($('form')[0]);
formData.append("presentation_name", document.getElementById('fileUpload').value.split(/(\\|\/)/g).pop());
formData.append("conference", meetingID);
formData.append("room", meetingID);
$.ajax({
url: '/bigbluebutton/presentation/upload', //server script to process data
type: 'POST',
xhr: function() { // custom xhr
myXhr = $.ajaxSettings.xhr();
if(myXhr.upload){ // check if upload property exists
myXhr.upload.addEventListener('progress',progressHandlingFunction, false); // for handling the progress of the upload
}
return myXhr;
},
//Ajax events
success: completeHandler,
error: errorHandler,
// Form data
data: formData,
//Options to tell JQuery not to process data or worry about content-type
cache: false,
contentType: false,
processData: false
});
});
}
function progressHandlingFunction(e){
if(e.lengthComputable){
console.log("progress: loaded " + e.loaded + " total:" + e.total);
}
}
function completeHandler(e){
$('form')[0].reset();
console.log("you file has been uploaded!");
}
function errorHandler(e){
console.log("There was an error uploading your file.");
}

View File

@ -1,406 +0,0 @@
var callerIdName, conferenceVoiceBridge, userAgent, userMicMedia, userWebcamMedia, currentSession, callTimeout, callActive, callICEConnected, callFailCounter, callPurposefullyEnded, uaConnected;
function callIntoConference(voiceBridge, callback) {
if (!callerIdName) {
BBB.getMyUserInfo(function(userInfo) {
console.log("User info callback [myUserID=" + userInfo.myUserID
+ ",myUsername=" + userInfo.myUsername + ",myAvatarURL=" + userInfo.myAvatarURL
+ ",myRole=" + userInfo.myRole + ",amIPresenter=" + userInfo.amIPresenter
+ ",dialNumber=" + userInfo.dialNumber + ",voiceBridge=" + userInfo.voiceBridge + "].");
callerIdName = userInfo.myUserID + "-bbbID-" + userInfo.myUsername;
conferenceVoiceBridge = userInfo.voiceBridge
voiceBridge = voiceBridge || conferenceVoiceBridge;
console.log(callerIdName);
webrtc_call(callerIdName, voiceBridge, callback);
});
} else {
voiceBridge = voiceBridge || conferenceVoiceBridge;
webrtc_call(callerIdName, voiceBridge, callback);
}
}
function joinWebRTCVoiceConference() {
console.log("Joining to the voice conference");
var callback = function(message) {
switch (message.status) {
case 'failed':
BBB.webRTCConferenceCallFailed(message.errorcode);
break;
case 'ended':
BBB.webRTCConferenceCallEnded();
break;
case 'started':
BBB.webRTCConferenceCallStarted();
break;
case 'connecting':
BBB.webRTCConferenceCallConnecting();
break;
case 'waitingforice':
BBB.webRTCConferenceCallWaitingForICE();
break;
case 'mediarequest':
BBB.webRTCMediaRequest();
break;
case 'mediasuccess':
BBB.webRTCMediaSuccess();
break;
case 'mediafail':
BBB.webRTCMediaFail();
break;
}
}
callIntoConference(conferenceVoiceBridge, callback);
}
function leaveWebRTCVoiceConference() {
console.log("Leaving the voice conference");
webrtc_hangup();
}
function startWebRTCAudioTest(){
console.log("Testing webrtc audio");
var callback = function(message) {
switch(message.status) {
case 'failed':
BBB.webRTCEchoTestFailed(message.errorcode);
break;
case 'ended':
BBB.webRTCEchoTestEnded();
break;
case 'started':
BBB.webRTCEchoTestStarted();
break;
case 'connecting':
BBB.webRTCEchoTestConnecting();
break;
case 'waitingforice':
BBB.webRTCEchoTestWaitingForICE();
break;
case 'mediarequest':
BBB.webRTCMediaRequest();
break;
case 'mediasuccess':
BBB.webRTCMediaSuccess();
break;
case 'mediafail':
BBB.webRTCMediaFail();
break;
}
}
callIntoConference("9196", callback);
}
function stopWebRTCAudioTest(){
console.log("Stopping webrtc audio test");
webrtc_hangup();
}
function stopWebRTCAudioTestJoinConference(){
console.log("Stopping webrtc audio test and joining conference afterwards");
var callback = function(request) {
joinWebRTCVoiceConference();
}
webrtc_hangup(callback);
}
function requestWebRTCWebcam(){
var callback = function(message) {
switch(message.status) {
case 'mediarequest':
BBB.webRTCWebcamRequest();
break;
case 'mediasuccess':
BBB.webRTCWebcamRequestSuccess();
break;
case 'mediafail':
BBB.webRTCWebcamRequestFail(message.cause);
break;
}
}
makeWebRTCWebcamRequest(callback);
}
function makeWebRTCWebcamRequest(callback)
{
console.log("Requesting webcam permissions on Chrome ");
callback({'status':'mediarequest'});
getUserWebcamMedia(function(stream) {
console.log("getUserWebcamMedia: success");
userWebcamMedia = stream;
callback({'status':'mediasuccess'});
}, function(error) {
console.error("getUserWebcamMedia: failure - " + error.name);
callback({'status':'mediafail', 'cause': error.name});
}
);
}
function createUA(username, server, callback) {
if (userAgent) {
console.log("User agent already created");
return;
}
console.log("Creating new user agent");
/* VERY IMPORTANT
* - You must escape the username because spaces will cause the connection to fail
* - We are connecting to the websocket through an nginx redirect instead of directly to 5066
*/
var configuration = {
uri: 'sip:' + encodeURIComponent(username) + '@' + server,
wsServers: 'ws://' + server + '/ws',
displayName: username,
register: false,
traceSip: true,
autostart: false,
userAgentString: "BigBlueButton",
stunServers: "stun:stun.freeswitch.org"
};
uaConnected = false;
console.log ("*****config =" + JSON.stringify( configuration));
userAgent = new SIP.UA(configuration);
userAgent.on('connected', function() {
uaConnected = true;
});
userAgent.on('disconnected', function() {
if (userAgent) {
userAgent.stop();
userAgent = null;
if (uaConnected) {
callback({'status':'failed', 'errorcode': 1001}); // WebSocket disconnected
} else {
callback({'status':'failed', 'errorcode': 1002}); // Could not make a WebSocket connection
}
}
});
userAgent.start();
};
function getUserWebcamMedia(getUserWebcamMediaSuccess, getUserWebcamMediaFailure) {
if (userWebcamMedia == undefined) {
if (SIP.WebRTC.isSupported()) {
SIP.WebRTC.getUserMedia({audio:false, video:true}, getUserWebcamMediaSuccess, getUserWebcamMediaFailure);
} else {
console.log("getUserWebcamMedia: webrtc not supported");
getUserWebcamMediaFailure("WebRTC is not supported");
}
} else {
console.log("getUserWebcamMedia: webcam already set");
getUserWebcamMediaSuccess(userWebcamMedia);
}
};
function getUserMicMedia(getUserMicMediaSuccess, getUserMicMediaFailure) {
if (userMicMedia == undefined) {
if (SIP.WebRTC.isSupported()) {
SIP.WebRTC.getUserMedia({audio:true, video:false}, getUserMicMediaSuccess, getUserMicMediaFailure);
} else {
console.log("getUserMicMedia: webrtc not supported");
getUserMicMediaFailure("WebRTC is not supported");
}
} else {
console.log("getUserMicMedia: mic already set");
getUserMicMediaSuccess(userMicMedia);
}
};
function webrtc_call(username, voiceBridge, callback) {
if (!isWebRTCAvailable()) {
callback({'status': 'failed', 'errorcode': 1003}); // Browser version not supported
return;
}
var server = window.document.location.hostname;
console.log("user " + username + " calling to " + voiceBridge);
if (!userAgent) {
createUA(username, server, callback);
}
if (userMicMedia !== undefined) {
make_call(username, voiceBridge, server, callback, false);
} else {
callback({'status':'mediarequest'});
getUserMicMedia(function(stream) {
console.log("getUserMicMedia: success");
userMicMedia = stream;
callback({'status':'mediasuccess'});
make_call(username, voiceBridge, server, callback, false);
}, function(e) {
console.error("getUserMicMedia: failure - " + e);
callback({'status':'mediafail', 'cause': e});
}
);
}
}
function make_call(username, voiceBridge, server, callback, recall) {
if (!userAgent.isConnected()) {
console.log("Trying to make call, but UserAgent hasn't connected yet. Delaying call");
userAgent.once('connected', function() {
console.log("UserAgent has now connected, retrying the call");
make_call(username, voiceBridge, server, callback, recall);
});
return;
}
if (currentSession) {
console.log('Active call detected ignoring second make_call');
return;
}
// Make an audio/video call:
console.log("Setting options.. ");
var options = {
media: {
stream: userMicMedia,
render: {
remote: {
audio: document.getElementById('remote-media')
}
}
}
};
callTimeout = setTimeout(function() {
console.log('Ten seconds without updates sending timeout code');
callback({'status':'failed', 'errorcode': 1006}); // Failure on call
currentSession = null;
var userAgentTemp = userAgent;
userAgent = null;
userAgentTemp.stop();
}, 10000);
callActive = false;
callICEConnected = false;
callPurposefullyEnded = false;
callFailCounter = 0;
console.log("Calling to " + voiceBridge + "....");
currentSession = userAgent.invite('sip:' + voiceBridge + '@' + server, options);
// Only send the callback if it's the first try
if (recall === false) {
console.log('call connecting');
callback({'status':'connecting'});
} else {
console.log('call connecting again');
}
// The connecting event fires before the listener can be added
currentSession.on('connecting', function(){
clearTimeout(callTimeout);
});
currentSession.on('progress', function(response){
console.log('call progress: ' + response);
clearTimeout(callTimeout);
});
currentSession.on('failed', function(response, cause){
console.log('call failed with cause: '+ cause);
if (currentSession) {
if (callActive === false) {
callback({'status':'failed', 'errorcode': 1004}); // Failure on call
currentSession = null;
var userAgentTemp = userAgent;
userAgent = null;
userAgentTemp.stop();
} else {
callActive = false;
//currentSession.bye();
currentSession = null;
userAgent.stop();
}
}
clearTimeout(callTimeout);
});
currentSession.on('bye', function(request){
callActive = false;
if (currentSession) {
console.log('call ended ' + currentSession.endTime);
if (callPurposefullyEnded === true) {
callback({'status':'ended'});
} else {
callback({'status':'failed', 'errorcode': 1005}); // Call ended unexpectedly
}
clearTimeout(callTimeout);
currentSession = null;
} else {
console.log('bye event already received');
}
});
currentSession.on('accepted', function(data){
callActive = true;
console.log('BigBlueButton call accepted');
if (callICEConnected === true) {
callback({'status':'started'});
} else {
callback({'status':'waitingforice'});
}
clearTimeout(callTimeout);
});
currentSession.mediaHandler.on('iceFailed', function() {
console.log('received ice negotiation failed');
callback({'status':'failed', 'errorcode': 1007}); // Failure on call
currentSession = null;
var userAgentTemp = userAgent;
userAgent = null;
userAgentTemp.stop();
clearTimeout(callTimeout);
});
// Some browsers use status of 'connected', others use 'completed', and a couple use both
currentSession.mediaHandler.on('iceConnected', function() {
console.log('Received ICE status changed to connected');
if (callICEConnected === false) {
callICEConnected = true;
if (callActive === true) {
callback({'status':'started'});
}
clearTimeout(callTimeout);
}
});
currentSession.mediaHandler.on('iceCompleted', function() {
console.log('Received ICE status changed to completed');
if (callICEConnected === false) {
callICEConnected = true;
if (callActive === true) {
callback({'status':'started'});
}
clearTimeout(callTimeout);
}
});
}
function webrtc_hangup(callback) {
callPurposefullyEnded = true;
console.log("Hanging up current session");
if (callback) {
currentSession.on('bye', callback);
}
currentSession.bye();
}
function isWebRTCAvailable() {
return SIP.WebRTC.isSupported();
}

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,7 @@ loadLib = (libname) ->
successCallback = ->
retryMessageCallback = (param) ->
console.log "Failed to load #{JSON.stringify(param)}"
Meteor.log.info "Failed to load library", param
Meteor.Loader.loadJs("http://#{window.location.hostname}/client/lib/#{libname}", successCallback, 10000).fail(retryMessageCallback)
@ -42,7 +42,6 @@ Meteor.startup ->
# Meteor.call "getMyInfo", uid, (error, result) -> #TODO should try to get rid of this?
# if error? then console.log "error:" + error
# else
setInSession "display_usersList", true
setInSession "display_navbar", true
@ -87,7 +86,7 @@ Template.header.events
toggleMic @
"click .raiseHand": (event) ->
console.log "navbar raise own hand from client"
Meteor.log.info "navbar raise own hand from client"
$(".tooltip").hide()
Meteor.call('userRaiseHand', getInSession("meetingId"), getInSession("DBID"), getInSession("userId"), getInSession("DBID") )
# "click .settingsIcon": (event) ->

View File

@ -1,3 +1,4 @@
# TODO: should be split on server and client side
# # Global configurations file
config = {}
@ -38,10 +39,22 @@ config.redis.channels.toBBBApps.whiteboard = "bigbluebutton:to-bbb-apps:whiteboa
# Logging
config.log = {}
config.log.path = if process?.env?.NODE_ENV is "production"
"/var/log/bigbluebutton/bbbnode.log"
if Meteor.isServer
config.log.path = if process?.env?.NODE_ENV is "production"
"/var/log/bigbluebutton/bbbnode.log"
else
# logs in the directory immediatly before the meteor app
process.env.PWD + '/../log/development.log'
# Setting up a logger in Meteor.log
winston = Meteor.require 'winston'
file = config.log.path
transports = [ new winston.transports.Console(), new winston.transports.File { filename: file } ]
Meteor.log = new winston.Logger
transports: transports
else
"./log/development.log"
Meteor.log = Winston
# Global instance of Modules, created by `app.coffee`
config.modules = null

View File

@ -8,6 +8,7 @@
path: "/meeting_id=*"
action: () ->
self = @
url = location.href
console.log "\n\nurl=#{url}\n\n"
#extract the meeting_id, user_id, auth_token, etc from the uri
@ -39,8 +40,7 @@
alert "did not find the user in the collection"
else
console.log "unable to extract from the URL some of {meetingId, userId, authToken}"
else
console.log "unable to extract the required information for the meeting from the URL"
@route "main",
path: "/"
onBeforeAction: ->

View File

@ -4,12 +4,12 @@ Meteor.methods
# and they pass their userId to this method as a param
transformedChatObject = chatObject
console.log "requesterUserId: #{requesterUserId} | from_userid: #{transformedChatObject.from_userid}"
Meteor.log.info "requesterUserId: #{requesterUserId} | from_userid: #{transformedChatObject.from_userid}"
requester = Meteor.Users.findOne({_id: transformedChatObject.from_userid, userId: requesterUserId})
forPublic = transformedChatObject.to_userid is 'public_chat_userid'
if requester? # User exists, and is valid
console.log "requester exists"
Meteor.log.info "requester exists"
# check if this is a private or a public chat message
eventName = ->
if transformedChatObject.chat_type is "PRIVATE_CHAT"
@ -32,11 +32,10 @@ Meteor.methods
"meeting_id": meetingId
"requester_id": transformedChatObject.from_userid
#
console.log JSON.stringify transformedChatObject
Meteor.log.info transformedChatObject
publish Meteor.config.redis.channels.toBBBApps.chat, message
#
else
console.log "requester no exists"
else
Meteor.log.info "requester no exists"
deletePrivateChatMessages: (userId, contact_id) ->
# if authorized pass through
@ -77,7 +76,7 @@ Meteor.methods
from_lang: transformedChatObject.from_lang
id = Meteor.Chat.insert(entry)
#console.log "added chat id=[#{id}]:#{transformedChatObject.message}. Chat.size is now #{Meteor.Chat.find({meetingId: meetingId}).count()}"
#Meteor.log.info "added chat id=[#{id}]:#{transformedChatObject.message}. Chat.size is now #{Meteor.Chat.find({meetingId: meetingId}).count()}"
# --------------------------------------------------------------------------------------------
# end Private methods on server
# --------------------------------------------------------------------------------------------

View File

@ -12,16 +12,16 @@
currentlyBeingRecorded: currentlyBeingRecorded,
voiceConf: voiceConf,
duration: duration)
console.log "added meeting _id=[#{id}]:meetingId=[#{meetingId}]:name=[#{name}]:duration=[#{duration}]:voiceConf=[#{voiceConf}].Meetings.size is now #{Meteor.Meetings.find().count()}"
Meteor.log.info "added meeting _id=[#{id}]:meetingId=[#{meetingId}]:name=[#{name}]:duration=[#{duration}]:voiceConf=[#{voiceConf}].Meetings.size is now #{Meteor.Meetings.find().count()}"
@removeMeetingFromCollection = (meetingId) ->
if Meteor.Meetings.findOne({meetingId: meetingId})?
if Meteor.Users.find({meetingId: meetingId}).count() isnt 0
console.log "\n!!!!!removing a meeting which has active users in it!!!!\n"
Meteor.log.info "\n!!!!!removing a meeting which has active users in it!!!!\n"
id = Meteor.Meetings.findOne({meetingId: meetingId})
if id?
Meteor.Meetings.remove(id._id)
console.log "removed from Meetings:#{meetingId} now there are only #{Meteor.Meetings.find().count()} meetings running"
Meteor.log.info "removed from Meetings:#{meetingId} now there are only #{Meteor.Meetings.find().count()} meetings running"
# --------------------------------------------------------------------------------------------
# end Private methods on server
# --------------------------------------------------------------------------------------------

View File

@ -16,14 +16,14 @@
y: 0.0
id = Meteor.Presentations.insert(entry)
#console.log "presentation added id =[#{id}]:#{presentationObject.id} in #{meetingId}. Presentations.size is now #{Meteor.Presentations.find({meetingId: meetingId}).count()}"
#Meteor.log.info "presentation added id =[#{id}]:#{presentationObject.id} in #{meetingId}. Presentations.size is now #{Meteor.Presentations.find({meetingId: meetingId}).count()}"
@removePresentationFromCollection = (meetingId, presentationId) ->
if meetingId? and presentationId? and Meteor.Presentations.findOne({meetingId: meetingId, "presentation.id": presentationId})?
id = Meteor.Presentations.findOne({meetingId: meetingId, "presentation.id": presentationId})
if id?
Meteor.Presentations.remove(id._id)
console.log "----removed presentation[" + presentationId + "] from " + meetingId
Meteor.log.info "----removed presentation[" + presentationId + "] from " + meetingId
# --------------------------------------------------------------------------------------------
# end Private methods on server
# --------------------------------------------------------------------------------------------

View File

@ -2,9 +2,9 @@
# Private methods on server
# --------------------------------------------------------------------------------------------
@addShapeToCollection = (meetingId, whiteboardId, shapeObject) ->
#console.log "shapeObject=" + JSON.stringify shapeObject
#Meteor.log.info "shapeObject=" + JSON.stringify shapeObject
if shapeObject?.shape_type is "text" and shapeObject.status is "textPublished"
console.log "we are dealing with a text shape"
Meteor.log.info "we are dealing with a text shape"
entry =
meetingId: meetingId
@ -28,7 +28,7 @@
id = Meteor.Shapes.insert(entry)
numShapesOnSlide = Meteor.Shapes.find({meetingId: meetingId, whiteboardId: whiteboardId}).count()
#console.log "added textShape id =[#{id}]:#{shapeObject.id} in #{meetingId} || now there are #{numShapesOnSlide} shapes on the slide"
#Meteor.log.info "added textShape id =[#{id}]:#{shapeObject.id} in #{meetingId} || now there are #{numShapesOnSlide} shapes on the slide"
else
# the mouse button was released - the drawing is complete
@ -55,27 +55,27 @@
id = Meteor.Shapes.insert(entry)
numShapesOnSlide = Meteor.Shapes.find({meetingId: meetingId, whiteboardId: whiteboardId}).count()
#console.log "added shape id =[#{id}]:#{shapeObject.id} in #{meetingId} || now there are #{numShapesOnSlide} shapes on the slide"
#Meteor.log.info "added shape id =[#{id}]:#{shapeObject.id} in #{meetingId} || now there are #{numShapesOnSlide} shapes on the slide"
@removeAllShapesFromSlide = (meetingId, whiteboardId) ->
console.log "removeAllShapesFromSlide__" + whiteboardId
Meteor.log.info "removeAllShapesFromSlide__" + whiteboardId
if meetingId? and whiteboardId? and Meteor.Shapes.find({meetingId: meetingId, whiteboardId: whiteboardId})?
shapesOnSlide = Meteor.Shapes.find({meetingId: meetingId, whiteboardId: whiteboardId}).fetch()
console.log "number of shapes:" + shapesOnSlide.length
Meteor.log.info "number of shapes:" + shapesOnSlide.length
for s in shapesOnSlide
console.log "shape=" + s.shape.id
Meteor.log.info "shape=" + s.shape.id
id = Meteor.Shapes.findOne({meetingId: meetingId, whiteboardId: whiteboardId, "shape.id": s.shape.id})
if id?
Meteor.Shapes.remove(id._id)
console.log "----removed shape[" + s.shape.id + "] from " + whiteboardId
console.log "remaining shapes on the slide:" + Meteor.Shapes.find({meetingId: meetingId, whiteboardId: whiteboardId}).fetch().length
Meteor.log.info "----removed shape[" + s.shape.id + "] from " + whiteboardId
Meteor.log.info "remaining shapes on the slide:" + Meteor.Shapes.find({meetingId: meetingId, whiteboardId: whiteboardId}).fetch().length
@removeShapeFromSlide = (meetingId, whiteboardId, shapeId) ->
shapeToRemove = Meteor.Shapes.findOne({meetingId: meetingId, whiteboardId: whiteboardId, "shape.id": shapeId})
if meetingId? and whiteboardId? and shapeId? and shapeToRemove?
Meteor.Shapes.remove(shapeToRemove._id)
console.log "----removed shape[" + shapeId + "] from " + whiteboardId
console.log "remaining shapes on the slide:" + Meteor.Shapes.find({meetingId: meetingId, whiteboardId: whiteboardId}).count()
Meteor.log.info "----removed shape[" + shapeId + "] from " + whiteboardId
Meteor.log.info "remaining shapes on the slide:" + Meteor.Shapes.find({meetingId: meetingId, whiteboardId: whiteboardId}).count()
# --------------------------------------------------------------------------------------------
# end Private methods on server
# --------------------------------------------------------------------------------------------

View File

@ -31,14 +31,14 @@
thumb_uri: slideObject.thumb_uri
id = Meteor.Slides.insert(entry)
#console.log "added slide id =[#{id}]:#{slideObject.id} in #{meetingId}. Now there are #{Meteor.Slides.find({meetingId: meetingId}).count()} slides in the meeting"
#Meteor.log.info "added slide id =[#{id}]:#{slideObject.id} in #{meetingId}. Now there are #{Meteor.Slides.find({meetingId: meetingId}).count()} slides in the meeting"
@removeSlideFromCollection = (meetingId, slideId) ->
if meetingId? and slideId? and Meteor.Slides.findOne({meetingId: meetingId, "slide.id": slideId})?
id = Meteor.Slides.findOne({meetingId: meetingId, "slide.id": slideId})
if id?
Meteor.Slides.remove(id._id)
console.log "----removed slide[" + slideId + "] from " + meetingId
Meteor.log.info "----removed slide[" + slideId + "] from " + meetingId
# --------------------------------------------------------------------------------------------
# end Private methods on server
# --------------------------------------------------------------------------------------------

View File

@ -26,11 +26,11 @@ Meteor.methods
publish Meteor.config.redis.channels.toBBBApps.voice, message
updateVoiceUser meetingId, {'user_id': user_id, talking:false, joined: false, muted:false}
else
console.log "did not have enough information to send a mute_user_request"
Meteor.log.info "did not have enough information to send a mute_user_request"
# Verifies muter exists, provided proper credentials, and has permission to mute the user
publishMuteRequest: (meetingId, mutee_id, requesterUserId, requester_id, mutedBoolean) ->
console.log "publishing a user mute #{mutedBoolean} request for #{mutee_id}"
Meteor.log.info "publishing a user mute #{mutedBoolean} request for #{mutee_id}"
mutee = Meteor.Users.findOne({'meetingId': meetingId, _id: mutee_id})
muter = Meteor.Users.findOne({'meetingId': meetingId, 'userId': requesterUserId, _id: requester_id})
if mutee? and muter?
@ -49,7 +49,7 @@ Meteor.methods
updateVoiceUser meetingId, {'user_id': mutee._id, talking:false, muted:mutedBoolean}
#
else
console.log "did not have enough information to send a mute_user_request"
Meteor.log.info "did not have enough information to send a mute_user_request"
# meetingId: the meetingId which both users are in
# user_id: the _id of the user to have their hand lowered
@ -106,7 +106,7 @@ Meteor.methods
publish Meteor.config.redis.channels.toBBBApps.users, message
userLogout: (meetingId, userId) ->
console.log "a user is logging out from #{meetingId}:" + userId
Meteor.log.info "a user is logging out from #{meetingId}:" + userId
u = Meteor.Users.findOne({meetingId: meetingId, userId: userId})
if u?
#remove from the collection and dispatch a message to redis
@ -124,9 +124,9 @@ Meteor.methods
u = Meteor.Users.findOne({'meetingId': meetingId, 'userId': userId})
if u?
Meteor.Users.remove(u._id)
console.log "----removed user[" + userId + "] from " + meetingId + " dbid:" + u._id
Meteor.log.info "----removed user[" + userId + "] from " + meetingId
else
console.log "did not find a user [userId] to delete in meetingid:#{meetingId}"
Meteor.log.info "did not find a user [userId] to delete in meetingid:#{meetingId}"
# Corresponds to a valid action on the HTML clientside
# After authorization, publish a user_leaving_request in redis
@ -142,12 +142,12 @@ Meteor.methods
"timestamp": new Date().getTime()
"name": "user_leaving_request"
"version": "0.0.1"
console.log "sending a user_leaving_request for #{meetingId}:#{u._id}"
Meteor.log.info "sending a user_leaving_request for #{meetingId}:#{u._id}"
if u.userId? and meetingId?
publish Meteor.config.redis.channels.toBBBApps.users, message
else
console.log "did not have enough information to send a user_leaving_request"
Meteor.log.info "did not have enough information to send a user_leaving_request"
#update a voiceUser - a helper method
@updateVoiceUser = (meetingId, voiceUserObject) ->
@ -164,7 +164,7 @@ Meteor.methods
if voiceUserObject.listenOnly?
Meteor.Users.update({meetingId: meetingId ,userId: voiceUserObject.web_userid}, {$set: {'user.listenOnly':voiceUserObject.listenOnly}}, {multi: false}) # muted
else
console.log "ERROR! did not find such voiceUser!"
Meteor.log.info "ERROR! did not find such voiceUser!"
@addUserToCollection = (meetingId, user) ->
userId = user.userid
@ -199,4 +199,4 @@ Meteor.methods
webcam_stream: user.webcam_stream
id = Meteor.Users.insert(entry)
console.log "added user id=[#{id}]:#{user.name}. Users.size is now #{Meteor.Users.find({meetingId: meetingId}).count()}"
Meteor.log.info "added user id=[#{id}]:#{user.name}. Users.size is now #{Meteor.Users.find({meetingId: meetingId}).count()}"

View File

@ -43,14 +43,14 @@ Meteor.publish 'presentations', (meetingId) ->
# Clear all data in subcriptions
@clearCollections = ->
Meteor.Users.remove({})
console.log "cleared Users Collection!"
Meteor.log.info "cleared Users Collection!"
Meteor.Chat.remove({})
console.log "cleared Chat Collection!"
Meteor.log.info "cleared Chat Collection!"
Meteor.Meetings.remove({})
console.log "cleared Meetings Collection!"
Meteor.log.info "cleared Meetings Collection!"
Meteor.Shapes.remove({})
console.log "cleared Shapes Collection!"
Meteor.log.info "cleared Shapes Collection!"
Meteor.Slides.remove({})
console.log "cleared Slides Collection!"
Meteor.log.info "cleared Slides Collection!"
Meteor.Presentations.remove({})
console.log "cleared Presentations Collection!"
Meteor.log.info "cleared Presentations Collection!"

View File

@ -6,7 +6,10 @@ Meteor.methods
# Construct and send a message to bbb-web to validate the user
validateAuthToken: (meetingId, userId, authToken) ->
console.log "\n\n sending a validate_auth_token with userid=#{userId}, authToken=#{authToken} meetingid=#{meetingId}"
Meteor.log.info "sending a validate_auth_token with",
userid: userId
authToken: authToken
meetingid: meetingId
message =
"payload":
@ -21,18 +24,17 @@ Meteor.methods
if authToken? and userId? and meetingId?
publish Meteor.config.redis.channels.toBBBApps.meeting, message
else
console.log "did not have enough information to send a validate_auth_token message"
Meteor.log.info "did not have enough information to send a validate_auth_token message"
class Meteor.RedisPubSub
constructor: (callback) ->
console.log "constructor RedisPubSub"
Meteor.log.info "constructor RedisPubSub"
@pubClient = redis.createClient()
@subClient = redis.createClient()
console.log("Subscribing message on channel: #{Meteor.config.redis.channels.fromBBBApps}")
Meteor.log.info("Subscribing message on channel: #{Meteor.config.redis.channels.fromBBBApps}")
#log.info
@subClient.on "psubscribe", Meteor.bindEnvironment(@_onSubscribe)
@subClient.on "pmessage", Meteor.bindEnvironment(@_onMessage)
@ -40,7 +42,7 @@ class Meteor.RedisPubSub
callback @
_onSubscribe: (channel, count) =>
console.log "Subscribed to #{channel}"
Meteor.log.info "Subscribed to #{channel}"
#grab data about all active meetings on the server
message =
@ -66,8 +68,8 @@ class Meteor.RedisPubSub
if message?.header? and message?.payload?
unless message.header.name in ignoredEventTypes
console.log "eventType=" + message.header.name #+ "\n"
#console.log jsonMsg
Meteor.log.info "eventType=" + message.header.name,
message: jsonMsg
# handle voice events
if message.header.name in ['user_left_voice_message', 'user_joined_voice_message', 'user_voice_talking_message', 'user_voice_muted_message']
@ -82,7 +84,7 @@ class Meteor.RedisPubSub
return
if message.header.name is "get_all_meetings_reply"
console.log "Let's store some data for the running meetings so that when an HTML5 client joins everything is ready!"
Meteor.log.info "Let's store some data for the running meetings so that when an HTML5 client joins everything is ready!"
listOfMeetings = message.payload.meetings
for meeting in listOfMeetings
# we currently do not have voice_conf or duration in this message.
@ -159,6 +161,7 @@ class Meteor.RedisPubSub
#request for shapes
whiteboardId = "#{presentation.id}/#{page.num}" # d2d9a672040fbde2a47a10bf6c37b6a4b5ae187f-1404411622872/1
Meteor.log.info "the whiteboard_id here is:" + whiteboardId
message =
"payload":
@ -173,7 +176,7 @@ class Meteor.RedisPubSub
if whiteboardId? and meetingId?
publish Meteor.config.redis.channels.toBBBApps.whiteboard, message
else
console.log "did not have enough information to send a user_leaving_request"
Meteor.log.info "did not have enough information to send a user_leaving_request"
return
if message.header.name is "presentation_page_changed_message"
@ -252,7 +255,7 @@ class Meteor.RedisPubSub
if message.header.name in ["meeting_ended_message", "meeting_destroyed_event",
"end_and_kick_all_message", "disconnect_all_users_message"]
if Meteor.Meetings.findOne({meetingId: meetingId})?
console.log "there are #{Meteor.Users.find({meetingId: meetingId}).count()} users in the meeting"
Meteor.log.info "there are #{Meteor.Users.find({meetingId: meetingId}).count()} users in the meeting"
for user in Meteor.Users.find({meetingId: meetingId}).fetch()
removeUserFromMeeting meetingId, user.userId
#TODO should we clear the chat messages for that meeting?!
@ -266,11 +269,15 @@ class Meteor.RedisPubSub
# message should be an object
@publish = (channel, message) ->
#console.log "Publishing channel=#{channel}, message=#{JSON.stringify(message)}"
if Meteor.redisPubSub?
Meteor.redisPubSub.pubClient.publish(channel, JSON.stringify(message), (err, res) ->
if err
console.log "err=" + err
)
else
console.log "\n ERROR!! Meteor.redisPubSub was undefined\n"
Meteor.log.info "Publishing",
channel: channel
message: message
if Meteor.redisPubSub?
Meteor.redisPubSub.pubClient.publish channel, JSON.stringify(message), (err, res) ->
if err
Meteor.log.info "error",
error: err
else
Meteor.log.info "ERROR!! Meteor.redisPubSub was undefined"

View File

@ -26,11 +26,11 @@ Meteor.methods
return {error: "did not find that user"}
Meteor.startup ->
console.log "server start"
Meteor.log.info "server start"
#remove all data
clearCollections()
# create create a PubSub connection, start listening
Meteor.redisPubSub = new Meteor.RedisPubSub(->
console.log "created pubsub")
Meteor.log.info "created pubsub")

View File

@ -2,6 +2,9 @@
"packages": {
"raphaeljs-package": {
"git": "https://github.com/tomconnors/raphaeljs-package.git"
}
},
"external-file-loader": {},
"winston": {},
"winston-client": {}
}
}

View File

@ -5,13 +5,31 @@
"raphaeljs-package": {
"git": "https://github.com/tomconnors/raphaeljs-package.git",
"branch": "master"
}
},
"external-file-loader": {},
"winston": {},
"winston-client": {}
},
"packages": {
"raphaeljs-package": {
"git": "https://github.com/tomconnors/raphaeljs-package.git",
"branch": "master",
"commit": "85eaef3664ec063e4bcb81be1226d126d4d20539"
},
"external-file-loader": {
"git": "https://github.com/davidd8/meteor-external-file-loader.git",
"tag": "v0.1.4",
"commit": "352694a7cf906b8241161c2fd1435161c1d5409f"
},
"winston": {
"git": "https://github.com/tomrogers3/meteor-winston.git",
"tag": "v0.0.3",
"commit": "60dc02303ca003ef05254f94fbb9bfd40915d5d3"
},
"winston-client": {
"git": "https://github.com/farpoint/meteor-winston-client.git",
"tag": "v0.0.4",
"commit": "bc9959bf320e7745052d42e84038b27eec0b1a68"
}
}
}