use of org.opencastproject.mediapackage.MediaPackageElementFlavor in project opencast by opencast.
the class ExportWorkflowPropertiesWOH method start.
@Override
public WorkflowOperationResult start(WorkflowInstance workflowInstance, JobContext context) throws WorkflowOperationException {
logger.info("Start exporting workflow properties for workflow {}", workflowInstance);
final MediaPackage mediaPackage = workflowInstance.getMediaPackage();
final Set<String> keys = $(getOptConfig(workflowInstance, KEYS_PROPERTY)).bind(Strings.splitCsv).toSet();
final String targetFlavorString = getOptConfig(workflowInstance, TARGET_FLAVOR_PROPERTY).getOr(DEFAULT_TARGET_FLAVOR);
final Stream<String> targetTags = $(getOptConfig(workflowInstance, TARGET_TAGS_PROPERTY)).bind(Strings.splitCsv);
final MediaPackageElementFlavor targetFlavor = MediaPackageElementFlavor.parseFlavor(targetFlavorString);
// Read optional existing workflow properties from mediapackage
Properties workflowProps = new Properties();
Opt<Attachment> existingPropsElem = loadPropertiesElementFromMediaPackage(targetFlavor, workflowInstance);
if (existingPropsElem.isSome()) {
workflowProps = loadPropertiesFromXml(workspace, existingPropsElem.get().getURI());
// Remove specified keys
for (String key : keys) workflowProps.remove(key);
}
// Extend with specified properties
for (String key : workflowInstance.getConfigurationKeys()) {
if (keys.isEmpty() || keys.contains(key))
workflowProps.put(key, workflowInstance.getConfiguration(key));
}
// Store properties as an attachment
Attachment attachment;
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
workflowProps.storeToXML(out, null, "UTF-8");
String elementId = UUID.randomUUID().toString();
URI uri = workspace.put(mediaPackage.getIdentifier().compact(), elementId, EXPORTED_PROPERTIES_FILENAME, new ByteArrayInputStream(out.toByteArray()));
MediaPackageElementBuilder builder = MediaPackageElementBuilderFactory.newInstance().newElementBuilder();
attachment = (Attachment) builder.elementFromURI(uri, Attachment.TYPE, targetFlavor);
attachment.setMimeType(MimeTypes.XML);
} catch (IOException e) {
logger.error("Unable to store workflow properties as Attachment with flavor '{}': {}", targetFlavorString, ExceptionUtils.getStackTrace(e));
throw new WorkflowOperationException("Unable to store workflow properties as Attachment", e);
}
// Add the target tags
for (String tag : targetTags) {
logger.trace("Tagging with '{}'", tag);
attachment.addTag(tag);
}
// Update attachment
if (existingPropsElem.isSome())
mediaPackage.remove(existingPropsElem.get());
mediaPackage.add(attachment);
logger.info("Added properties from {} as Attachment with flavor {}", workflowInstance, targetFlavorString);
logger.debug("Workflow properties: {}", propertiesAsString(workflowProps));
return createResult(mediaPackage, null, Action.CONTINUE, 0);
}
use of org.opencastproject.mediapackage.MediaPackageElementFlavor in project opencast by opencast.
the class ProbeResolutionWorkflowOperationHandler method start.
@Override
public WorkflowOperationResult start(WorkflowInstance workflowInstance, JobContext context) throws WorkflowOperationException {
logger.info("Running probe-resolution workflow operation");
final MediaPackage mediaPackage = workflowInstance.getMediaPackage();
final String sourceFlavorName = getConfig(workflowInstance, OPT_SOURCE_FLAVOR);
final MediaPackageElementFlavor sourceFlavor = MediaPackageElementFlavor.parseFlavor(sourceFlavorName);
// Ensure we have a matching track
final Track[] tracks = mediaPackage.getTracks(sourceFlavor);
if (tracks.length <= 0) {
logger.info("No tracks with specified flavor ({}).", sourceFlavorName);
return createResult(mediaPackage, Action.CONTINUE);
}
// Create mapping: resolution -> [varNames]
Map<Fraction, Set<String>> resolutionMapping = new HashMap<>();
for (String key : workflowInstance.getCurrentOperation().getConfigurationKeys()) {
if (key.startsWith(OPT_VAR_PREFIX)) {
String varName = key.substring(OPT_VAR_PREFIX.length());
for (Fraction resolution : getResolutions(getConfig(workflowInstance, key))) {
if (!resolutionMapping.containsKey(resolution)) {
resolutionMapping.put(resolution, new HashSet<String>());
}
resolutionMapping.get(resolution).add(varName);
}
}
}
// Create mapping: varName -> value
Map<String, String> valueMapping = new HashMap<>();
for (String key : workflowInstance.getCurrentOperation().getConfigurationKeys()) {
if (key.startsWith(OPT_VAL_PREFIX)) {
String varName = key.substring(OPT_VAL_PREFIX.length());
valueMapping.put(varName, getConfig(workflowInstance, key));
}
}
Map<String, String> properties = new HashMap<String, String>();
for (Track track : tracks) {
final String flavor = toVariableName(track.getFlavor());
// Check if resolution fits
if (track.hasVideo()) {
for (VideoStream video : ((TrackImpl) track).getVideo()) {
Fraction resolution = Fraction.getFraction(video.getFrameWidth(), video.getFrameHeight());
if (resolutionMapping.containsKey(resolution)) {
for (String varName : resolutionMapping.get(resolution)) {
String value = valueMapping.containsKey(varName) ? valueMapping.get(varName) : "true";
properties.put(flavor + varName, value);
}
}
}
}
}
logger.info("Finished workflow operation adding the properties: {}", properties);
return createResult(mediaPackage, properties, Action.CONTINUE, 0);
}
use of org.opencastproject.mediapackage.MediaPackageElementFlavor in project opencast by opencast.
the class SeriesWorkflowOperationHandler method start.
/**
* {@inheritDoc}
*
* @see org.opencastproject.workflow.api.WorkflowOperationHandler#start(org.opencastproject.workflow.api.WorkflowInstance,
* JobContext)
*/
@Override
public WorkflowOperationResult start(final WorkflowInstance workflowInstance, JobContext context) throws WorkflowOperationException {
logger.debug("Running series workflow operation");
MediaPackage mediaPackage = workflowInstance.getMediaPackage();
Opt<String> optSeries = getOptConfig(workflowInstance.getCurrentOperation(), SERIES_PROPERTY);
Opt<String> optAttachFlavors = getOptConfig(workflowInstance.getCurrentOperation(), ATTACH_PROPERTY);
Boolean applyAcl = getOptConfig(workflowInstance.getCurrentOperation(), APPLY_ACL_PROPERTY).map(toBoolean).getOr(false);
Opt<String> optCopyMetadata = getOptConfig(workflowInstance.getCurrentOperation(), COPY_METADATA_PROPERTY);
String defaultNamespace = getOptConfig(workflowInstance.getCurrentOperation(), DEFAULT_NS_PROPERTY).getOr(DublinCore.TERMS_NS_URI);
logger.debug("Using default namespace: '{}'", defaultNamespace);
if (optSeries.isSome() && !optSeries.get().equals(mediaPackage.getSeries())) {
logger.info("Changing series id from '{}' to '{}'", StringUtils.trimToEmpty(mediaPackage.getSeries()), optSeries.get());
mediaPackage.setSeries(optSeries.get());
}
String seriesId = mediaPackage.getSeries();
if (seriesId == null) {
logger.info("No series set, skip operation");
return createResult(mediaPackage, Action.SKIP);
}
DublinCoreCatalog series;
try {
series = seriesService.getSeries(seriesId);
} catch (NotFoundException e) {
logger.info("No series with the identifier '{}' found, skip operation", seriesId);
return createResult(mediaPackage, Action.SKIP);
} catch (UnauthorizedException e) {
logger.warn("Not authorized to get series with identifier '{}' found, skip operation", seriesId);
return createResult(mediaPackage, Action.SKIP);
} catch (SeriesException e) {
logger.error("Unable to get series with identifier '{}', skip operation: {}", seriesId, ExceptionUtils.getStackTrace(e));
throw new WorkflowOperationException(e);
}
mediaPackage.setSeriesTitle(series.getFirst(DublinCore.PROPERTY_TITLE));
// Process extra metadata
HashSet<EName> extraMetadata = new HashSet<>();
if (optCopyMetadata.isSome()) {
for (String strEName : optCopyMetadata.get().split(",+\\s*")) try {
if (!strEName.isEmpty()) {
extraMetadata.add(EName.fromString(strEName, defaultNamespace));
}
} catch (IllegalArgumentException iae) {
logger.warn("Ignoring incorrect dublincore metadata property: '{}'", strEName);
}
}
// Update the episode catalog
for (Catalog episodeCatalog : mediaPackage.getCatalogs(MediaPackageElements.EPISODE)) {
DublinCoreCatalog episodeDublinCore = DublinCoreUtil.loadDublinCore(workspace, episodeCatalog);
// Make sure the MP catalog has bindings defined
episodeDublinCore.addBindings(XmlNamespaceContext.mk(XmlNamespaceBinding.mk(DublinCore.TERMS_NS_PREFIX, DublinCore.TERMS_NS_URI)));
episodeDublinCore.addBindings(XmlNamespaceContext.mk(XmlNamespaceBinding.mk(DublinCore.ELEMENTS_1_1_NS_PREFIX, DublinCore.ELEMENTS_1_1_NS_URI)));
episodeDublinCore.addBindings(XmlNamespaceContext.mk(XmlNamespaceBinding.mk(DublinCores.OC_PROPERTY_NS_PREFIX, DublinCores.OC_PROPERTY_NS_URI)));
episodeDublinCore.set(DublinCore.PROPERTY_IS_PART_OF, seriesId);
for (EName property : extraMetadata) {
if (!episodeDublinCore.hasValue(property) && series.hasValue(property)) {
episodeDublinCore.set(property, series.get(property));
}
}
try (InputStream in = IOUtils.toInputStream(episodeDublinCore.toXmlString(), "UTF-8")) {
String filename = FilenameUtils.getName(episodeCatalog.getURI().toString());
URI uri = workspace.put(mediaPackage.getIdentifier().toString(), episodeCatalog.getIdentifier(), filename, in);
episodeCatalog.setURI(uri);
// setting the URI to a new source so the checksum will most like be invalid
episodeCatalog.setChecksum(null);
} catch (Exception e) {
logger.error("Unable to update episode catalog isPartOf field: {}", ExceptionUtils.getStackTrace(e));
throw new WorkflowOperationException(e);
}
}
// Attach series catalogs
if (optAttachFlavors.isSome()) {
// Remove existing series catalogs
AbstractMediaPackageElementSelector<Catalog> catalogSelector = new CatalogSelector();
String[] seriesFlavors = StringUtils.split(optAttachFlavors.get(), ",");
for (String flavor : seriesFlavors) {
if ("*".equals(flavor)) {
catalogSelector.addFlavor("*/*");
} else {
catalogSelector.addFlavor(flavor);
}
}
for (Catalog c : catalogSelector.select(mediaPackage, false)) {
if (MediaPackageElements.SERIES.equals(c.getFlavor()) || "series".equals(c.getFlavor().getSubtype())) {
mediaPackage.remove(c);
}
}
List<SeriesCatalogUIAdapter> adapters = getSeriesCatalogUIAdapters();
for (String flavorString : seriesFlavors) {
MediaPackageElementFlavor flavor;
if ("*".equals(flavorString)) {
flavor = MediaPackageElementFlavor.parseFlavor("*/*");
} else {
flavor = MediaPackageElementFlavor.parseFlavor(flavorString);
}
for (SeriesCatalogUIAdapter a : adapters) {
MediaPackageElementFlavor adapterFlavor = MediaPackageElementFlavor.parseFlavor(a.getFlavor());
if (flavor.matches(adapterFlavor)) {
if (MediaPackageElements.SERIES.eq(a.getFlavor())) {
addDublinCoreCatalog(series, MediaPackageElements.SERIES, mediaPackage);
} else {
try {
Opt<byte[]> seriesElementData = seriesService.getSeriesElementData(seriesId, adapterFlavor.getType());
if (seriesElementData.isSome()) {
DublinCoreCatalog catalog = DublinCores.read(new ByteArrayInputStream(seriesElementData.get()));
addDublinCoreCatalog(catalog, adapterFlavor, mediaPackage);
} else {
logger.warn("No extended series catalog found for flavor '{}' and series '{}', skip adding catalog", adapterFlavor.getType(), seriesId);
}
} catch (SeriesException e) {
logger.error("Unable to load extended series metadata for flavor {}", adapterFlavor.getType());
throw new WorkflowOperationException(e);
}
}
}
}
}
}
if (applyAcl) {
try {
AccessControlList acl = seriesService.getSeriesAccessControl(seriesId);
if (acl != null)
authorizationService.setAcl(mediaPackage, AclScope.Series, acl);
} catch (Exception e) {
logger.error("Unable to update series ACL: {}", ExceptionUtils.getStackTrace(e));
throw new WorkflowOperationException(e);
}
}
return createResult(mediaPackage, Action.CONTINUE);
}
use of org.opencastproject.mediapackage.MediaPackageElementFlavor in project opencast by opencast.
the class CloneWorkflowOperationHandlerTest method testSingleSourceFlavor.
@Test
public void testSingleSourceFlavor() throws Exception {
// operation configuration
Map<String, String> configurations = new HashMap<String, String>();
configurations.put(CloneWorkflowOperationHandler.OPT_SOURCE_FLAVOR, "presentation/source");
configurations.put(CloneWorkflowOperationHandler.OPT_TARGET_FLAVOR, "*/target");
// run the operation handler
WorkflowOperationResult result = getWorkflowOperationResult(mp, configurations);
Assert.assertEquals(Action.CONTINUE, result.getAction());
MediaPackageElementFlavor newFlavor = MediaPackageElementFlavor.parseFlavor("presentation/target");
Assert.assertTrue(result.getMediaPackage().getElementsByFlavor(newFlavor).length == 1);
}
use of org.opencastproject.mediapackage.MediaPackageElementFlavor in project opencast by opencast.
the class CloneWorkflowOperationHandlerTest method testTagsAsSourceSelector.
@Test
public void testTagsAsSourceSelector() throws Exception {
// operation configuration
Map<String, String> configurations = new HashMap<String, String>();
configurations.put(CloneWorkflowOperationHandler.OPT_SOURCE_TAGS, "first");
configurations.put(CloneWorkflowOperationHandler.OPT_TARGET_FLAVOR, "*/target");
// run the operation handler
WorkflowOperationResult result = getWorkflowOperationResult(mp, configurations);
Assert.assertEquals(Action.CONTINUE, result.getAction());
MediaPackageElementFlavor newFlavor = MediaPackageElementFlavor.parseFlavor("*/target");
Assert.assertTrue(result.getMediaPackage().getElementsByFlavor(newFlavor).length == 1);
}
Aggregations