Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: new command: screenshot #631

Merged
merged 8 commits into from
Sep 7, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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,120 @@
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.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);

Check warning on line 56 in src/main/java/com/crowdin/cli/commands/actions/ScreenshotUploadAction.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/crowdin/cli/commands/actions/ScreenshotUploadAction.java#L55-L56

Added lines #L55 - L56 were not covered by tests
}
if (!plainView) {
out.println(OK.withIcon(String.format(RESOURCE_BUNDLE.getString("message.screenshot.updated"), screenshot.getName())));
} else {
out.println(String.valueOf(screenshot.getName()));

Check warning on line 61 in src/main/java/com/crowdin/cli/commands/actions/ScreenshotUploadAction.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/crowdin/cli/commands/actions/ScreenshotUploadAction.java#L61

Added line #L61 was not covered by tests
}
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)) {
FileInfo fileInfo = project.getFileInfos().stream()
.filter(f -> pathToSourceFile.equals(f.getPath())).findFirst()
.orElseThrow(() -> new RuntimeException(String.format(RESOURCE_BUNDLE.getString("error.file_not_exists"), pathToSourceFile)));
request.setFileId(fileInfo.getId());
}
if (nonNull(directoryPath)) {
Directory directory = project.getDirectories().values().stream()
.filter(d -> directoryPath.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) {

Check warning on line 95 in src/main/java/com/crowdin/cli/commands/actions/ScreenshotUploadAction.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/crowdin/cli/commands/actions/ScreenshotUploadAction.java#L95

Added line #L95 was not covered by tests
if (!plainView) {
out.println(WARNING.withIcon(String.format(RESOURCE_BUNDLE.getString("message.screenshot.not_auto-tagged"), file.getName())));

Check warning on line 97 in src/main/java/com/crowdin/cli/commands/actions/ScreenshotUploadAction.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/crowdin/cli/commands/actions/ScreenshotUploadAction.java#L97

Added line #L97 was not covered by tests
} else {
out.println(String.format(RESOURCE_BUNDLE.getString("message.screenshot.not_auto-tagged"), file.getName()));

Check warning on line 99 in src/main/java/com/crowdin/cli/commands/actions/ScreenshotUploadAction.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/crowdin/cli/commands/actions/ScreenshotUploadAction.java#L99

Added line #L99 was not covered by tests
}
} catch (Exception e) {
throw new RuntimeException(String.format(RESOURCE_BUNDLE.getString("error.screenshot.not_uploaded"), request), e);

Check warning on line 102 in src/main/java/com/crowdin/cli/commands/actions/ScreenshotUploadAction.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/crowdin/cli/commands/actions/ScreenshotUploadAction.java#L101-L102

Added lines #L101 - L102 were not covered by tests
}
if (!plainView) {
out.println(OK.withIcon(String.format(RESOURCE_BUNDLE.getString("message.screenshot.uploaded"), file.getName())));
} else {
out.println(file.getName());

Check warning on line 107 in src/main/java/com/crowdin/cli/commands/actions/ScreenshotUploadAction.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/crowdin/cli/commands/actions/ScreenshotUploadAction.java#L107

Added line #L107 was not covered by tests
}
}

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);

Check warning on line 116 in src/main/java/com/crowdin/cli/commands/actions/ScreenshotUploadAction.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/crowdin/cli/commands/actions/ScreenshotUploadAction.java#L115-L116

Added lines #L115 - L116 were not covered by tests
}
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()));

Check warning on line 31 in src/main/java/com/crowdin/cli/commands/picocli/ActCommandScreenshot.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/crowdin/cli/commands/picocli/ActCommandScreenshot.java#L31

Added line #L31 was not covered by tests
}
}
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.crowdin.cli.commands.picocli;

import com.crowdin.cli.client.ClientScreenshot;
import com.crowdin.cli.commands.Actions;
import com.crowdin.cli.commands.NewAction;
import com.crowdin.cli.properties.ProjectProperties;
import picocli.CommandLine;

@CommandLine.Command(
name = CommandNames.SCREENSHOT_DELETE
)
class ScreenshotDeleteSubcommand extends ActCommandScreenshot {

@CommandLine.Parameters(descriptionKey = "crowdin.screenshot.delete.name")
protected String name;

@Override
protected NewAction<ProjectProperties, ClientScreenshot> getAction(Actions actions) {
return actions.screenshotDelete(name);
}
}
Loading