Improvements on bbb-lti (#6277)
* Fix listing multiple playbacks * Fix localization * Consider X-Forwarded-Proto header to determine which endpoint to use * Allow custom context different than /lti * Add pt_BR strings
This commit is contained in:
parent
4fa0b0fa2c
commit
58761e1a74
@ -33,6 +33,7 @@ RUN cd /source \
|
||||
&& sed -i "s|\(<lticp:name>\)[^<]*|\1$vendor_name|g" grails-app/controllers/org/bigbluebutton/ToolController.groovy \
|
||||
&& sed -i "s|\(<lticp:description>\)[^<]*|\1$vendor_description|g" grails-app/controllers/org/bigbluebutton/ToolController.groovy \
|
||||
&& sed -i "s|\(<lticp:url>\)[^<]*|\1$vendor_url|g" grails-app/controllers/org/bigbluebutton/ToolController.groovy \
|
||||
&& sed -i "s|BigBlueButton|$title|g" grails-app/i18n/*.properties \
|
||||
&& grails war
|
||||
|
||||
FROM tomcat:7-jre8
|
||||
@ -44,9 +45,8 @@ RUN rm -r webapps/*
|
||||
|
||||
COPY --from=builder /source/target/lti-*.war webapps/lti.war
|
||||
|
||||
RUN unzip -q webapps/lti.war -d webapps/lti \
|
||||
&& rm webapps/lti.war
|
||||
|
||||
COPY docker-entrypoint.sh /usr/local/bin/
|
||||
|
||||
ENV LTI_CONTEXT_PATH lti
|
||||
|
||||
CMD ["docker-entrypoint.sh"]
|
||||
|
@ -1,7 +1,13 @@
|
||||
#!/bin/bash -xe
|
||||
|
||||
export JAVA_OPTS="$JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -DbigbluebuttonSalt=$BIGBLUEBUTTON_SHARED_SECRET -DbigbluebuttonURL=$BIGBLUEBUTTON_URL -DltiEndPoint=$LTI_ENDPOINT -DltiConsumers=$LTI_CONSUMERS -DltiAllRecordedByDefault=$RECORDED_BY_DEFAULT"
|
||||
export JAVA_OPTS="$JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -DbigbluebuttonSalt=$BIGBLUEBUTTON_SHARED_SECRET -DbigbluebuttonURL=$BIGBLUEBUTTON_URL -DltiEndPoint=$LTI_ENDPOINT -DltiConsumers=$LTI_CONSUMERS -DltiAllRecordedByDefault=$RECORDED_BY_DEFAULT -DltiCanvasPlacements=$LTI_CANVAS_PLACEMENTS -DltiCanvasPlacementName=$LTI_CANVAS_PLACEMENT_NAME"
|
||||
sed -i "s|^securerandom\.source=.*|securerandom.source=file:/dev/./urandom|g" $JAVA_HOME/lib/security/java.security
|
||||
|
||||
if [ -f webapps/lti.war ]; then
|
||||
mkdir -p webapps/$LTI_CONTEXT_PATH
|
||||
unzip -q webapps/lti.war -d webapps/$LTI_CONTEXT_PATH
|
||||
rm webapps/lti.war
|
||||
fi
|
||||
|
||||
catalina.sh run
|
||||
|
||||
|
@ -44,6 +44,10 @@ ltiRestrictedAccess=true
|
||||
# Sets all the meetings to be recorded by default
|
||||
# Format: [<false>|true]
|
||||
ltiAllRecordedByDefault=false
|
||||
# The list of placements enabled on lti service.
|
||||
# Format: assignment_menu,assignment_selection,assignments_menu,collaboration,course_navigation,course_home_sub_navigation,course_settings_sub_navigation
|
||||
ltiCanvasPlacements=
|
||||
ltiCanvasPlacementName=BigBlueButton
|
||||
|
||||
#----------------------------------------------------
|
||||
# Inject configuration values into BigbluebuttonSrvice beans
|
||||
@ -57,3 +61,5 @@ beans.ltiService.consumers=${ltiConsumers}
|
||||
beans.ltiService.mode=${ltiMode}
|
||||
beans.ltiService.restrictedAccess=${ltiRestrictedAccess}
|
||||
beans.ltiService.recordedByDefault=${ltiAllRecordedByDefault}
|
||||
beans.ltiService.canvasPlacements=${ltiCanvasPlacements}
|
||||
beans.ltiService.canvasPlacementName=${ltiCanvasPlacementName}
|
||||
|
@ -60,7 +60,9 @@ class ToolController {
|
||||
return
|
||||
}
|
||||
// On post request proceed with the launch.
|
||||
def endPoint = ltiService.getScheme(request) + "://" + ltiService.endPoint + "/" + grailsApplication.metadata['app.name'] + "/" + params.get("controller") + (params.get("format") != null ? "." + params.get("format") : "")
|
||||
def schemeHeader = request.getHeader("X-Forwarded-Proto")
|
||||
def scheme = schemeHeader == null ? ltiService.getScheme(request) : schemeHeader
|
||||
def endPoint = scheme + "://" + ltiService.endPoint + "/" + grailsApplication.metadata['app.name'] + "/" + params.get("controller") + (params.get("format") != null ? "." + params.get("format") : "")
|
||||
log.info "endPoint: " + endPoint
|
||||
ArrayList<String> missingParams = new ArrayList<String>()
|
||||
|
||||
@ -177,7 +179,7 @@ class ToolController {
|
||||
private void setLocalization(Map<String, String> params){
|
||||
String locale = params.get(Parameter.LAUNCH_LOCALE)
|
||||
locale = (locale == null || locale.equals("")?"en":locale)
|
||||
String[] localeCodes = locale.split("_")
|
||||
String[] localeCodes = locale.split("[_-]")
|
||||
// Localize the default welcome message
|
||||
session['org.springframework.web.servlet.i18n.SessionLocaleResolver.LOCALE'] = new Locale(localeCodes[0])
|
||||
if (localeCodes.length > 1) {
|
||||
@ -326,10 +328,23 @@ class ToolController {
|
||||
recording.put("unixDate", startTime / 1000)
|
||||
// Add sanitized thumbnails
|
||||
recording.put("thumbnails", sanitizeThumbnails(recording.playback.format))
|
||||
recording.put("playbacks", sanitizePlayback(recording.playback.format))
|
||||
}
|
||||
return recordings
|
||||
}
|
||||
|
||||
private List<Object> sanitizePlayback(Object format) {
|
||||
def response = new ArrayList<Object>()
|
||||
if (format instanceof Map<?,?>) {
|
||||
response.add(format)
|
||||
} else if (format instanceof Collection<?>) {
|
||||
response = new ArrayList(format)
|
||||
} else {
|
||||
response = format
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
private List<Object> sanitizeThumbnails(Object format) {
|
||||
if (format.preview == null || format.preview.images == null || format.preview.images.image == null) {
|
||||
return new ArrayList()
|
||||
@ -347,6 +362,26 @@ class ToolController {
|
||||
def icon = 'http://' + lti_endpoint + '/assets/icon.ico'
|
||||
def secure_icon = 'https://' + lti_endpoint + '/assets/icon.ico'
|
||||
def isSSLEnabled = ltiService.isSSLEnabled('https://' + lti_endpoint + '/tool/test')
|
||||
def extension_url = isSSLEnabled ? secure_launch_url : launch_url
|
||||
def extension_icon = isSSLEnabled ? secure_icon : icon
|
||||
def canvasPlacements = ''
|
||||
def canvasPlacementsList = ltiService.canvasPlacements
|
||||
if (canvasPlacementsList.length > 0) {
|
||||
canvasPlacements += '' +
|
||||
' <blti:extensions platform="canvas.instructure.com">'
|
||||
canvasPlacementsList.each { placement ->
|
||||
canvasPlacements += '' +
|
||||
' <lticm:options name="' + placement + '">' +
|
||||
' <lticm:property name="canvas_icon_class">icon-lti</lticm:property>' +
|
||||
' <lticm:property name="icon_url">' + extension_icon + '</lticm:property>' +
|
||||
' <lticm:property name="text">' + ltiService.canvasPlacementName + '</lticm:property>' +
|
||||
' <lticm:property name="url">' + extension_url + '</lticm:property>' +
|
||||
' </lticm:options>'
|
||||
}
|
||||
canvasPlacements += '' +
|
||||
' </blti:extensions>'
|
||||
}
|
||||
|
||||
def cartridge = '' +
|
||||
'<?xml version="1.0" encoding="UTF-8"?>' +
|
||||
'<cartridge_basiclti_link xmlns="http://www.imsglobal.org/xsd/imslticc_v1p0"' +
|
||||
@ -370,6 +405,7 @@ class ToolController {
|
||||
' <lticp:description>Open source web conferencing system for distance learning.</lticp:description>' +
|
||||
' <lticp:url>http://www.bigbluebutton.org/</lticp:url>' +
|
||||
' </blti:vendor>' +
|
||||
canvasPlacements +
|
||||
' <cartridge_bundle identifierref="BLTI001_Bundle"/>' +
|
||||
' <cartridge_icon identifierref="BLTI001_Icon"/>' +
|
||||
'</cartridge_basiclti_link>'
|
||||
|
@ -27,8 +27,9 @@ tool.view.app=BigBlueButton
|
||||
tool.view.title=BigBlueButton LTI Interface
|
||||
tool.view.join=Join Meeting
|
||||
tool.view.recording=Recording
|
||||
tool.view.recording.format.presentation=presentation
|
||||
tool.view.recording.format.video=video
|
||||
tool.view.recording.format.presentation=Watch
|
||||
tool.view.recording.format.video=Video
|
||||
tool.view.recording.format.presentation_video=Download
|
||||
tool.view.recording.delete.confirmation=Are you sure to permanently delete this recording?
|
||||
tool.view.recording.delete.confirmation.warning=Warning
|
||||
tool.view.recording.delete.confirmation.yes=Yes
|
||||
|
48
bbb-lti/grails-app/i18n/messages_pt.properties
Normal file
48
bbb-lti/grails-app/i18n/messages_pt.properties
Normal file
@ -0,0 +1,48 @@
|
||||
#
|
||||
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
#
|
||||
# Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Lesser General Public License as published by the Free Software
|
||||
# Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License along
|
||||
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
# The welcome.header can be static, however if you want the name of the activity (meeting) to be injected use {0} as part of the text
|
||||
# {1} can be used to inject the name of the course
|
||||
bigbluebutton.welcome.header=Bem-vindo à sala <b>{0}</b>!
|
||||
bigbluebutton.welcome.footer=Para saber mais sobre o BigBlueButton, acesse nossos <a href=\"event:http://www.bigbluebutton.org/content/videos\"><u>vídeos tutoriais</u></a>.<br><br>Para habilitar o áudio, clique no ícone do hearset. <b>Utilize um headset para evitar ruídos na sessão.
|
||||
bigbluebutton.welcome.record=Esta sessão está sendo gravada
|
||||
bigbluebutton.welcome.duration=A duração máxima desta sessão é de {0} minutos
|
||||
|
||||
tool.view.app=BigBlueButton
|
||||
tool.view.title=Inteface LTI do BigBlueButton
|
||||
tool.view.join=Entrar na sessão
|
||||
tool.view.recording=Gravação
|
||||
tool.view.recording.format.presentation=Assistir
|
||||
tool.view.recording.format.video=Vídeo
|
||||
tool.view.recording.format.presentation_video=Baixar
|
||||
tool.view.recording.delete.confirmation=Você tem certeza que deseja excluir permanentemente esta gravação?
|
||||
tool.view.recording.delete.confirmation.warning=Aviso
|
||||
tool.view.recording.delete.confirmation.yes=Sim
|
||||
tool.view.recording.delete.confirmation.no=Não
|
||||
tool.view.recording.publish=Publicar
|
||||
tool.view.recording.unpublish=Esconder
|
||||
tool.view.recording.delete=Excluir
|
||||
tool.view.activity=Atividade
|
||||
tool.view.description=Descrição
|
||||
tool.view.preview=Preview
|
||||
tool.view.date=Data
|
||||
tool.view.duration=Duração
|
||||
tool.view.actions=Ações
|
||||
tool.view.dateFormat=E, MM dd, yyyy HH:mm:ss Z
|
||||
|
||||
tool.error.general=Não foi possível estabelecer a coenxão.
|
@ -33,6 +33,8 @@ class LtiService {
|
||||
def mode = "simple"
|
||||
def restrictedAccess = "true"
|
||||
def recordedByDefault = "false"
|
||||
def canvasPlacements = ""
|
||||
def canvasPlacementName = "BigBlueButton"
|
||||
|
||||
Map<String, String> consumerMap
|
||||
|
||||
@ -144,4 +146,9 @@ class LtiService {
|
||||
def String getScheme(request) {
|
||||
return request.isSecure() ? "https" : "http"
|
||||
}
|
||||
|
||||
def String[] getCanvasPlacements() {
|
||||
return this.canvasPlacements
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,8 +41,8 @@
|
||||
<tr class="r0 lastrow">
|
||||
<td class="cell c0" style="text-align:center;">
|
||||
<g:if test="${r.published}">
|
||||
<g:each in="${r.playback}" var="format">
|
||||
<a title="<g:message code="tool.view.recording.format.${format.getValue().type}" />" target="_new" href="${format.getValue().url}"><g:message code="tool.view.recording.format.${format.getValue().type}" /></a> 
|
||||
<g:each in="${r.playbacks}" var="format">
|
||||
<a title="<g:message code="tool.view.recording.format.${format.type}" />" target="_new" href="${format.url}"><g:message code="tool.view.recording.format.${format.type}" /></a><br>
|
||||
</g:each>
|
||||
</g:if>
|
||||
</td>
|
||||
|
Loading…
Reference in New Issue
Block a user