From edced50ef982044c9f869f1170e8adaa3f83f49e Mon Sep 17 00:00:00 2001 From: yzerk Date: Mon, 19 Dec 2022 11:50:41 +0200 Subject: [PATCH 1/5] #312 - handle empty files upload --- .../com/crowdin/cli/client/CrowdinProjectClient.java | 9 +++++++-- .../com/crowdin/cli/client/EmptyFileException.java | 9 +++++++++ .../java/com/crowdin/cli/client/ProjectClient.java | 2 +- .../cli/commands/actions/UploadSourcesAction.java | 10 ++++++++++ src/main/resources/messages/messages.properties | 1 + 5 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/crowdin/cli/client/EmptyFileException.java diff --git a/src/main/java/com/crowdin/cli/client/CrowdinProjectClient.java b/src/main/java/com/crowdin/cli/client/CrowdinProjectClient.java index b34cbeec9..4609f7250 100644 --- a/src/main/java/com/crowdin/cli/client/CrowdinProjectClient.java +++ b/src/main/java/com/crowdin/cli/client/CrowdinProjectClient.java @@ -140,8 +140,12 @@ public List listBranches() { } @Override - public Long uploadStorage(String fileName, InputStream content) { - Storage storage = executeRequest(() -> this.client.getStorageApi() + public Long uploadStorage(String fileName, InputStream content) throws ResponseException { + Map, ResponseException> errorHandlers = new LinkedHashMap, ResponseException>() {{ + put((code, message) -> StringUtils.containsAny(message, "streamIsEmpty", "Stream size is null. Not empty content expected"), + new EmptyFileException("Not empty content expected")); + }}; + Storage storage = executeRequest(errorHandlers, () -> this.client.getStorageApi() .addStorage(fileName, content) .getData()); return storage.getId(); @@ -187,6 +191,7 @@ public void addSource(AddFileRequest request) throws ResponseException { put((code, message) -> message.contains("File from storage with id #" + request.getStorageId() + " was not found"), new RepeatException()); put((code, message) -> StringUtils.contains(message, "Name must be unique"), new ExistsResponseException()); put((code, message) -> StringUtils.contains(message, "Invalid SRX specified"), new ResponseException("Invalid SRX file specified")); + put((code, message) -> StringUtils.containsAny(message, "isEmpty", "Value is required and can't be empty"), new EmptyFileException("Value is required and can't be empty")); }}; executeRequestWithPossibleRetry( errorHandlers, diff --git a/src/main/java/com/crowdin/cli/client/EmptyFileException.java b/src/main/java/com/crowdin/cli/client/EmptyFileException.java new file mode 100644 index 000000000..52fa34cee --- /dev/null +++ b/src/main/java/com/crowdin/cli/client/EmptyFileException.java @@ -0,0 +1,9 @@ +package com.crowdin.cli.client; + + +public class EmptyFileException extends ResponseException { + + public EmptyFileException(String message) { + super(message); + } +} diff --git a/src/main/java/com/crowdin/cli/client/ProjectClient.java b/src/main/java/com/crowdin/cli/client/ProjectClient.java index 2208644b1..4e5daa5a5 100644 --- a/src/main/java/com/crowdin/cli/client/ProjectClient.java +++ b/src/main/java/com/crowdin/cli/client/ProjectClient.java @@ -39,7 +39,7 @@ public interface ProjectClient extends Client { List listBranches(); - Long uploadStorage(String fileName, InputStream content); + Long uploadStorage(String fileName, InputStream content) throws ResponseException; Directory addDirectory(AddDirectoryRequest request) throws ResponseException; diff --git a/src/main/java/com/crowdin/cli/commands/actions/UploadSourcesAction.java b/src/main/java/com/crowdin/cli/commands/actions/UploadSourcesAction.java index 49e8a94f6..fa648ce2c 100644 --- a/src/main/java/com/crowdin/cli/commands/actions/UploadSourcesAction.java +++ b/src/main/java/com/crowdin/cli/commands/actions/UploadSourcesAction.java @@ -1,6 +1,7 @@ package com.crowdin.cli.commands.actions; import com.crowdin.cli.client.CrowdinProjectFull; +import com.crowdin.cli.client.EmptyFileException; import com.crowdin.cli.client.ExistsResponseException; import com.crowdin.cli.client.ProjectClient; import com.crowdin.cli.commands.NewAction; @@ -221,6 +222,9 @@ public void act(Outputter out, PropertiesWithFiles pb, ProjectClient client) { } else { out.println(fileFullPath); } + } catch (EmptyFileException e){ + errorsPresented.set(false); + out.println(WARNING.withIcon("!!!!!!!")); } catch (Exception e) { errorsPresented.set(true); throw new RuntimeException(String.format(RESOURCE_BUNDLE.getString("error.uploading_file"), fileFullPath), e); @@ -259,6 +263,9 @@ public void act(Outputter out, PropertiesWithFiles pb, ProjectClient client) { try (InputStream fileStream = new FileInputStream(sourceFile)) { request.setStorageId(client.uploadStorage(source.substring(source.lastIndexOf(Utils.PATH_SEPARATOR) + 1), fileStream)); + } catch (EmptyFileException e){ + errorsPresented.set(false); + out.println(WARNING.withIcon(String.format(RESOURCE_BUNDLE.getString("error.upload_to_storage"), fileFullPath))); } catch (Exception e) { errorsPresented.set(true); throw new RuntimeException( @@ -269,6 +276,9 @@ public void act(Outputter out, PropertiesWithFiles pb, ProjectClient client) { } catch (ExistsResponseException e) { errorsPresented.set(true); throw new RuntimeException(String.format(RESOURCE_BUNDLE.getString("error.file_already_exists"), fileFullPath)); + } catch (EmptyFileException e){ + errorsPresented.set(false); + out.println(WARNING.withIcon(String.format(RESOURCE_BUNDLE.getString("error.empty_file_upload"), e.getMessage()))); } catch (Exception e) { errorsPresented.set(true); throw new RuntimeException(String.format(RESOURCE_BUNDLE.getString("error.uploading_file"), fileFullPath), e); diff --git a/src/main/resources/messages/messages.properties b/src/main/resources/messages/messages.properties index 3e0961531..7dc131960 100755 --- a/src/main/resources/messages/messages.properties +++ b/src/main/resources/messages/messages.properties @@ -260,6 +260,7 @@ error.cast_param_list_type='%s' list contains value(s) of type '%s' instead of ' error.dest_and_pattern_in_source=The 'dest' parameter only works for single files specified in the 'source' parameter error.dest_and_preserve_hierarchy=The 'dest' parameter only works for single files with the specified 'preserve_hierarchy': true option error.upload_to_storage=Failed to upload the '%s' file to the storage. Please contact our support team for help +error.empty_file_upload=Wrong parameters: %s error.language_not_exist=Language '%s' doesn't exist in the project. Try specifying another language code error.languages_not_exist=Language(s) %s doesn't exist in the project. Try specifying another language code(s) error.building_translation=Failed to build translation. Please contact our support team for help From 7675ec23ae0e6010c8b1eaeefd7fd48a86972e01 Mon Sep 17 00:00:00 2001 From: yzerk Date: Wed, 21 Dec 2022 11:04:25 +0200 Subject: [PATCH 2/5] fix failed tests --- .../java/com/crowdin/cli/client/CrowdinProjectClientTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/crowdin/cli/client/CrowdinProjectClientTest.java b/src/test/java/com/crowdin/cli/client/CrowdinProjectClientTest.java index 8225f5be5..97ac0bd84 100644 --- a/src/test/java/com/crowdin/cli/client/CrowdinProjectClientTest.java +++ b/src/test/java/com/crowdin/cli/client/CrowdinProjectClientTest.java @@ -329,7 +329,7 @@ public void testAddBranch() { } @Test - public void testUploadStorage() throws IOException { + public void testUploadStorage() throws IOException, ResponseException { InputStream requestData = IOUtils.toInputStream("Something to send", "UTF-8"); StorageResponseObject response = new StorageResponseObject() {{ setData(new Storage()); From f4e09f5695cdac099c2de69fea946f66f0876f58 Mon Sep 17 00:00:00 2001 From: yzerk Date: Wed, 21 Dec 2022 14:51:49 +0200 Subject: [PATCH 3/5] fix review notes --- .../cli/commands/actions/UploadSourcesAction.java | 9 ++------- src/main/resources/messages/messages.properties | 1 + 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/crowdin/cli/commands/actions/UploadSourcesAction.java b/src/main/java/com/crowdin/cli/commands/actions/UploadSourcesAction.java index fa648ce2c..2d9f92f70 100644 --- a/src/main/java/com/crowdin/cli/commands/actions/UploadSourcesAction.java +++ b/src/main/java/com/crowdin/cli/commands/actions/UploadSourcesAction.java @@ -222,9 +222,6 @@ public void act(Outputter out, PropertiesWithFiles pb, ProjectClient client) { } else { out.println(fileFullPath); } - } catch (EmptyFileException e){ - errorsPresented.set(false); - out.println(WARNING.withIcon("!!!!!!!")); } catch (Exception e) { errorsPresented.set(true); throw new RuntimeException(String.format(RESOURCE_BUNDLE.getString("error.uploading_file"), fileFullPath), e); @@ -265,7 +262,8 @@ public void act(Outputter out, PropertiesWithFiles pb, ProjectClient client) { request.setStorageId(client.uploadStorage(source.substring(source.lastIndexOf(Utils.PATH_SEPARATOR) + 1), fileStream)); } catch (EmptyFileException e){ errorsPresented.set(false); - out.println(WARNING.withIcon(String.format(RESOURCE_BUNDLE.getString("error.upload_to_storage"), fileFullPath))); + out.println(WARNING.withIcon(String.format(RESOURCE_BUNDLE.getString("message.uploading_file_skipped"), fileFullPath))); + return; } catch (Exception e) { errorsPresented.set(true); throw new RuntimeException( @@ -276,9 +274,6 @@ public void act(Outputter out, PropertiesWithFiles pb, ProjectClient client) { } catch (ExistsResponseException e) { errorsPresented.set(true); throw new RuntimeException(String.format(RESOURCE_BUNDLE.getString("error.file_already_exists"), fileFullPath)); - } catch (EmptyFileException e){ - errorsPresented.set(false); - out.println(WARNING.withIcon(String.format(RESOURCE_BUNDLE.getString("error.empty_file_upload"), e.getMessage()))); } catch (Exception e) { errorsPresented.set(true); throw new RuntimeException(String.format(RESOURCE_BUNDLE.getString("error.uploading_file"), fileFullPath), e); diff --git a/src/main/resources/messages/messages.properties b/src/main/resources/messages/messages.properties index 7dc131960..459cf17ee 100755 --- a/src/main/resources/messages/messages.properties +++ b/src/main/resources/messages/messages.properties @@ -398,6 +398,7 @@ message.new_version_text=New version of Crowdin CLI is available! %s -> %s message.new_version_text.2=Changelog: @|cyan https://github.com/crowdin/crowdin-cli/releases/latest|@ message.new_version_text.3=Please update for the best experience! message.uploading_file=File @|bold '%s'|@ +message.uploading_file_skipped=File @|bold '%s'|@ was skipped since it is empty message.downloaded_file=File @|bold '%s'|@ message.translation_file=Translation file @|bold '%s'|@ message.build_language_archive=Building ZIP archive with the latest translations for @|bold '%s'|@ From bf2ab865d886b86249a79fa02eaa592b483bbcd9 Mon Sep 17 00:00:00 2001 From: yzerk Date: Wed, 21 Dec 2022 15:08:18 +0200 Subject: [PATCH 4/5] fix review notes --- .../com/crowdin/cli/commands/actions/UploadSourcesAction.java | 2 +- src/main/resources/messages/messages.properties | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/crowdin/cli/commands/actions/UploadSourcesAction.java b/src/main/java/com/crowdin/cli/commands/actions/UploadSourcesAction.java index 2d9f92f70..68551c3a1 100644 --- a/src/main/java/com/crowdin/cli/commands/actions/UploadSourcesAction.java +++ b/src/main/java/com/crowdin/cli/commands/actions/UploadSourcesAction.java @@ -262,7 +262,7 @@ public void act(Outputter out, PropertiesWithFiles pb, ProjectClient client) { request.setStorageId(client.uploadStorage(source.substring(source.lastIndexOf(Utils.PATH_SEPARATOR) + 1), fileStream)); } catch (EmptyFileException e){ errorsPresented.set(false); - out.println(WARNING.withIcon(String.format(RESOURCE_BUNDLE.getString("message.uploading_file_skipped"), fileFullPath))); + out.println(SKIPPED.withIcon(String.format(RESOURCE_BUNDLE.getString("message.uploading_file_skipped"), fileFullPath))); return; } catch (Exception e) { errorsPresented.set(true); diff --git a/src/main/resources/messages/messages.properties b/src/main/resources/messages/messages.properties index 459cf17ee..a6f80340b 100755 --- a/src/main/resources/messages/messages.properties +++ b/src/main/resources/messages/messages.properties @@ -260,7 +260,6 @@ error.cast_param_list_type='%s' list contains value(s) of type '%s' instead of ' error.dest_and_pattern_in_source=The 'dest' parameter only works for single files specified in the 'source' parameter error.dest_and_preserve_hierarchy=The 'dest' parameter only works for single files with the specified 'preserve_hierarchy': true option error.upload_to_storage=Failed to upload the '%s' file to the storage. Please contact our support team for help -error.empty_file_upload=Wrong parameters: %s error.language_not_exist=Language '%s' doesn't exist in the project. Try specifying another language code error.languages_not_exist=Language(s) %s doesn't exist in the project. Try specifying another language code(s) error.building_translation=Failed to build translation. Please contact our support team for help From cec22c2c39281e890bba64f7d37dfcff937f4b8d Mon Sep 17 00:00:00 2001 From: yzerk Date: Wed, 21 Dec 2022 15:10:32 +0200 Subject: [PATCH 5/5] fix review notes --- src/main/java/com/crowdin/cli/client/EmptyFileException.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/crowdin/cli/client/EmptyFileException.java b/src/main/java/com/crowdin/cli/client/EmptyFileException.java index 52fa34cee..b7a4e7acd 100644 --- a/src/main/java/com/crowdin/cli/client/EmptyFileException.java +++ b/src/main/java/com/crowdin/cli/client/EmptyFileException.java @@ -1,6 +1,5 @@ package com.crowdin.cli.client; - public class EmptyFileException extends ResponseException { public EmptyFileException(String message) {