示例#1
0
        private static void Process(int iLookAheadHours)
        {
            //Get the CMIS timetable for the next ?? hours
            IEnumerable <DataRow> dtTimetable = GetTimetable(iLookAheadHours);

            //Iterate through each event in the timetable
            foreach (DataRow drEvent in dtTimetable)
            {
                //Try/Catch. If this particular event has problems, we probably want the loop to continue
                try
                {
                    //Firstly, check there is a remote recorder in this location
                    RemoteRecorderManagement.RemoteRecorder rRecorder = GetRecorder(drEvent.Field <string>("RoomId"));

                    //If we have a recorder, then we can record this room/event
                    if (rRecorder != null)
                    {
                        //Get/create the folder for this recording
                        SessionManagement.Folder fFolder = GetFolder(drEvent.Field <string>("LecturerIds"));

                        //Ensure that the owner of this recording has access to said folder
                        //The data from CMIS stores multiple lecturers as CSV data inside the LecturerIds field. eg. LECT001, LECT002, LECT003
                        //Ideally, we would split this into an array and ensure that each lecturer had creator access on the folder
                        foreach (string sUser in drEvent.Field <string>("LecturerIds").Split(','))
                        {
                            //Another try/catch block - Panopto will throw an exception if user doesn't exist or already has permission
                            try
                            {
                                //Get/create the user
                                UserManagement.User uUser = GetUser(sUser);

                                //Create AccessManagement Client
                                AccessManagement.AccessManagementClient AMC = new AccessManagement.AccessManagementClient();
                                //Give user permission on our folder
                                AMC.GrantUsersAccessToFolder(AccessAuthentication(), fFolder.Id, new Guid[] { uUser.UserId }, AccessManagement.AccessRole.Creator);
                            } catch (Exception ex)
                            {
                                //Do nothing
                            }
                        }

                        //Now, we schedule the recording
                        //Create the RemoteRecorderManagement client
                        RemoteRecorderManagement.RemoteRecorderManagementClient RMC = new RemoteRecorderManagement.RemoteRecorderManagementClient();

                        //Name this recording
                        string sName = drEvent.Field <string>("ModuleIds") + " - " + drEvent.Field <string>("RoomId") + " - " + drEvent.Field <DateTime>("StartTime"); //Module, Location, Time
                        //Build the RemoteRecorderSettings object:
                        RemoteRecorderManagement.RecorderSettings RecorderSetting = new RemoteRecorderManagement.RecorderSettings()
                        {
                            RecorderId = rRecorder.Id
                        };
                        //Schedule the recording
                        //Note that we trim 1 minute from the end of the recording to give the remoterecorder time to recover between back-to-back recordings
                        RemoteRecorderManagement.ScheduledRecordingResult RemoteRecorderResult = RMC.ScheduleRecording(RemoteRecorderAuthentication(), sName, fFolder.Id, false, drEvent.Field <DateTime>("StartTime").ToUniversalTime(), drEvent.Field <DateTime>("StartTime").ToUniversalTime().AddMinutes(-1), new RemoteRecorderManagement.RecorderSettings[] { RecorderSetting });

                        //Check that the event was scheduled properly
                        if (!RemoteRecorderResult.ConflictsExist)
                        {
                            //Nothing clashed

                            //We're only adding a single schedule, so can grab first DeliveryID
                            Guid gDeliveryIGuid = RemoteRecorderResult.SessionIDs.FirstOrDefault();
                            //At this point you could store the Guid in a database somewhere, to keep track of Panopto sessions and CMIS events
                        }
                        else
                        {
                            //The schedule was not created because it clashes with an existing schedule on this remote recorder
                            //Our new schedule has not been added to Panopto
                            //RemoteRecorderResult.ConflictingSessions will tell us the DeliveryIDs of the existing sessions
                        }
                    }
                    ;
                }
                catch (Exception ex)
                {
                    //Something happened whilst retrieving the remoterecorder, creating the folder and user, assigning permissions, or scheduling the recording
                    //Deal with this problem as you deem appropriate
                }
            }
        }
示例#2
0
        //A quick note on the following methods:
        //These all assume that you are adding 1-2 events from CMIS to Panopto.
        //It's likely that in the real-world, you'll be adding 100+ events in one go. This can have pretty horrific performance issues with all the required API calls.
        //In a lot of cases it is far easier to cache some lookups locally and refer to them instead (eg. a list of remote recorders). The information is relatively static and this is safe to do.
        //None of this example code uses caching.

        /// <summary>
        /// Finds a Panopto Remote Recorder by name (description)
        /// </summary>
        private static RemoteRecorderManagement.RemoteRecorder GetRecorder(string sLocation)
        {
            //Local variables
            string sRemoteRecorderName;

            //This method could be used to translate between rooms and remote recorder names.
            //To keep things simple in this example, we'll assume that the remote recorder name is the same as the room name (eg. remote recorder 'LTB06' is located in room 'LTB06')

            //But there are several different ways to handle remote recorder names:
            //- Name your remote recorders after the location they are installed in (whcih is what we'll do here)
            //- Use a lookup table to determine where your remote recorders are located (University of Essex does this)
            //- Use the ExternalId property of the RemoteRecorder object to store a custom ID for each recorder

            //LOOKUP CODE GOES HERE (as above, for brevity we'll assume the remote recorder's name (description) is the same as its location
            sRemoteRecorderName = sLocation;

            //Pagination isn't strictly necessary as we've increased maxReceivedMessageSize="6553560" in the app.config
            //But we'll keep the pagination code for sake of completeness
            RemoteRecorderManagement.Pagination RemoteRecorderPagination = new RemoteRecorderManagement.Pagination()
            {
                MaxNumberResults = iResultsPerPage,
                PageNumber       = 0
            };

            //Create a Remote Recorder Management Client
            RemoteRecorderManagement.RemoteRecorderManagementClient RemoteRecorderClient = new RemoteRecorderManagement.RemoteRecorderManagementClient();

            //Lookup all Remote Recorders
            //Note: if you had stored the RecorderId or ExternalId elsewhere, you could use the RemoteRecorderClient.GetRecordersById or RemoteRecorderClient.GetRecordersByExternalID methods to return a single recorder
            //Note 2: you could potentially cache this response in a global object and check/use it in subsequent calls to speed up the code
            RemoteRecorderManagement.ListRecordersResponse RemoteRecorderResponse = RemoteRecorderClient.ListRecorders(RemoteRecorderAuthentication(), RemoteRecorderPagination, RemoteRecorderManagement.RecorderSortField.Name);

            #region ListRecorders handling
            //Loop through the returned pages, add each result to a List
            //If we wanted to speed up this code we could potentially stop at the first match, but that carries risk of ignoring duplicate remote recorders
            List <RemoteRecorderManagement.RemoteRecorder> lRecorders = new List <RemoteRecorderManagement.RemoteRecorder>();

            //Keep track of the number of items remaining in the RemoteRecorderResponse queue
            int iTotalPages  = (int)Math.Ceiling(((double)RemoteRecorderResponse.TotalResultCount / (double)iResultsPerPage)); //Total number of pages (total items/items per page)
            int iCurrentPage = 0;

            while (iCurrentPage < iTotalPages)
            {
                //Increment the page number
                iCurrentPage++;

                //Grab results from this age and add to list
                lRecorders.AddRange(RemoteRecorderResponse.PagedResults.AsEnumerable());

                //If we still have items outstanding, we should grab the next page
                if (iCurrentPage < iTotalPages)
                {
                    RemoteRecorderPagination = new RemoteRecorderManagement.Pagination()
                    {
                        //Keep the same number of items per page as before
                        MaxNumberResults = iResultsPerPage,
                        PageNumber       = iCurrentPage
                    };
                    //Grab the next page from Panopto's API
                    RemoteRecorderResponse = RemoteRecorderClient.ListRecorders(RemoteRecorderAuthentication(), RemoteRecorderPagination, RemoteRecorderManagement.RecorderSortField.Name);
                }
                ;
            }

            //Narrow down our list of recorders to match the one we're after
            lRecorders = lRecorders.Where(r => r.Name.ToLower().Trim() == sRemoteRecorderName.Trim().ToLower()).ToList();

            //Duplicate matches?
            if (lRecorders.Count > 1)
            {
                throw new Exception("More than one remote recorder found: " + sRemoteRecorderName);
            }
            else if (lRecorders.Count == 0)
            {
                return(null);
            }
            else
            {
                return(lRecorders.FirstOrDefault());
            }
            #endregion
        }