001/* 002 * (C) Copyright 2015 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 * Nelson Silva 018 */ 019 020package org.nuxeo.ecm.media.publishing; 021 022import org.apache.commons.logging.Log; 023import org.apache.commons.logging.LogFactory; 024import org.jboss.seam.ScopeType; 025import org.jboss.seam.annotations.In; 026import org.jboss.seam.annotations.Name; 027import org.jboss.seam.annotations.Scope; 028import org.jboss.seam.core.Interpolator; 029import org.jboss.seam.faces.FacesMessages; 030import org.nuxeo.ecm.core.api.CoreSession; 031import org.nuxeo.ecm.core.api.DocumentModel; 032import org.nuxeo.ecm.core.work.api.Work; 033import org.nuxeo.ecm.core.work.api.WorkManager; 034import org.nuxeo.ecm.platform.actions.Action; 035import org.nuxeo.ecm.platform.actions.ActionContext; 036import org.nuxeo.ecm.platform.ui.web.api.NavigationContext; 037import org.nuxeo.ecm.platform.ui.web.api.WebActions; 038import org.nuxeo.ecm.media.publishing.adapter.PublishableMedia; 039import org.nuxeo.ecm.media.publishing.upload.MediaPublishingUploadWork; 040import org.nuxeo.ecm.webapp.action.ActionContextProvider; 041import org.nuxeo.ecm.webapp.helpers.ResourcesAccessor; 042import org.nuxeo.runtime.api.Framework; 043 044import java.io.Serializable; 045import java.util.HashMap; 046import java.util.List; 047import java.util.Map; 048 049/** 050 * @since 7.3 051 */ 052@Name("mediaPublishing") 053@Scope(ScopeType.EVENT) 054public class MediaPublishingActions implements Serializable { 055 056 private static final long serialVersionUID = 1L; 057 058 private static final String MEDIA_PUBLISHING_OPTIONS_CATEGORY = "MEDIA_PUBLISHING_OPTIONS_CATEGORY"; 059 060 private static final Log log = LogFactory.getLog(MediaPublishingActions.class); 061 062 @In(create = true, required = false) 063 protected transient CoreSession documentManager; 064 065 @In(create = true, required = false) 066 protected transient FacesMessages facesMessages; 067 068 @In(create = true, required = false) 069 protected transient ActionContextProvider actionContextProvider; 070 071 @In(create = true, required = false) 072 protected transient WebActions webActions; 073 074 @In(create = true) 075 protected transient ResourcesAccessor resourcesAccessor; 076 077 @In(create = true) 078 protected transient NavigationContext navigationContext; 079 080 private static String selectedAccount; 081 082 private Map<String, Object> providersStats; 083 084 private Map<String, String> providersURL; 085 086 private Map<String, String> providersEmbedCode; 087 088 private Map<String, Boolean> publishedProviders; 089 090 Map<String, String> options; 091 092 private DocumentModel currentDoc; 093 094 public MediaPublishingActions() { 095 providersStats = new HashMap<>(); 096 providersEmbedCode = new HashMap<>(); 097 providersURL = new HashMap<>(); 098 options = new HashMap<>(); 099 publishedProviders = new HashMap<>(); 100 } 101 102 public String[] getAvailableServices(DocumentModel doc) { 103 return getMediaPublishingService().getAvailableProviders(doc); 104 } 105 106 public UploadStatus getUploadStatus(DocumentModel doc, String uploadServiceName) { 107 WorkManager workManager = Framework.getService(WorkManager.class); 108 109 String workId = MediaPublishingUploadWork.getIdFor(doc.getRepositoryName(), doc.getId(), uploadServiceName); 110 Work.State state = workManager.getWorkState(workId); 111 112 if (state == null) { 113 return null; 114 } else { 115 switch (state) { 116 case SCHEDULED: 117 return new UploadStatus(UploadStatus.STATUS_UPLOAD_QUEUED, new Work.Progress(0)); 118 case RUNNING: 119 return new UploadStatus(UploadStatus.STATUS_UPLOAD_PENDING, new Work.Progress(0)); 120 default: 121 return null; 122 } 123 } 124 } 125 126 public boolean isPublished(DocumentModel doc, String provider) { 127 if (!publishedProviders.containsKey(provider)) { 128 PublishableMedia media = doc.getAdapter(PublishableMedia.class); 129 boolean isPublished = media != null && media.getId(provider) != null && media.isPublishedByProvider(provider); 130 publishedProviders.put(provider, isPublished); 131 } 132 return publishedProviders.get(provider); 133 } 134 135 public String getPublishedURL(DocumentModel doc, String provider) { 136 String url = providersURL.get(provider); 137 if (url == null) { 138 PublishableMedia media = doc.getAdapter(PublishableMedia.class); 139 url = media.getUrl(provider); 140 providersURL.put(provider, url); 141 } 142 return url; 143 } 144 145 public void publish(String provider) { 146 DocumentModel doc = navigationContext.getCurrentDocument(); 147 if (selectedAccount == null || selectedAccount.length() == 0) { 148 return; 149 } 150 getMediaPublishingService().publish(doc, provider, selectedAccount, options); 151 selectedAccount = null; 152 } 153 154 public void unpublish(String provider) { 155 DocumentModel doc = navigationContext.getCurrentDocument(); 156 getMediaPublishingService().unpublish(doc, provider); 157 publishedProviders.remove(provider); 158 } 159 160 public String getEmbedCode(DocumentModel doc, String provider) { 161 String embedCode = providersEmbedCode.get(provider); 162 if (embedCode == null) { 163 PublishableMedia media = doc.getAdapter(PublishableMedia.class); 164 embedCode = media.getEmbedCode(provider); 165 providersEmbedCode.put(provider, embedCode); 166 } 167 return embedCode; 168 } 169 170 public Map<String, String> getStats(DocumentModel doc, String provider) { 171 Map<String, String> stats = (Map<String, String>) providersStats.get(provider); 172 if (stats == null) { 173 PublishableMedia media = doc.getAdapter(PublishableMedia.class); 174 stats = media.getStats(provider); 175 providersStats.put(provider, stats); 176 } 177 return stats; 178 } 179 180 private MediaPublishingService getMediaPublishingService() { 181 return Framework.getService(MediaPublishingService.class); 182 } 183 184 public String getStatusMessageFor(UploadStatus status) { 185 if (status == null) { 186 return ""; 187 } 188 String i18nMessageTemplate = resourcesAccessor.getMessages().get(status.getMessage()); 189 if (i18nMessageTemplate == null) { 190 return ""; 191 } else { 192 return Interpolator.instance().interpolate(i18nMessageTemplate, 193 status.positionInQueue, status.queueSize, status.progress.getCurrent()); 194 } 195 } 196 197 public String getSelectedAccount() { 198 return selectedAccount; 199 } 200 201 public void setSelectedAccount(String selectedAccount) { 202 this.selectedAccount = selectedAccount; 203 } 204 205 public DocumentModel getCurrentDoc() { 206 if (currentDoc == null) { 207 currentDoc = navigationContext.getCurrentDocument(); 208 currentDoc.refresh(); 209 } 210 return currentDoc; 211 } 212 213 /** 214 * Helper to retrieve Options widgets for a given Publishing provider 215 */ 216 public List<Action> getProviderOptionsWidgets(String provider) { 217 ActionContext ctx = actionContextProvider.createActionContext(); 218 ctx.putLocalVariable("provider", provider); 219 return webActions.getActionsList(MEDIA_PUBLISHING_OPTIONS_CATEGORY, ctx); 220 } 221 222 public Map<String, String> getOptions() { 223 return options; 224 } 225 226 public void setOptions(Map<String, String> options) { 227 this.options = options; 228 } 229 230 /** 231 * Data transfer object to report on the state of a video upload. 232 */ 233 public class UploadStatus { 234 public static final String STATUS_UPLOAD_QUEUED = "status.video.uploadQueued"; 235 236 public static final String STATUS_UPLOAD_PENDING = "status.video.uploadPending"; 237 238 public final String message; 239 240 public final int positionInQueue; 241 242 public final int queueSize; 243 244 public final Work.Progress progress; 245 246 public UploadStatus(String message, Work.Progress progress) { 247 this(message, progress, 0, 0); 248 } 249 250 public UploadStatus(String message, Work.Progress progress, int positionInQueue, int queueSize) { 251 this.message = message; 252 this.progress = progress; 253 this.positionInQueue = positionInQueue; 254 this.queueSize = queueSize; 255 } 256 257 public String getMessage() { 258 return message; 259 } 260 261 public Work.Progress getProgress() { 262 return progress; 263 } 264 265 public int getPositionInQueue() { 266 return positionInQueue; 267 } 268 269 public int getQueueSize() { 270 return queueSize; 271 } 272 } 273 274 public boolean canPublish(String provider) { 275 return getMediaPublishingService().getProvider(provider).isAvailable(); 276 } 277 278 public boolean isMediaAvailable(DocumentModel doc, String provider) { 279 PublishableMedia media = doc.getAdapter(PublishableMedia.class); 280 return getMediaPublishingService().getProvider(provider).isMediaAvailable(media); 281 } 282}