From: David A. Velasco Date: Tue, 27 Nov 2012 13:28:19 +0000 (+0100) Subject: New policy: uploaded files are copied to the local storage ownCloud directory bu... X-Git-Tag: oc-android-1.4.3~80^2~14 X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/commitdiff_plain/fd9086a8833c8ec7df08f6b3d5a3ce8b4c26864e?ds=inline;hp=-c New policy: uploaded files are copied to the local storage ownCloud directory bu default --- fd9086a8833c8ec7df08f6b3d5a3ce8b4c26864e diff --git a/src/com/owncloud/android/files/services/FileUploader.java b/src/com/owncloud/android/files/services/FileUploader.java index 958036a7..9f3f1c42 100644 --- a/src/com/owncloud/android/files/services/FileUploader.java +++ b/src/com/owncloud/android/files/services/FileUploader.java @@ -38,7 +38,6 @@ import com.owncloud.android.operations.RemoteOperationResult; import com.owncloud.android.operations.UploadFileOperation; import com.owncloud.android.ui.activity.FileDetailActivity; import com.owncloud.android.ui.fragment.FileDetailFragment; -import com.owncloud.android.utils.FileStorageUtils; import com.owncloud.android.utils.OwnCloudVersion; import eu.alefzero.webdav.OnDatatransferProgressListener; @@ -238,9 +237,9 @@ public class FileUploader extends Service implements OnDatatransferProgressListe for (int i=0; i < files.length; i++) { uploadKey = buildRemoteName(account, files[i].getRemotePath()); if (chunked) { - newUpload = new ChunkedUploadFileOperation(account, files[i], isInstant, forceOverwrite); + newUpload = new ChunkedUploadFileOperation(account, files[i], isInstant, forceOverwrite, false); } else { - newUpload = new UploadFileOperation(account, files[i], isInstant, forceOverwrite); + newUpload = new UploadFileOperation(account, files[i], isInstant, forceOverwrite, false); } if (fixed && i==0) { newUpload.setRemoteFolderToBeCreated(); @@ -458,23 +457,19 @@ public class FileUploader extends Service implements OnDatatransferProgressListe } catch (Exception e) { result = new RemoteOperationResult(e); - Log.i(TAG, "Update: synchronizing properties for uploaded " + mCurrentUpload.getRemotePath() + ": " + result.getLogMessage(), e); + Log.e(TAG, "Update: synchronizing properties for uploaded " + mCurrentUpload.getRemotePath() + ": " + result.getLogMessage(), e); } finally { if (propfind != null) propfind.releaseConnection(); } - + /// maybe this would be better as part of UploadFileOperation... or maybe all this method if (mCurrentUpload.wasRenamed()) { OCFile oldFile = mCurrentUpload.getOldFile(); - if (!oldFile.fileExists()) { - // just a name coincidence - file.setStoragePath(oldFile.getStoragePath()); - - } else { - // conflict resolved with 'Keep both' by the user - File localFile = new File(oldFile.getStoragePath()); + if (oldFile.fileExists()) { + // the upload was the result of a conflict resolved with 'Keep both' by the user + /*File localFile = new File(file.getStoragePath()); File newLocalFile = new File(FileStorageUtils.getDefaultSavePathFor(mCurrentUpload.getAccount().name, file)); boolean renameSuccessed = localFile.renameTo(newLocalFile); if (renameSuccessed) { @@ -490,10 +485,15 @@ public class FileUploader extends Service implements OnDatatransferProgressListe // BUT: // - no loss of data happened // - when the user downloads again the renamed and original file from the server, local file names and contents will be correctly synchronized with names and contents in server + }*/ + if (oldFile.isDown()) { + File oldLocalFile = new File(oldFile.getStoragePath()); + oldLocalFile.delete(); // the RemoteFileOperation copied and renamed it! // TODO launch the 'Keep both' option with mMove set 'ture' } oldFile.setStoragePath(null); mStorageManager.saveFile(oldFile); - } + + } // else: it was just an automatic renaming due to a name coincidence; nothing else is needed, the storagePath is right in the instance returned by mCurrentUpload.getFile() } mStorageManager.saveFile(file); diff --git a/src/com/owncloud/android/operations/ChunkedUploadFileOperation.java b/src/com/owncloud/android/operations/ChunkedUploadFileOperation.java index 67ff7ce7..4e71314a 100644 --- a/src/com/owncloud/android/operations/ChunkedUploadFileOperation.java +++ b/src/com/owncloud/android/operations/ChunkedUploadFileOperation.java @@ -45,9 +45,10 @@ public class ChunkedUploadFileOperation extends UploadFileOperation { public ChunkedUploadFileOperation( Account account, OCFile file, boolean isInstant, - boolean forceOverwrite) { + boolean forceOverwrite, + boolean moveLocalFile) { - super(account, file, isInstant, forceOverwrite); + super(account, file, isInstant, forceOverwrite, moveLocalFile); } @Override diff --git a/src/com/owncloud/android/operations/DownloadFileOperation.java b/src/com/owncloud/android/operations/DownloadFileOperation.java index 59343d15..d752b3cc 100644 --- a/src/com/owncloud/android/operations/DownloadFileOperation.java +++ b/src/com/owncloud/android/operations/DownloadFileOperation.java @@ -145,7 +145,7 @@ public class DownloadFileOperation extends RemoteOperation { moved = tmpFile.renameTo(newFile); } if (!moved) - result = new RemoteOperationResult(RemoteOperationResult.ResultCode.STORAGE_ERROR_MOVING_FROM_TMP); + result = new RemoteOperationResult(RemoteOperationResult.ResultCode.LOCAL_STORAGE_NOT_MOVED); else result = new RemoteOperationResult(isSuccess(status), status); Log.i(TAG, "Download of " + mFile.getRemotePath() + " to " + getSavePath() + ": " + result.getLogMessage()); diff --git a/src/com/owncloud/android/operations/RemoteOperationResult.java b/src/com/owncloud/android/operations/RemoteOperationResult.java index 557c9cd2..973c8a6b 100644 --- a/src/com/owncloud/android/operations/RemoteOperationResult.java +++ b/src/com/owncloud/android/operations/RemoteOperationResult.java @@ -65,12 +65,13 @@ public class RemoteOperationResult implements Serializable { SSL_ERROR, SSL_RECOVERABLE_PEER_UNVERIFIED, BAD_OC_VERSION, - STORAGE_ERROR_MOVING_FROM_TMP, CANCELLED, INVALID_LOCAL_FILE_NAME, INVALID_OVERWRITE, CONFLICT, - SYNC_CONFLICT + SYNC_CONFLICT, + LOCAL_STORAGE_FULL, + LOCAL_STORAGE_NOT_MOVED } private boolean mSuccess = false; @@ -254,8 +255,11 @@ public class RemoteOperationResult implements Serializable { } else if (mCode == ResultCode.BAD_OC_VERSION) { return "No valid ownCloud version was found at the server"; - } else if (mCode == ResultCode.STORAGE_ERROR_MOVING_FROM_TMP) { - return "Error while moving file from temporal to final directory"; + } else if (mCode == ResultCode.LOCAL_STORAGE_FULL) { + return "Local storage full"; + + } else if (mCode == ResultCode.LOCAL_STORAGE_NOT_MOVED) { + return "Error while moving file to final directory"; } return "Operation finished with HTTP status code " + mHttpCode + " (" + (isSuccess()?"success":"fail") + ")"; diff --git a/src/com/owncloud/android/operations/UploadFileOperation.java b/src/com/owncloud/android/operations/UploadFileOperation.java index afdd3cbe..0cee73b8 100644 --- a/src/com/owncloud/android/operations/UploadFileOperation.java +++ b/src/com/owncloud/android/operations/UploadFileOperation.java @@ -19,7 +19,11 @@ package com.owncloud.android.operations; import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.util.HashSet; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; @@ -31,6 +35,8 @@ import org.apache.http.HttpStatus; import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.operations.RemoteOperation; import com.owncloud.android.operations.RemoteOperationResult; +import com.owncloud.android.operations.RemoteOperationResult.ResultCode; +import com.owncloud.android.utils.FileStorageUtils; import eu.alefzero.webdav.FileRequestEntity; import eu.alefzero.webdav.OnDatatransferProgressListener; @@ -55,6 +61,7 @@ public class UploadFileOperation extends RemoteOperation { private boolean mIsInstant = false; private boolean mRemoteFolderToBeCreated = false; private boolean mForceOverwrite = false; + private boolean mMoveLocalFile = false; private boolean mWasRenamed = false; PutMethod mPutMethod = null; private Set mDataTransferListeners = new HashSet(); @@ -64,7 +71,8 @@ public class UploadFileOperation extends RemoteOperation { public UploadFileOperation( Account account, OCFile file, boolean isInstant, - boolean forceOverwrite) { + boolean forceOverwrite, + boolean moveLocalFile) { if (account == null) throw new IllegalArgumentException("Illegal NULL account in UploadFileOperation creation"); if (file == null) @@ -78,6 +86,7 @@ public class UploadFileOperation extends RemoteOperation { mRemotePath = file.getRemotePath(); mIsInstant = isInstant; mForceOverwrite = forceOverwrite; + mMoveLocalFile = moveLocalFile; } @@ -137,7 +146,9 @@ public class UploadFileOperation extends RemoteOperation { @Override protected RemoteOperationResult run(WebdavClient client) { RemoteOperationResult result = null; - boolean nameCheckPassed = false; + boolean localCopyPassed = false, nameCheckPassed = false; + File temporalFile = null, originalFile = null; + String originalStoragePath = mFile.getStoragePath(); try { /// rename the file to upload, if necessary if (!mForceOverwrite) { @@ -147,28 +158,100 @@ public class UploadFileOperation extends RemoteOperation { createNewOCFile(remotePath); } } + nameCheckPassed = true; + /// check location of local file, and copy to a temporal file to upload it if not in its corresponding directory + String targetLocalPath = FileStorageUtils.getDefaultSavePathFor(mAccount.name, mFile); + if (!originalStoragePath.equals(targetLocalPath)) { + File ocLocalFolder = new File(FileStorageUtils.getSavePath(mAccount.name)); + originalFile = new File(originalStoragePath); + if (!mMoveLocalFile) { + // the file must be copied to the ownCloud local folder + + if (ocLocalFolder.getUsableSpace() < originalFile.length()) { + result = new RemoteOperationResult(ResultCode.LOCAL_STORAGE_FULL); + return result; + + } else { + String temporalPath = FileStorageUtils.getTemporalPath(mAccount.name) + mFile.getRemotePath(); + mFile.setStoragePath(temporalPath); + temporalFile = new File(temporalPath); + if (!originalStoragePath.equals(temporalPath)) { // preventing weird but possible situation + InputStream in = new FileInputStream(originalFile); + OutputStream out = new FileOutputStream(temporalFile); + byte[] buf = new byte[1024]; + int len; + while ((len = in.read(buf)) > 0){ + out.write(buf, 0, len); + } + in.close(); + out.close(); + } + } + } // else - the file will be MOVED to the corresponding directory AFTER the upload finishes + } + localCopyPassed = true; + /// perform the upload - nameCheckPassed = true; synchronized(mCancellationRequested) { if (mCancellationRequested.get()) { throw new OperationCancelledException(); } else { - mPutMethod = new PutMethod(client.getBaseUri() + WebdavUtils.encodePath(mRemotePath)); + mPutMethod = new PutMethod(client.getBaseUri() + WebdavUtils.encodePath(mFile.getRemotePath())); } } int status = uploadFile(client); - result = new RemoteOperationResult(isSuccess(status), status); - Log.i(TAG, "Upload of " + mFile.getStoragePath() + " to " + mRemotePath + ": " + result.getLogMessage()); - + + + /// move local temporal file or original file to its corresponding location in the ownCloud local folder + if (isSuccess(status)) { + File fileToMove = null; + if (temporalFile != null) { + fileToMove = temporalFile; + } else if (originalFile != null) { + fileToMove = originalFile; + } + if (fileToMove != null) { + mFile.setStoragePath(FileStorageUtils.getDefaultSavePathFor(mAccount.name, mFile)); + File finalFile = new File(mFile.getStoragePath()); + if (!fileToMove.renameTo(finalFile)) { + result = new RemoteOperationResult(ResultCode.LOCAL_STORAGE_NOT_MOVED); + } + } + } + + if (result == null) + result = new RemoteOperationResult(isSuccess(status), status); + + } catch (Exception e) { - // TODO something cleaner if (mCancellationRequested.get()) { result = new RemoteOperationResult(new OperationCancelledException()); } else { result = new RemoteOperationResult(e); } - Log.e(TAG, "Upload of " + mFile.getStoragePath() + " to " + mRemotePath + ": " + result.getLogMessage() + (nameCheckPassed?"":" (while checking file existence in server)"), result.getException()); + + + } finally { + if (temporalFile != null && !originalFile.equals(temporalFile)) { + temporalFile.delete(); + } + if (result.isSuccess()) { + Log.i(TAG, "Upload of " + originalStoragePath + " to " + mRemotePath + ": " + result.getLogMessage()); + + } else { + if (result.getException() != null) { + String complement = ""; + if (!nameCheckPassed) { + complement = " (while checking file existence in server)"; + } else if (!localCopyPassed) { + complement = " (while copying local file to " + FileStorageUtils.getSavePath(mAccount.name) + ")"; + } + Log.e(TAG, "Upload of " + originalStoragePath + " to " + mRemotePath + ": " + result.getLogMessage() + complement, result.getException()); + } else { + Log.e(TAG, "Upload of " + originalStoragePath + " to " + mRemotePath + ": " + result.getLogMessage()); + } + } } return result;