diff --git a/src/main/java/org/olat/core/gui/components/download/DownloadComponent.java b/src/main/java/org/olat/core/gui/components/download/DownloadComponent.java index 7e7b4c76933148da685768dbaf153aedc539a779..0020bf3d9870ae26946acf5bb6cfcc87a3f202be 100644 --- a/src/main/java/org/olat/core/gui/components/download/DownloadComponent.java +++ b/src/main/java/org/olat/core/gui/components/download/DownloadComponent.java @@ -22,6 +22,7 @@ package org.olat.core.gui.components.download; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.ComponentRenderer; +import org.olat.core.gui.media.MediaResource; import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSMediaResource; @@ -37,7 +38,7 @@ import org.olat.core.util.vfs.VFSMediaResource; */ public class DownloadComponent extends Component { private static final ComponentRenderer RENDERER = new DownloadComponentRenderer(); - private VFSMediaResource mediaResource; + private MediaResource mediaResource; private String linkText; private String linkToolTip; private String linkCssIconClass; @@ -53,6 +54,11 @@ public class DownloadComponent extends Component { this(name, downloadItem, downloadItem.getName(), null, getCssIconClass(downloadItem.getName())); } + + public DownloadComponent(String name, MediaResource downloadItem) { + super(name); + this.mediaResource = downloadItem; + } /** * Detailed constructor @@ -91,14 +97,18 @@ public class DownloadComponent extends Component { } this.setDirty(true); } + + public void setMediaResource(MediaResource mediaResource) { + this.mediaResource = mediaResource; + } /** * Package scope getter method for file download media resource * * @return */ - VFSMediaResource getDownloadMediaResoruce() { - return this.mediaResource; + MediaResource getDownloadMediaResoruce() { + return mediaResource; } /** diff --git a/src/main/java/org/olat/course/nodes/OpenMeetingsCourseNode.java b/src/main/java/org/olat/course/nodes/OpenMeetingsCourseNode.java index 0bde04f236912fccc51464513fe1a4cf5a38a3b9..ea5dd461ed0fae4f8031a38f81a6d5258a7f9354 100644 --- a/src/main/java/org/olat/course/nodes/OpenMeetingsCourseNode.java +++ b/src/main/java/org/olat/course/nodes/OpenMeetingsCourseNode.java @@ -26,9 +26,7 @@ import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.stack.StackedController; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; -import org.olat.core.gui.control.generic.messages.MessageUIFactory; import org.olat.core.gui.control.generic.tabbable.TabbableController; -import org.olat.core.gui.translator.Translator; import org.olat.core.id.OLATResourceable; import org.olat.core.id.Roles; import org.olat.core.util.Util; @@ -40,12 +38,15 @@ import org.olat.course.condition.ConditionEditController; import org.olat.course.editor.CourseEditorEnv; import org.olat.course.editor.NodeEditController; import org.olat.course.editor.StatusDescription; +import org.olat.course.groupsandrights.CourseGroupManager; +import org.olat.course.nodes.cp.CPEditController; import org.olat.course.nodes.openmeetings.OpenMeetingsEditController; import org.olat.course.nodes.openmeetings.OpenMeetingsPeekViewController; import org.olat.course.run.navigation.NodeRunConstructionResult; import org.olat.course.run.userview.NodeEvaluation; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.modules.openmeetings.manager.OpenMeetingsManager; +import org.olat.modules.openmeetings.ui.OpenMeetingsRoomEditController; import org.olat.modules.openmeetings.ui.OpenMeetingsRunController; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryManager; @@ -64,6 +65,8 @@ public class OpenMeetingsCourseNode extends AbstractAccessableCourseNode { // configuration public static final String CONF_VC_CONFIGURATION = "vc_configuration"; + private transient CourseGroupManager groupMgr; + public OpenMeetingsCourseNode() { super(TYPE); } @@ -91,37 +94,30 @@ public class OpenMeetingsCourseNode extends AbstractAccessableCourseNode { public NodeRunConstructionResult createNodeRunConstructionResult(UserRequest ureq, WindowControl wControl, UserCourseEnvironment userCourseEnv, NodeEvaluation ne, String nodecmd) { updateModuleConfigDefaults(false); - Controller runCtr; + Roles roles = ureq.getUserSession().getRoles(); - if (roles.isGuestOnly()) { - Translator trans = Util.createPackageTranslator(OpenMeetingsPeekViewController.class, ureq.getLocale()); - String title = trans.translate("guestnoaccess.title"); - String message = trans.translate("guestnoaccess.message"); - runCtr = MessageUIFactory.createInfoMessage(ureq, wControl, title, message); - } else { - // check if user is moderator of the virtual classroom - boolean moderator = roles.isOLATAdmin(); - Long key = userCourseEnv.getCourseEnvironment().getCourseResourceableId(); - if (!moderator) { - if(roles.isInstitutionalResourceManager() | roles.isAuthor()) { - RepositoryManager rm = RepositoryManager.getInstance(); - ICourse course = CourseFactory.loadCourse(key); - RepositoryEntry re = rm.lookupRepositoryEntry(course, false); - if (re != null) { - moderator = rm.isOwnerOfRepositoryEntry(ureq.getIdentity(), re); - if(!moderator) { - moderator = rm.isInstitutionalRessourceManagerFor(re, ureq.getIdentity()); - } - } + + // check if user is moderator of the virtual classroom + boolean moderator = roles.isOLATAdmin(); + Long key = userCourseEnv.getCourseEnvironment().getCourseResourceableId(); + if (!moderator) { + if(roles.isInstitutionalResourceManager() || roles.isAuthor()) { + RepositoryManager rm = RepositoryManager.getInstance(); + ICourse course = CourseFactory.loadCourse(key); + RepositoryEntry re = rm.lookupRepositoryEntry(course, false); + if (re != null) { + moderator = rm.isOwnerOfRepositoryEntry(ureq.getIdentity(), re) + || rm.isInstitutionalRessourceManagerFor(re, ureq.getIdentity()); } } - // create run controller - Long resourceId = userCourseEnv.getCourseEnvironment().getCourseResourceableId(); - OLATResourceable ores = OresHelper.createOLATResourceableInstance(CourseModule.class, resourceId); - String courseTitle = userCourseEnv.getCourseEnvironment().getCourseTitle(); - runCtr = new OpenMeetingsRunController(ureq, wControl, null, ores, getIdent(), courseTitle, moderator); } - Controller controller = TitledWrapperHelper.getWrapper(ureq, wControl, runCtr, this, "o_vitero_icon"); + + // create run controller + Long resourceId = userCourseEnv.getCourseEnvironment().getCourseResourceableId(); + OLATResourceable ores = OresHelper.createOLATResourceableInstance(CourseModule.class, resourceId); + String courseTitle = userCourseEnv.getCourseEnvironment().getCourseTitle(); + Controller runCtr = new OpenMeetingsRunController(ureq, wControl, null, ores, getIdent(), courseTitle, moderator); + Controller controller = TitledWrapperHelper.getWrapper(ureq, wControl, runCtr, this, "o_openmeetings_icon"); return new NodeRunConstructionResult(controller); } @@ -133,6 +129,9 @@ public class OpenMeetingsCourseNode extends AbstractAccessableCourseNode { @Override public StatusDescription[] isConfigValid(CourseEditorEnv cev) { String translatorStr = Util.getPackageName(ConditionEditController.class); + if (groupMgr == null) { + groupMgr = cev.getCourseGroupManager(); + } List<StatusDescription> statusDescs = isConfigValidWithTranslator(cev, translatorStr, getConditionExpressions()); return StatusDescriptionHelper.sort(statusDescs); } @@ -145,8 +144,21 @@ public class OpenMeetingsCourseNode extends AbstractAccessableCourseNode { @Override public StatusDescription isConfigValid() { if (oneClickStatusCache != null) { return oneClickStatusCache[0]; } - StatusDescription status = StatusDescription.NOERROR; - return status; + + StatusDescription sd = StatusDescription.NOERROR; + OpenMeetingsManager openMeetingsManager = CoreSpringFactory.getImpl(OpenMeetingsManager.class); + Long roomId = openMeetingsManager.getRoomId(null, groupMgr.getCourseResource(), getIdent()); + if(roomId == null) { + String shortKey = "error.noroom.short"; + String longKey = "error.noroom.long"; + String[] params = new String[] { getShortTitle() }; + String translPackage = Util.getPackageName(OpenMeetingsRoomEditController.class); + sd = new StatusDescription(StatusDescription.ERROR, shortKey, longKey, params, translPackage); + sd.setDescriptionForUnit(getIdent()); + // set which pane is affected by error + sd.setActivateableViewIdentifier(CPEditController.PANE_TAB_CPCONFIG); + } + return sd; } @Override diff --git a/src/main/java/org/olat/course/nodes/openmeetings/OpenMeetingsEditFormController.java b/src/main/java/org/olat/course/nodes/openmeetings/OpenMeetingsEditFormController.java index 6e69c18bb3b2c766173b7e3ac7245e890a945d99..9e8303b7cdc36c3dfe35a5d0043b7c3e81a9868d 100644 --- a/src/main/java/org/olat/course/nodes/openmeetings/OpenMeetingsEditFormController.java +++ b/src/main/java/org/olat/course/nodes/openmeetings/OpenMeetingsEditFormController.java @@ -5,17 +5,19 @@ import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; import org.olat.core.gui.components.form.flexible.elements.FormLink; +import org.olat.core.gui.components.form.flexible.elements.StaticTextElement; import org.olat.core.gui.components.form.flexible.impl.FormBasicController; import org.olat.core.gui.components.form.flexible.impl.FormEvent; import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer; import org.olat.core.gui.components.link.Link; import org.olat.core.gui.control.Controller; +import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController; import org.olat.core.id.OLATResourceable; import org.olat.course.nodes.OpenMeetingsCourseNode; -import org.olat.modules.openmeetings.manager.OpenMeetingsManager; import org.olat.modules.openmeetings.manager.OpenMeetingsException; +import org.olat.modules.openmeetings.manager.OpenMeetingsManager; import org.olat.modules.openmeetings.model.OpenMeetingsRoom; import org.olat.modules.openmeetings.ui.OpenMeetingsRoomEditController; @@ -27,6 +29,7 @@ import org.olat.modules.openmeetings.ui.OpenMeetingsRoomEditController; public class OpenMeetingsEditFormController extends FormBasicController { private FormLink editLink; + private StaticTextElement roomNameEl; private CloseableModalController cmc; private OpenMeetingsRoomEditController editController; @@ -53,18 +56,20 @@ public class OpenMeetingsEditFormController extends FormBasicController { @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { - if(room == null) { - FormLayoutContainer buttonContainer = FormLayoutContainer.createButtonLayout("buttons", getTranslator()); - formLayout.add(buttonContainer); - editLink = uifactory.addFormLink("create.room", buttonContainer, Link.BUTTON); - } else { - String name = room.getName(); - uifactory.addStaticTextElement("room.name", "room.name", name, formLayout); + String name = room == null ? "" : room.getName(); + roomNameEl = uifactory.addStaticTextElement("room.name", "room.name", name, formLayout); - FormLayoutContainer buttonContainer = FormLayoutContainer.createButtonLayout("buttons", getTranslator()); - formLayout.add(buttonContainer); - editLink = uifactory.addFormLink("edit.room", buttonContainer, Link.BUTTON); - } + FormLayoutContainer buttonContainer = FormLayoutContainer.createButtonLayout("buttons", getTranslator()); + formLayout.add(buttonContainer); + String key = room == null ? "create.room" : "edit.room"; + editLink = uifactory.addFormLink(key, buttonContainer, Link.BUTTON); + } + + private void updateUI() { + String name = room == null ? "" : room.getName(); + roomNameEl.setValue(name); + String key = room == null ? "create.room" : "edit.room"; + editLink.setI18nKey(key); } @Override @@ -72,6 +77,28 @@ public class OpenMeetingsEditFormController extends FormBasicController { // } + @Override + protected void event(UserRequest ureq, Controller source, Event event) { + if(source == cmc) { + cleanupPopups(); + } else if(source == editController) { + if(event == Event.CHANGED_EVENT) { + room = editController.getRoom(); + updateUI(); + } + cmc.deactivate(); + cleanupPopups(); + } + super.event(ureq, source, event); + } + + private void cleanupPopups() { + this.removeAsListenerAndDispose(cmc); + this.removeAsListenerAndDispose(editController); + cmc = null; + editController = null; + } + @Override protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { if(source == editLink) { @@ -87,10 +114,8 @@ public class OpenMeetingsEditFormController extends FormBasicController { } protected void doEditRoom(UserRequest ureq) { - removeAsListenerAndDispose(editController); - removeAsListenerAndDispose(cmc); - try { + cleanupPopups(); editController = new OpenMeetingsRoomEditController(ureq, getWindowControl(), null, course, courseNode.getIdent(), courseTitle, true); listenTo(editController); @@ -101,7 +126,4 @@ public class OpenMeetingsEditFormController extends FormBasicController { showError(OpenMeetingsException.SERVER_NOT_I18N_KEY); } } - - - -} +} \ No newline at end of file diff --git a/src/main/java/org/olat/course/nodes/openmeetings/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/nodes/openmeetings/_i18n/LocalStrings_de.properties index 319f3264823f3c040a01e83eb6b16a6a0d1df52c..57be8087e7bb8c9e280f16e9bdc88fbfce54e1a2 100644 --- a/src/main/java/org/olat/course/nodes/openmeetings/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/course/nodes/openmeetings/_i18n/LocalStrings_de.properties @@ -9,5 +9,6 @@ guestnoaccess.message=$org.olat.course.nodes\:guestnoaccess.message create.room=Raum erstellen edit.room=Raum editieren +room.name=$org.olat.modules.openmeetings.ui\:room.name error.notAvailable=$org.olat.modules.openmeetings.ui\:error.notAvailable error.unkown=$org.olat.modules.openmeetings.ui\:error.unkown \ No newline at end of file diff --git a/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsManager.java b/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsManager.java index 8d1d80c343bf90dca9b9edb66517badd08b03941..42f426dfe8aaa35ab4f1b4ef6b5265e7211fcb1e 100644 --- a/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsManager.java +++ b/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsManager.java @@ -25,6 +25,7 @@ import java.util.Locale; import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; import org.olat.group.BusinessGroup; +import org.olat.modules.openmeetings.model.OpenMeetingsRecording; import org.olat.modules.openmeetings.model.OpenMeetingsRoom; import org.olat.modules.openmeetings.model.OpenMeetingsUser; @@ -44,6 +45,9 @@ public interface OpenMeetingsManager { public String setUserToRoom(Identity identity, long roomId, boolean moderator) throws OpenMeetingsException; + public String setGuestUserToRoom(String firstName, String lastName, long roomId, boolean moderator) + throws OpenMeetingsException; + public Long getRoomId(BusinessGroup group, OLATResourceable ores, String subIdentifier); public List<OpenMeetingsRoom> getOpenOLATRooms(); @@ -55,8 +59,34 @@ public interface OpenMeetingsManager { public OpenMeetingsRoom updateRoom(BusinessGroup group, OLATResourceable ores, String subIdentifier, OpenMeetingsRoom room); + /** + * Open the room + * @param roomId + * @throws OpenMeetingsException + */ + public void openRoom(long roomId) throws OpenMeetingsException; + + /** + * Close the room + * @param roomId + * @throws OpenMeetingsException + */ + public void closeRoom(long roomId) throws OpenMeetingsException; + public boolean deleteRoom(OpenMeetingsRoom room); + public List<OpenMeetingsRecording> getRecordings(long roomId) + throws OpenMeetingsException; + + /** + * Forge the recording URL + * @param filename + * @param roomId + * @param sid + * @return + */ + public String getRecordingURL(OpenMeetingsRecording recording, String sid); + public List<OpenMeetingsUser> getUsersOf(OpenMeetingsRoom room); diff --git a/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsManagerImpl.java b/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsManagerImpl.java index 4b3ab82abf0d00c563bc5a6ab83935a62bd19f74..48a4b0ca2b70b08c68c49eea656250f8000dcff4 100644 --- a/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsManagerImpl.java +++ b/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsManagerImpl.java @@ -27,8 +27,10 @@ import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.UUID; import javax.annotation.PostConstruct; +import javax.ws.rs.core.UriBuilder; import org.apache.axis2.AxisFault; import org.olat.admin.user.delete.service.UserDeletionManager; @@ -44,6 +46,7 @@ import org.olat.core.util.resource.OresHelper; import org.olat.core.util.xml.XStreamHelper; import org.olat.group.BusinessGroup; import org.olat.modules.openmeetings.OpenMeetingsModule; +import org.olat.modules.openmeetings.model.OpenMeetingsRecording; import org.olat.modules.openmeetings.model.OpenMeetingsRoom; import org.olat.modules.openmeetings.model.OpenMeetingsUser; import org.olat.modules.openmeetings.model.RoomReturnInfo; @@ -51,11 +54,16 @@ import org.olat.properties.Property; import org.olat.properties.PropertyManager; import org.olat.user.UserDataDeletable; import org.openmeetings.app.conference.session.xsd.RoomClient; +import org.openmeetings.app.persistence.beans.flvrecord.xsd.FlvRecording; import org.openmeetings.app.persistence.beans.rooms.xsd.Rooms; import org.openmeetings.axis.services.AddRoomWithModerationAndExternalType; import org.openmeetings.axis.services.AddRoomWithModerationAndExternalTypeResponse; +import org.openmeetings.axis.services.CloseRoom; +import org.openmeetings.axis.services.CloseRoomResponse; import org.openmeetings.axis.services.DeleteRoom; import org.openmeetings.axis.services.DeleteRoomResponse; +import org.openmeetings.axis.services.GetFlvRecordingByRoomId; +import org.openmeetings.axis.services.GetFlvRecordingByRoomIdResponse; import org.openmeetings.axis.services.GetRoomById; import org.openmeetings.axis.services.GetRoomByIdResponse; import org.openmeetings.axis.services.GetRoomWithClientObjectsById; @@ -73,6 +81,8 @@ import org.openmeetings.axis.services.KickUserResponse; import org.openmeetings.axis.services.LoginUser; import org.openmeetings.axis.services.LoginUserResponse; import org.openmeetings.axis.services.SetUserObjectAndGenerateRoomHashByURL; +import org.openmeetings.axis.services.SetUserObjectAndGenerateRoomHashByURLAndRecFlag; +import org.openmeetings.axis.services.SetUserObjectAndGenerateRoomHashByURLAndRecFlagResponse; import org.openmeetings.axis.services.SetUserObjectAndGenerateRoomHashByURLResponse; import org.openmeetings.axis.services.UpdateRoomWithModeration; import org.openmeetings.axis.services.UpdateRoomWithModerationResponse; @@ -237,7 +247,7 @@ public class OpenMeetingsManagerImpl implements OpenMeetingsManager, UserDataDel try { UserServiceStub userWs = getUserWebService(); String adminSessionId = adminLogin(); - +/* SetUserObjectAndGenerateRoomHashByURL userObj = new SetUserObjectAndGenerateRoomHashByURL(); userObj.setBecomeModeratorAsInt(moderator ? 1 : 0); userObj.setEmail(identity.getUser().getProperty(UserConstants.EMAIL, null)); @@ -251,6 +261,63 @@ public class OpenMeetingsManagerImpl implements OpenMeetingsManager, UserDataDel userObj.setSID(adminSessionId); userObj.setUsername(identity.getName()); + SetUserObjectAndGenerateRoomHashByURLResponse response = userWs.setUserObjectAndGenerateRoomHashByURL(userObj); + String hashedUrl = response.get_return(); + */ + + + SetUserObjectAndGenerateRoomHashByURLAndRecFlag userObj = new SetUserObjectAndGenerateRoomHashByURLAndRecFlag(); + userObj.setBecomeModeratorAsInt(moderator ? 1 : 0); + userObj.setEmail(identity.getUser().getProperty(UserConstants.EMAIL, null)); + userObj.setExternalUserId(getOpenOLATUserExternalId(identity)); + userObj.setExternalUserType(getOpenOLATExternalType()); + userObj.setFirstname(identity.getUser().getProperty(UserConstants.FIRSTNAME, null)); + userObj.setLastname(identity.getUser().getProperty(UserConstants.LASTNAME, null)); + userObj.setProfilePictureUrl(""); + userObj.setRoom_id(roomId); + userObj.setShowAudioVideoTestAsInt(0); + userObj.setSID(adminSessionId); + userObj.setUsername(identity.getName()); + userObj.setAllowRecording(1); + + SetUserObjectAndGenerateRoomHashByURLAndRecFlagResponse response = userWs.setUserObjectAndGenerateRoomHashByURLAndRecFlag(userObj); + String hashedUrl = response.get_return(); + + + + + + + + + return hashedUrl; + } catch (Exception e) { + log.error("", e); + throw translateException(e, 0); + } + } + + @Override + public String setGuestUserToRoom(String firstName, String lastName, long roomId, boolean moderator) + throws OpenMeetingsException { + try { + UserServiceStub userWs = getUserWebService(); + String adminSessionId = adminLogin(); + + String username = UUID.randomUUID().toString().replace("-", ""); + SetUserObjectAndGenerateRoomHashByURL userObj = new SetUserObjectAndGenerateRoomHashByURL(); + userObj.setBecomeModeratorAsInt(moderator ? 1 : 0); + userObj.setEmail(""); + userObj.setExternalUserId(getOpenOLATUserExternalId(username)); + userObj.setExternalUserType(getOpenOLATExternalType()); + userObj.setFirstname(firstName); + userObj.setLastname(lastName); + userObj.setProfilePictureUrl(""); + userObj.setRoom_id(roomId); + userObj.setShowAudioVideoTestAsInt(0); + userObj.setSID(adminSessionId); + userObj.setUsername(username); + SetUserObjectAndGenerateRoomHashByURLResponse response = userWs.setUserObjectAndGenerateRoomHashByURL(userObj); String hashedUrl = response.get_return(); return hashedUrl; @@ -320,6 +387,89 @@ public class OpenMeetingsManagerImpl implements OpenMeetingsManager, UserDataDel return new OpenMeetingsException(e, type); } + public void openRoom(long roomId) throws OpenMeetingsException { + closeOpenMeetingsRoom(roomId, true); + } + + public void closeRoom(long roomId) throws OpenMeetingsException { + closeOpenMeetingsRoom(roomId, false); + } + + /** + * In OpenMeetings, close can mean open :-) + * @param roomId The room id + * @param status false = close, true = open + * @throws OpenMeetingsException + */ + private void closeOpenMeetingsRoom(long roomId, boolean status) throws OpenMeetingsException { + int responseCode = 0; + try { + String adminSID = adminLogin(); + + RoomServiceStub roomWs = getRoomWebService(); + CloseRoom closeRoom = new CloseRoom(); + closeRoom.setRoom_id(roomId); + closeRoom.setSID(adminSID); + closeRoom.setStatus(status); //false = close, true = open + + CloseRoomResponse closeResponse = roomWs.closeRoom(closeRoom); + responseCode = closeResponse.get_return(); + } catch (Exception e) { + log.error("", e); + throw translateException(e, responseCode); + } + } + + @Override + public List<OpenMeetingsRecording> getRecordings(long roomId) + throws OpenMeetingsException { + + try { + String adminSID = adminLogin(); + + RoomServiceStub roomWs = getRoomWebService(); + GetFlvRecordingByRoomId recordingByRoom = new GetFlvRecordingByRoomId(); + recordingByRoom.setRoomId(roomId); + recordingByRoom.setSID(adminSID); + GetFlvRecordingByRoomIdResponse recordingResponse = roomWs.getFlvRecordingByRoomId(recordingByRoom); + FlvRecording[] recordings = recordingResponse.get_return(); + + List<OpenMeetingsRecording> recList = new ArrayList<OpenMeetingsRecording>(); + if(recordings != null) { + for(FlvRecording recording:recordings) { + if(recording != null) { + OpenMeetingsRecording rec = new OpenMeetingsRecording(); + rec.setRoomId(recording.getRoom_id()); + rec.setRecordingId(recording.getFlvRecordingId()); + rec.setFilename(recording.getFileName()); + rec.setDownloadName(recording.getFileHash()); + rec.setDownloadNameAlt(recording.getAlternateDownload()); + rec.setPreviewImage(recording.getPreviewImage()); + recList.add(rec); + } + } + } + + return recList; + } catch (Exception e) { + throw translateException(e, 0); + } + } + + @Override + public String getRecordingURL(OpenMeetingsRecording recording, String sid) { + if(sid == null) { + sid = adminLogin(); + } + + String url = UriBuilder.fromUri(openMeetingsModule.getOpenMeetingsURI()).path("DownloadHandler") + .queryParam("fileName", recording.getDownloadName()) + .queryParam("moduleName", "lzRecorderApp") + .queryParam("parentPath", "") + .queryParam("room_id", Long.toString(recording.getRoomId())) + .queryParam("sid", sid).build().toString(); + return url; + } @Override public OpenMeetingsRoom addRoom(BusinessGroup group, OLATResourceable ores, String subIdentifier, OpenMeetingsRoom room) { @@ -361,7 +511,11 @@ public class OpenMeetingsManagerImpl implements OpenMeetingsManager, UserDataDel } private String getOpenOLATUserExternalId(Identity identity) { - return identity.getName() + "@" + WebappHelper.getInstanceId(); + return getOpenOLATUserExternalId(identity.getName()); + } + + private String getOpenOLATUserExternalId(String username) { + return username + "@" + WebappHelper.getInstanceId(); } @Override @@ -384,6 +538,7 @@ public class OpenMeetingsManagerImpl implements OpenMeetingsManager, UserDataDel omRoom.setIspublic(false); omRoom.setName(room.getName()); omRoom.setNumberOfPartizipants(room.getSize()); + omRoom.setRoom_id(room.getRoomId()); omRoom.setRoomtypes_id(room.getType()); omRoom.setSID(sessionId); diff --git a/src/main/java/org/olat/modules/openmeetings/model/OpenMeetingsRecording.java b/src/main/java/org/olat/modules/openmeetings/model/OpenMeetingsRecording.java new file mode 100644 index 0000000000000000000000000000000000000000..7f7f8e0b82ee050a151283652ac358c0e8097087 --- /dev/null +++ b/src/main/java/org/olat/modules/openmeetings/model/OpenMeetingsRecording.java @@ -0,0 +1,89 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * 12.10.2011 by frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.modules.openmeetings.model; + + + +/** + * + * Initial date: 07.11.2012<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + */ +public class OpenMeetingsRecording { + + private long roomId; + private long recordingId; + private String filename; + private String downloadName; + private String downloadNameAlt; + private String previewImage; + + + public long getRoomId() { + return roomId; + } + + public void setRoomId(long roomId) { + this.roomId = roomId; + } + + public long getRecordingId() { + return recordingId; + } + + public void setRecordingId(long recordingId) { + this.recordingId = recordingId; + } + + public String getFilename() { + return filename; + } + + public void setFilename(String filename) { + this.filename = filename; + } + + public String getDownloadName() { + return downloadName; + } + + public void setDownloadName(String downloadName) { + this.downloadName = downloadName; + } + + public String getDownloadNameAlt() { + return downloadNameAlt; + } + + public void setDownloadNameAlt(String downloadNameAlt) { + this.downloadNameAlt = downloadNameAlt; + } + + public String getPreviewImage() { + return previewImage; + } + + public void setPreviewImage(String previewImage) { + this.previewImage = previewImage; + } + + + +} diff --git a/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsGuestController.java b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsGuestController.java new file mode 100644 index 0000000000000000000000000000000000000000..3f391f812372f8a1e8b67285ec16f4dbec62da58 --- /dev/null +++ b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsGuestController.java @@ -0,0 +1,99 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * 12.10.2011 by frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.modules.openmeetings.ui; + +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.form.flexible.FormItemContainer; +import org.olat.core.gui.components.form.flexible.elements.TextElement; +import org.olat.core.gui.components.form.flexible.impl.FormBasicController; +import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer; +import org.olat.core.gui.control.Controller; +import org.olat.core.gui.control.Event; +import org.olat.core.gui.control.WindowControl; +import org.olat.core.util.StringHelper; + +/** + * + * Initial date: 06.11.2012<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class OpenMeetingsGuestController extends FormBasicController { + + private TextElement firstNameEl; + private TextElement lastNameEl; + + + public OpenMeetingsGuestController(UserRequest ureq, WindowControl wControl) { + super(ureq, wControl); + + initForm(ureq); + } + + @Override + protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { + firstNameEl = uifactory.addTextElement("first.name", "first.name", 128, "", formLayout); + lastNameEl = uifactory.addTextElement("last.name", "last.name", 128, "", formLayout); + + FormLayoutContainer buttonsCont = FormLayoutContainer.createButtonLayout("buttons", getTranslator()); + formLayout.add(buttonsCont); + uifactory.addFormSubmitButton("open.room", "open.room", buttonsCont); + uifactory.addFormCancelButton("cancel", buttonsCont, ureq, getWindowControl()); + } + + @Override + protected void doDispose() { + // + } + + public String getFirstName() { + return firstNameEl.getValue(); + } + + public String getLastName() { + return lastNameEl.getValue(); + } + + @Override + protected boolean validateFormLogic(UserRequest ureq) { + String firstName = firstNameEl.getValue(); + firstNameEl.clearError(); + if(!StringHelper.containsNonWhitespace(firstName)) { + firstNameEl.setErrorKey("form.legende.mandatory", null); + } + + String lastName = lastNameEl.getValue(); + lastNameEl.clearError(); + if(!StringHelper.containsNonWhitespace(lastName)) { + lastNameEl.setErrorKey("form.legende.mandatory", null); + } + return super.validateFormLogic(ureq); + } + + @Override + protected void formOK(UserRequest ureq) { + fireEvent(ureq, Event.DONE_EVENT); + } + + @Override + protected void formCancelled(UserRequest ureq) { + fireEvent(ureq, Event.CANCELLED_EVENT); + } +} \ No newline at end of file diff --git a/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRoomEditController.java b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRoomEditController.java index db1342df0862c48c9ce3cb6fae8be0fe510be0f8..74d923494dc7f3abe69f054f38455033b8405aac 100644 --- a/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRoomEditController.java +++ b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRoomEditController.java @@ -27,6 +27,7 @@ import org.olat.core.gui.components.form.flexible.elements.TextElement; import org.olat.core.gui.components.form.flexible.impl.FormBasicController; import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer; import org.olat.core.gui.control.Controller; +import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.id.OLATResourceable; import org.olat.core.util.StringHelper; @@ -65,7 +66,6 @@ public class OpenMeetingsRoomEditController extends FormBasicController { private OpenMeetingsRoom room; private final OpenMeetingsManager openMeetingsManager; - public OpenMeetingsRoomEditController(UserRequest ureq, WindowControl wControl, BusinessGroup group, OLATResourceable ores, String subIdentifier, String resourceName, boolean admin) { @@ -95,6 +95,10 @@ public class OpenMeetingsRoomEditController extends FormBasicController { } initForm(ureq); } + + public OpenMeetingsRoom getRoom() { + return room; + } @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { @@ -133,6 +137,7 @@ public class OpenMeetingsRoomEditController extends FormBasicController { FormLayoutContainer buttonContainer = FormLayoutContainer.createButtonLayout("buttons", getTranslator()); formLayout.add(buttonContainer); uifactory.addFormSubmitButton("save", "save", buttonContainer); + uifactory.addFormCancelButton("cancel", buttonContainer, ureq, getWindowControl()); } @Override @@ -164,9 +169,15 @@ public class OpenMeetingsRoomEditController extends FormBasicController { } if(room.getRoomId() > 0) { - openMeetingsManager.updateRoom(group, ores, subIdentifier, room); + room = openMeetingsManager.updateRoom(group, ores, subIdentifier, room); } else { - openMeetingsManager.addRoom(group, ores, subIdentifier, room); + room = openMeetingsManager.addRoom(group, ores, subIdentifier, room); } + fireEvent(ureq, Event.CHANGED_EVENT); + } + + @Override + protected void formCancelled(UserRequest ureq) { + fireEvent(ureq, Event.CANCELLED_EVENT); } -} +} \ No newline at end of file diff --git a/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRunController.java b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRunController.java index 239b3860880552bb6a6f758b54b7cf864aade451..64e3b4df418b4d65d6198bde44b4895c4840e39f 100644 --- a/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRunController.java +++ b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRunController.java @@ -19,23 +19,27 @@ */ package org.olat.modules.openmeetings.ui; +import java.util.List; + import org.olat.core.CoreSpringFactory; import org.olat.core.gui.UserRequest; -import org.olat.core.gui.components.form.flexible.FormItem; -import org.olat.core.gui.components.form.flexible.FormItemContainer; -import org.olat.core.gui.components.form.flexible.elements.FormLink; -import org.olat.core.gui.components.form.flexible.impl.FormBasicController; -import org.olat.core.gui.components.form.flexible.impl.FormEvent; -import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer; +import org.olat.core.gui.components.Component; +import org.olat.core.gui.components.download.DisplayOrDownloadComponent; import org.olat.core.gui.components.link.Link; +import org.olat.core.gui.components.link.LinkFactory; +import org.olat.core.gui.components.velocity.VelocityContainer; import org.olat.core.gui.control.Controller; +import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; +import org.olat.core.gui.control.controller.BasicController; +import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController; import org.olat.core.gui.media.RedirectMediaResource; import org.olat.core.id.OLATResourceable; import org.olat.group.BusinessGroup; import org.olat.modules.openmeetings.OpenMeetingsModule; -import org.olat.modules.openmeetings.manager.OpenMeetingsManager; import org.olat.modules.openmeetings.manager.OpenMeetingsException; +import org.olat.modules.openmeetings.manager.OpenMeetingsManager; +import org.olat.modules.openmeetings.model.OpenMeetingsRecording; /** * @@ -43,43 +47,63 @@ import org.olat.modules.openmeetings.manager.OpenMeetingsException; * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ -public class OpenMeetingsRunController extends FormBasicController { +public class OpenMeetingsRunController extends BasicController { - private FormLink openLink; + private Link openLink, closeLink, startLink, startGuestLink; + private VelocityContainer mainVC; + private CloseableModalController cmc; + private OpenMeetingsGuestController guestController; + + private final boolean admin; private final Long roomId; private final OpenMeetingsModule openMeetingsModule; private final OpenMeetingsManager openMeetingsManager; public OpenMeetingsRunController(UserRequest ureq, WindowControl wControl, BusinessGroup group, OLATResourceable ores, String subIdentifier, String resourceName, boolean admin) { - super(ureq, wControl, "room"); - + super(ureq, wControl); + + this.admin = admin; openMeetingsModule = CoreSpringFactory.getImpl(OpenMeetingsModule.class); openMeetingsManager = CoreSpringFactory.getImpl(OpenMeetingsManager.class); roomId = openMeetingsManager.getRoomId(group, ores, subIdentifier); - initForm(ureq); + try { + List<OpenMeetingsRecording> recList = openMeetingsManager.getRecordings(roomId); + for(OpenMeetingsRecording rec:recList) { + System.out.println(openMeetingsManager.getRecordingURL(rec, null)); + } + System.out.println(recList); + } catch (OpenMeetingsException e) { + e.printStackTrace(); + } + + mainVC = createVelocityContainer("room"); + init(ureq); + + putInitialPanel(mainVC); } - @Override - protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { - if(formLayout instanceof FormLayoutContainer) { - FormLayoutContainer layoutCont = (FormLayoutContainer)formLayout; - if(!openMeetingsModule.isEnabled()) { - layoutCont.contextPut("disabled", Boolean.TRUE); - } else if(roomId == null) { - layoutCont.contextPut("norroom", Boolean.TRUE); - } else { - - FormLayoutContainer roomCont = FormLayoutContainer.createDefaultFormLayout("openroom", getTranslator()); - layoutCont.add(roomCont); + protected void init(UserRequest ureq) { + if(!openMeetingsModule.isEnabled()) { + mainVC.contextPut("disabled", Boolean.TRUE); + } else if(roomId == null) { + mainVC.contextPut("norroom", Boolean.TRUE); + } else if (ureq.getUserSession().getRoles().isGuestOnly() || ureq.getUserSession().getRoles().isInvitee()){ + startGuestLink = LinkFactory.createButton("start.room.guest", mainVC, this); + mainVC.put("start.room.guest", startGuestLink); + } else { + if (admin) { + openLink = LinkFactory.createButton("open.room", mainVC, this); + mainVC.put("open.room", openLink); - String name = "Hello"; - uifactory.addStaticTextElement("room.name", "room.name", name, roomCont); - openLink = uifactory.addFormLink("open", "open.room", null, roomCont, Link.BUTTON); - ((Link)openLink.getComponent()).setTarget("openmeetings"); + closeLink = LinkFactory.createButton("close.room", mainVC, this); + mainVC.put("close.room", closeLink); } + startLink = LinkFactory.createButton("start.room", mainVC, this); + startLink.setTarget("openmeetings"); + mainVC.put("start.room", startLink); } } @@ -88,33 +112,96 @@ public class OpenMeetingsRunController extends FormBasicController { // } + @Override - protected void formOK(UserRequest ureq) { - if(roomId != null && roomId.longValue() > 0) { - doOpenRoom(ureq); + protected void event(UserRequest ureq, Component source, Event event) { + if(source == startLink) { + doStart(ureq); + } else if (source == startGuestLink) { + doStartAsGuest(ureq); + } else if(source == openLink) { + doOpen(ureq); + } else if(source == closeLink) { + doClose(ureq); } } @Override - protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { - if(source == openLink) { - doOpenRoom(ureq); - } else { - super.formInnerEvent(ureq, source, event); + protected void event(UserRequest ureq, Controller source, Event event) { + if(source == guestController) { + if(event == Event.DONE_EVENT) { + String firstName = guestController.getFirstName(); + String lastName = guestController.getLastName(); + redirectToGuestRoom(ureq, firstName, lastName); + } + cmc.deactivate(); + cleanupPopups(); + } else if(source == cmc) { + cleanupPopups(); } + super.event(ureq, source, event); } - private void doOpenRoom(UserRequest ureq) { - if(roomId == null && roomId.longValue() <= 0) { - + private void cleanupPopups() { + removeAsListenerAndDispose(guestController); + removeAsListenerAndDispose(cmc); + guestController = null; + cmc = null; + } + + private void doOpen(UserRequest ureq) { + try { + openMeetingsManager.openRoom(roomId); + } catch (OpenMeetingsException e) { + showError(e.getType().i18nKey()); } + } + + private void doClose(UserRequest ureq) { try { - String securedHash = openMeetingsManager.setUserToRoom(getIdentity(), roomId, true); - String url = openMeetingsManager.getURL(getIdentity(), roomId.longValue(), securedHash, getLocale()); - RedirectMediaResource redirect = new RedirectMediaResource(url); - ureq.getDispatchResult().setResultingMediaResource(redirect); + openMeetingsManager.closeRoom(roomId); } catch (OpenMeetingsException e) { showError(e.getType().i18nKey()); - } + } + } + + private void doStartAsGuest(UserRequest ureq) { + cleanupPopups(); + guestController = new OpenMeetingsGuestController(ureq, getWindowControl()); + listenTo(guestController); + + cmc = new CloseableModalController(getWindowControl(), translate("close"), guestController.getInitialComponent(), true, translate("guest.room")); + listenTo(cmc); + cmc.activate(); + } + + private void redirectToGuestRoom(UserRequest ureq, String firstName, String lastName) { + if(roomId == null && roomId.longValue() <= 0) { + showError("room.notfound.error"); + } else { + try { + String securedHash = openMeetingsManager.setGuestUserToRoom(firstName, lastName, roomId, true); + String url = openMeetingsManager.getURL(getIdentity(), roomId.longValue(), securedHash, getLocale()); + DisplayOrDownloadComponent cmp = new DisplayOrDownloadComponent("openCommand", url); + mainVC.put("openCmd", cmp); + } catch (OpenMeetingsException e) { + showError(e.getType().i18nKey()); + } + } + } + + private void doStart(UserRequest ureq) { + if(roomId == null && roomId.longValue() <= 0) { + showError("room.notfound.error"); + } else { + try { + String securedHash = openMeetingsManager.setUserToRoom(getIdentity(), roomId, true); + String url = openMeetingsManager.getURL(getIdentity(), roomId.longValue(), securedHash, getLocale()); + RedirectMediaResource redirect = new RedirectMediaResource(url); + ureq.getDispatchResult().setResultingMediaResource(redirect); + } catch (OpenMeetingsException e) { + showError(e.getType().i18nKey()); + } + } } } diff --git a/src/main/java/org/olat/modules/openmeetings/ui/_content/room.html b/src/main/java/org/olat/modules/openmeetings/ui/_content/room.html index 95e336c3fdca7c43bd168dcf3904c8141de99167..4a7350da417c29fed92bdf4bb54c3d78a197896a 100644 --- a/src/main/java/org/olat/modules/openmeetings/ui/_content/room.html +++ b/src/main/java/org/olat/modules/openmeetings/ui/_content/room.html @@ -3,5 +3,19 @@ #elseif($noroom) <div class="b_warning">$r.translate("room.notfound.error")</div> #else - $r.render("openroom") + #if($r.available("open.room")) + $r.render("open.room") + $r.render("close.room") + #end + + + #if($r.available("start.room.guest")) + $r.render("start.room.guest") + #else + $r.render("start.room") + #end +#end + +#if($r.available("openCmd")) + $r.render("openCmd") #end \ No newline at end of file diff --git a/src/main/java/org/olat/modules/openmeetings/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/openmeetings/ui/_i18n/LocalStrings_de.properties index 5a4ec02f113ed898cb34d2e673be6230705b41c4..16bdd6e6ddcc359c10dff008d62671b011928bd5 100644 --- a/src/main/java/org/olat/modules/openmeetings/ui/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/modules/openmeetings/ui/_i18n/LocalStrings_de.properties @@ -6,6 +6,8 @@ check.nok=Der Verbindungstest war nicht erfolgreich. Bitte pr\u00FCfen Sie die S enabled=eingeschaltet error.notAvailable=Der Server ist nicht verfügbar, error.unkown=Unerwartet Fehler +error.noroom.short=Der Raum ist noch konfiguiert in "{0}"; +error.noroom.long=Der Raum ist noch konfiguiert in "{0}"; delete=Löschen delete.confirm=Wollen Sie wirklich diesen Raum "{0}" löschen? delete.ok=Der Raum würde erfolgreich gelöscht. @@ -34,8 +36,14 @@ room.recording=Recording room.resource=Ressourcen room.numOfUsers=#Benutzer room.infos=Detailinformationen -open.room=Zum Raum gehen +start.room=Zum Raum gehen +start.room.guest=Zum Raum gehen +open.room=Offnen +close.room=Schliessen room.raw.title=Detailinformationen +guest.room=Benutzer Informationen +first.name=Vorname +last.name=Nachname users=Benutzer users.empty=Der Raum ist noch leer openolat.externaltype=External type