Skip to content

Commit 8663e2f

Browse files
author
Alexandre Papin
committed
I'm not sure about file organization.
1 parent da0c8dc commit 8663e2f

File tree

10 files changed

+739
-0
lines changed

10 files changed

+739
-0
lines changed

__init__.py

Whitespace-only changes.

admin.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from django.contrib import admin
2+
from django_bigbluebutton.models import Meeting
3+
from django_bigbluebutton.models import RegisteredUser
4+
5+
admin.site.register(Meeting)
6+
admin.site.register(RegisteredUser)

bbb_api.py

Lines changed: 372 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,372 @@
1+
# Copyright 2011 Omar Shammas
2+
#
3+
# This program is free software; you can redistribute it and/or modify
4+
# it under the terms of the GNU General Public License as published by
5+
# the Free Software Foundation; either version 2 of the License, or
6+
# (at your option) any later version.
7+
#
8+
# This program is distributed in the hope that it will be useful,
9+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
# GNU General Public License for more details.
12+
#
13+
# You should have received a copy of the GNU General Public License
14+
# along with this program; if not, write to the Free Software
15+
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16+
17+
#Versions:
18+
# 0.1 -- written by Omar Shammas (email : omar DOT shammas [a t ] g m ail DOT com)
19+
# Initial version works with 0.7 version of the BBB API
20+
# test comment
21+
22+
import urllib.request, urllib.parse, urllib.error, urllib.request, urllib.error, urllib.parse, socket
23+
import hashlib, random
24+
from xml.dom import minidom
25+
from xml.dom.minidom import Node
26+
27+
28+
def bbb_wrap_load_file(url):
29+
timeout = 10
30+
socket.setdefaulttimeout(timeout)
31+
32+
try:
33+
req = urllib.request.urlopen(url)
34+
return minidom.parse(req)
35+
except:
36+
return False
37+
38+
39+
def assign2Dict(xml):
40+
try:
41+
mapping = {}
42+
response = xml.firstChild
43+
for child in response.childNodes:
44+
45+
if( child.hasChildNodes() ):
46+
mapping[child.tagName] = child.firstChild.nodeValue
47+
else:
48+
mapping[child.tagName] = None
49+
50+
return mapping
51+
except:
52+
return False
53+
54+
#------------------------------------------------GET URLs-------------------------------------------------
55+
#
56+
#This method returns the url to join the specified meeting.
57+
#
58+
#@param meetingID -- the unique meeting identifier used to store the meeting in the bigbluebutton server
59+
#@param username -- the display name to be used when the user joins the meeting
60+
#@param PW -- the attendee or moderator password of the meeting
61+
#@param SALT -- the security salt of the bigbluebutton server
62+
#@param URL -- the url of the bigbluebutton server
63+
#
64+
#@return The url to join the meeting
65+
66+
def joinMeetingURL(meetingID, username, PW, URL, SALT):
67+
url_join = URL + "api/join?"
68+
69+
parameters = {'meetingID' : meetingID,
70+
'fullName' : username,
71+
'password' : PW,
72+
}
73+
74+
parameters = urllib.parse.urlencode(parameters)
75+
return url_join + parameters + '&checksum=' + hashlib.sha1(("join" + parameters + SALT).encode('utf-8')).hexdigest()
76+
77+
#
78+
#This method returns the url to join the specified meeting.
79+
#
80+
#@param name -- a name fot the meeting
81+
#@param meetingID -- the unique meeting identifier used to store the meeting in the bigbluebutton server
82+
#@param attendeePW -- the attendee of the meeting
83+
#@param moderatorPW -- the moderator of the meeting
84+
#@param welcome -- the welcome message that gets displayed on the chat window
85+
#@param logoutURL -- the URL that the bbb client will go to after users logouut
86+
#@param SALT -- the security salt of the bigbluebutton server
87+
#@param URL -- the url of the bigbluebutton server
88+
#
89+
#@return The url to join the meeting
90+
91+
def createMeetingURL(name, meetingID, attendeePW, moderatorPW, welcome, logoutURL, URL, SALT):
92+
url_create = URL + "api/create?"
93+
voiceBridge = 70000 + random.randint(0, 9999);
94+
parameters = {'name': name,
95+
'meetingID' : meetingID,
96+
'attendeePW' : attendeePW,
97+
'moderatorPW' : moderatorPW,
98+
'voiceBridge' : voiceBridge,
99+
'logoutURL' : logoutURL,
100+
}
101+
102+
#if (welcome and welcome != ''):
103+
# parameters.update({'welcome': welcome.strip()})
104+
105+
parameters = urllib.parse.urlencode(parameters)
106+
107+
return url_create + parameters + '&checksum=' + hashlib.sha1(("create" + parameters + SALT).encode('utf-8')).hexdigest()
108+
109+
110+
#
111+
#This method returns the url to check if the specified meeting is running.
112+
#
113+
#@param meetingID -- the unique meeting identifier used to store the meeting in the bigbluebutton server
114+
#@param SALT -- the security salt of the bigbluebutton server
115+
#@param URL -- the url of the bigbluebutton server
116+
#
117+
#@return The url to check if the specified meeting is running.
118+
#
119+
def isMeetingRunningURL( meetingID, URL, SALT ):
120+
base_url = URL + "api/isMeetingRunning?"
121+
122+
parameters = {'meetingID' : meetingID,}
123+
parameters = urllib.parse.urlencode(parameters)
124+
125+
return base_url + parameters + '&checksum=' + hashlib.sha1(("isMeetingRunning" + parameters + SALT).encode('utf-8')).hexdigest()
126+
127+
128+
#
129+
#This method returns the url to getMeetingInfo of the specified meeting.
130+
#
131+
#@param meetingID -- the unique meeting identifier used to store the meeting in the bigbluebutton server
132+
#@param modPW -- the moderator password of the meeting
133+
#@param SALT -- the security salt of the bigbluebutton server
134+
#@param URL -- the url of the bigbluebutton server
135+
#
136+
#@return The url to check if the specified meeting is running.
137+
#
138+
def getMeetingInfoURL( meetingID, modPW, URL, SALT ):
139+
base_url = URL + "api/getMeetingInfo?"
140+
141+
parameters = {'meetingID' : meetingID,
142+
'password' : modPW,
143+
}
144+
parameters = urllib.parse.urlencode(parameters)
145+
146+
return base_url + parameters + '&checksum=' + hashlib.sha1(("getMeetingInfo" + parameters + SALT).encode('utf-8')).hexdigest()
147+
148+
149+
#
150+
#This method returns the url for listing all meetings in the bigbluebutton server.
151+
#
152+
#@param SALT -- the security salt of the bigbluebutton server
153+
#@param URL -- the url of the bigbluebutton server
154+
#
155+
#@return The url of getMeetings.
156+
#
157+
def getMeetingsURL(URL, SALT):
158+
base_url = URL + "api/getMeetings?"
159+
160+
parameters = {'random' : (random.random() * 1000 ),}
161+
parameters = urllib.parse.urlencode(parameters)
162+
163+
return base_url + parameters + '&checksum=' + hashlib.sha1(("getMeetings" + parameters + SALT).encode('utf-8')).hexdigest()
164+
165+
166+
#
167+
#This method returns the url to end the specified meeting.
168+
#
169+
#@param meetingID -- the unique meeting identifier used to store the meeting in the bigbluebutton server
170+
#@param modPW -- the moderator password of the meeting
171+
#@param SALT -- the security salt of the bigbluebutton server
172+
#@param URL -- the url of the bigbluebutton server
173+
#
174+
#@return The url to end the specified meeting.
175+
#
176+
def endMeetingURL( meetingID, modPW, URL, SALT ):
177+
base_url = URL + "api/end?"
178+
179+
parameters = {'meetingID' : meetingID,
180+
'password' : modPW,
181+
}
182+
parameters = urllib.parse.urlencode(parameters)
183+
184+
return base_url + parameters + '&checksum=' + hashlib.sha1(("end" + parameters + SALT).encode('utf-8')).hexdigest()
185+
186+
187+
188+
189+
#-----------------------------------------------CREATE----------------------------------------------------
190+
#
191+
#This method creates a meeting and return an array of the xml packet
192+
#
193+
#@param username
194+
#@param meetingID -- the unique meeting identifier used to store the meeting in the bigbluebutton server
195+
#@param welcomeString -- the welcome message to be displayed when a user logs in to the meeting
196+
#@param mPW -- the moderator password of the meeting
197+
#@param aPW -- the attendee password of the meeting
198+
#@param SALT -- the security salt of the bigbluebutton server
199+
#@param URL -- the url of the bigbluebutton server
200+
#@param logoutURL -- the url the user should be redirected to when they logout of bigbluebutton
201+
#
202+
#@return
203+
# - Null if unable to reach the bigbluebutton server
204+
# - False if an error occurs while parsing
205+
# - Dictionary containing the values of the xml packet
206+
#
207+
def createMeeting(name, meeting_id, welcome_message, moderator_pw, attendee_pw, logout_url, url, secret):
208+
209+
create_url = createMeetingURL(name, meeting_id, attendee_pw, moderator_pw, welcome_message, logout_url, url, secret)
210+
xml = bbb_wrap_load_file( create_url )
211+
212+
if(xml):
213+
return assign2Dict(xml)
214+
215+
#if unable to reach the server
216+
return None
217+
218+
219+
#-------------------------------------------getMeetingInfo---------------------------------------------------
220+
#
221+
#This method calls the getMeetingInfo on the bigbluebutton server and returns an array.
222+
#
223+
#@param meetingID -- the unique meeting identifier used to store the meeting in the bigbluebutton server
224+
#@param modPW -- the moderator password of the meeting
225+
#@param SALT -- the security salt of the bigbluebutton server
226+
#@param URL -- the url of the bigbluebutton server
227+
#
228+
#@return
229+
# - None if unable to reach the bigbluebutton server
230+
# - Dictionary containing the values of the xml packet
231+
# - If the returncode == 'FAILED' it returns a dictionary containing a returncode, messagekey, and message.
232+
# - If the returncode == 'SUCCESS' it returns a dictionary containing a meetingID, moderatorPW, attendeePW,
233+
# hasBeenForciblyEnded, running, startTime, endTime, participantCount, moderatorCount, and attendees.
234+
235+
def getMeetingInfo( meetingID, modPW, URL, SALT ):
236+
getMeetingInfo_url = getMeetingInfoURL(meetingID, modPW, URL, SALT )
237+
xml = bbb_wrap_load_file( getMeetingInfo_url )
238+
239+
if(xml):
240+
mapping = {}
241+
response = xml.firstChild
242+
for child in response.childNodes:
243+
244+
if( child.hasChildNodes() ):
245+
#Makes a dictionary for attendees inside mapping
246+
if(child.tagName == "attendees"):
247+
attendees = {}
248+
#Makes a dictionary for attendee inside attendees
249+
for atnds in child.childNodes:
250+
attendee = {}
251+
#Adds the elements to the attendee dictionary
252+
for atnd in atnds.childNodes:
253+
if( atnd.hasChildNodes() ):
254+
attendee[atnd.tagName] = atnd.firstChild.nodeValue
255+
else:
256+
attendee[atnd.tagName] = None
257+
#Updates the attendees dictionary with the attendee we just parsed
258+
attendees[ attendee["userID"] ] = attendee
259+
260+
#Once completed parsing the attendees we add that dictionary to mapping
261+
mapping[child.tagName] = attendees
262+
else:
263+
mapping[child.tagName] = child.firstChild.nodeValue
264+
else:
265+
mapping[child.tagName] = None
266+
return mapping
267+
268+
#if unable to reach the server
269+
return None
270+
271+
272+
#-----------------------------------------------getMeetings------------------------------------------------------
273+
#
274+
#This method calls getMeetings on the bigbluebutton server, then calls getMeetingInfo for each meeting and concatenates the result.
275+
#
276+
#@param URL -- the url of the bigbluebutton server
277+
#@param SALT -- the security salt of the bigbluebutton server
278+
#
279+
#@return
280+
# - None if unable to reach the bigbluebutton server
281+
# - Dictionary containing the values of the xml packet
282+
# - If the returncode == 'FAILED' it returns a dictionary containing a returncode, messagekey, and message.
283+
# - If the returncode == 'SUCCESS' it returns a dictionary containing all the meetings. Each item meetingID, moderatorPW, attendeePW,
284+
# hasBeenForciblyEnded, running, startTime, endTime, participantCount, moderatorCount, and attendees.
285+
286+
# - Null if the server is unreachable
287+
# - If FAILED then returns an array containing a returncode, messageKey, message.
288+
# - If SUCCESS then returns an array of all the meetings. Each element in the array is an array containing a meetingID,
289+
# moderatorPW, attendeePW, hasBeenForciblyEnded, running.
290+
#
291+
def getMeetings( URL, SALT ):
292+
getMeetings_url = getMeetingsURL( URL, SALT )
293+
xml = bbb_wrap_load_file( getMeetings_url )
294+
295+
if(xml):
296+
mapping = {}
297+
response = xml.firstChild
298+
for child in response.childNodes:
299+
300+
if( child.hasChildNodes() ):
301+
302+
#Makes a dictionary for meetings inside mapping
303+
if(child.tagName == "meetings"):
304+
meetings = {}
305+
306+
#Makes a dictionary for meeting inside meetings
307+
for mtgs in child.childNodes:
308+
meeting = {}
309+
310+
#Adds the elements to the meeting dictionary
311+
for mtg in mtgs.childNodes:
312+
if( mtg.hasChildNodes() ):
313+
meeting[mtg.tagName] = mtg.firstChild.nodeValue
314+
else:
315+
meeting[mtg.tagName] = None
316+
#Updates the meetings dictionary with the meeting we just parsed
317+
meetings[ meeting["meetingID"] ] = meeting
318+
#Once completed parsing the meetings we add that dictionary to mapping
319+
mapping[child.tagName] = meetings
320+
321+
else:
322+
mapping[child.tagName] = child.firstChild.nodeValue
323+
else:
324+
mapping[child.tagName] = None
325+
326+
return mapping
327+
328+
#if unable to reach the server
329+
return None
330+
331+
#------------------------------------------------End Meeting------------------------------------
332+
#
333+
#This method calls end meeting on the specified meeting in the bigbluebutton server.
334+
#
335+
#@param meetingID -- the unique meeting identifier used to store the meeting in the bigbluebutton server
336+
#@param modPW -- the moderator password of the meeting
337+
#@param SALT -- the security salt of the bigbluebutton server
338+
#@param URL -- the url of the bigbluebutton server
339+
#
340+
#@return
341+
# - Null if the server is unreachable
342+
# - A dictionary containing a returncode, messageKey, message.
343+
#
344+
def endMeeting( meetingID, modPW, URL, SALT ):
345+
endMeeting_url = endMeetingURL( meetingID, modPW, URL, SALT )
346+
xml = bbb_wrap_load_file( endMeeting_url )
347+
348+
if(xml):
349+
return assign2Dict(xml)
350+
351+
#if unable to reach the server
352+
return None
353+
354+
#------------------------------------------------isMeetingRunning------------------------------------
355+
#
356+
#This method check the BigBlueButton server to see if the meeting is running (i.e. there is someone in the meeting)
357+
#
358+
#@param meetingID -- the unique meeting identifier used to store the meeting in the bigbluebutton server
359+
#@param SALT -- the security salt of the bigbluebutton server
360+
#@param URL -- the url of the bigbluebutton server
361+
#
362+
#@return A boolean of true if the meeting is running and false if it is not running
363+
#
364+
def isMeetingRunning( meetingID, URL, SALT ):
365+
isMeetingRunning_url = isMeetingRunningURL( meetingID, URL, SALT )
366+
xml = bbb_wrap_load_file( isMeetingRunning_url )
367+
368+
if(xml):
369+
return assign2Dict(xml)
370+
371+
#if unable to reach the server
372+
return None

cms_app.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from cms.app_base import CMSApp
2+
from cms.apphook_pool import apphook_pool
3+
from django.utils.translation import ugettext_lazy as _
4+
5+
6+
class BigBlueButtonApp(CMSApp):
7+
name = _("BigBlueButton App")
8+
urls = ["django_bigbluebutton.urls"]
9+
10+
apphook_pool.register(BigBlueButtonApp)

0 commit comments

Comments
 (0)