Loading app/src/main/java/foundation/e/drive/operations/ListFileRemoteOperation.java +88 −57 Original line number Diff line number Diff line Loading @@ -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<ArrayList<RemoteFile>> { private final String TAG = ListFileRemoteOperation.class.getSimpleName(); private final List<SyncedFolder> mSyncedFolders; private final Context mContext; private final List<SyncedFolder> syncedFolders; private final Context context; private final int initialFolderNumber; private final ArrayList<RemoteFile> remoteFiles; public ListFileRemoteOperation(List<SyncedFolder> syncedFolders, Context context, int initialFolderNumber) { this.mSyncedFolders = syncedFolders; this.mContext = context; this.syncedFolders = syncedFolders; this.context = context; this.initialFolderNumber = initialFolderNumber; remoteFiles = new ArrayList<>(); } /** Loading @@ -50,12 +51,10 @@ public class ListFileRemoteOperation extends RemoteOperation<ArrayList<RemoteFil */ @Override protected RemoteOperationResult<ArrayList<RemoteFile>> run(OwnCloudClient ownCloudClient) { Log.i(TAG, "run()"); final ArrayList<RemoteFile> mRemoteFiles = new ArrayList<>(); RemoteOperationResult finalResult; boolean atLeastOneDirAsChanged = false; final ListIterator<SyncedFolder> mSyncedFolderIterator = mSyncedFolders.listIterator(); final ListIterator<SyncedFolder> mSyncedFolderIterator = syncedFolders.listIterator(); while (mSyncedFolderIterator.hasNext()) { try { Loading @@ -71,73 +70,106 @@ public class ListFileRemoteOperation extends RemoteOperation<ArrayList<RemoteFil } if (syncedFolder.getId() == -1) { final int syncedFolderId = (int) DbHelper.insertSyncedFolder(syncedFolder, mContext); if (syncedFolderId > 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()) { atLeastOneDirAsChanged = onListFileSuccess(mSyncedFolderIterator, syncedFolder, result); } else { //Result isn't a success if (result.getHttpCode() == 404) { //dir has not been found atLeastOneDirAsChanged = true; 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.syncedFolders, this.context); finalResult.setResultData(remoteFiles); } return finalResult; } /** * Analyze list of remote files for a given Directory * @param iterator ListIterator<SyncedFolder> 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<SyncedFolder> 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())) { continue; return false; } syncedFolder.setLastEtag(directory.getEtag()).setToSync(true); atLeastOneDirAsChanged = true; if (dataSize > 1) { final List<Object> remoteFiles = result.getData().subList(1, dataSize); //get list of subfiles final List<Object> subFiles = result.getData().subList(1, dataSize); //loop through subelements for (int i = -1, remoteFilesSize = remoteFiles.size(); ++i < remoteFilesSize; ) { final RemoteFile remoteFile = (RemoteFile) remoteFiles.get(i); 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 mSyncedFolderIterator.add(subSyncedFolder); mSyncedFolderIterator.previous(); } else { mRemoteFiles.add(remoteFile); iterator.add(subSyncedFolder); iterator.previous(); } else if (!isHiddenFile(remoteFile)) { this.remoteFiles.add(remoteFile); } } return true; } }else { //Result isn't a success if (result.getHttpCode() == 404) { //File not found atLeastOneDirAsChanged = true; /** * Handle a case where the checked directory is missing on cloud * @param iterator ListIterator<SyncedFolder> list of syncedFolder to scan * @param syncedFolder Missing syncedFolder on cloud */ private void onHttp404Received(final ListIterator<SyncedFolder> iterator, SyncedFolder syncedFolder) { 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) { 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); } Log.w(TAG, "ReadFolderRemoteOperation failed : http " + result.getHttpCode() + ", " + result.getLogMessage() + " => Ignored"); } iterator.remove(); } finalResult = new RemoteOperationResult<>(RemoteOperationResult.ResultCode.OK); if (atLeastOneDirAsChanged) { DbHelper.updateSyncedFolders(this.mSyncedFolders, this.mContext); finalResult.setResultData(mRemoteFiles); } return finalResult; /** * 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(".")) Loading @@ -145,10 +177,9 @@ public class ListFileRemoteOperation extends RemoteOperation<ArrayList<RemoteFil } /** * * @return list of syncedFolder */ public List<SyncedFolder> getSyncedFolderList(){ return this.mSyncedFolders; return this.syncedFolders; } } Loading
app/src/main/java/foundation/e/drive/operations/ListFileRemoteOperation.java +88 −57 Original line number Diff line number Diff line Loading @@ -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<ArrayList<RemoteFile>> { private final String TAG = ListFileRemoteOperation.class.getSimpleName(); private final List<SyncedFolder> mSyncedFolders; private final Context mContext; private final List<SyncedFolder> syncedFolders; private final Context context; private final int initialFolderNumber; private final ArrayList<RemoteFile> remoteFiles; public ListFileRemoteOperation(List<SyncedFolder> syncedFolders, Context context, int initialFolderNumber) { this.mSyncedFolders = syncedFolders; this.mContext = context; this.syncedFolders = syncedFolders; this.context = context; this.initialFolderNumber = initialFolderNumber; remoteFiles = new ArrayList<>(); } /** Loading @@ -50,12 +51,10 @@ public class ListFileRemoteOperation extends RemoteOperation<ArrayList<RemoteFil */ @Override protected RemoteOperationResult<ArrayList<RemoteFile>> run(OwnCloudClient ownCloudClient) { Log.i(TAG, "run()"); final ArrayList<RemoteFile> mRemoteFiles = new ArrayList<>(); RemoteOperationResult finalResult; boolean atLeastOneDirAsChanged = false; final ListIterator<SyncedFolder> mSyncedFolderIterator = mSyncedFolders.listIterator(); final ListIterator<SyncedFolder> mSyncedFolderIterator = syncedFolders.listIterator(); while (mSyncedFolderIterator.hasNext()) { try { Loading @@ -71,73 +70,106 @@ public class ListFileRemoteOperation extends RemoteOperation<ArrayList<RemoteFil } if (syncedFolder.getId() == -1) { final int syncedFolderId = (int) DbHelper.insertSyncedFolder(syncedFolder, mContext); if (syncedFolderId > 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()) { atLeastOneDirAsChanged = onListFileSuccess(mSyncedFolderIterator, syncedFolder, result); } else { //Result isn't a success if (result.getHttpCode() == 404) { //dir has not been found atLeastOneDirAsChanged = true; 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.syncedFolders, this.context); finalResult.setResultData(remoteFiles); } return finalResult; } /** * Analyze list of remote files for a given Directory * @param iterator ListIterator<SyncedFolder> 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<SyncedFolder> 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())) { continue; return false; } syncedFolder.setLastEtag(directory.getEtag()).setToSync(true); atLeastOneDirAsChanged = true; if (dataSize > 1) { final List<Object> remoteFiles = result.getData().subList(1, dataSize); //get list of subfiles final List<Object> subFiles = result.getData().subList(1, dataSize); //loop through subelements for (int i = -1, remoteFilesSize = remoteFiles.size(); ++i < remoteFilesSize; ) { final RemoteFile remoteFile = (RemoteFile) remoteFiles.get(i); 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 mSyncedFolderIterator.add(subSyncedFolder); mSyncedFolderIterator.previous(); } else { mRemoteFiles.add(remoteFile); iterator.add(subSyncedFolder); iterator.previous(); } else if (!isHiddenFile(remoteFile)) { this.remoteFiles.add(remoteFile); } } return true; } }else { //Result isn't a success if (result.getHttpCode() == 404) { //File not found atLeastOneDirAsChanged = true; /** * Handle a case where the checked directory is missing on cloud * @param iterator ListIterator<SyncedFolder> list of syncedFolder to scan * @param syncedFolder Missing syncedFolder on cloud */ private void onHttp404Received(final ListIterator<SyncedFolder> iterator, SyncedFolder syncedFolder) { 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) { 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); } Log.w(TAG, "ReadFolderRemoteOperation failed : http " + result.getHttpCode() + ", " + result.getLogMessage() + " => Ignored"); } iterator.remove(); } finalResult = new RemoteOperationResult<>(RemoteOperationResult.ResultCode.OK); if (atLeastOneDirAsChanged) { DbHelper.updateSyncedFolders(this.mSyncedFolders, this.mContext); finalResult.setResultData(mRemoteFiles); } return finalResult; /** * 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(".")) Loading @@ -145,10 +177,9 @@ public class ListFileRemoteOperation extends RemoteOperation<ArrayList<RemoteFil } /** * * @return list of syncedFolder */ public List<SyncedFolder> getSyncedFolderList(){ return this.mSyncedFolders; return this.syncedFolders; } }