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