Search in sources :

Example 61 with MediaPackageElement

use of org.opencastproject.mediapackage.MediaPackageElement in project opencast by opencast.

the class SchedulerRestService method startCapture.

@POST
@Path("capture/{agent}")
@RestQuery(name = "startcapture", description = "Create an immediate event", returnDescription = "If events were successfully generated, status CREATED is returned", pathParameters = { @RestParameter(name = "agent", isRequired = true, type = Type.STRING, description = "The agent identifier") }, restParameters = { @RestParameter(name = "workflowDefinitionId", isRequired = false, type = Type.STRING, description = "The workflow definition id to use") }, reponses = { @RestResponse(responseCode = HttpServletResponse.SC_CREATED, description = "Recording started"), @RestResponse(responseCode = HttpServletResponse.SC_NOT_FOUND, description = "There is no such agent"), @RestResponse(responseCode = HttpServletResponse.SC_CONFLICT, description = "The agent is already recording"), @RestResponse(responseCode = HttpServletResponse.SC_UNAUTHORIZED, description = "You do not have permission to start this immediate capture. Maybe you need to authenticate."), @RestResponse(responseCode = HttpServletResponse.SC_SERVICE_UNAVAILABLE, description = "The agent is not ready to communicate") })
public Response startCapture(@PathParam("agent") String agentId, @FormParam("workflowDefinitionId") String wfId) throws NotFoundException, UnauthorizedException {
    if (service == null || agentService == null || prolongingService == null)
        return Response.serverError().status(Response.Status.SERVICE_UNAVAILABLE).entity("Scheduler service is unavailable, please wait...").build();
    // Lookup the agent. If it doesn't exist, add a temporary registration
    boolean adHocRegistration = false;
    try {
        agentService.getAgent(agentId);
    } catch (NotFoundException e) {
        Properties adHocProperties = new Properties();
        adHocProperties.put(AGENT_REGISTRATION_TYPE, AGENT_REGISTRATION_TYPE_ADHOC);
        agentService.setAgentConfiguration(agentId, adHocProperties);
        agentService.setAgentState(agentId, AgentState.CAPTURING);
        adHocRegistration = true;
        logger.info("Temporarily registered agent '{}' for ad-hoc recording", agentId);
    }
    try {
        Date now = new Date();
        Date temporaryEndDate = DateTime.now().plus(prolongingService.getInitialTime()).toDate();
        try {
            List<MediaPackage> events = service.findConflictingEvents(agentId, now, temporaryEndDate);
            if (!events.isEmpty()) {
                logger.info("An already existing event is in a conflict with the the one to be created on the agent {}!", agentId);
                return Response.status(Status.CONFLICT).build();
            }
        } catch (SchedulerException e) {
            logger.error("Unable to create immediate event on agent {}: {}", agentId, e);
            throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
        }
        String workflowId = defaultWorkflowDefinitionId;
        if (StringUtils.isNotBlank(wfId))
            workflowId = wfId;
        Map<String, String> caProperties = new HashMap<>();
        caProperties.put("org.opencastproject.workflow.definition", workflowId);
        caProperties.put("event.location", agentId);
        caProperties.put("event.title", "Capture now event");
        // caProperties.put("org.opencastproject.workflow.config.captionHold", "false");
        // caProperties.put("org.opencastproject.workflow.config.archiveOp", "true");
        // caProperties.put("org.opencastproject.workflow.config.trimHold", "false");
        // TODO default metadata? configurable?
        // A temporal with start and end period is needed! As well PROPERTY_SPATIAL is needed
        DublinCoreCatalog eventCatalog = DublinCores.mkOpencastEpisode().getCatalog();
        eventCatalog.set(PROPERTY_TITLE, "Capture now event");
        eventCatalog.set(PROPERTY_TEMPORAL, EncodingSchemeUtils.encodePeriod(new DCMIPeriod(now, temporaryEndDate), Precision.Second));
        eventCatalog.set(PROPERTY_SPATIAL, agentId);
        eventCatalog.set(PROPERTY_CREATED, EncodingSchemeUtils.encodeDate(new Date(), Precision.Minute));
        // eventCatalog.set(PROPERTY_CREATOR, "demo");
        // eventCatalog.set(PROPERTY_SUBJECT, "demo");
        // eventCatalog.set(PROPERTY_LANGUAGE, "demo");
        // eventCatalog.set(PROPERTY_CONTRIBUTOR, "demo");
        // eventCatalog.set(PROPERTY_DESCRIPTION, "demo");
        // TODO workflow properties
        Map<String, String> wfProperties = new HashMap<>();
        MediaPackage mediaPackage = null;
        try {
            mediaPackage = MediaPackageBuilderFactory.newInstance().newMediaPackageBuilder().createNew();
            mediaPackage = addCatalog(workspace, IOUtils.toInputStream(eventCatalog.toXmlString(), "UTF-8"), "dublincore.xml", MediaPackageElements.EPISODE, mediaPackage);
            prolongingService.schedule(agentId);
            service.addEvent(now, temporaryEndDate, agentId, Collections.<String>emptySet(), mediaPackage, wfProperties, caProperties, Opt.<Boolean>none(), Opt.<String>none(), SchedulerService.ORIGIN);
            return Response.status(Status.CREATED).header("Location", serverUrl + serviceUrl + '/' + mediaPackage.getIdentifier().compact() + ".xml").build();
        } catch (Exception e) {
            prolongingService.stop(agentId);
            if (e instanceof UnauthorizedException)
                throw (UnauthorizedException) e;
            logger.error("Unable to create immediate event on agent {}: {}", agentId, e);
            throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
        } finally {
            if (mediaPackage != null) {
                for (MediaPackageElement elem : $(mediaPackage.getElements()).bind(MediaPackageSupport.Filters.byFlavor(MediaPackageElements.EPISODE).toFn())) {
                    try {
                        workspace.delete(elem.getURI());
                    } catch (NotFoundException e) {
                        logger.warn("Unable to find (and hence, delete), this mediapackage '{}' element '{}'", mediaPackage.getIdentifier(), elem.getIdentifier());
                    } catch (IOException e) {
                        chuck(e);
                    }
                }
            }
        }
    } catch (Throwable t) {
        throw t;
    } finally {
        if (adHocRegistration) {
            agentService.removeAgent(agentId);
            logger.info("Removed temporary registration for agent '{}'", agentId);
        }
    }
}
Also used : SchedulerException(org.opencastproject.scheduler.api.SchedulerException) WebApplicationException(javax.ws.rs.WebApplicationException) HashMap(java.util.HashMap) DCMIPeriod(org.opencastproject.metadata.dublincore.DCMIPeriod) NotFoundException(org.opencastproject.util.NotFoundException) IOException(java.io.IOException) Properties(java.util.Properties) Date(java.util.Date) SchedulerException(org.opencastproject.scheduler.api.SchedulerException) SchedulerConflictException(org.opencastproject.scheduler.api.SchedulerConflictException) WebApplicationException(javax.ws.rs.WebApplicationException) IOException(java.io.IOException) SchedulerTransactionLockException(org.opencastproject.scheduler.api.SchedulerTransactionLockException) ParseException(java.text.ParseException) MediaPackageException(org.opencastproject.mediapackage.MediaPackageException) UnauthorizedException(org.opencastproject.security.api.UnauthorizedException) NotFoundException(org.opencastproject.util.NotFoundException) MediaPackageElement(org.opencastproject.mediapackage.MediaPackageElement) MediaPackage(org.opencastproject.mediapackage.MediaPackage) UnauthorizedException(org.opencastproject.security.api.UnauthorizedException) DublinCoreCatalog(org.opencastproject.metadata.dublincore.DublinCoreCatalog) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) RestQuery(org.opencastproject.util.doc.rest.RestQuery)

Example 62 with MediaPackageElement

use of org.opencastproject.mediapackage.MediaPackageElement in project opencast by opencast.

the class AbstractFeedGenerator method getEnclosures.

/**
 * Returns the identifier of those tracks that are to be included as enclosures in the feed. Note that for a feed type
 * of {@link Feed.Type#RSS}, the list must exactly contain one single entry.
 * <p>
 * This default implementation will include the track identified by the flavor as specified in the constructor for rss
 * feeds and every distribution track for atom feeds.
 *
 * @param feed
 *          the feed
 * @param resultItem
 *          the result item
 * @return the set of identifier
 */
protected List<MediaPackageElement> getEnclosures(Feed feed, SearchResultItem resultItem) {
    MediaPackage mediaPackage = resultItem.getMediaPackage();
    List<MediaPackageElement> candidateElements = new ArrayList<MediaPackageElement>();
    List<MediaPackageElementFlavor> flavors = new ArrayList<MediaPackageElementFlavor>();
    Set<String> tags = new HashSet<String>();
    switch(feed.getType()) {
        case Atom:
            flavors.addAll(atomTrackFlavors);
            tags.addAll(atomTags);
            break;
        default:
            flavors.addAll(rssTrackFlavors);
            tags.addAll(rssTags);
            break;
    }
    // Collect track id's by flavor
    if (flavors.size() > 0) {
        for (MediaPackageElementFlavor flavor : flavors) {
            MediaPackageElement[] elements = mediaPackage.getElementsByFlavor(flavor);
            for (MediaPackageElement element : elements) {
                if (element.containsTag(tags)) {
                    candidateElements.add(element);
                }
            }
        }
    }
    if (candidateElements.size() == 0) {
        logger.debug("No distributed media found for feed entry '{}'", resultItem.getDcTitle());
    }
    return candidateElements;
}
Also used : MediaPackageElement(org.opencastproject.mediapackage.MediaPackageElement) MediaPackage(org.opencastproject.mediapackage.MediaPackage) ArrayList(java.util.ArrayList) MediaPackageElementFlavor(org.opencastproject.mediapackage.MediaPackageElementFlavor) HashSet(java.util.HashSet)

Example 63 with MediaPackageElement

use of org.opencastproject.mediapackage.MediaPackageElement in project opencast by opencast.

the class AbstractFeedGenerator method addEpisode.

/**
 * Adds episode information to the feed.
 *
 * @param feed
 *          the feed
 * @param query
 *          the query that results in the feed
 * @param resultItem
 *          the episodes item
 * @param organization
 *          the organization
 * @return the feed
 */
protected Feed addEpisode(Feed feed, String[] query, SearchResultItem resultItem, Organization organization) {
    String link = getLinkForEntry(feed, resultItem, organization);
    String title = resultItem.getDcTitle();
    // Get the media enclosures
    List<MediaPackageElement> enclosures = getEnclosures(feed, resultItem);
    if (enclosures.size() == 0) {
        logger.debug("No media formats found for feed entry: {}", title);
        return feed;
    }
    String entryUri = null;
    // For RSS feeds, create multiple entries (one per enclosure). For Atom, add all enclosures to the same item
    switch(feed.getType()) {
        case RSS:
            entryUri = resultItem.getId();
            for (MediaPackageElement e : enclosures) {
                List<MediaPackageElement> enclosure = new ArrayList<MediaPackageElement>(1);
                enclosure.add(e);
                FeedEntry entry = createEntry(feed, title, link, entryUri);
                entry = populateFeedEntry(entry, resultItem, enclosure);
                entry.setUri(entry.getUri() + "/" + e.getIdentifier());
                feed.addEntry(entry);
            }
            break;
        case Atom:
            entryUri = generateEntryUri(resultItem.getId());
            FeedEntry entry = createEntry(feed, title, link, entryUri);
            entry = populateFeedEntry(entry, resultItem, enclosures);
            if (getLinkSelf(organization) != null) {
                LinkImpl self = new LinkImpl(getSelfLinkForEntry(feed, resultItem, organization));
                self.setRel("self");
                entry.addLink(self);
            }
            feed.addEntry(entry);
            if (feed.getUpdatedDate() == null)
                feed.setUpdatedDate(entry.getUpdatedDate());
            else if (entry.getUpdatedDate().before(feed.getUpdatedDate()))
                feed.setUpdatedDate(entry.getUpdatedDate());
            break;
        default:
            throw new IllegalStateException("Unsupported feed type " + feed.getType());
    }
    return feed;
}
Also used : FeedEntry(org.opencastproject.feed.api.FeedEntry) MediaPackageElement(org.opencastproject.mediapackage.MediaPackageElement) ArrayList(java.util.ArrayList)

Example 64 with MediaPackageElement

use of org.opencastproject.mediapackage.MediaPackageElement in project opencast by opencast.

the class AbstractFeedGenerator method populateFeedEntry.

/**
 * Populates the feed entry with metadata and the enclosures.
 *
 * @param entry
 *          the entry to enrich
 * @param metadata
 *          the metadata
 * @param enclosures
 *          the media enclosures
 * @return the enriched item
 */
private FeedEntry populateFeedEntry(FeedEntry entry, SearchResultItem metadata, List<MediaPackageElement> enclosures) {
    Date d = metadata.getDcCreated();
    Date updatedDate = metadata.getModified();
    String title = metadata.getDcTitle();
    // Configure the iTunes extension
    ITunesFeedEntryExtension iTunesEntry = new ITunesFeedEntryExtension();
    iTunesEntry.setDuration(metadata.getDcExtent());
    iTunesEntry.setBlocked(false);
    iTunesEntry.setExplicit(false);
    if (StringUtils.isNotBlank(metadata.getDcCreator()))
        iTunesEntry.setAuthor(metadata.getDcCreator());
    // TODO: Add iTunes keywords and subtitles
    // iTunesEntry.setKeywords(keywords);
    // iTunesEntry.setSubtitle(subtitle);
    // Configure the DC extension
    DublinCoreExtension dcExtension = new DublinCoreExtension();
    dcExtension.setTitle(title);
    dcExtension.setIdentifier(metadata.getId());
    // Set contributor
    if (!StringUtils.isEmpty(metadata.getDcContributor())) {
        for (String contributor : metadata.getDcContributor().split(";;")) {
            entry.addContributor(new PersonImpl(contributor));
            dcExtension.addContributor(contributor);
        }
    }
    // Set creator
    if (!StringUtils.isEmpty(metadata.getDcCreator())) {
        for (String creator : metadata.getDcCreator().split(";;")) {
            if (iTunesEntry.getAuthor() == null)
                iTunesEntry.setAuthor(creator);
            entry.addAuthor(new PersonImpl(creator));
            dcExtension.addCreator(creator);
        }
    }
    // Set publisher
    if (!StringUtils.isEmpty(metadata.getDcPublisher())) {
        dcExtension.addPublisher(metadata.getDcPublisher());
    }
    // Set rights
    if (!StringUtils.isEmpty(metadata.getDcAccessRights())) {
        dcExtension.setRights(metadata.getDcAccessRights());
    }
    // Set description
    if (!StringUtils.isEmpty(metadata.getDcDescription())) {
        String summary = metadata.getDcDescription();
        entry.setDescription(new ContentImpl(summary));
        iTunesEntry.setSummary(summary);
        dcExtension.setDescription(summary);
    }
    // Set the language
    if (!StringUtils.isEmpty(metadata.getDcLanguage())) {
        dcExtension.setLanguage(metadata.getDcLanguage());
    }
    // Set the publication date
    if (d != null) {
        entry.setPublishedDate(d);
        dcExtension.setDate(d);
    } else if (metadata.getModified() != null) {
        entry.setPublishedDate(metadata.getModified());
        dcExtension.setDate(metadata.getModified());
    }
    // Set the updated date
    if (updatedDate == null)
        updatedDate = d;
    entry.setUpdatedDate(updatedDate);
    // TODO: Finish dc support
    // Set format
    // if (!StringUtils.isEmpty(resultItem.getMediaType())) {
    // dcExtension.setFormat(resultItem.getMediaType());
    // }
    // dcEntry.setCoverage(arg0);
    // dcEntry.setRelation(arg0);
    // dcEntry.setSource(arg0);
    // dcEntry.setSubject(arg0);
    // Set the cover image
    String coverUrl = null;
    if (!StringUtils.isEmpty(metadata.getCover())) {
        coverUrl = metadata.getCover();
        setImage(entry, coverUrl);
    }
    entry.addExtension(iTunesEntry);
    entry.addExtension(dcExtension);
    // Add the enclosures
    for (MediaPackageElement element : enclosures) {
        String trackMimeType = element.getMimeType().toString();
        long trackLength = element.getSize();
        if (trackLength <= 0 && element instanceof Track) {
            // filesize unset so estimate from duration and bitrate
            trackLength = 0;
            if (((TrackImpl) element).hasVideo()) {
                List<VideoStream> video = ((TrackImpl) element).getVideo();
                if (video.get(0).getBitRate() != null) {
                    trackLength += metadata.getDcExtent() / 1000 * video.get(0).getBitRate() / 8;
                }
            }
            if (((TrackImpl) element).hasAudio()) {
                List<AudioStream> audio = ((TrackImpl) element).getAudio();
                if (audio.get(0).getBitRate() != null) {
                    trackLength += metadata.getDcExtent() / 1000 * audio.get(0).getBitRate() / 8;
                }
            }
        }
        // order of magnitude correct
        if (trackLength <= 0) {
            trackLength = metadata.getDcExtent();
        }
        String trackFlavor = element.getFlavor().toString();
        String trackUrl = null;
        try {
            trackUrl = element.getURI().toURL().toExternalForm();
        } catch (MalformedURLException e) {
        // Can't happen
        }
        Enclosure enclosure = new EnclosureImpl(trackUrl, trackMimeType, trackFlavor, trackLength);
        entry.addEnclosure(enclosure);
    }
    return entry;
}
Also used : MalformedURLException(java.net.MalformedURLException) TrackImpl(org.opencastproject.mediapackage.track.TrackImpl) VideoStream(org.opencastproject.mediapackage.VideoStream) Enclosure(org.opencastproject.feed.api.Enclosure) Date(java.util.Date) AudioStream(org.opencastproject.mediapackage.AudioStream) MediaPackageElement(org.opencastproject.mediapackage.MediaPackageElement) Track(org.opencastproject.mediapackage.Track)

Example 65 with MediaPackageElement

use of org.opencastproject.mediapackage.MediaPackageElement in project opencast by opencast.

the class OaiPmhPublicationServiceImpl method retract.

protected Publication retract(Job job, MediaPackage mediaPackage, String repository) throws PublicationException, NotFoundException {
    String mpId = mediaPackage.getIdentifier().compact();
    // track elements for retraction
    MediaPackage oaiPmhMp = null;
    SearchResult searchResult = oaiPmhDatabase.search(QueryBuilder.queryRepo(repository).mediaPackageId(mpId).isDeleted(false).build());
    for (SearchResultItem searchResultItem : searchResult.getItems()) {
        if (oaiPmhMp == null) {
            oaiPmhMp = searchResultItem.getMediaPackage();
        } else {
            for (MediaPackageElement mpe : searchResultItem.getMediaPackage().getElements()) {
                oaiPmhMp.add(mpe);
            }
        }
    }
    // retract oai-pmh
    try {
        oaiPmhDatabase.delete(mpId, repository);
    } catch (OaiPmhDatabaseException e) {
        throw new PublicationException(format("Unable to retract media package %s from OAI-PMH repository %s", mpId, repository), e);
    }
    if (oaiPmhMp != null && oaiPmhMp.getElements().length > 0) {
        // retract files from distribution channels
        Set<String> mpeIds = new HashSet<>();
        for (MediaPackageElement mpe : oaiPmhMp.elements()) {
            if (MediaPackageElement.Type.Publication == mpe.getElementType())
                continue;
            mpeIds.add(mpe.getIdentifier());
        }
        if (!mpeIds.isEmpty()) {
            List<Job> retractionJobs = new ArrayList<>();
            // retract download
            try {
                Job retractDownloadJob = downloadDistributionService.retract(getPublicationChannelName(repository), oaiPmhMp, mpeIds);
                if (retractDownloadJob != null) {
                    retractionJobs.add(retractDownloadJob);
                }
            } catch (DistributionException e) {
                throw new PublicationException(format("Unable to create retraction job from distribution channel download for the media package %s ", mpId), e);
            }
            // retract streaming
            try {
                Job retractDownloadJob = streamingDistributionService.retract(getPublicationChannelName(repository), oaiPmhMp, mpeIds);
                if (retractDownloadJob != null) {
                    retractionJobs.add(retractDownloadJob);
                }
            } catch (DistributionException e) {
                throw new PublicationException(format("Unable to create retraction job from distribution channel streaming for the media package %s ", mpId), e);
            }
            if (retractionJobs.size() > 0) {
                // wait for distribution jobs
                if (!waitForJobs(job, serviceRegistry, retractionJobs).isSuccess())
                    throw new PublicationException(format("Unable to retract elements of media package %s from distribution channels.", mpId));
            }
        }
    }
    String publicationChannel = getPublicationChannelName(repository);
    for (Publication p : mediaPackage.getPublications()) {
        if (StringUtils.equals(publicationChannel, p.getChannel()))
            return p;
    }
    return null;
}
Also used : OaiPmhDatabaseException(org.opencastproject.oaipmh.persistence.OaiPmhDatabaseException) PublicationException(org.opencastproject.publication.api.PublicationException) SearchResultItem(org.opencastproject.oaipmh.persistence.SearchResultItem) ArrayList(java.util.ArrayList) Publication(org.opencastproject.mediapackage.Publication) SearchResult(org.opencastproject.oaipmh.persistence.SearchResult) MediaPackageElement(org.opencastproject.mediapackage.MediaPackageElement) MediaPackage(org.opencastproject.mediapackage.MediaPackage) DistributionException(org.opencastproject.distribution.api.DistributionException) Job(org.opencastproject.job.api.Job) HashSet(java.util.HashSet)

Aggregations

MediaPackageElement (org.opencastproject.mediapackage.MediaPackageElement)153 MediaPackage (org.opencastproject.mediapackage.MediaPackage)72 NotFoundException (org.opencastproject.util.NotFoundException)50 Job (org.opencastproject.job.api.Job)49 URI (java.net.URI)48 IOException (java.io.IOException)39 ArrayList (java.util.ArrayList)39 MediaPackageException (org.opencastproject.mediapackage.MediaPackageException)39 Test (org.junit.Test)36 WorkflowOperationException (org.opencastproject.workflow.api.WorkflowOperationException)27 MediaPackageElementFlavor (org.opencastproject.mediapackage.MediaPackageElementFlavor)25 ServiceRegistryException (org.opencastproject.serviceregistry.api.ServiceRegistryException)24 File (java.io.File)21 Track (org.opencastproject.mediapackage.Track)21 DistributionException (org.opencastproject.distribution.api.DistributionException)20 InputStream (java.io.InputStream)19 WorkflowOperationInstance (org.opencastproject.workflow.api.WorkflowOperationInstance)19 HashSet (java.util.HashSet)18 URISyntaxException (java.net.URISyntaxException)16 Path (javax.ws.rs.Path)16