Przeglądaj źródła

New policy: uploaded files are copied to the local storage ownCloud directory bu default

David A. Velasco 12 lat temu
rodzic
commit
fd9086a883

+ 13 - 13
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);

+ 3 - 2
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

+ 1 - 1
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());

+ 8 - 4
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") + ")";

+ 92 - 9
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<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>();
@@ -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;