package com.openfarmanager.android.core.network.yandexdisk; import android.database.Cursor; import android.util.Base64; 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.YandexDiskFile; import com.openfarmanager.android.model.NetworkAccount; import com.openfarmanager.android.model.NetworkEnum; import com.openfarmanager.android.model.exeptions.InAppAuthException; import com.openfarmanager.android.model.exeptions.InitYandexDiskException; import com.openfarmanager.android.model.exeptions.NetworkException; import com.yandex.disk.client.Credentials; import com.yandex.disk.client.ListItem; import com.yandex.disk.client.ListParsingHandler; import com.yandex.disk.client.TransportClient; import com.yandex.disk.client.exceptions.UnknownServerWebdavException; import com.yandex.disk.client.exceptions.WebdavClientInitException; import com.yandex.disk.client.exceptions.WebdavException; import com.yandex.disk.client.exceptions.WebdavNotAuthorizedException; import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; import java.util.ArrayList; import java.util.List; /** * @author Vlad Namashko */ public class YandexDiskApi implements NetworkApi { public static final String CLIENT_ID = "f16fa6cd94954c2ca68ccb7ca626f29b"; public static final String CLIENT_SECRET = " c2b0f694984248178f3ab50cc020889e"; private static String YANDEX_TOKEN = "yandex_disk_token"; private static String YANDEX_AUTH_NAME = "yandex_auth_name"; private static String YANDEX_AUTH_PASSWORD = "yandex_auth_password"; public static final String ACCOUNT_TYPE = "com.yandex"; public static final String AUTH_URL = "https://oauth.yandex.ru/authorize?response_type=token&client_id=" + CLIENT_ID; private static final String ACTION_ADD_ACCOUNT = "com.yandex.intent.ADD_ACCOUNT"; private static final String KEY_CLIENT_SECRET = "clientSecret"; private NetworkAccount mCurrentAccount; private TransportClient mTransportClient; public NetworkAccount saveAccount(Credentials credentials) { JSONObject authData = new JSONObject(); try { authData.put(YANDEX_AUTH_NAME, credentials.getName()); authData.put(YANDEX_AUTH_PASSWORD, credentials.getPassword()); long id = NetworkAccountDbAdapter.insert(credentials.getUser(), NetworkEnum.YandexDisk.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 YandexDiskAccount(cursor.getLong(idxId), cursor.getString(idxUserName), data.getString(YANDEX_AUTH_NAME), data.getString(YANDEX_AUTH_PASSWORD)); } } catch (JSONException e) { e.printStackTrace(); } return null; } public void setupToken(NetworkAccount networkAccount) throws InitYandexDiskException{ mCurrentAccount = networkAccount; try { YandexDiskAccount account = (YandexDiskAccount) networkAccount; mTransportClient = TransportClient.getInstance(App.sInstance.getApplicationContext(), new Credentials(networkAccount.getUserName(), account.getToken(), account.getUser(), account.getPassword())); } catch (WebdavClientInitException e) { e.printStackTrace(); throw new InitYandexDiskException(); } } public List<FileProxy> getDirectoryFiles(String path) throws NetworkException { List<FileProxy> files = new ArrayList<FileProxy>(); final List<ListItem> fileItemList = new ArrayList<ListItem>(); try { mTransportClient.getList(path, new ListParsingHandler() { // First item in PROPFIND is the current collection name boolean ignoreFirstItem = true; @Override public boolean hasCancelled() { return false; } @Override public void onPageFinished(int itemsOnPage) { } @Override public boolean handleItem(ListItem item) { if (ignoreFirstItem) { ignoreFirstItem = false; return false; } else { fileItemList.add(item); return true; } } }); } catch (Exception ex) { ex.printStackTrace(); throw NetworkException.handleNetworkException(ex); } for (ListItem item : fileItemList) { files.add(new YandexDiskFile(item)); } return files; } public TransportClient client() { return mTransportClient; } @Override public int getAuthorizedAccountsCount() { return NetworkAccountDbAdapter.count(NetworkEnum.YandexDisk.ordinal()); } @Override public List<NetworkAccount> getAuthorizedAccounts() { List<NetworkAccount> accounts = new ArrayList<NetworkAccount>(); Cursor cursor = NetworkAccountDbAdapter.getAccounts(NetworkEnum.YandexDisk.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); YandexDiskAccount account; if (data.has(YANDEX_TOKEN)) { account = new YandexDiskAccount(cursor.getLong(idxId), cursor.getString(idxUserName), data.getString(YANDEX_TOKEN)); } else { account = new YandexDiskAccount(cursor.getLong(idxId), cursor.getString(idxUserName), data.getString(YANDEX_AUTH_NAME), data.getString(YANDEX_AUTH_PASSWORD)); } accounts.add(account); } catch (JSONException e) { e.printStackTrace(); } } } finally { cursor.close(); DataStorageHelper.closeDatabase(); } return accounts; } @Override public NetworkAccount newAccount() { return new YandexDiskAccount(-1, App.sInstance.getResources().getString(R.string.btn_new), (String) null); } @Override public NetworkAccount getCurrentNetworkAccount() { return mCurrentAccount; } @Override public void delete(FileProxy file) throws Exception { try { mTransportClient.delete(file.getFullPath()); } catch (UnknownServerWebdavException e) { if (e.statusCode >= 200 && e.statusCode <= 300) { // ignore } } catch (Exception e) { throw new RuntimeException(e.getMessage()); } } @Override public String createDirectory(String baseDirectory, String newDirectoryName) throws Exception { String path = baseDirectory + "/" + newDirectoryName; mTransportClient.makeFolder(path); return path; } @Override public List<FileProxy> search(String path, String query) { return null; } @Override public boolean rename(FileProxy srcFile, String s) throws Exception { mTransportClient.move(srcFile.getFullPath(), s); return true; } public void connectAndSave(String userName, String password, String saveAs) throws InAppAuthException { try { mTransportClient = TransportClient.getInstance(App.sInstance.getApplicationContext(), new Credentials(saveAs, null, userName, password)); mTransportClient.getList("/", new ListParsingHandler() { @Override public boolean handleItem(ListItem item) { return false; } }); mCurrentAccount = saveAccount(new Credentials(saveAs, null, userName, password)); } catch (Exception e) { throw new InitYandexDiskException(); } } public static class YandexDiskAccount extends NetworkAccount { private String mToken; private String mUser; private String mPassword; public YandexDiskAccount(long id, String userName, JSONObject data) throws JSONException { if (data.has(YANDEX_TOKEN)) { mId = id; mUserName = userName; mToken = data.getString(YANDEX_TOKEN); } else { mId = id; mUserName = userName; mUser = data.getString(YANDEX_AUTH_NAME); mPassword = data.getString(YANDEX_AUTH_PASSWORD); } } public YandexDiskAccount(long id, String userName, String token) { mId = id; mUserName = userName; mToken = token; } public YandexDiskAccount(long id, String userName, String user, String password) { mId = id; mUserName = userName; mUser = user; mPassword = password; } public String getToken() { return mToken; } public String getUser() { return mUser; } public String getPassword() { return mPassword; } @Override public NetworkEnum getNetworkType() { return NetworkEnum.YandexDisk; } } }