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

This commit is contained in:
David A. Velasco 2012-11-27 14:28:19 +01:00
parent b83064eb83
commit fd9086a883
5 changed files with 118 additions and 30 deletions

View file

@ -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);

View file

@ -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

View file

@ -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());

View file

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

View file

@ -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);
}
}
/// perform the upload
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
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;