Commit acf89af4 authored by Matija Obreza's avatar Matija Obreza
Browse files

Fetch and update all translations in one go

parent fb0910b2
...@@ -17,10 +17,15 @@ ...@@ -17,10 +17,15 @@
package org.genesys2.server.servlet.controller; package org.genesys2.server.servlet.controller;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;
import javax.annotation.Resource;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.genesys2.server.model.impl.Article; import org.genesys2.server.model.impl.Article;
import org.genesys2.server.service.ContentService; import org.genesys2.server.service.ContentService;
...@@ -60,12 +65,17 @@ public class ArticleController extends BaseController { ...@@ -60,12 +65,17 @@ public class ArticleController extends BaseController {
@Autowired @Autowired
private RequestAttributeLocaleResolver localeResolver; private RequestAttributeLocaleResolver localeResolver;
@Resource
private Set<String> supportedLocales;
private static final String defaultLanguage = "en";
@Autowired @Autowired
private ObjectMapper mapper; private ObjectMapper mapper;
@RequestMapping(value = "/transifex", params = { "post" }, method = RequestMethod.POST) @RequestMapping(value = "/transifex", params = { "post" }, method = RequestMethod.POST)
@PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER')") @PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER')")
public String postTotransifex(@RequestParam("slug") String slug, RedirectAttributes redirectAttrs) { public String postToTransifex(@RequestParam("slug") String slug, RedirectAttributes redirectAttrs) {
if (transifexService == null) { if (transifexService == null) {
throw new ResourceNotFoundException("translationService not enabled"); throw new ResourceNotFoundException("translationService not enabled");
} }
...@@ -90,7 +100,7 @@ public class ArticleController extends BaseController { ...@@ -90,7 +100,7 @@ public class ArticleController extends BaseController {
@RequestMapping(value = "/transifex", params = { "remove" }, method = RequestMethod.POST) @RequestMapping(value = "/transifex", params = { "remove" }, method = RequestMethod.POST)
@PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER')") @PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER')")
public String deleteFromtransifex(@RequestParam("slug") String slug, RedirectAttributes redirectAttrs) { public String deleteFromTransifex(@RequestParam("slug") String slug, RedirectAttributes redirectAttrs) {
if (transifexService == null) { if (transifexService == null) {
throw new ResourceNotFoundException("translationService not enabled"); throw new ResourceNotFoundException("translationService not enabled");
} }
...@@ -109,9 +119,83 @@ public class ArticleController extends BaseController { ...@@ -109,9 +119,83 @@ public class ArticleController extends BaseController {
return "redirect:/content/" + slug + "/edit/" + LocaleContextHolder.getLocale().getLanguage(); return "redirect:/content/" + slug + "/edit/" + LocaleContextHolder.getLocale().getLanguage();
} }
/**
* Fetch all from Transifex and store
*
* @param slug
* @param language
* @param model
* @return
* @throws Exception
*/
@RequestMapping(value = "/transifex", params = { "fetch-all" }, method = RequestMethod.POST)
@PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER')")
public String fetchAllFromTransifex(@RequestParam("slug") String slug, RedirectAttributes redirectAttrs) throws Exception {
if (transifexService == null) {
throw new ResourceNotFoundException("translationService not enabled");
}
List<String> responses = new ArrayList<String>(20);
for (String lang : supportedLocales) {
if (defaultLanguage.equalsIgnoreCase(lang)) {
continue;
}
Locale locale = Locale.forLanguageTag(lang);
_logger.info("Fetching article " + slug + " translation for " + locale);
String translatedResource;
try {
translatedResource = transifexService.getTranslatedResource("article-" + slug, locale);
} catch (TransifexException e) {
_logger.warn(e.getMessage(), e);
if (e.getCause() != null) {
responses.add(e.getLocalizedMessage() + ": " + e.getCause().getLocalizedMessage());
} else {
responses.add(e.getLocalizedMessage());
}
// throw new Exception(e.getMessage(), e);
continue;
}
String title = null;
String body = null;
String summary = null;
try {
JsonNode jsonObject = mapper.readTree(translatedResource);
String content = jsonObject.get("content").asText();
Document doc = Jsoup.parse(content);
title = doc.title();
if (content.contains("class=\"summary")) {
// 1st <div class="summary">...
summary = doc.body().child(0).html();
// 2nd <div class="body">...
body = doc.body().child(1).html();
} else {
// Old fashioned body-only approach
body = doc.body().html();
}
contentService.updateGlobalArticle(slug, locale, title, body, summary);
responses.add("article.translations-updated");
} catch (IOException e) {
_logger.warn(e.getMessage(), e);
responses.add(e.getMessage());
continue;
}
}
redirectAttrs.addFlashAttribute("responseFromTransifex", responses);
return "redirect:/content/" + slug;
}
@RequestMapping(value = "/translate/{slug}/{language}", method = RequestMethod.GET) @RequestMapping(value = "/translate/{slug}/{language}", method = RequestMethod.GET)
@PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER')") @PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER')")
public String fetchFromtransifex(@PathVariable("slug") String slug, @PathVariable("language") String language, Model model) throws Exception { public String fetchFromTransifex(@PathVariable("slug") String slug, @PathVariable("language") String language, Model model) throws Exception {
if (transifexService == null) { if (transifexService == null) {
throw new ResourceNotFoundException("translationService not enabled"); throw new ResourceNotFoundException("translationService not enabled");
} }
......
...@@ -442,9 +442,11 @@ article.body=Article body ...@@ -442,9 +442,11 @@ article.body=Article body
article.summary=Summary (HTML metadata) article.summary=Summary (HTML metadata)
article.post-to-transifex=Post to Transifex article.post-to-transifex=Post to Transifex
article.remove-from-transifex=Remove from Transifex article.remove-from-transifex=Remove from Transifex
article.fetch-from-transifex=Fetch translations
article.transifex-resource-updated=The resource was successfully updated on Transifex. article.transifex-resource-updated=The resource was successfully updated on Transifex.
article.transifex-resource-removed=The resource was successfully removed from Transifex. article.transifex-resource-removed=The resource was successfully removed from Transifex.
article.transifex-failed=An error occured while exchanging data with Transifex article.transifex-failed=An error occured while exchanging data with Transifex
article.translations-updated=Resource successfully updated with translated data!
article.share=Share this article article.share=Share this article
activitypost=Activity post activitypost=Activity post
......
...@@ -5,85 +5,88 @@ ...@@ -5,85 +5,88 @@
<html> <html>
<head> <head>
<title>${title}</title> <title>${title}</title>
</head> </head>
<body> <body>
<div class="main-col"> <div class="main-col">
<h1> <h1>
<spring:message code="article.edit-article"/> <spring:message code="article.edit-article" />
</h1> </h1>
<c:if test="${article.lang eq 'en'}"> <%@include file="transifex-responses.jsp" %>
<div class="form-group">
<c:if test="${responseFromTransifex ne null}">
<div class="alert alert-warning"><spring:message code="${responseFromTransifex}" /></div>
</c:if>
<form method="post" action="<c:url value="/content/transifex"/>">
<input id="articleSlug" type="hidden" name="slug" value="${article.slug}"/>
<input type="submit" name="post" class="btn btn-default" value="<spring:message code="article.post-to-transifex" />" />
<input type="submit" name="remove" class="btn btn-default" value="<spring:message code="article.remove-from-transifex" />" />
<!-- CSRF protection -->
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form>
</div>
<div>${resource}</div>
</c:if>
<c:if test="${article.lang ne 'en'}"> <c:if test="${article.lang eq 'en'}">
<div class="form-group"> <div class="form-group">
<div> ${responseFromTransifex}</div> <form method="post" action="<c:url value="/content/transifex"/>">
<a href="<c:url value="/content/translate/${article.slug}/${article.lang}"/>" class="btn btn-default">Fetch from <input id="articleSlug" type="hidden" name="slug" value="${article.slug}" />
Transifex</a> <input type="submit" name="post" class="btn btn-default" value="<spring:message code="article.post-to-transifex" />" />
</div> <input type="submit" name="remove" class="btn btn-default" value="<spring:message code="article.remove-from-transifex" />" />
</c:if> <input type="submit" name="fetch-all" class="btn btn-default" value="<spring:message code="article.fetch-from-transifex" />" />
<!-- CSRF protection -->
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
</div>
<div>${resource}</div>
</c:if>
<form dir="${article.lang=='fa' || article.lang=='ar' ? 'rtl' : 'ltr'}" role="form" id="editForm" class="" <c:if test="${article.lang ne 'en'}">
action="<c:url value="/content/save-article/${article.lang}" />" method="post"> <div class="form-group">
<c:if test="${article.id ne null}"> <div>${responseFromTransifex}</div>
<input type="hidden" name="id" value="${article.id}"/> <a href="<c:url value="/content/translate/${article.slug}/${article.lang}"/>" class="btn btn-default">
</c:if> <spring:message code="article.fetch-from-transifex" />
<div class="form-group"> </a>
<label for="article-slug" class="control-label"><spring:message code="article.slug"/></label> </div>
</c:if>
<div class="controls"> <form dir="${article.lang=='fa' || article.lang=='ar' ? 'rtl' : 'ltr'}" role="form" id="editForm" class="" action="<c:url value="/content/save-article/${article.lang}" />" method="post">
<input type="text" id="article-slug" name="slug" value="<c:out value="${article.slug}" />" <c:if test="${article.id ne null}">
class="span9 form-control required"/> <input type="hidden" name="id" value="${article.id}" />
</div> </c:if>
</div> <div class="form-group">
<div class="form-group"> <label for="article-slug" class="control-label">
<label for="article-title" class="control-label"><spring:message code="article.title"/></label> <spring:message code="article.slug" />
</label>
<div class="controls"> <div class="controls">
<input type="text" id="article-title" name="title" value="<c:out value="${article.title}" />" <input type="text" id="article-slug" name="slug" value="<c:out value="${article.slug}" />" class="span9 form-control required" />
class="span9 form-control required"/> </div>
</div> </div>
</div> <div class="form-group">
<div dir="${article.lang=='fa' || article.lang=='ar' ? 'rtl' : 'ltr'}" class="form-group"> <label for="article-title" class="control-label">
<label for="article-body" class="control-label"><spring:message code="article.body"/></label> <spring:message code="article.title" />
</label>
<div class="controls"> <div class="controls">
<textarea id="article-body" name="body" class="span9 required form-control html-editor"><c:out <input type="text" id="article-title" name="title" value="<c:out value="${article.title}" />" class="span9 form-control required" />
value="${article.body}" escapeXml="false"/></textarea> </div>
</div> </div>
</div> <div dir="${article.lang=='fa' || article.lang=='ar' ? 'rtl' : 'ltr'}" class="form-group">
<div class="form-group"> <label for="article-body" class="control-label">
<label for="article-summary" class="control-label"><spring:message code="article.summary"/></label> <spring:message code="article.body" />
</label>
<div class="controls"> <div class="controls">
<textarea id="article-summary" name="summary" class="span9 required form-control html-editor"><c:out <textarea id="article-body" name="body" class="span9 required form-control html-editor"><c:out value="${article.body}" escapeXml="false" /></textarea>
value="${article.summary}" escapeXml="false"/></textarea> </div>
</div> </div>
</div> <div class="form-group">
<label for="article-summary" class="control-label">
<spring:message code="article.summary" />
</label>
<input type="submit" value="<spring:message code="save"/>" class="btn btn-primary"/> <div class="controls">
<a href="<c:url value="${article.id ne null ? '/content/'.concat(article.slug) : '/' }" />" class="btn btn-default">Cancel</a> <textarea id="article-summary" name="summary" class="span9 required form-control html-editor"><c:out value="${article.summary}" escapeXml="false" /></textarea>
<!-- CSRF protection --> </div>
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/> </div>
</form>
</div>
<content tag="javascript"> <input type="submit" value="<spring:message code="save"/>" class="btn btn-primary" />
<a href="<c:url value="${article.id ne null ? '/content/'.concat(article.slug) : '/' }" />" class="btn btn-default">Cancel</a>
<!-- CSRF protection -->
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
</div>
<content tag="javascript">
<script type="text/javascript"> <script type="text/javascript">
jQuery(document).ready(function () { jQuery(document).ready(function () {
if (window.location.hash == '#raw') { if (window.location.hash == '#raw') {
...@@ -92,6 +95,6 @@ ...@@ -92,6 +95,6 @@
} }
}); });
</script> </script>
</content> </content>
</body> </body>
</html> </html>
\ No newline at end of file
...@@ -4,8 +4,8 @@ ...@@ -4,8 +4,8 @@
<html> <html>
<head> <head>
<title>${title}</title> <title>${title}</title>
<local:content-headers description="${jspHelper.htmlToText(article.summary, 150)}" title="${title}" /> <local:content-headers description="${jspHelper.htmlToText(article.summary, 150)}" title="${title}" />
</head> </head>
<body> <body>
<content tag="header"> <content tag="header">
...@@ -13,6 +13,21 @@ ...@@ -13,6 +13,21 @@
<div class="banner-<c:out value="${article.slug}" />"></div> <div class="banner-<c:out value="${article.slug}" />"></div>
<c:if test="${title ne ''}"> <c:if test="${title ne ''}">
<div class="container"> <div class="container">
<security:authorize access="hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER')">
<form class="inline-form pull-right" method="post" action="<c:url value="/content/transifex"/>">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
<input id="articleSlug" type="hidden" name="slug" value="${article.slug}" />
<a href="<c:url value="/content/${article.slug}/edit" />" class="btn btn-default">
<spring:message code="edit" />
</a>
<a href="<c:url value="/content/${article.slug}/edit#raw" />" class="btn btn-default">
<spring:message code="edit" />
</a>
<input type="submit" name="fetch-all" class="btn btn-default" value="<spring:message code="article.fetch-from-transifex" />" />
</form>
</security:authorize>
<h1> <h1>
<c:out value="${title}" escapeXml="false" /> <c:out value="${title}" escapeXml="false" />
</h1> </h1>
...@@ -25,16 +40,10 @@ ...@@ -25,16 +40,10 @@
<%@include file="/WEB-INF/jsp/not-translated.jsp"%> <%@include file="/WEB-INF/jsp/not-translated.jsp"%>
</c:if> </c:if>
<%@include file="transifex-responses.jsp"%>
<div class="article"> <div class="article">
<div class="right-side main-col col-md-9"> <div class="right-side main-col col-md-9">
<security:authorize access="hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER')">
<a href="<c:url value="/content/${article.slug}/edit" />" class="close">
<spring:message code="edit" />
</a>
<a href="<c:url value="/content/${article.slug}/edit#raw" />" class="close">
<spring:message code="edit" />
</a>
</security:authorize>
<div class="free-text" dir="${article.lang=='fa' || article.lang=='ar' ? 'rtl' : 'ltr'}"> <div class="free-text" dir="${article.lang=='fa' || article.lang=='ar' ? 'rtl' : 'ltr'}">
<c:out value="${article.body}" escapeXml="false" /> <c:out value="${article.body}" escapeXml="false" />
...@@ -43,7 +52,7 @@ ...@@ -43,7 +52,7 @@
<div class="article-timestamp"> <div class="article-timestamp">
<local:prettyTime date="${article.postDate.time}" locale="${pageContext.response.locale}" /> <local:prettyTime date="${article.postDate.time}" locale="${pageContext.response.locale}" />
</div> </div>
<div class="share-article"> <div class="share-article">
<p> <p>
<spring:message code="article.share" /> <spring:message code="article.share" />
...@@ -90,8 +99,8 @@ ...@@ -90,8 +99,8 @@
</div> </div>
</div> --%> </div> --%>
</div> </div>
<div class="col-md-3 sidebar-nav col-xs-12"> <div class="col-md-3 sidebar-nav col-xs-12">
<cms:menu key="${menu.key}" items="${menu.items}" /> <cms:menu key="${menu.key}" items="${menu.items}" />
</div> </div>
......
<%@include file="/WEB-INF/jsp/init.jsp" %>
<c:if test="${responseFromTransifex ne null}">
<div class="alert alert-warning">
<c:forEach items="${responseFromTransifex}" var="rpt">
<div>
<spring:message code="${rpt}" />
</div>
</c:forEach>
</div>
</c:if>
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment