mirror of
https://github.com/nextcloud/android.git
synced 2024-11-22 21:25:35 +03:00
ETag used to detect changes in remote files (not only in folders)
This commit is contained in:
parent
c0c52fa16a
commit
5f41bb14d3
16 changed files with 105 additions and 308 deletions
|
@ -498,10 +498,9 @@ public class OCFile implements Parcelable, Comparable<OCFile> {
|
|||
}
|
||||
|
||||
public void setEtag(String etag) {
|
||||
this.mEtag = etag;
|
||||
this.mEtag = (etag != null ? etag : "");
|
||||
}
|
||||
|
||||
|
||||
public boolean isShareByLink() {
|
||||
return mShareByLink;
|
||||
}
|
||||
|
@ -602,4 +601,5 @@ public class OCFile implements Parcelable, Comparable<OCFile> {
|
|||
// TODO real implementation
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,7 +34,6 @@ import com.owncloud.android.files.services.FileDownloader;
|
|||
import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
|
||||
import com.owncloud.android.files.services.FileUploader;
|
||||
import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
|
||||
import com.owncloud.android.services.OperationsService;
|
||||
import com.owncloud.android.services.OperationsService.OperationsServiceBinder;
|
||||
import com.owncloud.android.ui.activity.ComponentsGetter;
|
||||
|
||||
|
|
|
@ -230,30 +230,6 @@ public class FileOperationsHelper {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Request the synchronization of a file or the DOWNLOAD OF A FOLDER, including its contents.
|
||||
*
|
||||
* For files, it's the same as syncFile(OCFile file); for folders, this method does not trigger uploads for
|
||||
* file locally modified.
|
||||
*
|
||||
* Kept 'til synchronization of full folders is considered good enough.
|
||||
*
|
||||
* @param file The file or folder to synchronize
|
||||
*/
|
||||
public void downloadFile(OCFile file) {
|
||||
if (!file.isFolder()){
|
||||
syncFile(file);
|
||||
|
||||
} else {
|
||||
Intent intent = new Intent(mFileActivity, OperationsService.class);
|
||||
intent.setAction(OperationsService.ACTION_DOWNLOAD_FOLDER);
|
||||
intent.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount());
|
||||
intent.putExtra(OperationsService.EXTRA_REMOTE_PATH, file.getRemotePath());
|
||||
mFileActivity.startService(intent);
|
||||
}
|
||||
}
|
||||
|
||||
public void toggleFavorite(OCFile file, boolean isFavorite) {
|
||||
file.setFavorite(isFavorite);
|
||||
mFileActivity.getStorageManager().saveFile(file);
|
||||
|
@ -327,15 +303,6 @@ public class FileOperationsHelper {
|
|||
FileDownloaderBinder downloaderBinder = mFileActivity.getFileDownloaderBinder();
|
||||
if (downloaderBinder != null && downloaderBinder.isDownloading(account, file)) {
|
||||
downloaderBinder.cancel(account, file);
|
||||
|
||||
// TODO - review why is this here, and solve in a better way
|
||||
// Remove etag for parent, if file is a favorite
|
||||
if (file.isFavorite()) {
|
||||
OCFile parent = mFileActivity.getStorageManager().getFileById(file.getParentId());
|
||||
parent.setEtag("");
|
||||
mFileActivity.getStorageManager().saveFile(parent);
|
||||
}
|
||||
|
||||
}
|
||||
FileUploaderBinder uploaderBinder = mFileActivity.getFileUploaderBinder();
|
||||
if (uploaderBinder != null && uploaderBinder.isUploading(account, file)) {
|
||||
|
|
|
@ -475,7 +475,7 @@ public class FileDownloader extends Service
|
|||
file.setNeedsUpdateThumbnail(true);
|
||||
file.setModificationTimestamp(mCurrentDownload.getModificationTimestamp());
|
||||
file.setModificationTimestampAtLastSyncForData(mCurrentDownload.getModificationTimestamp());
|
||||
// file.setEtag(mCurrentDownload.getEtag()); // TODO Etag, where available
|
||||
file.setEtag(mCurrentDownload.getEtag());
|
||||
file.setMimetype(mCurrentDownload.getMimeType());
|
||||
file.setStoragePath(mCurrentDownload.getSavePath());
|
||||
file.setFileLength((new File(mCurrentDownload.getSavePath()).length()));
|
||||
|
|
|
@ -688,6 +688,8 @@ public class FileUploader extends Service
|
|||
if (result.isSuccess()) {
|
||||
updateOCFile(file, (RemoteFile) result.getData().get(0));
|
||||
file.setLastSyncDateForProperties(syncDate);
|
||||
} else {
|
||||
Log_OC.e(TAG, "Error reading properties of file after successful upload; this is gonna hurt...");
|
||||
}
|
||||
|
||||
// / maybe this would be better as part of UploadFileOperation... or
|
||||
|
@ -712,7 +714,7 @@ public class FileUploader extends Service
|
|||
file.setMimetype(remoteFile.getMimeType());
|
||||
file.setModificationTimestamp(remoteFile.getModifiedTimestamp());
|
||||
file.setModificationTimestampAtLastSyncForData(remoteFile.getModifiedTimestamp());
|
||||
// file.setEtag(remoteFile.getEtag()); // TODO Etag, where available
|
||||
file.setEtag(remoteFile.getEtag());
|
||||
file.setRemoteId(remoteFile.getRemoteId());
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ public class DownloadFileOperation extends RemoteOperation {
|
|||
private OCFile mFile;
|
||||
private Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>();
|
||||
private long mModificationTimestamp = 0;
|
||||
private String mEtag = "";
|
||||
private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false);
|
||||
|
||||
private DownloadRemoteFileOperation mDownloadOperation;
|
||||
|
@ -127,6 +128,10 @@ public class DownloadFileOperation extends RemoteOperation {
|
|||
mFile.getModificationTimestamp();
|
||||
}
|
||||
|
||||
public String getEtag() {
|
||||
return mEtag;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RemoteOperationResult run(OwnCloudClient client) {
|
||||
RemoteOperationResult result = null;
|
||||
|
@ -154,6 +159,7 @@ public class DownloadFileOperation extends RemoteOperation {
|
|||
|
||||
if (result.isSuccess()) {
|
||||
mModificationTimestamp = mDownloadOperation.getModificationTimestamp();
|
||||
mEtag = mDownloadOperation.getEtag();
|
||||
newFile = new File(getSavePath());
|
||||
newFile.getParentFile().mkdirs();
|
||||
moved = tmpFile.renameTo(newFile);
|
||||
|
|
|
@ -540,7 +540,7 @@ public class DownloadFolderOperation extends SyncOperation {
|
|||
|
||||
private void startSyncFolderOperation(String path){
|
||||
Intent intent = new Intent(mContext, OperationsService.class);
|
||||
intent.setAction(OperationsService.ACTION_DOWNLOAD_FOLDER);
|
||||
intent.setAction(OperationsService.ACTION_SYNC_FOLDER);
|
||||
intent.putExtra(OperationsService.EXTRA_ACCOUNT, mAccount);
|
||||
intent.putExtra(OperationsService.EXTRA_REMOTE_PATH, path);
|
||||
mContext.startService(intent);
|
||||
|
|
|
@ -20,26 +20,17 @@
|
|||
|
||||
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.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.apache.http.HttpStatus;
|
||||
import android.accounts.Account;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
//import android.support.v4.content.LocalBroadcastManager;
|
||||
|
||||
import com.owncloud.android.MainApp;
|
||||
import com.owncloud.android.datamodel.FileDataStorageManager;
|
||||
import com.owncloud.android.datamodel.OCFile;
|
||||
|
||||
|
@ -50,7 +41,6 @@ import com.owncloud.android.lib.common.operations.RemoteOperationResult;
|
|||
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
import com.owncloud.android.lib.resources.shares.GetRemoteSharesForFileOperation;
|
||||
import com.owncloud.android.lib.resources.files.FileUtils;
|
||||
import com.owncloud.android.lib.resources.files.ReadRemoteFileOperation;
|
||||
import com.owncloud.android.lib.resources.files.ReadRemoteFolderOperation;
|
||||
import com.owncloud.android.lib.resources.files.RemoteFile;
|
||||
|
@ -120,7 +110,10 @@ public class RefreshFolderOperation extends RemoteOperation {
|
|||
/** 'True' means that Etag will be ignored */
|
||||
private boolean mIgnoreETag;
|
||||
|
||||
|
||||
private List<SynchronizeFileOperation> mFilesToSyncContents;
|
||||
// this will be used for every file when 'folder synchronization' replaces 'folder download'
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new instance of {@link RefreshFolderOperation}.
|
||||
*
|
||||
|
@ -154,6 +147,7 @@ public class RefreshFolderOperation extends RemoteOperation {
|
|||
mForgottenLocalFiles = new HashMap<String, String>();
|
||||
mRemoteFolderChanged = false;
|
||||
mIgnoreETag = ignoreETag;
|
||||
mFilesToSyncContents = new Vector<SynchronizeFileOperation>();
|
||||
}
|
||||
|
||||
|
||||
|
@ -191,7 +185,7 @@ public class RefreshFolderOperation extends RemoteOperation {
|
|||
mConflictsFound = 0;
|
||||
mForgottenLocalFiles.clear();
|
||||
|
||||
if (FileUtils.PATH_SEPARATOR.equals(mLocalFolder.getRemotePath()) && !mSyncFullAccount) {
|
||||
if (OCFile.ROOT_PATH.equals(mLocalFolder.getRemotePath()) && !mSyncFullAccount) {
|
||||
updateOCVersion(client);
|
||||
}
|
||||
|
||||
|
@ -201,9 +195,14 @@ public class RefreshFolderOperation extends RemoteOperation {
|
|||
if (mRemoteFolderChanged) {
|
||||
result = fetchAndSyncRemoteFolder(client);
|
||||
} else {
|
||||
// TODO Enable when "On Device" is recovered ?
|
||||
fetchFavoritesToSyncFromLocalData();
|
||||
mChildren = mStorageManager.getFolderContent(mLocalFolder/*, false*/);
|
||||
}
|
||||
|
||||
if (result.isSuccess()) {
|
||||
// request for the synchronization of KEPT-IN-SYNC file contents
|
||||
startContentSynchronizations(mFilesToSyncContents, client);
|
||||
}
|
||||
}
|
||||
|
||||
if (!mSyncFullAccount) {
|
||||
|
@ -239,9 +238,8 @@ public class RefreshFolderOperation extends RemoteOperation {
|
|||
private RemoteOperationResult checkForChanges(OwnCloudClient client) {
|
||||
mRemoteFolderChanged = true;
|
||||
RemoteOperationResult result = null;
|
||||
String remotePath = null;
|
||||
String remotePath = mLocalFolder.getRemotePath();
|
||||
|
||||
remotePath = mLocalFolder.getRemotePath();
|
||||
Log_OC.d(TAG, "Checking changes in " + mAccount.name + remotePath);
|
||||
|
||||
// remote request
|
||||
|
@ -264,7 +262,7 @@ public class RefreshFolderOperation extends RemoteOperation {
|
|||
|
||||
result = new RemoteOperationResult(ResultCode.OK);
|
||||
|
||||
Log_OC.i(TAG, "Checked " + mAccount.name + remotePath + " : " +
|
||||
Log_OC.i(TAG, "Checked " + mAccount.name + remotePath + " : " +
|
||||
(mRemoteFolderChanged ? "changed" : "not changed"));
|
||||
|
||||
} else {
|
||||
|
@ -337,15 +335,15 @@ public class RefreshFolderOperation extends RemoteOperation {
|
|||
mLocalFolder = mStorageManager.getFileByPath(mLocalFolder.getRemotePath());
|
||||
|
||||
// parse data from remote folder
|
||||
OCFile remoteFolder = fillOCFile((RemoteFile)folderAndFiles.get(0));
|
||||
OCFile remoteFolder = FileStorageUtils.fillOCFile((RemoteFile) folderAndFiles.get(0));
|
||||
remoteFolder.setParentId(mLocalFolder.getParentId());
|
||||
remoteFolder.setFileId(mLocalFolder.getFileId());
|
||||
|
||||
Log_OC.d(TAG, "Remote folder " + mLocalFolder.getRemotePath()
|
||||
Log_OC.d(TAG, "Remote folder " + mLocalFolder.getRemotePath()
|
||||
+ " changed - starting update of local data ");
|
||||
|
||||
List<OCFile> updatedFiles = new Vector<OCFile>(folderAndFiles.size() - 1);
|
||||
List<SynchronizeFileOperation> filesToSyncContents = new Vector<SynchronizeFileOperation>();
|
||||
mFilesToSyncContents.clear();
|
||||
|
||||
// get current data about local contents of the folder to synchronize
|
||||
// TODO Enable when "On Device" is recovered ?
|
||||
|
@ -359,7 +357,7 @@ public class RefreshFolderOperation extends RemoteOperation {
|
|||
OCFile remoteFile = null, localFile = null;
|
||||
for (int i=1; i<folderAndFiles.size(); i++) {
|
||||
/// new OCFile instance with the data from the server
|
||||
remoteFile = fillOCFile((RemoteFile)folderAndFiles.get(i));
|
||||
remoteFile = FileStorageUtils.fillOCFile((RemoteFile) folderAndFiles.get(i));
|
||||
remoteFile.setParentId(mLocalFolder.getFileId());
|
||||
|
||||
/// retrieve local data for the read file
|
||||
|
@ -377,9 +375,8 @@ public class RefreshFolderOperation extends RemoteOperation {
|
|||
localFile.getModificationTimestampAtLastSyncForData()
|
||||
);
|
||||
remoteFile.setStoragePath(localFile.getStoragePath());
|
||||
// eTag will not be updated unless contents are synchronized
|
||||
// (Synchronize[File|Folder]Operation with remoteFile as parameter)
|
||||
remoteFile.setEtag(localFile.getEtag());
|
||||
// eTag will not be updated unless file CONTENTS are synchronized
|
||||
remoteFile.setEtag(localFile.getEtag());
|
||||
if (remoteFile.isFolder()) {
|
||||
remoteFile.setFileLength(localFile.getFileLength());
|
||||
// TODO move operations about size of folders to FileContentProvider
|
||||
|
@ -392,15 +389,12 @@ public class RefreshFolderOperation extends RemoteOperation {
|
|||
remoteFile.setPublicLink(localFile.getPublicLink());
|
||||
remoteFile.setShareByLink(localFile.isShareByLink());
|
||||
} else {
|
||||
// remote eTag will not be updated unless contents are synchronized
|
||||
// (Synchronize[File|Folder]Operation with remoteFile as parameter)
|
||||
remoteFile.setEtag("");
|
||||
// remote eTag will not be updated unless file CONTENTS are synchronized
|
||||
remoteFile.setEtag("");
|
||||
}
|
||||
|
||||
/// check and fix, if needed, local storage path
|
||||
checkAndFixForeignStoragePath(remoteFile); // policy - local files are COPIED
|
||||
// into the ownCloud local folder;
|
||||
searchForLocalFileInDefaultPath(remoteFile); // legacy
|
||||
FileStorageUtils.searchForLocalFileInDefaultPath(remoteFile, mAccount);
|
||||
|
||||
/// prepare content synchronization for kept-in-sync files
|
||||
if (remoteFile.isFavorite()) {
|
||||
|
@ -411,18 +405,15 @@ public class RefreshFolderOperation extends RemoteOperation {
|
|||
mContext
|
||||
);
|
||||
|
||||
filesToSyncContents.add(operation);
|
||||
mFilesToSyncContents.add(operation);
|
||||
}
|
||||
|
||||
|
||||
updatedFiles.add(remoteFile);
|
||||
}
|
||||
|
||||
// save updated contents in local database
|
||||
mStorageManager.saveFolder(remoteFolder, updatedFiles, localFilesMap.values());
|
||||
|
||||
// request for the synchronization of file contents AFTER saving current remote properties
|
||||
startContentSynchronizations(filesToSyncContents, client);
|
||||
|
||||
mChildren = updatedFiles;
|
||||
}
|
||||
|
||||
|
@ -460,97 +451,6 @@ public class RefreshFolderOperation extends RemoteOperation {
|
|||
}
|
||||
|
||||
|
||||
public boolean isMultiStatus(int status) {
|
||||
return (status == HttpStatus.SC_MULTI_STATUS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and populates a new {@link OCFile} object with the data read from the server.
|
||||
*
|
||||
* @param remote remote file read from the server (remote file or folder).
|
||||
* @return New OCFile instance representing the remote resource described by we.
|
||||
*/
|
||||
private OCFile fillOCFile(RemoteFile remote) {
|
||||
OCFile file = new OCFile(remote.getRemotePath());
|
||||
file.setCreationTimestamp(remote.getCreationTimestamp());
|
||||
file.setFileLength(remote.getLength());
|
||||
file.setMimetype(remote.getMimeType());
|
||||
file.setModificationTimestamp(remote.getModifiedTimestamp());
|
||||
file.setEtag(remote.getEtag());
|
||||
file.setPermissions(remote.getPermissions());
|
||||
file.setRemoteId(remote.getRemoteId());
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks the storage path of the OCFile received as parameter.
|
||||
* If it's out of the local ownCloud folder, tries to copy the file inside it.
|
||||
*
|
||||
* If the copy fails, the link to the local file is nullified. The account of forgotten
|
||||
* files is kept in {@link #mForgottenLocalFiles}
|
||||
*)
|
||||
* @param file File to check and fix.
|
||||
*/
|
||||
private void checkAndFixForeignStoragePath(OCFile file) {
|
||||
String storagePath = file.getStoragePath();
|
||||
String expectedPath = FileStorageUtils.getDefaultSavePathFor(mAccount.name, file);
|
||||
if (storagePath != null && !storagePath.equals(expectedPath)) {
|
||||
/// fix storagePaths out of the local ownCloud folder
|
||||
File originalFile = new File(storagePath);
|
||||
if (FileStorageUtils.getUsableSpace(mAccount.name) < originalFile.length()) {
|
||||
mForgottenLocalFiles.put(file.getRemotePath(), storagePath);
|
||||
file.setStoragePath(null);
|
||||
|
||||
} else {
|
||||
InputStream in = null;
|
||||
OutputStream out = null;
|
||||
try {
|
||||
File expectedFile = new File(expectedPath);
|
||||
File expectedParent = expectedFile.getParentFile();
|
||||
expectedParent.mkdirs();
|
||||
if (!expectedParent.isDirectory()) {
|
||||
throw new IOException(
|
||||
"Unexpected error: parent directory could not be created"
|
||||
);
|
||||
}
|
||||
expectedFile.createNewFile();
|
||||
if (!expectedFile.isFile()) {
|
||||
throw new IOException("Unexpected error: target file could not be created");
|
||||
}
|
||||
in = new FileInputStream(originalFile);
|
||||
out = new FileOutputStream(expectedFile);
|
||||
byte[] buf = new byte[1024];
|
||||
int len;
|
||||
while ((len = in.read(buf)) > 0){
|
||||
out.write(buf, 0, len);
|
||||
}
|
||||
file.setStoragePath(expectedPath);
|
||||
|
||||
} catch (Exception e) {
|
||||
Log_OC.e(TAG, "Exception while copying foreign file " + expectedPath, e);
|
||||
mForgottenLocalFiles.put(file.getRemotePath(), storagePath);
|
||||
file.setStoragePath(null);
|
||||
|
||||
} finally {
|
||||
try {
|
||||
if (in != null) in.close();
|
||||
} catch (Exception e) {
|
||||
Log_OC.d(TAG, "Weird exception while closing input stream for "
|
||||
+ storagePath + " (ignoring)", e);
|
||||
}
|
||||
try {
|
||||
if (out != null) out.close();
|
||||
} catch (Exception e) {
|
||||
Log_OC.d(TAG, "Weird exception while closing output stream for "
|
||||
+ expectedPath + " (ignoring)", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private RemoteOperationResult refreshSharesForFolder(OwnCloudClient client) {
|
||||
RemoteOperationResult result = null;
|
||||
|
||||
|
@ -572,24 +472,6 @@ public class RefreshFolderOperation extends RemoteOperation {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Scans the default location for saving local copies of files searching for
|
||||
* a 'lost' file with the same full name as the {@link OCFile} received as
|
||||
* parameter.
|
||||
*
|
||||
* @param file File to associate a possible 'lost' local file.
|
||||
*/
|
||||
private void searchForLocalFileInDefaultPath(OCFile file) {
|
||||
if (file.getStoragePath() == null && !file.isFolder()) {
|
||||
File f = new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, file));
|
||||
if (f.exists()) {
|
||||
file.setStoragePath(f.getAbsolutePath());
|
||||
file.setLastSyncDateForData(f.lastModified());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sends a message to any application component interested in the progress
|
||||
* of the synchronization.
|
||||
|
@ -614,8 +496,20 @@ public class RefreshFolderOperation extends RemoteOperation {
|
|||
}
|
||||
|
||||
|
||||
public boolean getRemoteFolderChanged() {
|
||||
return mRemoteFolderChanged;
|
||||
private void fetchFavoritesToSyncFromLocalData() {
|
||||
List<OCFile> children = mStorageManager.getFolderContent(mLocalFolder);
|
||||
for (OCFile child : children) {
|
||||
if (!child.isFolder() && child.isFavorite()) {
|
||||
SynchronizeFileOperation operation = new SynchronizeFileOperation(
|
||||
child,
|
||||
child, // cheating with the remote file to get an update to server; to refactor
|
||||
mAccount,
|
||||
true,
|
||||
mContext
|
||||
);
|
||||
mFilesToSyncContents.add(operation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
|
||||
package com.owncloud.android.operations;
|
||||
|
||||
import com.owncloud.android.MainApp;
|
||||
import com.owncloud.android.datamodel.OCFile;
|
||||
import com.owncloud.android.files.services.FileDownloader;
|
||||
import com.owncloud.android.files.services.FileUploader;
|
||||
|
@ -208,15 +207,13 @@ public class SynchronizeFileOperation extends SyncOperation {
|
|||
|
||||
/// check changes in server and local file
|
||||
boolean serverChanged = false;
|
||||
/* time for eTag is coming, but not yet
|
||||
if (mServerFile.getEtag() != null) {
|
||||
serverChanged = (!mServerFile.getEtag().equals(mLocalFile.getEtag()));
|
||||
} else { */
|
||||
serverChanged = (
|
||||
mServerFile.getModificationTimestamp() !=
|
||||
mLocalFile.getModificationTimestampAtLastSyncForData()
|
||||
);
|
||||
//}
|
||||
if (mLocalFile.getEtag() == null || mLocalFile.getEtag().length() == 0) {
|
||||
// file uploaded (null) or downloaded ("") before upgrade to version 1.8.0; check the old condition
|
||||
serverChanged = mServerFile.getModificationTimestamp() !=
|
||||
mLocalFile.getModificationTimestampAtLastSyncForData();
|
||||
} else {
|
||||
serverChanged = (!mServerFile.getEtag().equals(mLocalFile.getEtag()));
|
||||
}
|
||||
boolean localChanged = (
|
||||
mLocalFile.getLocalModificationTimestamp() > mLocalFile.getLastSyncDateForData()
|
||||
);
|
||||
|
|
|
@ -278,7 +278,7 @@ public class SynchronizeFolderOperation extends SyncOperation {
|
|||
FileDataStorageManager storageManager = getStorageManager();
|
||||
|
||||
// parse data from remote folder
|
||||
OCFile remoteFolder = fillOCFile((RemoteFile)folderAndFiles.get(0));
|
||||
OCFile remoteFolder = FileStorageUtils.fillOCFile((RemoteFile) folderAndFiles.get(0));
|
||||
remoteFolder.setParentId(mLocalFolder.getParentId());
|
||||
remoteFolder.setFileId(mLocalFolder.getFileId());
|
||||
|
||||
|
@ -305,7 +305,7 @@ public class SynchronizeFolderOperation extends SyncOperation {
|
|||
OCFile remoteFile = null, localFile = null;
|
||||
for (int i=1; i<folderAndFiles.size(); i++) {
|
||||
/// new OCFile instance with the data from the server
|
||||
remoteFile = fillOCFile((RemoteFile)folderAndFiles.get(i));
|
||||
remoteFile = FileStorageUtils.fillOCFile((RemoteFile)folderAndFiles.get(i));
|
||||
remoteFile.setParentId(mLocalFolder.getFileId());
|
||||
|
||||
/// retrieve local data for the read file
|
||||
|
@ -324,7 +324,6 @@ public class SynchronizeFolderOperation extends SyncOperation {
|
|||
);
|
||||
remoteFile.setStoragePath(localFile.getStoragePath());
|
||||
// eTag will not be updated unless contents are synchronized
|
||||
// (Synchronize[File|Folder]Operation with remoteFile as parameter)
|
||||
remoteFile.setEtag(localFile.getEtag());
|
||||
if (remoteFile.isFolder()) {
|
||||
remoteFile.setFileLength(localFile.getFileLength());
|
||||
|
@ -339,7 +338,6 @@ public class SynchronizeFolderOperation extends SyncOperation {
|
|||
remoteFile.setShareByLink(localFile.isShareByLink());
|
||||
} else {
|
||||
// remote eTag will not be updated unless contents are synchronized
|
||||
// (Synchronize[File|Folder]Operation with remoteFile as parameter)
|
||||
remoteFile.setEtag("");
|
||||
}
|
||||
|
||||
|
@ -356,9 +354,8 @@ public class SynchronizeFolderOperation extends SyncOperation {
|
|||
startSyncFolderOperation(remoteFile.getRemotePath());
|
||||
}
|
||||
|
||||
//} else if (remoteFile.isFavorite()) {
|
||||
} else {
|
||||
/// prepare content synchronization for kept-in-sync files
|
||||
/// prepare content synchronization for files (any file, not just favorites)
|
||||
SynchronizeFileOperation operation = new SynchronizeFileOperation(
|
||||
localFile,
|
||||
remoteFile,
|
||||
|
@ -368,17 +365,6 @@ public class SynchronizeFolderOperation extends SyncOperation {
|
|||
);
|
||||
mFilesToSyncContents.add(operation);
|
||||
|
||||
/*} else {
|
||||
/// prepare limited synchronization for regular files
|
||||
SynchronizeFileOperation operation = new SynchronizeFileOperation(
|
||||
localFile,
|
||||
remoteFile,
|
||||
mAccount,
|
||||
true,
|
||||
false,
|
||||
mContext
|
||||
);
|
||||
mFilesToSyncContentsWithoutUpload.add(operation);*/
|
||||
}
|
||||
|
||||
updatedFiles.add(remoteFile);
|
||||
|
@ -405,7 +391,7 @@ public class SynchronizeFolderOperation extends SyncOperation {
|
|||
}
|
||||
|
||||
} else {
|
||||
/// prepare limited synchronization for regular files
|
||||
/// synchronization for regular files
|
||||
if (!child.isDown()) {
|
||||
mFilesForDirectDownload.add(child);
|
||||
|
||||
|
@ -487,26 +473,6 @@ public class SynchronizeFolderOperation extends SyncOperation {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates and populates a new {@link com.owncloud.android.datamodel.OCFile}
|
||||
* object with the data read from the server.
|
||||
*
|
||||
* @param remote remote file read from the server (remote file or folder).
|
||||
* @return New OCFile instance representing the remote resource described by we.
|
||||
*/
|
||||
private OCFile fillOCFile(RemoteFile remote) {
|
||||
OCFile file = new OCFile(remote.getRemotePath());
|
||||
file.setCreationTimestamp(remote.getCreationTimestamp());
|
||||
file.setFileLength(remote.getLength());
|
||||
file.setMimetype(remote.getMimeType());
|
||||
file.setModificationTimestamp(remote.getModifiedTimestamp());
|
||||
file.setEtag(remote.getEtag());
|
||||
file.setPermissions(remote.getPermissions());
|
||||
file.setRemoteId(remote.getRemoteId());
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Scans the default location for saving local copies of files searching for
|
||||
* a 'lost' file with the same full name as the {@link com.owncloud.android.datamodel.OCFile}
|
||||
|
|
|
@ -403,7 +403,7 @@ public class UploadFileOperation extends RemoteOperation {
|
|||
newFile.setModificationTimestamp(mFile.getModificationTimestamp());
|
||||
newFile.setModificationTimestampAtLastSyncForData(
|
||||
mFile.getModificationTimestampAtLastSyncForData());
|
||||
// newFile.setEtag(mFile.getEtag())
|
||||
newFile.setEtag(mFile.getEtag());
|
||||
newFile.setFavorite(mFile.isFavorite());
|
||||
newFile.setLastSyncDateForProperties(mFile.getLastSyncDateForProperties());
|
||||
newFile.setLastSyncDateForData(mFile.getLastSyncDateForData());
|
||||
|
|
|
@ -53,7 +53,6 @@ import com.owncloud.android.lib.resources.shares.ShareType;
|
|||
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
||||
import com.owncloud.android.lib.resources.users.GetRemoteUserNameOperation;
|
||||
import com.owncloud.android.operations.CopyFileOperation;
|
||||
import com.owncloud.android.operations.DownloadFolderOperation;
|
||||
import com.owncloud.android.operations.CreateFolderOperation;
|
||||
import com.owncloud.android.operations.CreateShareOperation;
|
||||
import com.owncloud.android.operations.GetServerInfoOperation;
|
||||
|
@ -102,7 +101,6 @@ public class OperationsService extends Service {
|
|||
public static final String ACTION_CREATE_FOLDER = "CREATE_FOLDER";
|
||||
public static final String ACTION_SYNC_FILE = "SYNC_FILE";
|
||||
public static final String ACTION_SYNC_FOLDER = "SYNC_FOLDER";
|
||||
public static final String ACTION_DOWNLOAD_FOLDER = "DOWNLOAD_FOLDER" ;
|
||||
public static final String ACTION_MOVE_FILE = "MOVE_FILE";
|
||||
public static final String ACTION_COPY_FILE = "COPY_FILE";
|
||||
|
||||
|
@ -626,16 +624,6 @@ public class OperationsService extends Service {
|
|||
System.currentTimeMillis() // TODO remove this dependency from construction time
|
||||
);
|
||||
|
||||
} else if (action.equals(ACTION_DOWNLOAD_FOLDER)) { // TODO remove when sync of folders is good enough
|
||||
// Download folder (all its descendant files are downloaded)
|
||||
String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
|
||||
operation = new DownloadFolderOperation(
|
||||
this,
|
||||
remotePath,
|
||||
account,
|
||||
System.currentTimeMillis()
|
||||
);
|
||||
|
||||
} else if (action.equals(ACTION_MOVE_FILE)) {
|
||||
// Move file/folder
|
||||
String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
|
||||
|
|
|
@ -30,7 +30,6 @@ import java.util.Map;
|
|||
|
||||
import org.apache.jackrabbit.webdav.DavException;
|
||||
|
||||
import com.owncloud.android.MainApp;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.authentication.AuthenticatorActivity;
|
||||
import com.owncloud.android.datamodel.FileDataStorageManager;
|
||||
|
@ -59,7 +58,7 @@ import android.support.v4.app.NotificationCompat;
|
|||
* Implementation of {@link AbstractThreadedSyncAdapter} responsible for synchronizing
|
||||
* ownCloud files.
|
||||
*
|
||||
* Performs a full synchronization of the account recieved in {@link #onPerformSync(Account, Bundle,
|
||||
* Performs a full synchronization of the account received in {@link #onPerformSync(Account, Bundle,
|
||||
* String, ContentProviderClient, SyncResult)}.
|
||||
*/
|
||||
public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
|
||||
|
@ -77,9 +76,7 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
|
|||
".EVENT_FULL_SYNC_END";
|
||||
public static final String EVENT_FULL_SYNC_FOLDER_CONTENTS_SYNCED =
|
||||
FileSyncAdapter.class.getName() + ".EVENT_FULL_SYNC_FOLDER_CONTENTS_SYNCED";
|
||||
//public static final String EVENT_FULL_SYNC_FOLDER_SIZE_SYNCED =
|
||||
// FileSyncAdapter.class.getName() + ".EVENT_FULL_SYNC_FOLDER_SIZE_SYNCED";
|
||||
|
||||
|
||||
public static final String EXTRA_ACCOUNT_NAME = FileSyncAdapter.class.getName() +
|
||||
".EXTRA_ACCOUNT_NAME";
|
||||
public static final String EXTRA_FOLDER_PATH = FileSyncAdapter.class.getName() +
|
||||
|
@ -268,16 +265,6 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
|
|||
if (mFailedResultsCounter > MAX_FAILED_RESULTS || isFinisher(mLastFailedResult))
|
||||
return;
|
||||
|
||||
/*
|
||||
OCFile folder,
|
||||
long currentSyncTime,
|
||||
boolean updateFolderProperties,
|
||||
boolean syncFullAccount,
|
||||
DataStorageManager dataStorageManager,
|
||||
Account account,
|
||||
Context context ) {
|
||||
}
|
||||
*/
|
||||
// folder synchronization
|
||||
RefreshFolderOperation synchFolderOp = new RefreshFolderOperation( folder,
|
||||
mCurrentSyncTime,
|
||||
|
@ -308,7 +295,7 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
|
|||
// synchronize children folders
|
||||
List<OCFile> children = synchFolderOp.getChildren();
|
||||
// beware of the 'hidden' recursion here!
|
||||
fetchChildren(folder, children, synchFolderOp.getRemoteFolderChanged());
|
||||
syncChildren(children);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
@ -351,25 +338,19 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
|
|||
|
||||
/**
|
||||
* Triggers the synchronization of any folder contained in the list of received files.
|
||||
*
|
||||
* No consideration of etag here because it MUST walk down anyway, in case that kept-in-sync files
|
||||
* have local changes.
|
||||
*
|
||||
* @param files Files to recursively synchronize.
|
||||
*/
|
||||
private void fetchChildren(OCFile parent, List<OCFile> files, boolean parentEtagChanged) {
|
||||
private void syncChildren(List<OCFile> files) {
|
||||
int i;
|
||||
OCFile newFile = null;
|
||||
//String etag = null;
|
||||
//boolean syncDown = false;
|
||||
OCFile newFile;
|
||||
for (i=0; i < files.size() && !mCancellation; i++) {
|
||||
newFile = files.get(i);
|
||||
if (newFile.isFolder()) {
|
||||
/*
|
||||
etag = newFile.getEtag();
|
||||
syncDown = (parentEtagChanged || etag == null || etag.length() == 0);
|
||||
if(syncDown) { */
|
||||
synchronizeFolder(newFile);
|
||||
//sendLocalBroadcast(EVENT_FULL_SYNC_FOLDER_SIZE_SYNCED, parent.getRemotePath(),
|
||||
// null);
|
||||
//}
|
||||
synchronizeFolder(newFile);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ package com.owncloud.android.ui.dialog;
|
|||
*
|
||||
* Triggers the removal according to the user response.
|
||||
*/
|
||||
import java.util.Vector;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.os.Bundle;
|
||||
|
@ -106,34 +105,6 @@ implements ConfirmationDialogFragmentListener {
|
|||
public void onCancel(String callerTag) {
|
||||
ComponentsGetter cg = (ComponentsGetter)getActivity();
|
||||
cg.getFileOperationsHelper().removeFile(mTargetFile, true);
|
||||
|
||||
FileDataStorageManager storageManager = cg.getStorageManager();
|
||||
|
||||
boolean containsFavorite = false;
|
||||
if (mTargetFile.isFolder()) {
|
||||
// TODO Enable when "On Device" is recovered ?
|
||||
Vector<OCFile> files = storageManager.getFolderContent(mTargetFile/*, false*/);
|
||||
for(OCFile file: files) {
|
||||
containsFavorite = file.isFavorite() || containsFavorite;
|
||||
|
||||
if (containsFavorite)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove etag for parent, if file is a favorite
|
||||
// or is a folder and contains favorite
|
||||
if (mTargetFile.isFavorite() || containsFavorite) {
|
||||
OCFile folder = null;
|
||||
if (mTargetFile.isFolder()) {
|
||||
folder = mTargetFile;
|
||||
} else {
|
||||
folder = storageManager.getFileById(mTargetFile.getParentId());
|
||||
}
|
||||
|
||||
folder.setEtag("");
|
||||
storageManager.saveFile(folder);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -363,10 +363,7 @@ public class OCFileListFragment extends ExtendedListFragment implements FileActi
|
|||
dialog.show(getFragmentManager(), ConfirmationDialogFragment.FTAG_CONFIRMATION);
|
||||
return true;
|
||||
}
|
||||
case R.id.action_download_file: {
|
||||
mContainerActivity.getFileOperationsHelper().downloadFile(mTargetFile);
|
||||
return true;
|
||||
}
|
||||
case R.id.action_download_file:
|
||||
case R.id.action_sync_file: {
|
||||
mContainerActivity.getFileOperationsHelper().syncFile(mTargetFile);
|
||||
return true;
|
||||
|
|
|
@ -32,6 +32,7 @@ import com.owncloud.android.R;
|
|||
import com.owncloud.android.datamodel.OCFile;
|
||||
import com.owncloud.android.lib.resources.files.RemoteFile;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
@ -120,7 +121,7 @@ public class FileStorageUtils {
|
|||
* Creates and populates a new {@link OCFile} object with the data read from the server.
|
||||
*
|
||||
* @param remote remote file read from the server (remote file or folder).
|
||||
* @return New OCFile instance representing the remote resource described by we.
|
||||
* @return New OCFile instance representing the remote resource described by remote.
|
||||
*/
|
||||
public static OCFile fillOCFile(RemoteFile remote) {
|
||||
OCFile file = new OCFile(remote.getRemotePath());
|
||||
|
@ -302,5 +303,33 @@ public class FileStorageUtils {
|
|||
String result = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.toLowerCase());
|
||||
return (result != null) ? result : "";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Scans the default location for saving local copies of files searching for
|
||||
* a 'lost' file with the same full name as the {@link OCFile} received as
|
||||
* parameter.
|
||||
*
|
||||
* This method helps to keep linked local copies of the files when the app is uninstalled, and then
|
||||
* reinstalled in the device. OR after the cache of the app was deleted in system settings.
|
||||
*
|
||||
* The method is assuming that all the local changes in the file where synchronized in the past. This is dangerous,
|
||||
* but assuming the contrary could lead to massive unnecessary synchronizations of downloaded file after deleting
|
||||
* the app cache.
|
||||
*
|
||||
* This should be changed in the near future to avoid any chance of data loss, but we need to add some options
|
||||
* to limit hard automatic synchronizations to wifi, unless the user wants otherwise.
|
||||
*
|
||||
* @param file File to associate a possible 'lost' local file.
|
||||
* @param account Account holding file.
|
||||
*/
|
||||
public static void searchForLocalFileInDefaultPath(OCFile file, Account account) {
|
||||
if (file.getStoragePath() == null && !file.isFolder()) {
|
||||
File f = new File(FileStorageUtils.getDefaultSavePathFor(account.name, file));
|
||||
if (f.exists()) {
|
||||
file.setStoragePath(f.getAbsolutePath());
|
||||
file.setLastSyncDateForData(f.lastModified());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue