From e1e30646449eb1433ee751d7e5c1f8706686c399 Mon Sep 17 00:00:00 2001 From: Alex Eng Date: Fri, 1 Jul 2016 10:58:02 +1000 Subject: [PATCH] glossary-push/pull for zanata-cli (#120) * feat(glossary): Implement glossary command in zanta-cli https://zanata.atlassian.net/browse/ZNTA-44 * Update comments and docs --- docs/commands/glossary-delete.md | 21 ++++++ docs/commands/glossary-pull.md | 30 +++++++++ docs/commands/glossary-push.md | 23 +++++++ mkdocs.yml | 3 + .../java/org/zanata/client/ZanataClient.java | 9 ++- .../ConfigurableGlossaryOptionsImpl.java | 30 +++++++++ .../delete/GlossaryDeleteOptionsImpl.java | 49 ++++++++++++++ .../glossary/pull/GlossaryPullCommand.java | 1 - .../glossary/pull/GlossaryPullOptions.java | 1 - .../pull/GlossaryPullOptionsImpl.java | 60 +++++++++++++++++ .../glossary/push/GlossaryPushCommand.java | 46 +++++++------ .../glossary/push/GlossaryPushOptions.java | 5 +- .../push/GlossaryPushOptionsImpl.java | 67 +++++++++++++++++++ .../org/zanata/maven/GlossaryPullMojo.java | 5 +- .../org/zanata/maven/GlossaryPushMojo.java | 22 ++---- 15 files changed, 327 insertions(+), 45 deletions(-) create mode 100644 docs/commands/glossary-delete.md create mode 100644 docs/commands/glossary-pull.md create mode 100644 docs/commands/glossary-push.md create mode 100644 zanata-client-commands/src/main/java/org/zanata/client/commands/ConfigurableGlossaryOptionsImpl.java create mode 100644 zanata-client-commands/src/main/java/org/zanata/client/commands/glossary/delete/GlossaryDeleteOptionsImpl.java create mode 100644 zanata-client-commands/src/main/java/org/zanata/client/commands/glossary/pull/GlossaryPullOptionsImpl.java create mode 100644 zanata-client-commands/src/main/java/org/zanata/client/commands/glossary/push/GlossaryPushOptionsImpl.java diff --git a/docs/commands/glossary-delete.md b/docs/commands/glossary-delete.md new file mode 100644 index 00000000..47d8c07a --- /dev/null +++ b/docs/commands/glossary-delete.md @@ -0,0 +1,21 @@ +To delete glossary entry in Zanata, the command-line client's `glossary-delete` command can be used. + +```bash +zanata-cli glossary-delete --id 1005 +``` + +This command will: + +1. Look up the server config from `zanata.xml`. +2. Delete glossary entry with id `1005` + +To delete all glossary in Zanata + +```bash +zanata-cli glossary-delete --all +``` + +To see all options available for `glossary-delete` option: +```bash +zanata-cli help glossary-delete +``` diff --git a/docs/commands/glossary-pull.md b/docs/commands/glossary-pull.md new file mode 100644 index 00000000..b6a72cae --- /dev/null +++ b/docs/commands/glossary-pull.md @@ -0,0 +1,30 @@ +To download glossary entries from Zanata, the command-line client's `glossary-pull` command can be used. + +```bash +zanata-cli glossary-pull +``` + +This command will: + +1. look up the server config from `zanata.xml`. +2. Download all glossary entries in server +3. The file will be in `.csv` format. (default) + +To download in different format, use the `--file-type` options (csv or po). +For example: + +```bash +zanata-cli glossary-pull --file-type po +``` + +To download only specific locales for `--file-type po`, use the ` --trans-lang` options. +For example to download `de` and `fr` locales only: + +```bash +zanata-cli glossary-pull --file-type po --trans-lang de,fr +``` + +To see all options available for `glossary-pull` option: +```bash +zanata-cli help glossary-pull +``` diff --git a/docs/commands/glossary-push.md b/docs/commands/glossary-push.md new file mode 100644 index 00000000..566b58e7 --- /dev/null +++ b/docs/commands/glossary-push.md @@ -0,0 +1,23 @@ +To push glossary entries to Zanata, the command-line client's `glossary-push` command can be used. +The source language of the glossary file should be in `en-US` + +```bash +zanata-cli glossary-push --file glossary.csv +``` + +This command will: + +1. Look up the server config from `zanata.xml`. +2. Push glossary.csv file to Zanata. + +To push a po file, `--trans-lang` option will be needed. +For example: + +```bash +zanata-cli glossary-push --file german-glossary.po --trans-lang de +``` + +To see all options available for `glossary-push` option: +```bash +zanata-cli help glossary-push +``` diff --git a/mkdocs.yml b/mkdocs.yml index 68843611..9f12727b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -19,6 +19,9 @@ pages: - init: 'commands/init.md' - push: 'commands/push.md' - pull: 'commands/pull.md' + - glossary-push: 'commands/glossary-push.md' + - glossary-pull: 'commands/glossary-pull.md' + - glossary-delete: 'commands/glossary-delete.md' - Maven Plugin: - Installation: 'maven-plugin/installation.md' - Configuration: 'maven-plugin/configuration.md' diff --git a/zanata-cli/src/main/java/org/zanata/client/ZanataClient.java b/zanata-cli/src/main/java/org/zanata/client/ZanataClient.java index 01993924..79ba3435 100644 --- a/zanata-cli/src/main/java/org/zanata/client/ZanataClient.java +++ b/zanata-cli/src/main/java/org/zanata/client/ZanataClient.java @@ -23,6 +23,9 @@ import org.zanata.client.commands.PutVersionOptionsImpl; import org.zanata.client.commands.SystemExitStrategy; import org.zanata.client.commands.ZanataCommand; +import org.zanata.client.commands.glossary.delete.GlossaryDeleteOptionsImpl; +import org.zanata.client.commands.glossary.pull.GlossaryPullOptionsImpl; +import org.zanata.client.commands.glossary.push.GlossaryPushOptionsImpl; import org.zanata.client.commands.init.InitOptionsImpl; import org.zanata.client.commands.pull.PullOptionsImpl; import org.zanata.client.commands.push.PushOptionsImpl; @@ -64,7 +67,11 @@ public class ZanataClient extends BasicOptionsImpl { @SubCommand(name = "put-user", impl = PutUserOptionsImpl.class), @SubCommand(name = "put-version", impl = PutVersionOptionsImpl.class), - @SubCommand(name = "stats", impl = GetStatisticsOptionsImpl.class) }) + @SubCommand(name = "stats", impl = GetStatisticsOptionsImpl.class), + @SubCommand(name = "glossary-delete", impl = GlossaryDeleteOptionsImpl.class), + @SubCommand(name = "glossary-push", impl = GlossaryPushOptionsImpl.class), + @SubCommand(name = "glossary-pull", impl = GlossaryPullOptionsImpl.class)}) + // if this field name changes, change COMMAND_FIELD too private Object command; private static final String COMMAND_FIELD = "command"; diff --git a/zanata-client-commands/src/main/java/org/zanata/client/commands/ConfigurableGlossaryOptionsImpl.java b/zanata-client-commands/src/main/java/org/zanata/client/commands/ConfigurableGlossaryOptionsImpl.java new file mode 100644 index 00000000..f6046548 --- /dev/null +++ b/zanata-client-commands/src/main/java/org/zanata/client/commands/ConfigurableGlossaryOptionsImpl.java @@ -0,0 +1,30 @@ +package org.zanata.client.commands; + +import java.io.File; + +import org.kohsuke.args4j.Option; + +/** + * @author Alex Eng aeng@redhat.com + */ +public abstract class ConfigurableGlossaryOptionsImpl extends ConfigurableOptionsImpl + implements ConfigurableGlossaryOptions { + + /** + * Configuration file for Zanata client. + */ + private File config = new File("zanata.xml"); + + @Override + public File getConfig() { + return config; + } + + @Option(name = "--config", metaVar = "FILENAME", + usage = "Configuration file, eg zanata.xml", + required = false) + public void setConfig(File config) { + this.config = config; + } + +} diff --git a/zanata-client-commands/src/main/java/org/zanata/client/commands/glossary/delete/GlossaryDeleteOptionsImpl.java b/zanata-client-commands/src/main/java/org/zanata/client/commands/glossary/delete/GlossaryDeleteOptionsImpl.java new file mode 100644 index 00000000..7f75e17a --- /dev/null +++ b/zanata-client-commands/src/main/java/org/zanata/client/commands/glossary/delete/GlossaryDeleteOptionsImpl.java @@ -0,0 +1,49 @@ +package org.zanata.client.commands.glossary.delete; + +import org.kohsuke.args4j.Option; +import org.zanata.client.commands.ConfigurableGlossaryOptionsImpl; +import org.zanata.client.commands.ZanataCommand; + +public class GlossaryDeleteOptionsImpl extends ConfigurableGlossaryOptionsImpl + implements GlossaryDeleteOptions { + + private String id; + private boolean allGlossary = false; + + @Override + public String getId() { + return id; + } + + @Override + public boolean getAllGlossary() { + return allGlossary; + } + + @Option(name = "--id", metaVar = "ID", + usage = "id of a glossary entry to delete.") + public void setId(String id) { + this.id = id; + } + + @Option(name = "--all", metaVar = "ALL", + usage = "Delete entire glossaries from the server. Default: false") + public void setAllGlossary(boolean allGlossary) { + this.allGlossary = allGlossary; + } + + @Override + public ZanataCommand initCommand() { + return new GlossaryDeleteCommand(this); + } + + @Override + public String getCommandName() { + return "glossary-delete"; + } + + @Override + public String getCommandDescription() { + return "Delete glossary entries in Zanata"; + } +} diff --git a/zanata-client-commands/src/main/java/org/zanata/client/commands/glossary/pull/GlossaryPullCommand.java b/zanata-client-commands/src/main/java/org/zanata/client/commands/glossary/pull/GlossaryPullCommand.java index bbda425b..312e0b43 100644 --- a/zanata-client-commands/src/main/java/org/zanata/client/commands/glossary/pull/GlossaryPullCommand.java +++ b/zanata-client-commands/src/main/java/org/zanata/client/commands/glossary/pull/GlossaryPullCommand.java @@ -21,7 +21,6 @@ package org.zanata.client.commands.glossary.pull; import java.io.File; -import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; diff --git a/zanata-client-commands/src/main/java/org/zanata/client/commands/glossary/pull/GlossaryPullOptions.java b/zanata-client-commands/src/main/java/org/zanata/client/commands/glossary/pull/GlossaryPullOptions.java index a35097d4..bed06ae8 100644 --- a/zanata-client-commands/src/main/java/org/zanata/client/commands/glossary/pull/GlossaryPullOptions.java +++ b/zanata-client-commands/src/main/java/org/zanata/client/commands/glossary/pull/GlossaryPullOptions.java @@ -1,7 +1,6 @@ package org.zanata.client.commands.glossary.pull; import org.zanata.client.commands.ConfigurableGlossaryOptions; -import org.zanata.client.commands.ConfigurableOptions; import com.google.common.collect.ImmutableList; diff --git a/zanata-client-commands/src/main/java/org/zanata/client/commands/glossary/pull/GlossaryPullOptionsImpl.java b/zanata-client-commands/src/main/java/org/zanata/client/commands/glossary/pull/GlossaryPullOptionsImpl.java new file mode 100644 index 00000000..1bb8a916 --- /dev/null +++ b/zanata-client-commands/src/main/java/org/zanata/client/commands/glossary/pull/GlossaryPullOptionsImpl.java @@ -0,0 +1,60 @@ +package org.zanata.client.commands.glossary.pull; + + +import org.kohsuke.args4j.Option; +import org.zanata.client.commands.ConfigurableGlossaryOptionsImpl; +import org.zanata.client.commands.ZanataCommand; + +import com.google.common.collect.ImmutableList; + +/** + * @author Alex Eng aeng@redhat.com + */ +public class GlossaryPullOptionsImpl extends ConfigurableGlossaryOptionsImpl + implements GlossaryPullOptions { + + private String fileType; + private String[] transLang; + + @Option(name = "--file-type", metaVar = "(CSV or PO)", + usage = "File type to be downloaded.\n" + + "csv (default) - csv file format with comma separated\n" + + "po - a zip file of po files on available locales") + public void setFileType(String fileType) { + this.fileType = fileType; + } + + @Option(name = "--trans-lang", metaVar = "LOCALE1,LOCALE2", + usage = "Translation languages to pull from Zanata.\nLeave empty for all available languages.") + public void setTransLang(String transLang) { + this.transLang = transLang.split(","); + } + + @Override + public String getFileType() { + return fileType; + } + + @Override + public ImmutableList getTransLang() { + if (transLang != null) { + return ImmutableList.copyOf(transLang); + } + return ImmutableList.of(); + } + + @Override + public ZanataCommand initCommand() { + return new GlossaryPullCommand(this); + } + + @Override + public String getCommandName() { + return "glossary-pull"; + } + + @Override + public String getCommandDescription() { + return "Pull glossary file from Zanata"; + } +} diff --git a/zanata-client-commands/src/main/java/org/zanata/client/commands/glossary/push/GlossaryPushCommand.java b/zanata-client-commands/src/main/java/org/zanata/client/commands/glossary/push/GlossaryPushCommand.java index ed34f5a2..0c3a325b 100644 --- a/zanata-client-commands/src/main/java/org/zanata/client/commands/glossary/push/GlossaryPushCommand.java +++ b/zanata-client-commands/src/main/java/org/zanata/client/commands/glossary/push/GlossaryPushCommand.java @@ -38,12 +38,13 @@ import org.zanata.adapter.glossary.GlossaryPoReader; import org.zanata.client.commands.ConfigurableCommand; import org.zanata.client.commands.OptionsUtil; -import org.zanata.client.config.LocaleMapping; import org.zanata.common.LocaleId; import org.zanata.rest.client.GlossaryClient; import org.zanata.rest.client.RestClientFactory; import org.zanata.rest.dto.GlossaryEntry; +import static org.zanata.client.commands.glossary.push.GlossaryPushOptions.DEFAULT_SOURCE_LANG; + /** * * @author Alex Eng aeng@redhat.com @@ -54,8 +55,8 @@ public class GlossaryPushCommand extends private static final Logger log = LoggerFactory .getLogger(GlossaryPushCommand.class); - private static final Map glossaryReaders = - new HashMap(); + private static final Map + glossaryReaders = new HashMap(); private final GlossaryClient client; public GlossaryPushCommand(GlossaryPushOptions opts, @@ -67,8 +68,10 @@ public GlossaryPushCommand(GlossaryPushOptions opts, public GlossaryPushCommand(GlossaryPushOptions opts) { this(opts, OptionsUtil.createClientFactory(opts)); - LocaleId srcLocaleId = new LocaleId(getOpts().getSourceLang()); - LocaleId transLocaleId = new LocaleId(getOpts().getTransLang()); + LocaleId srcLocaleId = new LocaleId(DEFAULT_SOURCE_LANG); + String transLang = getOpts().getTransLang(); + LocaleId transLocaleId = StringUtils.isNotBlank(transLang) + ? new LocaleId(transLang) : null; glossaryReaders.put("po", new GlossaryPoReader( srcLocaleId, transLocaleId, getOpts().getBatchSize())); glossaryReaders @@ -86,40 +89,39 @@ private AbstractGlossaryPushReader getReader(String fileExtension) { private String validateFileExtensionWithTransLang() throws RuntimeException { String fileExtension = - FilenameUtils.getExtension(getOpts().getGlossaryFile() - .getName()); - - if (StringUtils.isEmpty(getOpts().getTransLang())) { - if (fileExtension.equals("po")) { - throw new RuntimeException( - "Option 'zanata.transLang' is required for this file type."); - } + FilenameUtils.getExtension(getOpts().getFile().getName()); + + if (fileExtension.equals("po") + && StringUtils.isBlank(getOpts().getTransLang())) { + throw new RuntimeException( + "Option '--trans-lang' is required for this file type."); } return fileExtension; } @Override public void run() throws Exception { + log.info("Server: {}", getOpts().getUrl()); log.info("Username: {}", getOpts().getUsername()); - log.info("Source language: {}", getOpts().getSourceLang()); + log.info("Source language: {}", DEFAULT_SOURCE_LANG); log.info("Translation language: {}", getOpts().getTransLang()); - log.info("Glossary file: {}", getOpts().getGlossaryFile()); + log.info("Glossary file: {}", getOpts().getFile()); log.info("Batch size: {}", getOpts().getBatchSize()); - File glossaryFile = getOpts().getGlossaryFile(); + File glossaryFile = getOpts().getFile(); + if (glossaryFile == null) { + throw new RuntimeException( + "Option '--file' is required."); + } if (!glossaryFile.exists()) { throw new RuntimeException("File '" + glossaryFile - + "' does not exist - check glossaryFile option"); - } - - if (getOpts().getSourceLang() == null || getOpts().getSourceLang().length() < 0) { - throw new RuntimeException("Need to specify source language."); + + "' does not exist. Check '--file' option"); } if (getOpts().getBatchSize() <= 0) { - throw new RuntimeException("Batch size needs to be 1 or more."); + throw new RuntimeException("Option '--batch-size' needs to be 1 or more."); } String fileExtension = validateFileExtensionWithTransLang(); diff --git a/zanata-client-commands/src/main/java/org/zanata/client/commands/glossary/push/GlossaryPushOptions.java b/zanata-client-commands/src/main/java/org/zanata/client/commands/glossary/push/GlossaryPushOptions.java index a8883983..9ed1c88b 100644 --- a/zanata-client-commands/src/main/java/org/zanata/client/commands/glossary/push/GlossaryPushOptions.java +++ b/zanata-client-commands/src/main/java/org/zanata/client/commands/glossary/push/GlossaryPushOptions.java @@ -6,9 +6,10 @@ import org.zanata.client.commands.ConfigurableOptions; public interface GlossaryPushOptions extends ConfigurableGlossaryOptions { - public File getGlossaryFile(); + public String DEFAULT_SOURCE_LANG = "en-US"; + public int DEFAULT_BATCH_SIZE = 50; - public String getSourceLang(); + public File getFile(); public String getTransLang(); diff --git a/zanata-client-commands/src/main/java/org/zanata/client/commands/glossary/push/GlossaryPushOptionsImpl.java b/zanata-client-commands/src/main/java/org/zanata/client/commands/glossary/push/GlossaryPushOptionsImpl.java new file mode 100644 index 00000000..cf0f97f5 --- /dev/null +++ b/zanata-client-commands/src/main/java/org/zanata/client/commands/glossary/push/GlossaryPushOptionsImpl.java @@ -0,0 +1,67 @@ +package org.zanata.client.commands.glossary.push; + +import java.io.File; + +import org.kohsuke.args4j.Option; +import org.zanata.client.commands.ConfigurableGlossaryOptionsImpl; +import org.zanata.client.commands.ZanataCommand; + +/** + * @author Alex Eng aeng@redhat.com + */ +public class GlossaryPushOptionsImpl extends ConfigurableGlossaryOptionsImpl + implements GlossaryPushOptions { + + private File file; + private String transLang; + private int batchSize = DEFAULT_BATCH_SIZE; + + @Option(name = "--file", + usage = "Location path for the glossary file.", required = true) + public void setFile(File file) { + this.file = file; + } + + @Option(name = "--trans-lang", metaVar = "LOCALE", + usage = "Translation language of the file.\n" + + "Not required for csv file type") + public void setTransLang(String transLang) { + this.transLang = transLang; + } + + @Option(name = "--batch-size", metaVar = "50", + usage = "Batch size to upload for large glossary file. (defaults to 50)") + public void setBatchSize(int batchSize) { + this.batchSize = batchSize; + } + + @Override + public File getFile() { + return file; + } + + @Override + public String getTransLang() { + return transLang; + } + + @Override + public int getBatchSize() { + return batchSize; + } + + @Override + public ZanataCommand initCommand() { + return new GlossaryPushCommand(this); + } + + @Override + public String getCommandName() { + return "glossary-push"; + } + + @Override + public String getCommandDescription() { + return "Push glossary to Zanata"; + } +} diff --git a/zanata-maven-plugin/src/main/java/org/zanata/maven/GlossaryPullMojo.java b/zanata-maven-plugin/src/main/java/org/zanata/maven/GlossaryPullMojo.java index 7d16316b..a829bcbe 100644 --- a/zanata-maven-plugin/src/main/java/org/zanata/maven/GlossaryPullMojo.java +++ b/zanata-maven-plugin/src/main/java/org/zanata/maven/GlossaryPullMojo.java @@ -70,7 +70,10 @@ public GlossaryPullCommand initCommand() { justification = "Injected by Maven") @Override public ImmutableList getTransLang() { - return ImmutableList.copyOf(transLang); + if (transLang != null) { + return ImmutableList.copyOf(transLang); + } + return ImmutableList.of(); } @Override diff --git a/zanata-maven-plugin/src/main/java/org/zanata/maven/GlossaryPushMojo.java b/zanata-maven-plugin/src/main/java/org/zanata/maven/GlossaryPushMojo.java index 0bb461ec..d1ae15bc 100644 --- a/zanata-maven-plugin/src/main/java/org/zanata/maven/GlossaryPushMojo.java +++ b/zanata-maven-plugin/src/main/java/org/zanata/maven/GlossaryPushMojo.java @@ -37,13 +37,6 @@ public class GlossaryPushMojo extends GlossaryMojo implements GlossaryPushOptions { - /** - * Source language of document - * - * @parameter expression="${zanata.sourceLang}" default-value="en-US" - */ - private String sourceLang = "en-US"; - /** * Translation language of document. Not required for csv file * @@ -54,17 +47,17 @@ public class GlossaryPushMojo extends GlossaryMojo /** * Location path for the glossary file * - * @parameter expression="${zanata.glossaryFile}" + * @parameter expression="${zanata.file}" * @required */ - private File glossaryFile; + private File file; /** * Batch size for large glossary file * * @parameter expression="${zanata.batchSize}" default-value=50 */ - private int batchSize = 50; + private int batchSize = DEFAULT_BATCH_SIZE; public GlossaryPushMojo() throws Exception { super(); @@ -73,13 +66,8 @@ public GlossaryPushMojo() throws Exception { @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "Injected by Maven") @Override - public File getGlossaryFile() { - return glossaryFile; - } - - @Override - public String getSourceLang() { - return sourceLang; + public File getFile() { + return file; } @Override