package com.openfarmanager.android.filesystem.actions.multi.network; import com.dropbox.client2.ProgressListener; import com.dropbox.client2.exception.DropboxException; import com.mediafire.sdk.MFApiException; import com.mediafire.sdk.MFException; import com.mediafire.sdk.MFSessionNotStartedException; import com.mediafire.sdk.uploader.MediaFireUpload; import com.mediafire.sdk.uploader.MediaFireUploadHandler; import com.microsoft.live.EntityEnclosingApiRequest; import com.microsoft.live.OverwriteOption; import com.openfarmanager.android.App; import com.openfarmanager.android.core.network.datasource.IdPathDataSource; import com.openfarmanager.android.core.network.dropbox.DropboxAPI; import com.openfarmanager.android.core.network.ftp.FtpAPI; import com.openfarmanager.android.core.network.ftp.SftpAPI; import com.openfarmanager.android.core.network.googledrive.GoogleDriveApi; import com.openfarmanager.android.core.network.mediafire.MediaFireApi; import com.openfarmanager.android.core.network.skydrive.SkyDriveAPI; import com.openfarmanager.android.core.network.smb.SmbAPI; import com.openfarmanager.android.core.network.webdav.InputStreamRequestEntity; import com.openfarmanager.android.core.network.webdav.WebDavApi; import com.openfarmanager.android.core.network.yandexdisk.YandexDiskApi; import com.openfarmanager.android.filesystem.actions.OnActionListener; import com.openfarmanager.android.fragments.NetworkPanel; import com.openfarmanager.android.googledrive.api.GoogleDriveWebApi; import com.openfarmanager.android.model.TaskStatusEnum; import com.openfarmanager.android.model.exeptions.NetworkException; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InterruptedIOException; import java.io.OutputStream; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.Future; import jcifs.smb.SmbFile; import jcifs.smb.SmbFileOutputStream; import static com.openfarmanager.android.model.TaskStatusEnum.CANCELED; import static com.openfarmanager.android.model.TaskStatusEnum.ERROR_COPY; import static com.openfarmanager.android.model.TaskStatusEnum.ERROR_FILE_NOT_EXISTS; import static com.openfarmanager.android.model.TaskStatusEnum.createNetworkError; /** * @author Vlad Namashko */ public class CopyToNetworkMultiTask extends NetworkActionMultiTask { protected String mDestination; public CopyToNetworkMultiTask(NetworkPanel panel, List<File> items, String destination) { super(panel, items); mDestination = destination; } @Override public TaskStatusEnum doAction() { for (File file : mItems) { if (isCancelled()) { onTaskDone(CANCELED); } try { switch (mNetworkType) { case SkyDrive: copyToSkyDrive(file, mDestination); break; case GoogleDrive: copyToGoogleDrive(file, mDestination); break; case Dropbox: default: copyToDropbox(file, mDestination); break; case FTP: copyToFtp(file, mDestination); break; case SFTP: copyToSftp(file, mDestination); break; case SMB: copyToSmb(file, mDestination); break; case YandexDisk: copyToYandexDisk(file, mDestination); break; case MediaFire: copyToMediaFire(file, mDestination); break; case WebDav: copyToWebDab(file, mDestination); break; } } catch (NullPointerException e) { return ERROR_FILE_NOT_EXISTS; } catch (InterruptedIOException e) { return CANCELED; } catch (IOException e) { NetworkException ex = NetworkException.handleNetworkException(e); return ex.getErrorCause() == NetworkException.ErrorCause.Unknown_Error ? ERROR_COPY : createNetworkError(ex); } catch (IllegalArgumentException e) { return ERROR_COPY; } catch (DropboxException e) { return createNetworkError(NetworkException.handleNetworkException(e)); } catch (Exception e) { e.printStackTrace(); return ERROR_COPY; } } mCurrentFile = getProgressText(); updateProgress(); return TaskStatusEnum.OK; } @Override public TaskStatusEnum handleSubTaskException(Exception e) { if (e instanceof NullPointerException) { return ERROR_FILE_NOT_EXISTS; } else if (e instanceof InterruptedIOException) { return CANCELED; } else if (e instanceof IllegalArgumentException) { return ERROR_COPY; } else { e.printStackTrace(); NetworkException ex = NetworkException.handleNetworkException(e); return ex.getErrorCause() == NetworkException.ErrorCause.Unknown_Error ? ERROR_COPY : createNetworkError(ex); } } @Override public void onSubTaskDone(Future future) { super.onSubTaskDone(future); mCurrentFile = getProgressText(); updateProgress(); } private void copyToGoogleDrive(final File source, final String destination) throws Exception { final GoogleDriveApi api = App.sInstance.getGoogleDriveApi(); if (isCancelled()) { throw new InterruptedIOException(); } IdPathDataSource dataSource = ((IdPathDataSource) mDataSource); final String destinationId = dataSource.getDirectoryId(destination); if (source.isDirectory()) { String newDirectoryPath = destination + "/" + source.getName(); String newDirectory = api.createDirectory(destinationId, source.getName()); if (newDirectory != null) { dataSource.putDirectoryId(newDirectory, newDirectoryPath); } String[] files = source.list(); for (String file : files) { copyToGoogleDrive(new File(source, file), newDirectoryPath); } } else { runSubTaskAsynk(new Callable() { @Override public Object call() throws Exception { api.upload(destinationId, source.getName(), source, new GoogleDriveWebApi.UploadListener() { @Override public void onProgress(int uploaded, int transferedPortion, int total) { mDoneSize += transferedPortion; updateProgress(); } }); return null; } }, source); } } private void copyToDropbox(final File source, final String destination) throws DropboxException, IOException { final DropboxAPI api = App.sInstance.getDropboxApi(); if (isCancelled()) { throw new InterruptedIOException(); } if (source.isDirectory()) { String[] files = source.list(); for (String file : files) { copyToDropbox(new File(source, file), destination + "/" + source.getName()); } } else { runSubTaskAsynk(new Callable() { @Override public Object call() throws Exception { api.putFileOverwrite(destination + "/" + source.getName(), new FileInputStream(source), source.length(), new ProgressListener() { long mPrevProgress = 0; @Override public void onProgress(long l, long l2) { mDoneSize += (l - mPrevProgress); mPrevProgress = l; System.out.println(":::: >>> " + mDoneSize); updateProgress(); } }); return null; } }, source); } } private void copyToSkyDrive(final File source, final String destination) throws Exception { final SkyDriveAPI api = App.sInstance.getSkyDriveApi(); if (isCancelled()) { throw new InterruptedIOException(); } IdPathDataSource dataSource = ((IdPathDataSource) mDataSource); final String destinationId = dataSource.getDirectoryId(destination); if (source.isDirectory()) { String newDirectoryPath = destination + "/" + source.getName(); String newDirectory = api.createDirectory(destinationId, source.getName()); if (newDirectory != null) { dataSource.putDirectoryId(newDirectory, newDirectoryPath); } String[] files = source.list(); for (String file : files) { copyToSkyDrive(new File(source, file), newDirectoryPath); } } else { runSubTaskAsynk(new Callable() { @Override public Object call() throws Exception { api.getConnectClient().upload(destinationId, source.getName(), source, OverwriteOption.Overwrite, new EntityEnclosingApiRequest.UploadProgressListener() { long mPrevProgress = 0; @Override public void onProgress(long totalBytes, long numBytesWritten) { mDoneSize += (numBytesWritten - mPrevProgress); mPrevProgress = numBytesWritten; updateProgress(); } }); mDoneSize += source.length(); updateProgress(); return null; } }, source); } } private void copyToFtp(final File source, final String destination) throws Exception { final FtpAPI api = App.sInstance.getFtpApi(); if (isCancelled()) { throw new InterruptedIOException(); } if (source.isDirectory()) { api.createDirectory(destination, source.getName()); String[] files = source.list(); for (String file : files) { copyToFtp(new File(source, file), destination + "/" + source.getName()); } } else { runSubTaskAsynk(new Callable() { @Override public Object call() throws Exception { api.client().changeWorkingDirectory(destination); copyStreamRoutine(source, api.client().storeFileStream(destination + "/" + source.getName())); if (!api.client().completePendingCommand()) { throw new IOException("Can't finish copy command"); } return null; } }, source); } } private void copyToSftp(final File source, final String destination) throws Exception { final SftpAPI api = App.sInstance.getSftpApi(); if (isCancelled()) { throw new InterruptedIOException(); } api.changeDirectory(destination); if (source.isDirectory()) { api.createDirectory(destination, source.getName()); String[] files = source.list(); for (String file : files) { copyToSftp(new File(source, file), destination + "/" + source.getName()); } } else { runSubTaskAsynk(new Callable() { @Override public Object call() throws Exception { OutputStream out = api.getUploadStream(destination + "/" + source.getName()); copyStreamRoutine(source, out); return null; } }, source); } } private void copyToSmb(final File source, final String destination) throws Exception { final SmbAPI api = App.sInstance.getSmbAPI(); if (isCancelled()) { throw new InterruptedIOException(); } if (source.isDirectory()) { api.createDirectory(destination, source.getName()); String[] files = source.list(); for (String file : files) { copyToSmb(new File(source, file), destination + "/" + source.getName()); } } else { runSubTaskAsynk(new Callable() { @Override public Object call() throws Exception { SmbFile destinationFile = api.createSmbFile(destination + "/" + source.getName()); SmbFileOutputStream out = new SmbFileOutputStream(destinationFile, true); copyStreamRoutine(source, out); return null; } }, source); } } private void copyToYandexDisk(final File source, final String destination) throws Exception { final YandexDiskApi api = App.sInstance.getYandexDiskApi(); if (isCancelled()) { throw new InterruptedIOException(); } if (source.isDirectory()) { api.createDirectory(destination, source.getName()); String[] files = source.list(); for (String file : files) { copyToYandexDisk(new File(source, file), destination + "/" + source.getName()); } } else { runSubTaskAsynk(new Callable() { @Override public Object call() throws Exception { api.client().uploadFile(source.getAbsolutePath(), destination + (destination.endsWith("/") ? "" : "/"), new com.yandex.disk.client.ProgressListener() { long mPrevProgress = 0; @Override public void updateProgress(long loaded, long total) { mDoneSize += (loaded - mPrevProgress); mPrevProgress = loaded; CopyToNetworkMultiTask.this.updateProgress(); } @Override public boolean hasCancelled() { return false; } }); return null; } }, source); } } private void copyToMediaFire(final File source, final String destination) throws Exception { final MediaFireApi api = App.sInstance.getMediaFireApi(); if (isCancelled()) { throw new InterruptedIOException(); } if (source.isDirectory()) { api.createDirectory(destination, source.getName()); String[] files = source.list(); for (String file : files) { copyToMediaFire(new File(source, file), destination + "/" + source.getName()); } } else { runSubTaskAsynk(new Callable() { @Override public Object call() throws Exception { MediaFireUpload upload = new MediaFireUpload(api.getMediaFire(), 200, source, source.getName(), destination, MediaFireUpload.ActionOnInAccount.UPLOAD_ALWAYS, new MediaFireUploadHandler() { @Override public void uploadFailed(long id, MFException e) { } @Override public void uploadFailed(long id, MFApiException e) { } @Override public void uploadFailed(long id, MFSessionNotStartedException e) { } @Override public void uploadFailed(long id, IOException e) { } @Override public void uploadFailed(long id, InterruptedException e) { } @Override public void uploadProgress(long id, double percentFinished) { } @Override public void uploadFinished(long id, String quickKey, String fileName) { mDoneSize += source.length(); updateProgress(); } @Override public void uploadPolling(long id, int statusCode, String description) { updateProgress(); } }, 1); upload.run(); return null; } }, source); } } private void copyToWebDab(final File source, final String destination) throws Exception { final WebDavApi api = App.sInstance.getWebDavApi(); if (isCancelled()) { throw new InterruptedIOException(); } if (source.isDirectory()) { api.createDirectory(destination, source.getName()); String[] files = source.list(); for (String file : files) { copyToWebDab(new File(source, file), destination + "/" + source.getName()); } } else { runSubTaskAsynk(new Callable() { @Override public Object call() throws Exception { api.copyToWebDav(source, new InputStreamRequestEntity.OutputStreamListener() { long mTotalFileSize; @Override public void onProgress(long bytes) { if (mTotalFileSize < source.length()) { mDoneSize += bytes; mTotalFileSize += bytes; updateProgress(); } } }, destination + (destination.endsWith("/") ? "" : "/"), source.getName()); return null; } }, source); } } private void copyStreamRoutine(File source, OutputStream out) throws IOException { FileInputStream in = new FileInputStream(source); int len; byte[] buf = new byte[512 * 1024]; while ((len = in.read(buf)) > 0) { out.write(buf, 0, len); mDoneSize += len; updateProgress(); } out.close(); in.close(); } }