bbb-web: Added code for updating recording metadata

This commit is contained in:
jfederico 2016-07-11 15:57:11 -04:00
parent 51ee64df44
commit 34ad74646a
5 changed files with 215 additions and 47 deletions

View File

@ -52,16 +52,19 @@ class UrlMappings {
"/api/getMeetings"(controller:"api") {
action = [GET:'getMeetingsHandler', POST:'getMeetingsHandler']
}
"/api/getSessions"(controller:"api") {
action = [GET:'getSessionsHandler', POST:'getSessionsHandler']
}
"/api/getSessions"(controller:"api") {
action = [GET:'getSessionsHandler', POST:'getSessionsHandler']
}
"/api/getRecordings"(controller:"api") {
action = [GET:'getRecordingsHandler', POST:'getRecordingsHandler']
}
"/api/updateRecordings"(controller:"api") {
action = [GET:'updateRecordingsHandler', POST:'updateRecordingsHandler']
}
"/$controller/$action?/$id?(.${format})?"{
constraints {
// apply constraints here

View File

@ -1767,7 +1767,6 @@ class ApiController {
/******************************************************
* PUBLISH_RECORDINGS API
******************************************************/
def publishRecordings = {
String API_CALL = "publishRecordings"
log.debug CONTROLLER_NAME + "#${API_CALL}"
@ -1924,6 +1923,85 @@ class ApiController {
}
}
/******************************************************
* UPDATE_RECORDINGS API
******************************************************/
def updateRecordingsHandler = {
String API_CALL = "updateRecordings"
log.debug CONTROLLER_NAME + "#${API_CALL}"
// BEGIN - backward compatibility
if (StringUtils.isEmpty(params.checksum)) {
invalid("checksumError", "You did not pass the checksum security check")
return
}
if (StringUtils.isEmpty(params.recordID)) {
invalid("missingParamRecordID", "You must specify a recordID.");
return
}
if (! paramsProcessorUtil.isChecksumSame(API_CALL, params.checksum, request.getQueryString())) {
invalid("checksumError", "You did not pass the checksum security check")
return
}
// END - backward compatibility
ApiErrors errors = new ApiErrors()
// Do we have a checksum? If none, complain.
if (StringUtils.isEmpty(params.checksum)) {
errors.missingParamError("checksum");
}
// Do we have a recording id? If none, complain.
String recordId = params.recordID
if (StringUtils.isEmpty(recordId)) {
errors.missingParamError("recordID");
}
if (errors.hasErrors()) {
respondWithErrors(errors)
return
}
// Do we agree on the checksum? If not, complain.
if (! paramsProcessorUtil.isChecksumSame(API_CALL, params.checksum, request.getQueryString())) {
errors.checksumError()
respondWithErrors(errors)
return
}
List<String> recordIdList = new ArrayList<String>();
if (!StringUtils.isEmpty(recordId)) {
recordIdList=paramsProcessorUtil.decodeIds(recordId);
}
if (!meetingService.existsAnyRecording(recordIdList)) {
// BEGIN - backward compatibility
invalid("notFound", "We could not find recordings");
return;
// END - backward compatibility
}
//Execute code specific for this call
Map<String, String> metaParams = ParamsProcessorUtil.processMetaParam(params)
if ( !metaParams.empty ) {
//Proceed with the update
meetingService.updateRecordings(recordIdList, metaParams);
}
withFormat {
xml {
render(contentType:"text/xml") {
response() {
returncode(RESP_CODE_SUCCESS)
updated(true)
}
}
}
}
}
def uploadDocuments(conf) {
log.debug("ApiController#uploadDocuments(${conf.getInternalId()})");

View File

@ -27,9 +27,9 @@ import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
@ -292,7 +292,7 @@ public class MeetingService implements MessageListener {
private void handleCreateMeeting(Meeting m) {
meetings.put(m.getInternalId(), m);
if (m.isRecord()) {
Map<String, String> metadata = new LinkedHashMap<String, String>();
Map<String, String> metadata = new TreeMap<String, String>();
metadata.putAll(m.getMetadata());
// TODO: Need a better way to store these values for recordings
metadata.put("meetingId", m.getExternalId());
@ -421,7 +421,7 @@ public class MeetingService implements MessageListener {
r.setMeetingID(mid);
r.setName(name);
ArrayList<Playback> plays = new ArrayList<Playback>();
List<Playback> plays = new ArrayList<Playback>();
if (r.getPlaybackFormat() != null) {
plays.add(new Playback(r.getPlaybackFormat(), r
@ -471,20 +471,24 @@ public class MeetingService implements MessageListener {
public void setPublishRecording(List<String> idList, boolean publish) {
for (String id : idList) {
if (publish) {
if (publish) {
recordingService.changeState(id, Recording.STATE_PUBLISHED);
} else {
} else {
recordingService.changeState(id, Recording.STATE_UNPUBLISHED);
}
}
}
public void deleteRecordings(ArrayList<String> idList){
for (String id : idList) {
recordingService.changeState(id, Recording.STATE_DELETED);
}
}
public void deleteRecordings(List<String> idList) {
for (String id : idList) {
recordingService.changeState(id, Recording.STATE_DELETED);
}
}
public void updateRecordings(List<String> idList, Map<String, String> metaParams) {
recordingService.updateMetaParams(idList, metaParams);
}
public void processRecording(String meetingId) {
recordingService.startIngestAndProcessing(meetingId);
}

View File

@ -76,8 +76,14 @@ public class RecordingService {
for (String recordID : recordIDs) {
for (Map.Entry<String, List<File>> entry : allDirectories.entrySet()) {
List<Recording> _recs = getRecordingsForPath(recordID, entry.getValue());
recs.addAll(_recs);
List<File> _recs = getRecordingsForPath(recordID, entry.getValue());
Iterator<File> iterator = _recs.iterator();
while (iterator.hasNext()) {
Recording r = getRecordingInfo(iterator.next());
if (r != null) {
recs.add(r);
}
}
}
}
@ -165,16 +171,14 @@ public class RecordingService {
return ids;
}
private List<Recording> getRecordingsForPath(String id, List<File> recordings) {
List<Recording> recs = new ArrayList<Recording>();
private List<File> getRecordingsForPath(String id, List<File> recordings) {
List<File> recs = new ArrayList<File>();
Iterator<File> iterator = recordings.iterator();
while (iterator.hasNext()) {
File recording = iterator.next();
if (recording.getName().startsWith(id)) {
Recording r = getRecordingInfo(recording);
if (r != null)
recs.add(r);
File rec = iterator.next();
if (rec.getName().startsWith(id)) {
recs.add(rec);
}
}
return recs;
@ -349,16 +353,7 @@ public class RecordingService {
private List<File> getAllDirectories(String state) {
List<File> allDirectories = new ArrayList<File>();
String dir = null;
if( state.equals(Recording.STATE_PUBLISHED) ) {
dir = publishedDir;
} else if ( state.equals(Recording.STATE_UNPUBLISHED) ){
dir = unpublishedDir;
} else if ( state.equals(Recording.STATE_DELETED) ){
dir = deletedDir;
} else if ( state.equals(Recording.STATE_PROCESSING) || state.equals(Recording.STATE_PROCESSED) ){
dir = processDir;
}
String dir = getDestinationBaseDirectoryName(state);
if ( dir != null ) {
String[] formats = getPlaybackFormats(dir);
@ -401,4 +396,79 @@ public class RecordingService {
return allDirectories;
}
public void updateMetaParams(List<String> recordIDs, Map<String,String> metaParams) {
updateMetaParams(recordIDs, metaParams, false);
}
public void updateMetaParams(List<String> recordIDs, Map<String,String> metaParams, boolean forced) {
// Define the directories used to lookup the recording
List<String> states = new ArrayList<String>();
states.add(Recording.STATE_PUBLISHED);
states.add(Recording.STATE_UNPUBLISHED);
states.add(Recording.STATE_DELETED);
// Gather all the existent directories based on the states defined for the lookup
Map<String, List<File>> allDirectories = getAllDirectories(states);
// Retrieve the actual recording from the directories gathered for the lookup
for (String recordID : recordIDs) {
for (Map.Entry<String, List<File>> entry : allDirectories.entrySet()) {
List<File> recs = getRecordingsForPath(recordID, entry.getValue());
// Lookup the target recording
Map<String,File> recsIndexed = indexRecordings(recs);
if ( recsIndexed.containsKey(recordID) ) {
File recFile = recsIndexed.get(recordID);
Recording rec = getRecordingInfo(recFile);
if (rec != null) {
for (Map.Entry<String,String> meta : metaParams.entrySet()) {
if ( rec.containsMetadata(meta.getKey()) || forced ) {
// The meta parameter already exists, update it
// Or if doesn't exist but forced, then add it
rec.updateMetadata(meta.getKey(), meta.getValue());
}
}
// Process the changes by saving the recording into metadata.xml
recordingServiceHelper.writeRecordingInfo(recFile.getAbsolutePath(), rec);
}
}
}
}
return;
}
private Map<String,File> indexRecordings(List<File> recs) {
Map<String,File> indexedRecs = new HashMap<String,File>();
Iterator<File> iterator = recs.iterator();
while (iterator.hasNext()) {
File rec = iterator.next();
indexedRecs.put(rec.getName(), rec);
}
return indexedRecs;
}
private String getDestinationBaseDirectoryName(String state) {
return getDestinationBaseDirectoryName(state, false);
}
private String getDestinationBaseDirectoryName(String state, boolean forceDefault) {
String baseDir = null;
if ( state.equals(Recording.STATE_PROCESSING) || state.equals(Recording.STATE_PROCESSED) )
baseDir = processDir;
else if ( state.equals(Recording.STATE_PUBLISHED) )
baseDir = publishedDir;
else if ( state.equals(Recording.STATE_UNPUBLISHED) )
baseDir = unpublishedDir;
else if ( state.equals(Recording.STATE_DELETED) )
baseDir = deletedDir;
else if ( forceDefault )
baseDir = publishedDir;
return baseDir;
}
}

View File

@ -23,8 +23,9 @@ import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import groovy.util.slurpersupport.GPathResult;
@ -35,8 +36,8 @@ public class Recording {
private boolean published;
private String startTime;
private String endTime;
private Map<String, String> metadata = new HashMap<String, String>();
private ArrayList<Playback> playbacks=new ArrayList<Playback>();
private Map<String, String> metadata = new TreeMap<String, String>();
private List<Playback> playbacks=new ArrayList<Playback>();
//TODO:
private String state;
@ -131,15 +132,27 @@ public class Recording {
}
public Map<String, String> getMetadata() {
return metadata;
return this.metadata;
}
public String getMetadata(String key) {
return this.metadata.get(key);
}
public void setMetadata(Map<String, String> metadata) {
this.metadata = metadata;
}
public void updateMetadata(String key, String value) {
this.metadata.put(key, value);
}
public boolean containsMetadata(String key) {
return this.metadata.containsKey(key);
}
public String getMeetingID() {
return meetingID;
return this.meetingID;
}
public void setMeetingID(String meetingID) {
@ -147,18 +160,18 @@ public class Recording {
}
public String getName() {
return name;
return this.name;
}
public void setName(String name) {
this.name = name;
}
public ArrayList<Playback> getPlaybacks() {
public List<Playback> getPlaybacks() {
return playbacks;
}
public void setPlaybacks(ArrayList<Playback> playbacks) {
public void setPlaybacks(List<Playback> playbacks) {
this.playbacks = playbacks;
}