From 033eaceb0a7086e44fba98aefbdcbaa884778c21 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Wed, 14 Sep 2022 11:26:42 +0200 Subject: [PATCH 1/4] Ignore hidden remote files & refactor ListFileRemoteOperation --- .../operations/ListFileRemoteOperation.java | 145 +++++++++++------- 1 file changed, 88 insertions(+), 57 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/operations/ListFileRemoteOperation.java b/app/src/main/java/foundation/e/drive/operations/ListFileRemoteOperation.java index 29dd762b..55a84b55 100644 --- a/app/src/main/java/foundation/e/drive/operations/ListFileRemoteOperation.java +++ b/app/src/main/java/foundation/e/drive/operations/ListFileRemoteOperation.java @@ -28,19 +28,20 @@ import foundation.e.drive.utils.CommonUtils; /** * /!\ Doesn't require NextcloudClient yet * @author Vincent Bourgmayer - * Created on 04/05/2018. */ public class ListFileRemoteOperation extends RemoteOperation> { private final String TAG = ListFileRemoteOperation.class.getSimpleName(); - private final List mSyncedFolders; - private final Context mContext; + private final List syncedFolders; + private final Context context; private final int initialFolderNumber; + private final ArrayList remoteFiles; public ListFileRemoteOperation(List syncedFolders, Context context, int initialFolderNumber) { - this.mSyncedFolders = syncedFolders; - this.mContext = context; + this.syncedFolders = syncedFolders; + this.context = context; this.initialFolderNumber = initialFolderNumber; + remoteFiles = new ArrayList<>(); } /** @@ -50,12 +51,10 @@ public class ListFileRemoteOperation extends RemoteOperation> run(OwnCloudClient ownCloudClient) { - Log.i(TAG, "run()"); - final ArrayList mRemoteFiles = new ArrayList<>(); RemoteOperationResult finalResult; boolean atLeastOneDirAsChanged = false; - final ListIterator mSyncedFolderIterator = mSyncedFolders.listIterator(); + final ListIterator mSyncedFolderIterator = syncedFolders.listIterator(); while (mSyncedFolderIterator.hasNext()) { try { @@ -71,73 +70,106 @@ public class ListFileRemoteOperation extends RemoteOperation 0) { - syncedFolder.setId(syncedFolderId); - } else { + final int syncedFolderId = (int) DbHelper.insertSyncedFolder(syncedFolder, context); + if (syncedFolderId <= 0) { mSyncedFolderIterator.remove(); Log.w(TAG, "syncedFolder " + syncedFolder.getRemoteFolder() + " doesn't have a valid ID"); continue; } + syncedFolder.setId(syncedFolderId); } final ReadFolderRemoteOperation operation = new ReadFolderRemoteOperation(syncedFolder.getRemoteFolder()); final RemoteOperationResult result = operation.execute(ownCloudClient); - if (result.isSuccess()) { - final int dataSize = result.getData().size(); - final RemoteFile directory = (RemoteFile) result.getData().get(0); - - if (directory.getEtag().equals(syncedFolder.getLastEtag())) { - continue; - } - syncedFolder.setLastEtag(directory.getEtag()).setToSync(true); - atLeastOneDirAsChanged = true; - - if (dataSize > 1) { - final List remoteFiles = result.getData().subList(1, dataSize); //get list of subfiles - - //loop through subelements - for (int i = -1, remoteFilesSize = remoteFiles.size(); ++i < remoteFilesSize; ) { - final RemoteFile remoteFile = (RemoteFile) remoteFiles.get(i); - - if (remoteFile.getMimeType().equals("DIR")) { - final String suffixPath = remoteFile.getRemotePath().substring(syncedFolder.getRemoteFolder().length()); - final SyncedFolder subSyncedFolder = new SyncedFolder(syncedFolder, suffixPath, 0L, ""); //need to set empty etag to allow it to be scan - mSyncedFolderIterator.add(subSyncedFolder); - mSyncedFolderIterator.previous(); - } else { - mRemoteFiles.add(remoteFile); - } - } - } - }else { //Result isn't a success - if (result.getHttpCode() == 404) { //File not found + atLeastOneDirAsChanged = onListFileSuccess(mSyncedFolderIterator, syncedFolder, result); + } else { //Result isn't a success + if (result.getHttpCode() == 404) { //dir has not been found atLeastOneDirAsChanged = true; - syncedFolder.setToSync(true); - - final File localFolder = new File(syncedFolder.getLocalFolder()); - if (!localFolder.exists()) { - if (syncedFolder.getId() > this.initialFolderNumber) { - final int deleteResult = DbHelper.deleteSyncedFolder(syncedFolder.getId(), mContext); - Log.d(TAG, "syncedFolder Id: " + syncedFolder.getId() + " deletion from db return " + deleteResult + " row affected"); - } - mSyncedFolderIterator.remove(); - } else if (localFolder.listFiles().length == 0) { - localFolder.delete(); - } + onHttp404Received(mSyncedFolderIterator, syncedFolder); } Log.w(TAG, "ReadFolderRemoteOperation failed : http " + result.getHttpCode() + ", " + result.getLogMessage() + " => Ignored"); } } finalResult = new RemoteOperationResult<>(RemoteOperationResult.ResultCode.OK); if (atLeastOneDirAsChanged) { - DbHelper.updateSyncedFolders(this.mSyncedFolders, this.mContext); - finalResult.setResultData(mRemoteFiles); + DbHelper.updateSyncedFolders(this.syncedFolders, this.context); + finalResult.setResultData(remoteFiles); } return finalResult; } + + /** + * Analyze list of remote files for a given Directory + * @param iterator ListIterator contains list of syncedFolder to check + * @param syncedFolder the SyncedFolder for the given Directory + * @param result Result of ListRemoteFile operation + * @return true if some directory has changed or its content + */ + private boolean onListFileSuccess(final ListIterator iterator, SyncedFolder syncedFolder, RemoteOperationResult result) { + final int dataSize = result.getData().size(); + final RemoteFile directory = (RemoteFile) result.getData().get(0); + + if (directory.getEtag().equals(syncedFolder.getLastEtag())) { + return false; + } + syncedFolder.setLastEtag(directory.getEtag()).setToSync(true); + + final List subFiles = result.getData().subList(1, dataSize); + + for (int i = -1, subFilesSize = subFiles.size(); ++i < subFilesSize;) { + final RemoteFile remoteFile = (RemoteFile) subFiles.get(i); + + if (remoteFile.getMimeType().equals("DIR")) { + final String suffixPath = remoteFile.getRemotePath().substring(syncedFolder.getRemoteFolder().length()); + final SyncedFolder subSyncedFolder = new SyncedFolder(syncedFolder, suffixPath, 0L, ""); //need to set empty etag to allow it to be scan + iterator.add(subSyncedFolder); + iterator.previous(); + } else if (!isHiddenFile(remoteFile)) { + this.remoteFiles.add(remoteFile); + } + } + return true; + } + + /** + * Handle a case where the checked directory is missing on cloud + * @param iterator ListIterator list of syncedFolder to scan + * @param syncedFolder Missing syncedFolder on cloud + */ + private void onHttp404Received(final ListIterator iterator, SyncedFolder syncedFolder) { + syncedFolder.setToSync(true); + + final File localFolder = new File(syncedFolder.getLocalFolder()); + if (localFolder.listFiles().length == 0) { + localFolder.delete(); + } + + if (!localFolder.exists()) { + if (syncedFolder.getId() > this.initialFolderNumber) { //Do not remove initial syncedFolder + DbHelper.deleteSyncedFolder(syncedFolder.getId(), context); + } + iterator.remove(); + } + } + + + /** + * Indicate if remote file is an hidden file + * @param file Remote file + * @return true if it's an hidden file + */ + private boolean isHiddenFile(RemoteFile file) { + final String fileName = CommonUtils.getFileNameFromPath(file.getRemotePath()); + return fileName.startsWith("."); + } + + /** + * Indicate if we should skip SyncedFolder + * @param syncedFolder + * @return + */ private boolean shouldSkipSyncedFolder(SyncedFolder syncedFolder) { return (syncedFolder.isMediaType() && CommonUtils.getFileNameFromPath(syncedFolder.getRemoteFolder()).startsWith(".")) @@ -145,10 +177,9 @@ public class ListFileRemoteOperation extends RemoteOperation getSyncedFolderList(){ - return this.mSyncedFolders; + return this.syncedFolders; } } -- GitLab From 62a4316bf03655381e68d625b5985ea2851b88dd Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Wed, 14 Sep 2022 11:27:18 +0200 Subject: [PATCH 2/4] Update version number to 1.2.2 remove useless todo in ObserverService Improve one log --- app/build.gradle | 2 +- .../foundation/e/drive/operations/ListFileRemoteOperation.java | 2 +- .../main/java/foundation/e/drive/services/ObserverService.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 033895ed..8d11cf62 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -5,7 +5,7 @@ plugins { def versionMajor = 1 def versionMinor = 2 -def versionPatch = 1 +def versionPatch = 2 diff --git a/app/src/main/java/foundation/e/drive/operations/ListFileRemoteOperation.java b/app/src/main/java/foundation/e/drive/operations/ListFileRemoteOperation.java index 55a84b55..3c5c4d7f 100644 --- a/app/src/main/java/foundation/e/drive/operations/ListFileRemoteOperation.java +++ b/app/src/main/java/foundation/e/drive/operations/ListFileRemoteOperation.java @@ -73,7 +73,7 @@ public class ListFileRemoteOperation extends RemoteOperation Date: Thu, 15 Sep 2022 12:18:40 +0200 Subject: [PATCH 3/4] fix ignored remote file due to boolean in listRemoteFileOperation --- .../e/drive/operations/ListFileRemoteOperation.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/foundation/e/drive/operations/ListFileRemoteOperation.java b/app/src/main/java/foundation/e/drive/operations/ListFileRemoteOperation.java index 3c5c4d7f..a3e7926e 100644 --- a/app/src/main/java/foundation/e/drive/operations/ListFileRemoteOperation.java +++ b/app/src/main/java/foundation/e/drive/operations/ListFileRemoteOperation.java @@ -82,7 +82,8 @@ public class ListFileRemoteOperation extends RemoteOperation Date: Thu, 15 Sep 2022 15:27:02 +0200 Subject: [PATCH 4/4] add private static field for HTTP 404 value in ListFileRemoteOperation --- .../foundation/e/drive/operations/ListFileRemoteOperation.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/foundation/e/drive/operations/ListFileRemoteOperation.java b/app/src/main/java/foundation/e/drive/operations/ListFileRemoteOperation.java index a3e7926e..e1e139db 100644 --- a/app/src/main/java/foundation/e/drive/operations/ListFileRemoteOperation.java +++ b/app/src/main/java/foundation/e/drive/operations/ListFileRemoteOperation.java @@ -31,6 +31,7 @@ import foundation.e.drive.utils.CommonUtils; */ public class ListFileRemoteOperation extends RemoteOperation> { private final String TAG = ListFileRemoteOperation.class.getSimpleName(); + private static final int HTTP_404 = 404; private final List syncedFolders; private final Context context; @@ -85,7 +86,7 @@ public class ListFileRemoteOperation extends RemoteOperation