bigbluebutton-web: Added filter parameter to getRecordings for filtering queries based on the state of the recording [published|unpublished|deleted]
This commit is contained in:
parent
3265709455
commit
6b911820e0
@ -19,9 +19,11 @@
|
||||
package org.bigbluebutton.web.controllers
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
@ -38,14 +40,18 @@ import org.bigbluebutton.web.services.turn.StunTurnService;
|
||||
import org.bigbluebutton.web.services.turn.TurnEntry;
|
||||
import org.bigbluebutton.presentation.PresentationUrlDownloadService;
|
||||
import org.bigbluebutton.presentation.UploadedPresentation
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import org.bigbluebutton.api.ApiErrors;
|
||||
import org.bigbluebutton.api.ClientConfigService;
|
||||
import org.bigbluebutton.api.ParamsProcessorUtil;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.text.DateFormat;
|
||||
|
||||
class ApiController {
|
||||
@ -1705,10 +1711,11 @@ class ApiController {
|
||||
internalRecordIds = paramsProcessorUtil.decodeIds(params.recordID)
|
||||
}
|
||||
|
||||
ArrayList<String> filters = new ArrayList<String>()
|
||||
Map<String, Object> filters = new LinkedHashMap<String, Object>()
|
||||
if (!StringUtils.isEmpty(params.filter)) {
|
||||
filters = paramsProcessorUtil.decodeIds(params.filter)
|
||||
filters = paramsProcessorUtil.decodeFilters(params.filter)
|
||||
}
|
||||
log.debug(new groovy.json.JsonBuilder( filters ).toPrettyString())
|
||||
|
||||
// Everything is good so far.
|
||||
if ( internalRecordIds.size() == 0 ) {
|
||||
@ -1716,7 +1723,7 @@ class ApiController {
|
||||
// Translate the external meeting ids to an internal meeting ids.
|
||||
internalRecordIds = paramsProcessorUtil.convertToInternalMeetingId(externalMeetingIds);
|
||||
}
|
||||
HashMap<String,Recording> recs = meetingService.getRecordings(internalRecordIds);
|
||||
HashMap<String,Recording> recs = meetingService.getRecordings(internalRecordIds, filters);
|
||||
recs = meetingService.filterRecordingsByMetadata(recs, ParamsProcessorUtil.processMetaParam(params));
|
||||
|
||||
if (recs.isEmpty()) {
|
||||
|
@ -339,9 +339,9 @@ public class MeetingService implements MessageListener {
|
||||
return null;
|
||||
}
|
||||
|
||||
public HashMap<String,Recording> getRecordings(ArrayList<String> idList) {
|
||||
public HashMap<String,Recording> getRecordings(ArrayList<String> idList, Map<String, Object> filters) {
|
||||
//TODO: this method shouldn't be used
|
||||
HashMap<String,Recording> recs= reorderRecordings(recordingService.getRecordings(idList));
|
||||
HashMap<String,Recording> recs= reorderRecordings(recordingService.getRecordings(idList, filters));
|
||||
return recs;
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
@ -42,69 +43,70 @@ import org.apache.commons.httpclient.*;
|
||||
import org.apache.commons.httpclient.methods.*;
|
||||
|
||||
public class ParamsProcessorUtil {
|
||||
private static Logger log = LoggerFactory.getLogger(ParamsProcessorUtil.class);
|
||||
|
||||
private final String URLDECODER_SEPARATOR=",";
|
||||
|
||||
private String apiVersion;
|
||||
private boolean serviceEnabled = false;
|
||||
private String securitySalt;
|
||||
private int defaultMaxUsers = 20;
|
||||
private String defaultWelcomeMessage;
|
||||
private String defaultWelcomeMessageFooter;
|
||||
private String defaultDialAccessNumber;
|
||||
private String testVoiceBridge;
|
||||
private String testConferenceMock;
|
||||
private String defaultLogoutUrl;
|
||||
private String defaultServerUrl;
|
||||
private int defaultNumDigitsForTelVoice;
|
||||
private String defaultClientUrl;
|
||||
private String defaultAvatarURL;
|
||||
private String defaultConfigURL;
|
||||
private int defaultMeetingDuration;
|
||||
private boolean disableRecordingDefault;
|
||||
private boolean autoStartRecording;
|
||||
private boolean allowStartStopRecording;
|
||||
|
||||
private String defaultConfigXML = null;
|
||||
|
||||
private String substituteKeywords(String message, String dialNumber, String telVoice, String meetingName) {
|
||||
String welcomeMessage = message;
|
||||
|
||||
String DIAL_NUM = "%%DIALNUM%%";
|
||||
String CONF_NUM = "%%CONFNUM%%";
|
||||
String CONF_NAME = "%%CONFNAME%%";
|
||||
ArrayList<String> keywordList = new ArrayList<String>();
|
||||
keywordList.add(DIAL_NUM);keywordList.add(CONF_NUM);keywordList.add(CONF_NAME);
|
||||
private static Logger log = LoggerFactory.getLogger(ParamsProcessorUtil.class);
|
||||
|
||||
Iterator<String> itr = keywordList.iterator();
|
||||
while(itr.hasNext()) {
|
||||
String keyword = (String) itr.next();
|
||||
if (keyword.equals(DIAL_NUM)) {
|
||||
welcomeMessage = welcomeMessage.replaceAll(DIAL_NUM, dialNumber);
|
||||
} else if (keyword.equals(CONF_NUM)) {
|
||||
welcomeMessage = welcomeMessage.replaceAll(CONF_NUM, telVoice);
|
||||
} else if (keyword.equals(CONF_NAME)) {
|
||||
welcomeMessage = welcomeMessage.replaceAll(CONF_NAME, meetingName);
|
||||
}
|
||||
}
|
||||
return welcomeMessage;
|
||||
}
|
||||
private final String URLDECODER_SEPARATOR=",";
|
||||
private final String FILTERDECODER_SEPARATOR_ELEMENTS=":";
|
||||
private final String FILTERDECODER_SEPARATOR_OPERATORS="\\|";
|
||||
|
||||
|
||||
public void processRequiredCreateParams(Map<String, String> params, ApiErrors errors) {
|
||||
// Do we have a checksum? If not, complain.
|
||||
if (StringUtils.isEmpty(params.get("checksum"))) {
|
||||
errors.missingParamError("checksum");
|
||||
private String apiVersion;
|
||||
private boolean serviceEnabled = false;
|
||||
private String securitySalt;
|
||||
private int defaultMaxUsers = 20;
|
||||
private String defaultWelcomeMessage;
|
||||
private String defaultWelcomeMessageFooter;
|
||||
private String defaultDialAccessNumber;
|
||||
private String testVoiceBridge;
|
||||
private String testConferenceMock;
|
||||
private String defaultLogoutUrl;
|
||||
private String defaultServerUrl;
|
||||
private int defaultNumDigitsForTelVoice;
|
||||
private String defaultClientUrl;
|
||||
private String defaultAvatarURL;
|
||||
private String defaultConfigURL;
|
||||
private int defaultMeetingDuration;
|
||||
private boolean disableRecordingDefault;
|
||||
private boolean autoStartRecording;
|
||||
private boolean allowStartStopRecording;
|
||||
|
||||
private String defaultConfigXML = null;
|
||||
|
||||
private String substituteKeywords(String message, String dialNumber, String telVoice, String meetingName) {
|
||||
String welcomeMessage = message;
|
||||
|
||||
String DIAL_NUM = "%%DIALNUM%%";
|
||||
String CONF_NUM = "%%CONFNUM%%";
|
||||
String CONF_NAME = "%%CONFNAME%%";
|
||||
ArrayList<String> keywordList = new ArrayList<String>();
|
||||
keywordList.add(DIAL_NUM);keywordList.add(CONF_NUM);keywordList.add(CONF_NAME);
|
||||
|
||||
Iterator<String> itr = keywordList.iterator();
|
||||
while(itr.hasNext()) {
|
||||
String keyword = (String) itr.next();
|
||||
if (keyword.equals(DIAL_NUM)) {
|
||||
welcomeMessage = welcomeMessage.replaceAll(DIAL_NUM, dialNumber);
|
||||
} else if (keyword.equals(CONF_NUM)) {
|
||||
welcomeMessage = welcomeMessage.replaceAll(CONF_NUM, telVoice);
|
||||
} else if (keyword.equals(CONF_NAME)) {
|
||||
welcomeMessage = welcomeMessage.replaceAll(CONF_NAME, meetingName);
|
||||
}
|
||||
}
|
||||
|
||||
return welcomeMessage;
|
||||
}
|
||||
|
||||
public void processRequiredCreateParams(Map<String, String> params, ApiErrors errors) {
|
||||
// Do we have a checksum? If not, complain.
|
||||
if (StringUtils.isEmpty(params.get("checksum"))) {
|
||||
errors.missingParamError("checksum");
|
||||
}
|
||||
|
||||
// Do we have a meeting id? If not, complain.
|
||||
if(!StringUtils.isEmpty(params.get("meetingID"))) {
|
||||
if (StringUtils.isEmpty(StringUtils.strip(params.get("meetingID")))) {
|
||||
errors.missingParamError("meetingID");
|
||||
}
|
||||
if (StringUtils.isEmpty(StringUtils.strip(params.get("meetingID")))) {
|
||||
errors.missingParamError("meetingID");
|
||||
}
|
||||
} else {
|
||||
errors.missingParamError("meetingID");
|
||||
errors.missingParamError("meetingID");
|
||||
}
|
||||
}
|
||||
|
||||
@ -702,8 +704,8 @@ public class ParamsProcessorUtil {
|
||||
public void setdefaultAvatarURL(String url) {
|
||||
this.defaultAvatarURL = url;
|
||||
}
|
||||
|
||||
public ArrayList<String> decodeIds(String encodeid){
|
||||
|
||||
public ArrayList<String> decodeIds(String encodeid) {
|
||||
ArrayList<String> ids=new ArrayList<String>();
|
||||
try {
|
||||
ids.addAll(Arrays.asList(URLDecoder.decode(encodeid,"UTF-8").split(URLDECODER_SEPARATOR)));
|
||||
@ -713,7 +715,7 @@ public class ParamsProcessorUtil {
|
||||
|
||||
return ids;
|
||||
}
|
||||
|
||||
|
||||
public ArrayList<String> convertToInternalMeetingId(ArrayList<String> extMeetingIds) {
|
||||
ArrayList<String> internalMeetingIds=new ArrayList<String>();
|
||||
for(String extid : extMeetingIds){
|
||||
@ -722,9 +724,9 @@ public class ParamsProcessorUtil {
|
||||
return internalMeetingIds;
|
||||
}
|
||||
|
||||
public Map<String,String> getUserCustomData(Map<String,String> params){
|
||||
public Map<String,String> getUserCustomData(Map<String,String> params) {
|
||||
Map<String,String> resp = new HashMap<String, String>();
|
||||
|
||||
|
||||
for (String key: params.keySet()) {
|
||||
if (key.contains("userdata")&&key.indexOf("userdata")==0){
|
||||
String[] userdata = key.split("-");
|
||||
@ -734,7 +736,28 @@ public class ParamsProcessorUtil {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
public Map<String, Object> decodeFilters(String encodedFilters) {
|
||||
Map<String, Object> filters = new LinkedHashMap<String, Object>();
|
||||
|
||||
try {
|
||||
String[] sFilters = encodedFilters.split(URLDECODER_SEPARATOR);
|
||||
for( String sFilter: sFilters) {
|
||||
String[] filterElements = sFilter.split(FILTERDECODER_SEPARATOR_ELEMENTS, 3);
|
||||
Map<String, Object> filter = new LinkedHashMap<String, Object>();
|
||||
filter.put("op", filterElements[1]);
|
||||
String[] fValues = filterElements[2].split(FILTERDECODER_SEPARATOR_OPERATORS);
|
||||
filter.put("values", fValues );
|
||||
filters.put(filterElements[0], filter);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Couldn't decode the filters");
|
||||
}
|
||||
|
||||
return filters;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ package org.bigbluebutton.api;
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -56,29 +57,66 @@ public class RecordingService {
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayList<Recording> getRecordings(ArrayList<String> meetingIds) {
|
||||
private boolean shouldIncludeDir( Map<String, Object> filters, String type ) {
|
||||
boolean r = false;
|
||||
|
||||
if( filters.containsKey("state") ) {
|
||||
Map<String, Object> filter = (Map<String, Object>)filters.get("state");
|
||||
String[] values = (String[])filter.get("values");
|
||||
if ( Arrays.asList(values).contains("any") ) {
|
||||
r = true;
|
||||
} else {
|
||||
if ( type.equals(Recording.STATE_PUBLISHED) && Arrays.asList(values).contains(Recording.STATE_PUBLISHED) ) {
|
||||
r = true;
|
||||
} else if ( type.equals(Recording.STATE_UNPUBLISHED) && Arrays.asList(values).contains(Recording.STATE_UNPUBLISHED) ) {
|
||||
r = true;
|
||||
} else if ( type.equals(Recording.STATE_DELETED) && Arrays.asList(values).contains(Recording.STATE_DELETED) ) {
|
||||
r = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( type.equals(Recording.STATE_PUBLISHED) || type.equals(Recording.STATE_UNPUBLISHED) ) {
|
||||
r = true;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
public ArrayList<Recording> getRecordings(ArrayList<String> meetingIds, Map<String, Object> filters) {
|
||||
ArrayList<Recording> recs = new ArrayList<Recording>();
|
||||
|
||||
if(meetingIds.isEmpty()){
|
||||
meetingIds.addAll(getAllRecordingIds(publishedDir));
|
||||
meetingIds.addAll(getAllRecordingIds(unpublishedDir));
|
||||
meetingIds.addAll(getAllRecordingIds(deletedDir));
|
||||
if ( shouldIncludeDir(filters, Recording.STATE_PUBLISHED) )
|
||||
meetingIds.addAll(getAllRecordingIds(publishedDir));
|
||||
|
||||
if ( shouldIncludeDir(filters, Recording.STATE_UNPUBLISHED) )
|
||||
meetingIds.addAll(getAllRecordingIds(unpublishedDir));
|
||||
|
||||
if ( shouldIncludeDir(filters, Recording.STATE_DELETED) )
|
||||
meetingIds.addAll(getAllRecordingIds(deletedDir));
|
||||
}
|
||||
|
||||
for(String meetingId : meetingIds){
|
||||
ArrayList<Recording> published = getRecordingsForPath(meetingId, publishedDir);
|
||||
if (!published.isEmpty()) {
|
||||
recs.addAll(published);
|
||||
if ( shouldIncludeDir(filters, Recording.STATE_PUBLISHED) ) {
|
||||
ArrayList<Recording> published = getRecordingsForPath(meetingId, publishedDir);
|
||||
if (!published.isEmpty()) {
|
||||
recs.addAll(published);
|
||||
}
|
||||
}
|
||||
|
||||
ArrayList<Recording> unpublished = getRecordingsForPath(meetingId, unpublishedDir);
|
||||
if (!unpublished.isEmpty()) {
|
||||
recs.addAll(unpublished);
|
||||
if ( shouldIncludeDir(filters, Recording.STATE_UNPUBLISHED) ) {
|
||||
ArrayList<Recording> unpublished = getRecordingsForPath(meetingId, unpublishedDir);
|
||||
if (!unpublished.isEmpty()) {
|
||||
recs.addAll(unpublished);
|
||||
}
|
||||
}
|
||||
|
||||
ArrayList<Recording> deleted = getRecordingsForPath(meetingId, deletedDir);
|
||||
if (!deleted.isEmpty()) {
|
||||
recs.addAll(deleted);
|
||||
if ( shouldIncludeDir(filters, Recording.STATE_DELETED) ) {
|
||||
ArrayList<Recording> deleted = getRecordingsForPath(meetingId, deletedDir);
|
||||
if (!deleted.isEmpty()) {
|
||||
recs.addAll(deleted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user