001/* 002 * (C) Copyright 2015-2016 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 * Andre Justo 018 */ 019package org.nuxeo.ecm.liveconnect.dropbox; 020 021import java.io.IOException; 022import java.io.InputStream; 023import java.net.URI; 024import java.util.Collections; 025import java.util.Locale; 026import java.util.Map; 027 028import javax.servlet.http.HttpServletRequest; 029 030import org.apache.commons.logging.Log; 031import org.apache.commons.logging.LogFactory; 032import org.nuxeo.ecm.core.api.DocumentModel; 033import org.nuxeo.ecm.core.blob.BlobManager.UsageHint; 034import org.nuxeo.ecm.core.blob.ManagedBlob; 035import org.nuxeo.ecm.core.model.Document; 036import org.nuxeo.ecm.liveconnect.core.AbstractLiveConnectBlobProvider; 037import org.nuxeo.ecm.liveconnect.core.LiveConnectFile; 038import org.nuxeo.ecm.liveconnect.core.LiveConnectFileInfo; 039import org.nuxeo.ecm.platform.oauth2.providers.OAuth2ServiceProvider; 040 041import com.dropbox.core.v2.files.FileMetadata; 042import com.dropbox.core.DbxException; 043import com.dropbox.core.DbxDownloader; 044import com.dropbox.core.v2.DbxClientV2; 045import com.dropbox.core.DbxRequestConfig; 046import com.dropbox.core.v2.files.ThumbnailFormat; 047import com.dropbox.core.v2.files.ThumbnailSize; 048 049import com.google.api.client.auth.oauth2.Credential; 050import com.google.api.client.http.GenericUrl; 051import com.google.api.client.http.HttpRequestFactory; 052import com.google.api.client.http.HttpResponse; 053 054/** 055 * Provider for blobs getting information from Dropbox. 056 * 057 * @since 7.3 058 */ 059public class DropboxBlobProvider extends AbstractLiveConnectBlobProvider<DropboxOAuth2ServiceProvider> { 060 061 private static final Log log = LogFactory.getLog(DropboxBlobProvider.class); 062 063 private static final String APPLICATION_NAME = "Nuxeo/0"; 064 065 private static final String FILE_CACHE_NAME = "dropbox"; 066 067 private static final String DROPBOX_DOCUMENT_TO_BE_UPDATED_PP = "dropbox_document_to_be_updated"; 068 069 @Override 070 protected String getCacheName() { 071 return FILE_CACHE_NAME; 072 } 073 074 @Override 075 public String getPageProviderNameForUpdate() { 076 return DROPBOX_DOCUMENT_TO_BE_UPDATED_PP; 077 } 078 079 @Override 080 public URI getURI(ManagedBlob blob, UsageHint usage, HttpServletRequest servletRequest) throws IOException { 081 LiveConnectFileInfo fileInfo = toFileInfo(blob); 082 String filePath = fileInfo.getFileId(); 083 String url = null; 084 DbxClientV2 client = getDropboxClient(getCredential(fileInfo)); 085 try { 086 switch (usage) { 087 case STREAM: 088 url = client.files().getTemporaryLink(filePath).getLink(); 089 break; 090 case DOWNLOAD: 091 url = client.files().getTemporaryLink(filePath).getLink(); 092 break; 093 case VIEW: 094 url = client.files().getTemporaryLink(filePath).getLink(); 095 break; 096 } 097 } catch (DbxException e) { 098 throw new IOException("Failed to get Dropbox file URI " + e); 099 } 100 return url == null ? null : asURI(url); 101 } 102 103 @Override 104 public Map<String, URI> getAvailableConversions(ManagedBlob blob, UsageHint hint) throws IOException { 105 return Collections.emptyMap(); 106 } 107 108 @Override 109 public InputStream getThumbnail(ManagedBlob blob) throws IOException { 110 LiveConnectFileInfo fileInfo = toFileInfo(blob); 111 String filePath = fileInfo.getFileId(); 112 try { 113 DbxDownloader downloader = getDropboxClient(getCredential(fileInfo)).files() 114 .getThumbnailBuilder(filePath) 115 .withFormat(ThumbnailFormat.JPEG) 116 .withSize(ThumbnailSize.W64H64) 117 .start(); 118 if (downloader == null) { 119 return null; 120 } 121 return downloader.getInputStream(); 122 } catch (DbxException e) { 123 log.warn(String.format("Failed to get thumbnail for file %s", filePath), e); 124 return null; 125 } 126 } 127 128 @Override 129 public InputStream getStream(ManagedBlob blob) throws IOException { 130 URI uri = getURI(blob, UsageHint.STREAM, null); 131 return uri == null ? null : doGet(uri); 132 } 133 134 @Override 135 public InputStream getConvertedStream(ManagedBlob blob, String mimeType, DocumentModel doc) throws IOException { 136 Map<String, URI> conversions = getAvailableConversions(blob, UsageHint.STREAM); 137 URI uri = conversions.get(mimeType); 138 if (uri == null) { 139 return null; 140 } 141 return doGet(uri); 142 } 143 144 @Override 145 public ManagedBlob freezeVersion(ManagedBlob blob, Document doc) throws IOException { 146 return null; 147 } 148 149 protected DbxClientV2 getDropboxClient(Credential credential) throws IOException { 150 return getDropboxClient(credential.getAccessToken()); 151 } 152 153 protected DbxClientV2 getDropboxClient(String accessToken) throws IOException { 154 DbxRequestConfig config = new DbxRequestConfig(APPLICATION_NAME, Locale.getDefault().toString()); 155 return new DbxClientV2(config, accessToken); 156 } 157 158 /** 159 * Executes a GET request 160 */ 161 protected InputStream doGet(URI url) throws IOException { 162 HttpRequestFactory requestFactory = getOAuth2Provider().getRequestFactory(); 163 HttpResponse response = requestFactory.buildGetRequest(new GenericUrl(url)).execute(); 164 return response.getContent(); 165 } 166 167 protected String getClientId() { 168 OAuth2ServiceProvider provider = getOAuth2Provider(); 169 return provider != null ? provider.getClientId() : null; 170 } 171 172 @Override 173 protected LiveConnectFile retrieveFile(LiveConnectFileInfo fileInfo) throws IOException { 174 try { 175 FileMetadata fileMetadata = getDropboxClient(getCredential(fileInfo)) 176 .files() 177 .download(fileInfo.getFileId()) 178 .getResult(); 179 180 if (fileMetadata == null) { 181 return null; 182 } 183 return new DropboxLiveConnectFile(fileInfo, fileMetadata); 184 } catch (DbxException e) { 185 throw new IOException("Failed to retrieve Dropbox file metadata", e); 186 } 187 } 188 189}