From 297fa267e5e5b8297080eba1bd5329353607a733 Mon Sep 17 00:00:00 2001 From: Philipp Crocoll Date: Mon, 6 Nov 2023 09:01:13 +0100 Subject: [PATCH] fix bug in shared preference handling fix issue with receiving meta data: previous implementation was repeatedly listing the full contents of pCloud recursively which is slow and might not work for large contents (https://github.com/pCloud/pcloud-sdk-java/issues/42) --- .../javafilestorage/PCloudFileStorage.java | 107 +++++++++--------- .../javafilestoragetest2/MainActivity.java | 5 +- 2 files changed, 58 insertions(+), 54 deletions(-) diff --git a/src/java/JavaFileStorage/app/src/main/java/keepass2android/javafilestorage/PCloudFileStorage.java b/src/java/JavaFileStorage/app/src/main/java/keepass2android/javafilestorage/PCloudFileStorage.java index 2652a4ef..0bba1276 100644 --- a/src/java/JavaFileStorage/app/src/main/java/keepass2android/javafilestorage/PCloudFileStorage.java +++ b/src/java/JavaFileStorage/app/src/main/java/keepass2android/javafilestorage/PCloudFileStorage.java @@ -146,7 +146,7 @@ public class PCloudFileStorage extends JavaFileStorageBase DataSource dataSource = DataSource.create(data); String filename = path.substring(path.lastIndexOf("/") + 1); - String filePath = path.substring(0, path.lastIndexOf("/") + 1); + String filePath = path.substring(0, path.lastIndexOf("/")); RemoteFolder remoteFolder = this.getRemoteFolderByPath(filePath); try { @@ -175,11 +175,14 @@ public class PCloudFileStorage extends JavaFileStorageBase @Override public String createFilePath(String parentPath, String newFileName) throws Exception { + String cleanpath = this.cleanPath(parentPath); + String filepath = this.getProtocolId() + "://"; + return ( - this.getProtocolId() + "://" + - this.cleanPath(parentPath) + - ("".equals(newFileName) ? "" : "/") + - newFileName + filepath + +cleanpath + +("".equals(newFileName) || "/".equals(cleanpath) ? "" : "/") +newFileName + ); } @@ -201,7 +204,7 @@ public class PCloudFileStorage extends JavaFileStorageBase @Override public FileEntry getFileEntry(String path) throws Exception { path = this.cleanPath(path); - + //do not call getRemoteFileByPath because path could represent a file or folder, we don't know here RemoteEntry remoteEntry = this.getRemoteEntryByPath(path); return this.convertRemoteEntryToFileEntry( @@ -214,10 +217,13 @@ public class PCloudFileStorage extends JavaFileStorageBase public void delete(String path) throws Exception { path = this.cleanPath(path); - RemoteEntry remoteEntry = this.getRemoteFileByPath(path); + RemoteEntry remoteEntry = this.getRemoteEntryByPath(path); try { - this.apiClient.delete(remoteEntry).execute(); + if (remoteEntry.isFolder()) + this.apiClient.deleteFolder(remoteEntry.asFolder(), true).execute(); + else + this.apiClient.delete(remoteEntry).execute(); } catch (ApiError e) { throw convertApiError(e); } @@ -289,7 +295,7 @@ public class PCloudFileStorage extends JavaFileStorageBase } private ApiClient createApiClientFromSharedPrefs() { - SharedPreferences prefs = this.ctx.getSharedPreferences(sharedPrefPrefix + SHARED_PREF_NAME, Context.MODE_PRIVATE); + SharedPreferences prefs = getPrefs(); String authToken = prefs.getString(SHARED_PREF_AUTH_TOKEN, null); String apiHost = prefs.getString(SHARED_PREF_API_HOST, null); return this.createApiClient(authToken, apiHost); @@ -313,15 +319,20 @@ public class PCloudFileStorage extends JavaFileStorageBase private void clearAuthToken() { this.apiClient = null; - SharedPreferences prefs = this.ctx.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE); + SharedPreferences prefs = getPrefs(); SharedPreferences.Editor edit = prefs.edit(); edit.clear(); edit.apply(); } + private SharedPreferences getPrefs() + { + return this.ctx.getSharedPreferences(sharedPrefPrefix + SHARED_PREF_NAME, Context.MODE_PRIVATE); + } + private void setAuthToken(String authToken, String apiHost) { this.apiClient = this.createApiClient(authToken, apiHost); - SharedPreferences prefs = this.ctx.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE); + SharedPreferences prefs = getPrefs(); SharedPreferences.Editor edit = prefs.edit(); edit.putString(SHARED_PREF_AUTH_TOKEN, authToken); edit.putString(SHARED_PREF_API_HOST, apiHost); @@ -335,27 +346,47 @@ public class PCloudFileStorage extends JavaFileStorageBase } private RemoteFile getRemoteFileByPath(String path) throws Exception { - RemoteEntry remoteEntry = this.getRemoteEntryByPath(path); + Call call = this.apiClient.loadFile(path); try { - return remoteEntry.asFile(); - } catch (IllegalStateException e) { - throw new FileNotFoundException(e.toString()); + return call.execute(); + } catch (ApiError apiError) { + throw convertApiError(apiError); } } private RemoteFolder getRemoteFolderByPath(String path) throws Exception { - RemoteEntry remoteEntry = this.getRemoteEntryByPath(path); + Call call; + if ("".equals(path)) + call = this.apiClient.listFolder(RemoteFolder.ROOT_FOLDER_ID, false); + else + call = this.apiClient.listFolder(path, false); try { - return remoteEntry.asFolder(); - } catch (IllegalStateException e) { - throw new FileNotFoundException(e.toString()); + return call.execute(); + } catch (ApiError apiError) { + throw convertApiError(apiError); } + } private RemoteEntry getRemoteEntryByPath(String path) throws Exception { - Call call = this.apiClient.listFolder(RemoteFolder.ROOT_FOLDER_ID, true); + if ("/".equals(path)) { + try { + return this.apiClient.listFolder(RemoteFolder.ROOT_FOLDER_ID, false).execute(); + } catch (ApiError apiError) { + throw convertApiError(apiError); + } + } + + String filename = path.substring(path.lastIndexOf("/") + 1); + String parentPath = path.substring(0, path.lastIndexOf("/")); + + Call call; + if ("".equals(parentPath)) + call = this.apiClient.listFolder(RemoteFolder.ROOT_FOLDER_ID, false); + else + call = this.apiClient.listFolder(parentPath, false); RemoteFolder folder; try { @@ -364,40 +395,12 @@ public class PCloudFileStorage extends JavaFileStorageBase throw convertApiError(apiError); } - if ("/".equals(path)) { - return folder; + for (RemoteEntry remoteEntry : folder.children()) { + if (remoteEntry.name() != null && remoteEntry.name().equals(filename)) + return remoteEntry; } + throw new FileNotFoundException("did not find " + path); - String[] fileNames = path.substring(1).split("/"); - RemoteFolder currentFolder = folder; - Iterator fileNamesIterator = Arrays.asList(fileNames).iterator(); - while (true) { - String fileName = fileNamesIterator.next(); - - Iterator entryIterator = currentFolder.children().iterator(); - while (true) { - RemoteEntry remoteEntry; - try { - remoteEntry = entryIterator.next(); - } catch (NoSuchElementException e) { - throw new FileNotFoundException(e.toString()); - } - - if (currentFolder.folderId() == remoteEntry.parentFolderId() && fileName.equals(remoteEntry.name())) { - if (!fileNamesIterator.hasNext()) { - return remoteEntry; - } - - try { - currentFolder = remoteEntry.asFolder(); - } catch (IllegalStateException e) { - throw new FileNotFoundException(e.toString()); - } - - break; - } - } - } } private Exception convertApiError(ApiError e) { diff --git a/src/java/JavaFileStorageTest-AS/app/src/main/java/com/crocoapps/javafilestoragetest2/MainActivity.java b/src/java/JavaFileStorageTest-AS/app/src/main/java/com/crocoapps/javafilestoragetest2/MainActivity.java index 328659b2..9e0bf46b 100644 --- a/src/java/JavaFileStorageTest-AS/app/src/main/java/com/crocoapps/javafilestoragetest2/MainActivity.java +++ b/src/java/JavaFileStorageTest-AS/app/src/main/java/com/crocoapps/javafilestoragetest2/MainActivity.java @@ -148,6 +148,7 @@ import java.util.List; import keepass2android.javafilestorage.GoogleDriveAppDataFileStorage; import keepass2android.javafilestorage.JavaFileStorage; import keepass2android.javafilestorage.JavaFileStorage.FileEntry; +import keepass2android.javafilestorage.PCloudFileStorage; import keepass2android.javafilestorage.SftpStorage; import keepass2android.javafilestorage.UserInteractionRequiredException; import keepass2android.javafilestorage.WebDavStorage; @@ -538,8 +539,8 @@ public class MainActivity extends Activity implements JavaFileStorage.FileStorag } static JavaFileStorage createStorageToTest(Context ctx, Context appContext, boolean simulateRestart) { - storageToTest = new SftpStorage(ctx.getApplicationContext()); - //storageToTest = new PCloudFileStorage(ctx, "yCeH59Ffgtm"); + //storageToTest = new SftpStorage(ctx.getApplicationContext()); + storageToTest = new PCloudFileStorage(ctx, "FLm22de7bdS", "pcloud", "pcloudtest"); //storageToTest = new SkyDriveFileStorage("000000004010C234", appContext);