diff --git a/cli/src/main/java/com/box/l10n/mojito/cli/command/DropViewCommand.java b/cli/src/main/java/com/box/l10n/mojito/cli/command/DropViewCommand.java new file mode 100644 index 0000000000..b14084e735 --- /dev/null +++ b/cli/src/main/java/com/box/l10n/mojito/cli/command/DropViewCommand.java @@ -0,0 +1,162 @@ +package com.box.l10n.mojito.cli.command; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; +import com.box.l10n.mojito.cli.command.param.Param; +import com.box.l10n.mojito.cli.console.Console; +import com.box.l10n.mojito.cli.console.ConsoleWriter; +import com.box.l10n.mojito.cli.structuredoutput.StructuredWriter; +import com.box.l10n.mojito.rest.client.DropClient; +import com.box.l10n.mojito.rest.entity.Drop; +import com.box.l10n.mojito.rest.entity.Repository; +import org.fusesource.jansi.Ansi.Color; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +/** + * Command to view info about drops. Displays the list of drops available. + * + * @author ehoogerbeets + */ +@Component +@Scope("prototype") +@Parameters(commandNames = {"drop-view"}, commandDescription = "View info about drops") +public class DropViewCommand extends Command { + + /** + * logger + */ + static Logger logger = LoggerFactory.getLogger(DropViewCommand.class); + + @Autowired + ConsoleWriter consoleWriter; + + @Autowired + StructuredWriter structuredWriter; + + @Parameter(names = {Param.REPOSITORY_LONG, Param.REPOSITORY_SHORT}, arity = 1, required = true, description = + Param.REPOSITORY_DESCRIPTION) + String repositoryParam; + + @Parameter(names = {"--number-drops-fetched"}, arity = 1, required = false, description = "Number of drops fetched") + Long numberOfDropsToFetchParam = 10L; + + @Parameter(names = {"--show-all", "-all"}, required = false, description = "Show drops with all statuses (already" + + " imported drops are hidden by default)") + Boolean alsoShowImportedParam = false; + + @Parameter(names = {"--drop-id", "-i"}, required = false, arity = 1, description = "Show information only about " + + "the drop with the given id") + Long dropId = null; + + @Autowired + CommandHelper commandHelper; + + @Autowired + Console console; + + @Autowired + DropClient dropClient; + + @Override + public void execute() throws CommandException { + Repository repository = commandHelper.findRepositoryByName(repositoryParam); + + Map numberedAvailableDrops = getNumberedAvailableDrops(repository.getId()); + if (dropId != null) { + // TODO: fetch info only for the specified drop instead of fetching an arbitrary page and hoping it's there + Optional drop = + numberedAvailableDrops.values().stream().filter(d -> d.getId().equals(dropId)).findAny(); + numberedAvailableDrops = + drop.map(value -> Collections.singletonMap(1L, value)).orElse(Collections.emptyMap()); + } + + writeStructuredOutput(numberedAvailableDrops); + + if (numberedAvailableDrops.isEmpty()) { + consoleWriter.newLine().a("No drop available").println(); + } else { + consoleWriter.newLine().a("Drops available").println(); + + logger.debug("Display drops information"); + for (Map.Entry entry : numberedAvailableDrops.entrySet()) { + + Drop drop = entry.getValue(); + + consoleWriter.a(" ").fg(Color.CYAN).a(entry.getKey()).reset(). + a(" - id: ").fg(Color.MAGENTA).a(drop.getId()).reset(). + a(", name: ").fg(Color.MAGENTA).a(drop.getName()).reset(); + + if (Boolean.TRUE.equals(drop.getCanceled())) { + consoleWriter.fg(Color.GREEN).a(" CANCELED"); + } else if (drop.getLastImportedDate() == null) { + consoleWriter.fg(Color.GREEN).a(" NEW"); + } else { + consoleWriter.a(", last import: ").fg(Color.MAGENTA).a(drop.getLastImportedDate()); + } + + consoleWriter.println(); + } + } + } + + /** + * Outputs available drops to a structured output writer + */ + private void writeStructuredOutput(Map drops) { + JSONArray jsonDrops = new JSONArray(); + for (Drop drop : drops.values()) { + JSONObject jsonDrop = new JSONObject(); + jsonDrop.put("id", drop.getId()); + jsonDrop.put("name", drop.getName()); + jsonDrop.put("lastImportedDate", drop.getLastImportedDate()); + jsonDrop.put("canceled", drop.getCanceled()); + jsonDrops.add(jsonDrop); + } + + JSONObject output = new JSONObject(); + output.put("drops", jsonDrops); + + structuredWriter.write(output); + } + + /** + * Gets available {@link Drop}s and returns a map where the drop id is + * the map key. + * + * @return + */ + private Map getNumberedAvailableDrops(Long repositoryId) { + + logger.debug("Build a map of drops keyed by the dropId"); + Map dropIds = new HashMap<>(); + + long i = 1; + + for (Drop availableDrop : dropClient.getDrops(repositoryId, getImportedFilter(), 0L, numberOfDropsToFetchParam).getContent()) { + dropIds.put(i++, availableDrop); + } + + return dropIds; + } + + /** + * Returns the "imported" filter to be passed to {@link DropClient#getDrops(java.lang.Long, java.lang.Boolean, java.lang.Long, java.lang.Long) + * } based on the CLI parameter {@link #alsoShowImportedParam}. + * + * @return the imported filter to get drops + */ + private Boolean getImportedFilter() { + return alsoShowImportedParam ? null : false; + } +}