package com.openfarmanager.android.core.network.googledrive; import android.database.Cursor; import com.openfarmanager.android.App; import com.openfarmanager.android.R; import com.openfarmanager.android.core.DataStorageHelper; import com.openfarmanager.android.core.dbadapters.NetworkAccountDbAdapter; import com.openfarmanager.android.core.network.NetworkApi; import com.openfarmanager.android.filesystem.FileProxy; import com.openfarmanager.android.filesystem.FileSystemScanner; import com.openfarmanager.android.filesystem.GoogleDriveFile; import com.openfarmanager.android.googledrive.api.GoogleDriveWebApi; import com.openfarmanager.android.googledrive.model.About; import com.openfarmanager.android.googledrive.model.File; import com.openfarmanager.android.googledrive.model.Token; import com.openfarmanager.android.model.NetworkAccount; import com.openfarmanager.android.model.NetworkEnum; import org.json.JSONException; import org.json.JSONObject; import java.io.BufferedInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; /** * author: Vlad Namashko */ public class GoogleDriveApi implements NetworkApi { private static String ACCESS_TOKEN = "access_token"; private static String REFRESH_TOKEN = "refresh_token"; private static String PERMISSION_ID = "permission_id"; private GoogleDriveWebApi mDriveApi; private GoogleDriveAccount mCurrentAccount; private final static byte[] BUFFER = new byte[512 * 1024]; public GoogleDriveApi() { mDriveApi = new GoogleDriveWebApi(); } public NetworkAccount saveAccount(About about, Token token) { JSONObject authData = new JSONObject(); try { authData.put(ACCESS_TOKEN, token.getAccessToken()); authData.put(REFRESH_TOKEN, token.getRefreshToken()); authData.put(PERMISSION_ID, about.getPermissionId()); long id = NetworkAccountDbAdapter.insert(about.getDisplayName(), NetworkEnum.GoogleDrive.ordinal(), authData.toString()); Cursor cursor = NetworkAccountDbAdapter.getAccountById(id); if (cursor != null) { int idxId = cursor.getColumnIndex(NetworkAccountDbAdapter.Columns.ID); int idxUserName = cursor.getColumnIndex(NetworkAccountDbAdapter.Columns.USER_NAME); int idxAuthData = cursor.getColumnIndex(NetworkAccountDbAdapter.Columns.AUTH_DATA); cursor.moveToNext(); String authDataString = cursor.getString(idxAuthData); JSONObject data = new JSONObject(authDataString); return new GoogleDriveAccount(cursor.getLong(idxId), cursor.getString(idxUserName), Token.fromLocalData(data.getString(ACCESS_TOKEN), data.getString(REFRESH_TOKEN)), data.getString(PERMISSION_ID)); } } catch (JSONException e) { e.printStackTrace(); } return null; } @Override public int getAuthorizedAccountsCount() { return NetworkAccountDbAdapter.count(NetworkEnum.GoogleDrive.ordinal()); } @Override public List<NetworkAccount> getAuthorizedAccounts() { List<NetworkAccount> accounts = new ArrayList<NetworkAccount>(); Cursor cursor = NetworkAccountDbAdapter.getAccounts(NetworkEnum.GoogleDrive.ordinal()); if (cursor == null) { return accounts; } try { int idxId = cursor.getColumnIndex(NetworkAccountDbAdapter.Columns.ID); int idxUserName = cursor.getColumnIndex(NetworkAccountDbAdapter.Columns.USER_NAME); int idxAuthData = cursor.getColumnIndex(NetworkAccountDbAdapter.Columns.AUTH_DATA); while(cursor.moveToNext()) { String authData = cursor.getString(idxAuthData); try { JSONObject data = new JSONObject(authData); GoogleDriveAccount account = new GoogleDriveAccount(cursor.getLong(idxId), cursor.getString(idxUserName), Token.fromLocalData(data.getString(ACCESS_TOKEN), data.getString(REFRESH_TOKEN)), data.getString(PERMISSION_ID)); accounts.add(account); } catch (JSONException e) { e.printStackTrace(); } } } finally { cursor.close(); DataStorageHelper.closeDatabase(); } return accounts; } public void setup(GoogleDriveAccount account) { mCurrentAccount = account; mDriveApi.setupToken(account.getToken()); } public void upload(String parentId, String title, java.io.File file, GoogleDriveWebApi.UploadListener listener) { mDriveApi.upload(parentId, title, file, listener); } public void download(FileProxy source, OutputStream outputStream) throws IOException { download(source, outputStream, BUFFER); } public void updateData(String fileId, String data) { mDriveApi.updateData(fileId, data); } public void download(FileProxy source, OutputStream outputStream, byte[] buffer) throws IOException { BufferedInputStream inputStream = new BufferedInputStream( mDriveApi.download(((GoogleDriveFile) source).getDownloadLink())); int len; while ((len = inputStream.read(buffer)) > 0) { outputStream.write(buffer, 0, len); } inputStream.close(); outputStream.close(); } public void download(String downloadLink, String destination) throws IOException { BufferedInputStream inputStream = new BufferedInputStream(mDriveApi.download(downloadLink)); int len; OutputStream outputStream = new FileOutputStream(destination); while ((len = inputStream.read(BUFFER)) > 0) { outputStream.write(BUFFER, 0, len); } inputStream.close(); outputStream.close(); } public String getDownloadLink(FileProxy file) { return mDriveApi.getDownloadLink(((GoogleDriveFile) file).getDownloadLink()); } public List<FileProxy> getDirectoryFiles(String path) { return getDirectoryFiles(path, null); } public List<FileProxy> getDirectoryFiles(String path, String parentPath) { List<FileProxy> list = new ArrayList<FileProxy>(); try { List<File> files = mDriveApi.listFiles(path); for (File file : files) { list.add(new GoogleDriveFile(file, parentPath != null ? parentPath : path)); } if (isRootDirectory(parentPath)) { list.add(new GoogleDriveFile(File.createSharedFolder(), "/")); list.add(new GoogleDriveFile(File.createStarredFolder(), "/")); } FileSystemScanner.sInstance.sort(list); } catch (Exception e) { e.printStackTrace(); } return list; } private boolean isRootDirectory(String parentPath) { return parentPath != null && (parentPath.equals("/") || parentPath.equals("")); } public FileProxy getFileInfo(String id) { try { return new GoogleDriveFile(mDriveApi.getFile(id), ""); } catch (Exception e) { return null; } } @Override public NetworkAccount newAccount() { return new GoogleDriveAccount(-1, App.sInstance.getResources().getString(R.string.btn_new), null, null); } @Override public NetworkAccount getCurrentNetworkAccount() { return mCurrentAccount; } @Override public void delete(FileProxy file) throws Exception { if (!mDriveApi.delete(file.getFullPath())) { throw new RuntimeException("Can't delete selected file"); } } @Override public String createDirectory(String baseDirectory, String newDirectoryName) throws Exception { try { File createdFolder = mDriveApi.createDirectory(newDirectoryName, baseDirectory); if (createdFolder != null) { return createdFolder.getId(); } } catch (Exception ignore) { } return null; } @Override public List<FileProxy> search(String path, String query) { List<FileProxy> list = new ArrayList<FileProxy>(); try { List<File> files = mDriveApi.search(query); for (File file : files) { list.add(new GoogleDriveFile(file, path)); } FileSystemScanner.sInstance.sort(list); } catch (Exception e) { e.printStackTrace(); } return list; } @Override public boolean rename(FileProxy srcFile, String name) throws Exception { return mDriveApi.rename(srcFile.getFullPath(), name.substring(name.lastIndexOf("/") + 1, name.length())); } public static class GoogleDriveAccount extends NetworkAccount { private Token mToken; private String mPermissionId; public GoogleDriveAccount(long id, String userName, JSONObject data) throws JSONException { this(id, userName, Token.fromLocalData(data.getString(ACCESS_TOKEN), data.getString(REFRESH_TOKEN)), data.getString(PERMISSION_ID)); } public GoogleDriveAccount(long id, String userName, Token token, String permissionId) { mId = id; mUserName = userName; mToken = token; mPermissionId = permissionId; } public Token getToken() { return mToken; } public String getPermissionId() { return mPermissionId; } @Override public NetworkEnum getNetworkType() { return NetworkEnum.GoogleDrive; } } }