Skip to content

Commit

Permalink
feat: new command: screenshot (#631)
Browse files Browse the repository at this point in the history
  • Loading branch information
katerina20 committed Sep 7, 2023
1 parent 950042b commit c704029
Show file tree
Hide file tree
Showing 32 changed files with 1,222 additions and 2 deletions.
1 change: 1 addition & 0 deletions prepare-docs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ sed -i.bak -e 's/\*\*--\[no-\]auto-approve-imported\*\*/`--[no-]auto-approve-imp
sed -i.bak -e 's/\*\*--\[no-\]import-eq-suggestions\*\*/`--[no-]import-eq-suggestions`/g' -- *.md
sed -i.bak -e 's/\*\*--\[no-\]translate-hidden\*\*/`--[no-]translate-hidden`/g' -- *.md
sed -i.bak -e 's/\*\*--\[no-\]preserve-hierarchy\*\*/`--[no-]preserve-hierarchy`/g' -- *.md
sed -i.bak -e 's/\*\*--\[no-\]auto-tag\*\*/`--[no-]auto-tag`/g' -- *.md

rm -- *.md.bak

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.crowdin.cli.client;

public class AutoTagInProgressException extends ResponseException {
}
18 changes: 18 additions & 0 deletions src/main/java/com/crowdin/cli/client/ClientScreenshot.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.crowdin.cli.client;

import com.crowdin.client.screenshots.model.AddScreenshotRequest;
import com.crowdin.client.screenshots.model.Screenshot;
import com.crowdin.client.screenshots.model.UpdateScreenshotRequest;

import java.util.List;

public interface ClientScreenshot extends Client {

List<Screenshot> listScreenshots(Long stringId);

Screenshot uploadScreenshot(AddScreenshotRequest request) throws ResponseException;

Screenshot updateScreenshot(Long screenshotId, UpdateScreenshotRequest request);

void deleteScreenshot(Long id);
}
5 changes: 5 additions & 0 deletions src/main/java/com/crowdin/cli/client/Clients.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ public static ClientBundle getClientBundle(String apiToken, String baseUrl, Stri
return new CrowdinClientBundle(client, projectId);
}

public static ClientScreenshot getClientScreenshot(String apiToken, String baseUrl, String projectId) {
com.crowdin.client.Client client = prepareClient(apiToken, baseUrl);
return new CrowdinClientScreenshot(client, projectId);
}

// mb divide args to move token and url to constructor?
public static ProjectClient getProjectClient(String apiToken, String baseUrl, long projectId) {
com.crowdin.client.Client client = prepareClient(apiToken, baseUrl);
Expand Down
53 changes: 53 additions & 0 deletions src/main/java/com/crowdin/cli/client/CrowdinClientScreenshot.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.crowdin.cli.client;

import com.crowdin.client.Client;
import com.crowdin.client.screenshots.model.AddScreenshotRequest;
import com.crowdin.client.screenshots.model.Screenshot;
import com.crowdin.client.screenshots.model.UpdateScreenshotRequest;
import lombok.AllArgsConstructor;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiPredicate;

import static java.lang.Long.parseLong;

@AllArgsConstructor
public class CrowdinClientScreenshot extends CrowdinClientCore implements ClientScreenshot {

private final Client client;
private final String projectId;

@Override
public List<Screenshot> listScreenshots(Long stringId) {
return executeRequestFullList((limit, offset) -> this.client.getScreenshotsApi()
.listScreenshots(parseLong(this.projectId), stringId, limit, offset));
}

@Override
public Screenshot uploadScreenshot(AddScreenshotRequest request) throws ResponseException {
Map<BiPredicate<String, String>, ResponseException> errorHandler = new LinkedHashMap<BiPredicate<String, String>, ResponseException>() {{
put((code, message) -> code.equals("409") && message.contains("Auto tag is currently in progress"),
new AutoTagInProgressException());
}};
return executeRequest(errorHandler, () -> this.client.getScreenshotsApi()
.addScreenshot(parseLong(this.projectId), request)
.getData());
}

@Override
public Screenshot updateScreenshot(Long screenshotId, UpdateScreenshotRequest request) {
return executeRequest(() -> this.client.getScreenshotsApi()
.updateScreenshot(parseLong(this.projectId), screenshotId, request)
.getData());
}

@Override
public void deleteScreenshot(Long id) {
executeRequest(() -> {
this.client.getScreenshotsApi().deleteScreenshot(parseLong(this.projectId), id);
return null;
});
}
}
5 changes: 5 additions & 0 deletions src/main/java/com/crowdin/cli/commands/Actions.java
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,9 @@ NewAction<PropertiesWithFiles, ProjectClient> preTranslate(

NewAction<ProjectProperties, ProjectClient> branchDelete(String name);

NewAction<ProjectProperties, ClientScreenshot> screenshotList(Long stringId, boolean plainView);

NewAction<ProjectProperties, ClientScreenshot> screenshotUpload(File file, String branchName, String directoryPath, String filePath, boolean autoTag, boolean plainView, boolean noProgress, ProjectClient projectClient);

NewAction<ProjectProperties, ClientScreenshot> screenshotDelete(String name);
}
15 changes: 15 additions & 0 deletions src/main/java/com/crowdin/cli/commands/actions/CliActions.java
Original file line number Diff line number Diff line change
Expand Up @@ -241,4 +241,19 @@ public NewAction<ProjectProperties, ProjectClient> branchAdd(String name, String
public NewAction<ProjectProperties, ProjectClient> branchDelete(String name) {
return new BranchDeleteAction(name);
}

@Override
public NewAction<ProjectProperties, ClientScreenshot> screenshotList(Long stringId, boolean plainView) {
return new ScreenshotListAction(stringId, plainView);
}

@Override
public NewAction<ProjectProperties, ClientScreenshot> screenshotUpload(File file, String branchName, String directoryPath, String filePath, boolean autoTag, boolean plainView, boolean noProgress, ProjectClient projectClient) {
return new ScreenshotUploadAction(file, branchName, filePath, directoryPath, autoTag, plainView, noProgress, projectClient);
}

@Override
public NewAction<ProjectProperties, ClientScreenshot> screenshotDelete(String name) {
return new ScreenshotDeleteAction(name);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.crowdin.cli.commands.actions;

import com.crowdin.cli.client.ClientScreenshot;
import com.crowdin.cli.commands.NewAction;
import com.crowdin.cli.commands.Outputter;
import com.crowdin.cli.properties.ProjectProperties;
import com.crowdin.cli.utils.console.ExecutionStatus;
import com.crowdin.client.screenshots.model.Screenshot;

import java.util.Map;
import java.util.stream.Collectors;

import static com.crowdin.cli.BaseCli.RESOURCE_BUNDLE;

class ScreenshotDeleteAction implements NewAction<ProjectProperties, ClientScreenshot> {

private final String name;

public ScreenshotDeleteAction(String name) {
this.name = name;
}

@Override
public void act(Outputter out, ProjectProperties properties, ClientScreenshot client) {
Map<String, Long> screenshots = client.listScreenshots(null).stream()
.collect(Collectors.toMap(Screenshot::getName, Screenshot::getId));
if (!screenshots.containsKey(name)) {
throw new RuntimeException(String.format(RESOURCE_BUNDLE.getString("error.screenshot.not_found"), name));
}
client.deleteScreenshot(screenshots.get(name));
out.println(ExecutionStatus.OK.withIcon(String.format(RESOURCE_BUNDLE.getString("message.screenshot.deleted"), name)));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.crowdin.cli.commands.actions;

import com.crowdin.cli.client.ClientScreenshot;
import com.crowdin.cli.commands.NewAction;
import com.crowdin.cli.commands.Outputter;
import com.crowdin.cli.properties.ProjectProperties;
import com.crowdin.client.screenshots.model.Screenshot;

import java.util.List;

import static com.crowdin.cli.BaseCli.RESOURCE_BUNDLE;
import static com.crowdin.cli.utils.console.ExecutionStatus.OK;

class ScreenshotListAction implements NewAction<ProjectProperties, ClientScreenshot> {

private final Long stringId;
private final boolean plainView;

public ScreenshotListAction(Long stringId, boolean plainView) {
this.stringId = stringId;
this.plainView = plainView;
}

@Override
public void act(Outputter out, ProjectProperties properties, ClientScreenshot client) {
List<Screenshot> screenshots = client.listScreenshots(stringId);
for (Screenshot screenshot : screenshots) {
if (!plainView) {
out.println(String.format(RESOURCE_BUNDLE.getString("message.screenshot.list"),
screenshot.getId(), screenshot.getName(), screenshot.getTagsCount()));
} else {
out.println(screenshot.getId() + " " + screenshot.getName());
}
}
if (screenshots.isEmpty()) {
if (!plainView) {
out.println(OK.withIcon(RESOURCE_BUNDLE.getString("message.screenshot.list_empty")));
} else {
out.println(RESOURCE_BUNDLE.getString("message.screenshot.list_empty"));
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package com.crowdin.cli.commands.actions;

import com.crowdin.cli.client.AutoTagInProgressException;
import com.crowdin.cli.client.ClientScreenshot;
import com.crowdin.cli.client.CrowdinProjectFull;
import com.crowdin.cli.client.ProjectClient;
import com.crowdin.cli.commands.NewAction;
import com.crowdin.cli.commands.Outputter;
import com.crowdin.cli.properties.ProjectProperties;
import com.crowdin.cli.utils.Utils;
import com.crowdin.cli.utils.console.ConsoleSpinner;
import com.crowdin.client.screenshots.model.AddScreenshotRequest;
import com.crowdin.client.screenshots.model.Screenshot;
import com.crowdin.client.screenshots.model.UpdateScreenshotRequest;
import com.crowdin.client.sourcefiles.model.Branch;
import com.crowdin.client.sourcefiles.model.Directory;
import com.crowdin.client.sourcefiles.model.FileInfo;
import lombok.AllArgsConstructor;

import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.List;
import java.util.Optional;

import static com.crowdin.cli.BaseCli.RESOURCE_BUNDLE;
import static com.crowdin.cli.utils.console.ExecutionStatus.OK;
import static com.crowdin.cli.utils.console.ExecutionStatus.WARNING;
import static java.util.Objects.nonNull;

@AllArgsConstructor
class ScreenshotUploadAction implements NewAction<ProjectProperties, ClientScreenshot> {

private final File file;
private final String branchName;
private final String pathToSourceFile;
private final String directoryPath;
private final boolean autoTag;
private final boolean plainView;
private final boolean noProgress;

private ProjectClient projectClient;

@Override
public void act(Outputter out, ProjectProperties properties, ClientScreenshot client) {
Screenshot screenshot;
List<Screenshot> screenshotList = client.listScreenshots(null);
Optional<Screenshot> existingScreenshot = screenshotList.stream()
.filter((s) -> file.getName().equals(s.getName())).findFirst();
if (existingScreenshot.isPresent()) {
UpdateScreenshotRequest request = new UpdateScreenshotRequest();
request.setStorageId(uploadToStorage(file));
request.setName(file.getName());
try {
screenshot = client.updateScreenshot(existingScreenshot.get().getId(), request);
} catch (Exception e) {
throw new RuntimeException(String.format(RESOURCE_BUNDLE.getString("error.screenshot.not_updated"), request), e);
}
if (!plainView) {
out.println(OK.withIcon(String.format(RESOURCE_BUNDLE.getString("message.screenshot.updated"), screenshot.getName())));
} else {
out.println(String.valueOf(screenshot.getName()));
}
return;
}
AddScreenshotRequest request = new AddScreenshotRequest();
CrowdinProjectFull project = ConsoleSpinner.execute(
out,
"message.spinner.fetching_project_info", "error.collect_project_info",
this.noProgress,
this.plainView,
() -> this.projectClient.downloadFullProject());
if (nonNull(branchName)) {
Branch branch = project.findBranchByName(branchName)
.orElseThrow(() -> new RuntimeException(String.format(RESOURCE_BUNDLE.getString("error.branch_not_exists"), branchName)));
request.setBranchId(branch.getId());
}
if (nonNull(pathToSourceFile)) {
final String normalizedPath = Utils.unixPath(Utils.sepAtStart(pathToSourceFile));
FileInfo fileInfo = project.getFileInfos().stream()
.filter(f -> normalizedPath.equals(f.getPath())).findFirst()
.orElseThrow(() -> new RuntimeException(String.format(RESOURCE_BUNDLE.getString("error.file_not_exists"), pathToSourceFile)));
request.setFileId(fileInfo.getId());
}
if (nonNull(directoryPath)) {
final String normalizedPath = Utils.unixPath(Utils.sepAtStart(directoryPath));
Directory directory = project.getDirectories().values().stream()
.filter(d -> normalizedPath.equals(d.getPath())).findFirst()
.orElseThrow(() -> new RuntimeException(String.format(RESOURCE_BUNDLE.getString("error.dir_not_exists"), directoryPath)));
request.setDirectoryId(directory.getId());
}
request.setStorageId(uploadToStorage(file));
request.setName(file.getName());
request.setAutoTag(autoTag);

try {
client.uploadScreenshot(request);
} catch (AutoTagInProgressException e) {
if (!plainView) {
out.println(WARNING.withIcon(String.format(RESOURCE_BUNDLE.getString("message.screenshot.not_auto-tagged"), file.getName())));
} else {
out.println(String.format(RESOURCE_BUNDLE.getString("message.screenshot.not_auto-tagged"), file.getName()));
}
} catch (Exception e) {
throw new RuntimeException(String.format(RESOURCE_BUNDLE.getString("error.screenshot.not_uploaded"), request), e);
}
if (!plainView) {
out.println(OK.withIcon(String.format(RESOURCE_BUNDLE.getString("message.screenshot.uploaded"), file.getName())));
} else {
out.println(file.getName());
}
}

private Long uploadToStorage(File fileToUpload) {
Long storageId;
try (InputStream fileStream = Files.newInputStream(fileToUpload.toPath())) {
storageId = this.projectClient.uploadStorage(fileToUpload.getName(), fileStream);
} catch (Exception e) {
throw new RuntimeException(String.format(RESOURCE_BUNDLE.getString("error.upload_to_storage"), fileToUpload.getName()), e);
}
return storageId;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.crowdin.cli.commands.picocli;

import com.crowdin.cli.client.ClientScreenshot;
import com.crowdin.cli.client.Clients;
import com.crowdin.cli.client.ProjectClient;
import com.crowdin.cli.commands.Outputter;
import com.crowdin.cli.properties.ProjectParams;
import com.crowdin.cli.properties.ProjectProperties;
import com.crowdin.cli.properties.PropertiesBuilders;
import picocli.CommandLine;

public abstract class ActCommandScreenshot extends GenericActCommand<ProjectProperties, ClientScreenshot> {

@CommandLine.Mixin
private ConfigurationFilesProperties properties;

@CommandLine.ArgGroup(exclusive = false, headingKey = "params.heading")
private ProjectParams params;

@Override
protected ProjectProperties getProperties(PropertiesBuilders propertiesBuilders, Outputter out) {
return propertiesBuilders.buildProjectProperties(out, properties.getConfigFile(), properties.getIdentityFile(), params);
}

@Override
protected ClientScreenshot getClient(ProjectProperties properties) {
return Clients.getClientScreenshot(properties.getApiToken(), properties.getBaseUrl(), properties.getProjectId());
}

protected ProjectClient getProjectClient(ProjectProperties properties) {
return Clients.getProjectClient(properties.getApiToken(), properties.getBaseUrl(), Long.parseLong(properties.getProjectId()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,9 @@ public final class CommandNames {
public static final String DISTRIBUTION_ADD = "add";
public static final String DISTRIBUTION_LIST = "list";
public static final String DISTRIBUTION_RELEASE = "release";

public static final String SCREENSHOT = "screenshot";
public static final String SCREENSHOT_LIST = "list";
public static final String SCREENSHOT_UPLOAD = "upload";
public static final String SCREENSHOT_DELETE = "delete";
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
PreTranslateSubcommand.class,
BranchSubcommand.class,
CommentSubcommand.class,
DistributionSubcommand.class
DistributionSubcommand.class,
ScreenshotSubcommand.class
})
class RootCommand extends HelpCommand {
@Override
Expand Down

0 comments on commit c704029

Please sign in to comment.