001/*
002 * (C) Copyright 2018 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     BenoƮt Delbosc <bdelbosc@nuxeo.com>
018 *     Antoine Taillefer <ataillefer@nuxeo.com>
019 */
020package org.nuxeo.ecm.platform.video.service;
021
022import static org.nuxeo.ecm.core.api.CoreSession.ALLOW_VERSION_WRITE;
023
024import java.io.IOException;
025import java.io.Serializable;
026import java.util.List;
027import java.util.Map;
028
029import org.apache.commons.logging.Log;
030import org.apache.commons.logging.LogFactory;
031import org.nuxeo.ecm.core.api.Blob;
032import org.nuxeo.ecm.core.api.DocumentModel;
033import org.nuxeo.ecm.core.api.IdRef;
034import org.nuxeo.ecm.core.api.blobholder.BlobHolder;
035import org.nuxeo.ecm.core.work.AbstractWork;
036import org.nuxeo.ecm.platform.video.VideoConstants;
037import org.nuxeo.ecm.platform.video.VideoHelper;
038
039/**
040 * Work to process the storyboard of a Video document.
041 *
042 * @since 10.1
043 */
044public class VideoStoryboardWork extends AbstractWork {
045
046    private static final long serialVersionUID = 1L;
047
048    private static final Log log = LogFactory.getLog(VideoStoryboardWork.class);
049
050    public static final String CATEGORY_VIDEO_STORYBOARD = "videoStoryboard";
051
052    protected static String computeIdPrefix(String repositoryName, String docId) {
053        return repositoryName + ':' + docId + ":videostoryboard:";
054    }
055
056    public VideoStoryboardWork(String repositoryName, String docId) {
057        super(computeIdPrefix(repositoryName, docId));
058        setDocument(repositoryName, docId);
059    }
060
061    @Override
062    public boolean isIdempotent() {
063        return false;
064    }
065
066    @Override
067    public String getCategory() {
068        return CATEGORY_VIDEO_STORYBOARD;
069    }
070
071    @Override
072    public String getTitle() {
073        return "Video Storyboard: " + getId();
074    }
075
076    @Override
077    public void work() {
078        setProgress(Progress.PROGRESS_INDETERMINATE);
079        openSystemSession();
080
081        // get video blob
082        DocumentModel doc = session.getDocument(new IdRef(docId));
083        BlobHolder blobHolder = doc.getAdapter(BlobHolder.class);
084        Blob video = blobHolder.getBlob();
085
086        // update storyboard
087        setStatus("Updating storyboard");
088        boolean save = updateStoryboard(doc, video);
089
090        // update previews
091        setStatus("Updating previews");
092        save |= updatePreviews(doc, video);
093
094        if (save) {
095            // save document
096            if (doc.isVersion()) {
097                doc.putContextData(ALLOW_VERSION_WRITE, Boolean.TRUE);
098            }
099            session.saveDocument(doc);
100        }
101
102        setStatus("Done");
103    }
104
105    protected boolean updateStoryboard(DocumentModel doc, Blob blob) {
106        var storyboard = (List<Map<String, Serializable>>) doc.getPropertyValue(VideoConstants.STORYBOARD_PROPERTY);
107        if (storyboard != null && !storyboard.isEmpty()) {
108            return false;
109        }
110
111        log.debug(String.format("Updating storyboard of Video document %s.", doc));
112        VideoHelper.updateStoryboard(doc, blob);
113        log.debug(String.format("End updating storyboard of Video document %s.", doc));
114        return true;
115    }
116
117    protected boolean updatePreviews(DocumentModel doc, Blob blob) {
118        var previews = (List<Map<String, Serializable>>) doc.getPropertyValue("picture:views");
119        if (previews != null && !previews.isEmpty()) {
120            return false;
121        }
122
123        log.debug(String.format("Updating previews of Video document %s.", doc));
124        try {
125            VideoHelper.updatePreviews(doc, blob);
126            log.debug(String.format("End updating previews of Video document %s.", doc));
127            return true;
128        } catch (IOException e) {
129            // this should only happen if the hard drive is full
130            log.debug(String.format("Failed to extract previews of Video document %s.", doc), e);
131            return false;
132        }
133    }
134
135}