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