Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
aurambaj committed Jun 11, 2024
1 parent 037124e commit 3f7088b
Show file tree
Hide file tree
Showing 11 changed files with 917 additions and 1 deletion.
6 changes: 6 additions & 0 deletions webapp/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

<dependency>
<groupId>com.phrase</groupId>
<artifactId>phrase-java</artifactId>
<version>2.0.2</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
Expand Down Expand Up @@ -158,7 +159,7 @@ TextUnitDTO addTextUnitDTOAttributes(TextUnitDTO textUnit) {
}

AndroidPluralQuantity androidPluralQuantity =
AndroidPluralQuantity.valueOf(textUnit.getPluralForm());
AndroidPluralQuantity.valueOf(textUnit.getPluralForm().toUpperCase(Locale.ROOT));
textUnit.setTmTextUnitId(ids.get(androidPluralQuantity.ordinal()));
}
textUnit.setAssetPath(nameParts[1]);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
package com.box.l10n.mojito.service.thirdparty;

import com.box.l10n.mojito.JSR310Migration;
import com.box.l10n.mojito.android.strings.AndroidStringDocument;
import com.box.l10n.mojito.android.strings.AndroidStringDocumentMapper;
import com.box.l10n.mojito.android.strings.AndroidStringDocumentReader;
import com.box.l10n.mojito.android.strings.AndroidStringDocumentWriter;
import com.box.l10n.mojito.entity.PollableTask;
import com.box.l10n.mojito.entity.Repository;
import com.box.l10n.mojito.entity.RepositoryLocale;
import com.box.l10n.mojito.service.pollableTask.PollableFuture;
import com.box.l10n.mojito.service.repository.RepositoryService;
import com.box.l10n.mojito.service.thirdparty.phrase.PhraseClient;
import com.box.l10n.mojito.service.tm.importer.TextUnitBatchImporterService;
import com.box.l10n.mojito.service.tm.search.StatusFilter;
import com.box.l10n.mojito.service.tm.search.TextUnitDTO;
import com.box.l10n.mojito.service.tm.search.TextUnitSearcher;
import com.box.l10n.mojito.service.tm.search.TextUnitSearcherParameters;
import com.box.l10n.mojito.service.tm.search.UsedFilter;
import com.google.common.collect.ImmutableList;
import com.phrase.client.model.Tag;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;

@ConditionalOnProperty(value = "l10n.ThirdPartyTMS.impl", havingValue = "ThirdPartyTMSPhrase")
@Component
public class ThirdPartyTMSPhrase implements ThirdPartyTMS {

static final int MAX_TEXT_UNIT_SUPPORTED = 10000;

static Logger logger = LoggerFactory.getLogger(ThirdPartyTMSPhrase.class);

@Autowired TextUnitSearcher textUnitSearcher = new TextUnitSearcher();

@Autowired TextUnitBatchImporterService textUnitBatchImporterService;

@Autowired PhraseClient phraseClient;

@Autowired RepositoryService repositoryService;

@Override
public void removeImage(String projectId, String imageId) {
throw new UnsupportedOperationException("Remove image is not supported");
}

@Override
public ThirdPartyTMSImage uploadImage(String projectId, String name, byte[] content) {
throw new UnsupportedOperationException("Upload image is not supported");
}

@Override
public List<ThirdPartyTextUnit> getThirdPartyTextUnits(
Repository repository, String projectId, List<String> optionList) {

throw new UnsupportedOperationException("Get third party text units is not supported");
}

@Override
public void createImageToTextUnitMappings(
String projectId, List<ThirdPartyImageToTextUnit> thirdPartyImageToTextUnits) {
throw new UnsupportedOperationException("Create image to text units is not supported");
}

@Override
public void push(
Repository repository,
String projectId,
String pluralSeparator,
String skipTextUnitsWithPattern,
String skipAssetsWithPathPattern,
List<String> options) {

List<TextUnitDTO> search =
getSourceTextUnitDTOs(repository, skipTextUnitsWithPattern, skipAssetsWithPathPattern);

String text = getFileContent(pluralSeparator, search, true);

String tagForUpload = getTagForUpload();
phraseClient.uploadAndWait(
projectId,
repository.getSourceLocale().getBcp47Tag(),
"xml",
repository.getName() + "-strings.xml",
text,
ImmutableList.of(tagForUpload));

phraseClient.removeKeysNotTaggedWith(projectId, tagForUpload);

List<Tag> tagsToDelete =
phraseClient.listTags(projectId).stream()
.filter(
tag ->
tag.getName() != null
&& !tag.getName().equals(tagForUpload)
&& tag.getName().startsWith("push_"))
.toList();
phraseClient.deleteTags(projectId, tagsToDelete);
}

private List<TextUnitDTO> getSourceTextUnitDTOs(
Repository repository, String skipTextUnitsWithPattern, String skipAssetsWithPathPattern) {
TextUnitSearcherParameters parameters = new TextUnitSearcherParameters();

parameters.setRepositoryIds(repository.getId());
parameters.setForRootLocale(true);
parameters.setDoNotTranslateFilter(false);
parameters.setUsedFilter(UsedFilter.USED);
parameters.setSkipTextUnitWithPattern(skipTextUnitsWithPattern);
parameters.setSkipAssetPathWithPattern(skipAssetsWithPathPattern);
parameters.setPluralFormsFiltered(false);
parameters.setOrderByTextUnitID(true);

return textUnitSearcher.search(parameters);
}

public static String getTagForUpload() {
ZonedDateTime zonedDateTime = JSR310Migration.dateTimeNowInUTC();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy_MM_dd_HH_mm_ss_SSS");
return "push_%s_%s"
.formatted(
formatter.format(zonedDateTime),
Math.abs(UUID.randomUUID().getLeastSignificantBits() % 1000));
}

@Override
public PollableFuture<Void> pull(
Repository repository,
String projectId,
String pluralSeparator,
Map<String, String> localeMapping,
String skipTextUnitsWithPattern,
String skipAssetsWithPathPattern,
List<String> optionList,
String schedulerName,
PollableTask currentTask) {

Set<RepositoryLocale> repositoryLocalesWithoutRootLocale =
repositoryService.getRepositoryLocalesWithoutRootLocale(repository);

for (RepositoryLocale repositoryLocale : repositoryLocalesWithoutRootLocale) {
String localeTag = repositoryLocale.getLocale().getBcp47Tag();
logger.info("Downloading locale: {} from Phrase", localeTag);
String fileContent = phraseClient.localeDownload(projectId, localeTag, "xml");

AndroidStringDocumentMapper mapper =
new AndroidStringDocumentMapper(
pluralSeparator, null, localeTag, repository.getName(), true);

List<TextUnitDTO> textUnitDTOS =
mapper.mapToTextUnits(AndroidStringDocumentReader.fromText(fileContent));

textUnitBatchImporterService.importTextUnits(textUnitDTOS, false, true);
}

return null;
}

@Override
public void pushTranslations(
Repository repository,
String projectId,
String pluralSeparator,
Map<String, String> localeMapping,
String skipTextUnitsWithPattern,
String skipAssetsWithPathPattern,
String includeTextUnitsWithPattern,
List<String> optionList) {

Set<RepositoryLocale> repositoryLocalesWithoutRootLocale =
repositoryService.getRepositoryLocalesWithoutRootLocale(repository);

for (RepositoryLocale repositoryLocale : repositoryLocalesWithoutRootLocale) {
List<TextUnitDTO> textUnitDTOS =
getTextUnitDTOSForLocale(
repository,
skipTextUnitsWithPattern,
skipAssetsWithPathPattern,
includeTextUnitsWithPattern,
repositoryLocale);

String fileContent = getFileContent(pluralSeparator, textUnitDTOS, false);

phraseClient.uploadCreateFile(
projectId,
repositoryLocale.getLocale().getBcp47Tag(),
"xml",
repository.getName() + "-strings.xml",
fileContent,
null);
}
}

private List<TextUnitDTO> getTextUnitDTOSForLocale(
Repository repository,
String skipTextUnitsWithPattern,
String skipAssetsWithPathPattern,
String includeTextUnitsWithPattern,
RepositoryLocale repositoryLocale) {
TextUnitSearcherParameters parameters = new TextUnitSearcherParameters();
parameters.setRepositoryIds(repository.getId());
parameters.setLocaleId(repositoryLocale.getLocale().getId());
parameters.setDoNotTranslateFilter(false);
parameters.setStatusFilter(StatusFilter.TRANSLATED);
parameters.setUsedFilter(UsedFilter.USED);
parameters.setSkipTextUnitWithPattern(skipTextUnitsWithPattern);
parameters.setSkipAssetPathWithPattern(skipAssetsWithPathPattern);
parameters.setIncludeTextUnitsWithPattern(includeTextUnitsWithPattern);
parameters.setPluralFormsFiltered(true);
return textUnitSearcher.search(parameters);
}

private static String getFileContent(
String pluralSeparator, List<TextUnitDTO> textUnitDTOS, boolean useSource) {

AndroidStringDocumentMapper androidStringDocumentMapper =
new AndroidStringDocumentMapper(pluralSeparator, null, null, null, true);

AndroidStringDocument androidStringDocument =
androidStringDocumentMapper.readFromTextUnits(textUnitDTOS, useSource);

return new AndroidStringDocumentWriter(androidStringDocument).toText();
}

@Override
public void pullSource(
Repository repository,
String projectId,
List<String> optionList,
Map<String, String> localeMapping) {
throw new UnsupportedOperationException("Pull source is not supported");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.box.l10n.mojito.service.thirdparty;

public class ThridPartyTMSPhraseException extends RuntimeException {
public ThridPartyTMSPhraseException(String msg, Throwable e) {
super(msg, e);
}
}
Loading

0 comments on commit 3f7088b

Please sign in to comment.