package com.brightcove.opensource.workflowengine.actors;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;
import com.brightcove.commons.catalog.objects.Video;
import com.brightcove.commons.catalog.objects.Videos;
import com.brightcove.commons.catalog.objects.enumerations.SortByTypeEnum;
import com.brightcove.commons.catalog.objects.enumerations.SortOrderTypeEnum;
import com.brightcove.commons.catalog.objects.enumerations.VideoFieldEnum;
import com.brightcove.commons.catalog.objects.enumerations.VideoStateFilterEnum;
import com.brightcove.commons.collection.CollectionUtils;
import com.brightcove.commons.misc.logging.LogUtils;
import com.brightcove.mediaapi.exceptions.BrightcoveException;
import com.brightcove.mediaapi.wrapper.ReadApi;
import com.brightcove.opensource.workflowengine.Actor;
import com.brightcove.opensource.workflowengine.Workflow;
import com.brightcove.opensource.workflowengine.record.Property;
import com.brightcove.opensource.workflowengine.record.Record;
/**
* <p>
* An input adapter that will read from Brightcove Video Cloud Media API
* using the find_modified_videos method.
* </p>
*
* <p>
* The following configuration properties will be honored:<ul>
* <li>read-api-token - Media API token to use the Read API</li>
* <li>video-fields - Comma separated list of video fields to retrieve</li>
* <li>custom-fields - Comma separated list of custom fields to retrieve</li>
* <li>video-state-filter - Commas separated list of item states valid to search for</li>
* <li>from-date - Earliest video to retrieve (based on last modified date). Format yyyy/MM/dd HH:mm:ss z</li>
* </ul>
* </p>
*
* @author <a href="https://github.com/three4clavin">Sander Gates</a>
*
*/
public class VideoCloudFindModifiedInputAdapter extends Actor {
private String readApiToken = null;
private ReadApi readApi = null;
private EnumSet<VideoFieldEnum> videoFields = null;
private Set<String> customFields = null;
private Set<VideoStateFilterEnum> videoStateFilter = null;
private Integer pageSize = null;
private Integer pageNumber = null;
private SortByTypeEnum sortBy = null;
private SortOrderTypeEnum sortOrderType = null;
private Long fromDate = null;
private String dateFormat = "yyyy/MM/dd HH:mm:ss z";
private SimpleDateFormat dateFormatter = new SimpleDateFormat(dateFormat);
/**
* <p>
* Default constructor - workflow this actor is part of must be
* provided
* </p>
*
* @param workflow Workflow this actor will be part of
*/
public VideoCloudFindModifiedInputAdapter(Workflow workflow){
super(workflow);
}
/* (non-Javadoc)
* @see com.brightcove.opensource.workflowengine.Actor#run()
*/
public void run(){
if(! hasStarted()){
Property<String> readApiTokenProp = getFirstProperty("read-api-token");
Property<String> videoFieldsProp = getFirstProperty("video-fields");
Property<String> customFieldsProp = getFirstProperty("custom-fields");
Property<String> videoStateProp = getFirstProperty("video-state-filter");
Property<String> fromDateProp = getFirstProperty("from-date");
if((readApiTokenProp == null) || (readApiTokenProp.getValue() == null)){
die("VideoCloudFindModifiedInputAdapter requires a read-api-token property.");
}
readApiToken = readApiTokenProp.getValue();
List<String> apiRedactStrings = new ArrayList<String>();
apiRedactStrings.add(readApiToken);
Logger apiLogger = LogUtils.getLogger(this.getClass().getCanonicalName(), apiRedactStrings);
readApi = new ReadApi(apiLogger);
videoFields = VideoFieldEnum.CreateEmptyEnumSet();
customFields = CollectionUtils.CreateEmptyStringSet();
if((videoFieldsProp != null) && (videoFieldsProp.getValue() != null)){
for(String videoField : videoFieldsProp.getValue().split(",")){
videoFields.add(VideoFieldEnum.valueOf(videoField));
}
}
if((customFieldsProp != null) && (customFieldsProp.getValue() != null)){
for(String customField : customFieldsProp.getValue().split(",")){
customFields.add(customField);
}
}
videoStateFilter = new HashSet<VideoStateFilterEnum>();
if((videoStateProp != null) && (videoStateProp.getValue() != null)){
for(String state : videoStateProp.getValue().split(",")){
VideoStateFilterEnum filter = VideoStateFilterEnum.valueOf(state);
videoStateFilter.add(filter);
}
}
else{
videoStateFilter.add(VideoStateFilterEnum.PLAYABLE);
}
fromDate = 0l;
if((fromDateProp != null) && (fromDateProp.getValue() != null)){
Date date = null;
try {
date = dateFormatter.parse(fromDateProp.getValue());
}
catch (ParseException pe) {
die("VideoCloudFindModifiedInputAdapter couldn't parse date '" + fromDateProp.getValue() + "' with simple date format '" + dateFormat + "'. Exception caught: '" + pe + "'.");
}
// Have milliseconds, need minutes
Long oneMinute = 1000l * 60l;
fromDate = date.getTime() / oneMinute;
}
pageSize = 100;
pageNumber = 0;
sortBy = SortByTypeEnum.MODIFIED_DATE;
sortOrderType = SortOrderTypeEnum.DESC;
Videos videos = getPage();
while((videos != null) && (videos.size() > 0)){
for(Video video : videos){
Record record = new Record();
Property<Video> prop = new Property<Video>("video", video);
record.addProperty(prop);
handleRecord(record);
}
pageNumber++;
videos = getPage();
}
}
super.run();
}
private Videos getPage(){
Videos videos = null;
try {
videos = readApi.FindModifiedVideos(readApiToken, fromDate, videoStateFilter, pageSize, pageNumber, sortBy, sortOrderType, videoFields, customFields);
}
catch (BrightcoveException be) {
die("Couldn't obtain page of videos. Exception caught: '" + be + "'.");
}
return videos;
}
}