import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.operations.ChunkedUploadFileOperation;
import com.owncloud.android.operations.CreateFolderOperation;
+import com.owncloud.android.operations.ExistenceCheckOperation;
import com.owncloud.android.operations.RemoteOperation;
import com.owncloud.android.operations.RemoteOperationResult;
import com.owncloud.android.operations.UploadFileOperation;
boolean forceOverwrite = intent.getBooleanExtra(KEY_FORCE_OVERWRITE, false);
boolean isInstant = intent.getBooleanExtra(KEY_INSTANT_UPLOAD, false);
int localAction = intent.getIntExtra(KEY_LOCAL_BEHAVIOUR, LOCAL_BEHAVIOUR_COPY);
- boolean fixed = false;
- if (isInstant) {
- fixed = checkAndFixInstantUploadDirectory(storageManager); // MUST
- // be
- // done
- // BEFORE
- // calling
- // obtainNewOCFileToUpload
- }
-
+
if (intent.hasExtra(KEY_FILE) && files == null) {
Log_OC.e(TAG, "Incorrect array for OCFiles provided in upload intent");
return Service.START_NOT_STICKY;
} else {
newUpload = new UploadFileOperation(account, files[i], isInstant, forceOverwrite, localAction);
}
- if (fixed && i == 0) {
+ if (isInstant) {
newUpload.setRemoteFolderToBeCreated();
}
mPendingUploads.putIfAbsent(uploadKey, newUpload); // Grants that the file only upload once time
notifyUploadStart(mCurrentUpload);
- RemoteOperationResult uploadResult = null;
+ RemoteOperationResult uploadResult = null, grantResult = null;
try {
/// prepare client object to send requests to the ownCloud server
mStorageManager = new FileDataStorageManager(mLastAccount, getContentResolver());
mUploadClient = OwnCloudClientUtils.createOwnCloudClient(mLastAccount, getApplicationContext());
}
-
- /// create remote folder for instant uploads
- if (mCurrentUpload.isRemoteFolderToBeCreated()) {
- RemoteOperation operation = new CreateFolderOperation( FileStorageUtils.getInstantUploadFilePath(this, ""),
- mStorageManager.getFileByPath(OCFile.PATH_SEPARATOR).getFileId(), // TODO generalize this : INSTANT_UPLOAD_DIR could not be a child of root
- mStorageManager);
- operation.execute(mUploadClient); // ignoring result; fail could just mean that it already exists, but local database is not synchronized; the upload will be tried anyway
- }
-
+
+ /// check the existence of the parent folder for the file to upload
+ String remoteParentPath = new File(mCurrentUpload.getRemotePath()).getParent();
+ remoteParentPath = remoteParentPath.endsWith(OCFile.PATH_SEPARATOR) ? remoteParentPath : remoteParentPath + OCFile.PATH_SEPARATOR;
+ grantResult = grantFolderExistence(remoteParentPath);
/// perform the upload
- uploadResult = mCurrentUpload.execute(mUploadClient);
- if (uploadResult.isSuccess()) {
- saveUploadedFile();
+ if (grantResult.isSuccess()) {
+ OCFile parent = mStorageManager.getFileByPath(remoteParentPath);
+ mCurrentUpload.getFile().setParentId(parent.getFileId());
+ uploadResult = mCurrentUpload.execute(mUploadClient);
+ if (uploadResult.isSuccess()) {
+ saveUploadedFile();
+ }
+ } else {
+ uploadResult = grantResult;
}
} catch (AccountsException e) {
}
/**
+ * Checks the existence of the folder where the current file will be uploaded both in the remote server
+ * and in the local database.
+ *
+ * If the upload is set to enforce the creation of the folder, the method tries to create it both remote
+ * and locally.
+ *
+ * @param pathToGrant Full remote path whose existence will be granted.
+ * @return An {@link OCFile} instance corresponding to the folder where the file will be uploaded.
+ */
+ private RemoteOperationResult grantFolderExistence(String pathToGrant) {
+ RemoteOperation operation = new ExistenceCheckOperation(pathToGrant, this, false);
+ RemoteOperationResult result = operation.execute(mUploadClient);
+ if (!result.isSuccess() && result.getCode() == ResultCode.FILE_NOT_FOUND && mCurrentUpload.isRemoteFolderToBeCreated()) {
+ operation = new CreateFolderOperation( pathToGrant,
+ true,
+ mStorageManager );
+ result = operation.execute(mUploadClient);
+ }
+ if (result.isSuccess()) {
+ OCFile parentDir = mStorageManager.getFileByPath(pathToGrant);
+ if (parentDir == null) {
+ parentDir = createLocalFolder(pathToGrant);
+ }
+ if (parentDir != null) {
+ result = new RemoteOperationResult(ResultCode.OK);
+ } else {
+ result = new RemoteOperationResult(ResultCode.UNKNOWN_ERROR);
+ }
+ }
+ return result;
+ }
+
+
+ private OCFile createLocalFolder(String remotePath) {
+ String parentPath = new File(remotePath).getParent();
+ parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath : parentPath + OCFile.PATH_SEPARATOR;
+ OCFile parent = mStorageManager.getFileByPath(parentPath);
+ if (parent == null) {
+ parent = createLocalFolder(parentPath);
+ }
+ if (parent != null) {
+ OCFile createdFolder = new OCFile(remotePath);
+ createdFolder.setMimetype("DIR");
+ createdFolder.setParentId(parent.getFileId());
+ mStorageManager.saveFile(createdFolder);
+ return createdFolder;
+ }
+ return null;
+ }
+
+
+ /**
* Saves a OC File after a successful upload.
*
* A PROPFIND is necessary to keep the props in the local database
// file.setEtag(mCurrentUpload.getEtag()); // TODO Etag, where available
}
- private boolean checkAndFixInstantUploadDirectory(FileDataStorageManager storageManager) {
- String instantUploadDirPath = FileStorageUtils.getInstantUploadFilePath(this, "");
- OCFile instantUploadDir = storageManager.getFileByPath(instantUploadDirPath);
- if (instantUploadDir == null) {
- // first instant upload in the account. never account not
- // synchronized after the remote InstantUpload folder was created
- OCFile newDir = new OCFile(instantUploadDirPath);
- newDir.setMimetype("DIR");
- OCFile path = storageManager.getFileByPath(OCFile.PATH_SEPARATOR);
-
- if (path != null) {
- newDir.setParentId(path.getFileId());
- storageManager.saveFile(newDir);
- return true;
- } else { // this should not happen anymore
- return false;
- }
-
- }
- return false;
- }
-
private OCFile obtainNewOCFileToUpload(String remotePath, String localPath, String mimeType,
FileDataStorageManager storageManager) {
OCFile newFile = new OCFile(remotePath);
}
newFile.setMimetype(mimeType);
- // parent dir
- String parentPath = new File(remotePath).getParent();
- parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath : parentPath + OCFile.PATH_SEPARATOR;
- OCFile parentDir = storageManager.getFileByPath(parentPath);
- long parentDirId = parentDir.getFileId();
- newFile.setParentId(parentDirId);
return newFile;
}
mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotification); // NOT
// AN
DbHandler db = new DbHandler(this.getBaseContext());
- db.removeIUPendingFile(mCurrentUpload.getFile().getStoragePath());
+ db.removeIUPendingFile(mCurrentUpload.getOriginalStoragePath());
db.close();
} else {
Log_OC.e(TAG, message + " Http-Code: " + uploadResult.getHttpCode());
if (uploadResult.getCode() == ResultCode.QUOTA_EXCEEDED) {
message = getString(R.string.failed_upload_quota_exceeded_text);
- }
- if (db.updateFileState(upload.getOriginalStoragePath(), DbHandler.UPLOAD_STATUS_UPLOAD_FAILED,
- message) == 0) {
- db.putFileForLater(upload.getOriginalStoragePath(), upload.getAccount().name, message);
+ if (db.updateFileState(upload.getOriginalStoragePath(), DbHandler.UPLOAD_STATUS_UPLOAD_FAILED,
+ message) == 0) {
+ db.putFileForLater(upload.getOriginalStoragePath(), upload.getAccount().name, message);
+ }
}
} finally {
if (db != null) {