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 * André Justo 016 */ 017 018package org.nuxeo.ecm.media.publishing.wistia; 019 020import com.google.api.client.auth.oauth2.Credential; 021import com.sun.jersey.core.util.MultivaluedMapImpl; 022import org.apache.commons.logging.Log; 023import org.apache.commons.logging.LogFactory; 024import org.nuxeo.ecm.core.api.Blob; 025import org.nuxeo.ecm.core.api.NuxeoException; 026import org.nuxeo.ecm.media.publishing.wistia.model.Media; 027import org.nuxeo.ecm.media.publishing.OAuth2MediaPublishingProvider; 028import org.nuxeo.ecm.media.publishing.adapter.PublishableMedia; 029import org.nuxeo.ecm.media.publishing.upload.MediaPublishingProgressListener; 030import org.nuxeo.ecm.media.publishing.wistia.model.Project; 031import org.nuxeo.ecm.media.publishing.wistia.model.Stats; 032 033import javax.ws.rs.core.MultivaluedMap; 034import java.io.IOException; 035import java.util.Collections; 036import java.util.HashMap; 037import java.util.List; 038import java.util.Map; 039import java.util.Map.Entry; 040 041/** 042 * Wistia Media Publishing Provider Service 043 * 044 * @since 7.3 045 */ 046public class WistiaService extends OAuth2MediaPublishingProvider { 047 048 private static final Log log = LogFactory.getLog(WistiaService.class); 049 050 public static final String PROVIDER = "Wistia"; 051 052 public WistiaService() { 053 super(PROVIDER); 054 } 055 056 public WistiaClient getWistiaClient(String account) { 057 Credential credential = getCredential(account); 058 if (credential == null) { 059 return null; 060 } 061 try { 062 // Refresh access token if needed (based on com.google.api.client.auth.oauth.Credential.intercept()) 063 // TODO: rely on Google Oauth aware client instead 064 Long expiresIn = credential.getExpiresInSeconds(); 065 // check if token will expire in a minute 066 if (credential.getAccessToken() == null || expiresIn != null && expiresIn <= 60) { 067 credential.refreshToken(); 068 if (credential.getAccessToken() == null) { 069 // nothing we can do without an access token 070 throw new NuxeoException("Failed to refresh access token"); 071 } 072 } 073 } catch (IOException e) { 074 throw new NuxeoException(e.getMessage(), e); 075 } 076 077 return new WistiaClient(credential.getAccessToken()); 078 } 079 080 @Override 081 public String upload(PublishableMedia media, MediaPublishingProgressListener progressListener, String account, Map<String, String> options) throws IOException { 082 MultivaluedMap<String, String> params = new MultivaluedMapImpl(); 083 084 params.putSingle("name", media.getTitle()); 085 params.putSingle("description", media.getDescription()); 086 087 for (Entry<String, String> entry : options.entrySet()) { 088 if (entry.getValue() != null && entry.getValue().length() > 0) { 089 params.putSingle(entry.getKey(), entry.getValue()); 090 } 091 } 092 093 // upload original video 094 Blob blob = media.getBlob(); 095 096 Media video = getWistiaClient(account).upload(blob.getFilename(), blob.getStream(), params); 097 098 return video.getHashedId(); 099 } 100 101 @Override 102 public boolean unpublish(PublishableMedia media) { 103 String account = media.getAccount(PROVIDER); 104 String mediaId = media.getId(PROVIDER); 105 return getWistiaClient(account).deleteMedia(mediaId) != null; 106 } 107 108 @Override 109 public String getPublishedUrl(String mediaId, String account) { 110 WistiaClient client = getWistiaClient(account); 111 return client == null ? null : client.getAccount().getUrl() + "/medias/" + mediaId; 112 } 113 114 @Override 115 public String getEmbedCode(String mediaId, String account) { 116 WistiaClient client = getWistiaClient(account); 117 return client == null ? null : client.getEmbedCode(getPublishedUrl(mediaId, account)); 118 } 119 120 @Override 121 public Map<String, String> getStats(String mediaId, String account) { 122 WistiaClient client = getWistiaClient(account); 123 if (client == null) { 124 return null; 125 } 126 127 Stats stats = client.getMediaStats(mediaId); 128 if (stats == null) { 129 return null; 130 } 131 132 Map<String, String> map = new HashMap<>(); 133 map.put("label.mediaPublishing.stats.visitors", Integer.toString(stats.getVisitors())); 134 map.put("label.mediaPublishing.stats.plays", Integer.toString(stats.getPlays())); 135 map.put("label.mediaPublishing.stats.averagePercentWatched", Integer.toString(stats.getAveragePercentWatched())); 136 map.put("label.mediaPublishing.stats.pageLoads", Integer.toString(stats.getPageLoads())); 137 map.put("label.mediaPublishing.stats.percentOfVisitorsClickingPlay", Integer.toString(stats.getPercentOfVisitorsClickingPlay())); 138 return map; 139 } 140 141 @Override 142 public boolean isMediaPublished(String mediaId, String account) { 143 WistiaClient client = getWistiaClient(account); 144 if (client == null) { 145 return false; 146 } 147 148 Media media = client.getMedia(mediaId); 149 return media != null; 150 } 151 152 public List<Project> getProjects(String account) { 153 WistiaClient client = getWistiaClient(account); 154 return client == null ? Collections.emptyList() : client.getProjects(); 155 } 156}