Commit 5bb0c9f2 authored by Alexander Basov's avatar Alexander Basov Committed by Matija Obreza
Browse files

Use external org.genesys2.transifex-client depedency

parent 3f3e7979
...@@ -112,6 +112,13 @@ ...@@ -112,6 +112,13 @@
</pluginRepositories> </pluginRepositories>
<dependencies> <dependencies>
<dependency>
<groupId>org.genesys2</groupId>
<artifactId>transifex-client</artifactId>
<version>0.1</version>
</dependency>
<!--Test dependencies --> <!--Test dependencies -->
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
...@@ -527,6 +534,11 @@ ...@@ -527,6 +534,11 @@
<artifactId>dom4j</artifactId> <artifactId>dom4j</artifactId>
<version>1.6.1</version> <version>1.6.1</version>
</dependency> </dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1</version>
</dependency>
</dependencies> </dependencies>
......
...@@ -18,10 +18,21 @@ package org.genesys2.server.persistence.domain; ...@@ -18,10 +18,21 @@ package org.genesys2.server.persistence.domain;
import org.genesys2.server.model.impl.Article; import org.genesys2.server.model.impl.Article;
import org.genesys2.server.model.impl.ClassPK; import org.genesys2.server.model.impl.ClassPK;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface ArticleRepository extends JpaRepository<Article, Long> { public interface ArticleRepository extends JpaRepository<Article, Long> {
Article findByClassPkAndTargetIdAndSlugAndLang(ClassPK classPk, Long id, String slug, String lang); Article findByClassPkAndTargetIdAndSlugAndLang(ClassPK classPk, Long id, String slug, String lang);
@Query("select a from Article a where a.lang = :lang")
Page<Article> getAllByLang(@Param("lang") String lang, Pageable pageable);
@Query("select a from Article a where a.slug = :slug and a.lang = :lang")
Article findBySlugAndLang(@Param("slug")String slug,
@Param("lang")String lang);
} }
...@@ -47,6 +47,8 @@ public interface ContentService { ...@@ -47,6 +47,8 @@ public interface ContentService {
Article getArticle(EntityId entity, String slug, Locale locale); Article getArticle(EntityId entity, String slug, Locale locale);
Article getArticleBySlugAndLang(String slug, String lang);
/** /**
* Global articles have ClassPK of Article.class and targetId of null * Global articles have ClassPK of Article.class and targetId of null
* *
...@@ -70,6 +72,8 @@ public interface ContentService { ...@@ -70,6 +72,8 @@ public interface ContentService {
Page<Article> listArticles(Pageable pageable); Page<Article> listArticles(Pageable pageable);
Page<Article> listArticlesByLang(String lang, Pageable pageable);
void save(Iterable<Article> articles); void save(Iterable<Article> articles);
/** /**
......
...@@ -16,13 +16,6 @@ ...@@ -16,13 +16,6 @@
package org.genesys2.server.service.impl; package org.genesys2.server.service.impl;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
...@@ -48,6 +41,13 @@ import org.springframework.security.access.prepost.PreAuthorize; ...@@ -48,6 +41,13 @@ import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@Service @Service
@Transactional(readOnly = true) @Transactional(readOnly = true)
public class ContentServiceImpl implements ContentService { public class ContentServiceImpl implements ContentService {
...@@ -86,9 +86,14 @@ public class ContentServiceImpl implements ContentService { ...@@ -86,9 +86,14 @@ public class ContentServiceImpl implements ContentService {
return articleRepository.findAll(pageable); return articleRepository.findAll(pageable);
} }
@Override @Override
public Page<Article> listArticlesByLang(String lang, Pageable pageable) {
return articleRepository.getAllByLang(lang, pageable);
}
@Override
@Transactional(readOnly = false) @Transactional(readOnly = false)
@PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER')") // @PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER')")
@CacheEvict(value = "contentcache", allEntries = true) @CacheEvict(value = "contentcache", allEntries = true)
public void save(Iterable<Article> articles) { public void save(Iterable<Article> articles) {
articleRepository.save(articles); articleRepository.save(articles);
...@@ -115,7 +120,12 @@ public class ContentServiceImpl implements ContentService { ...@@ -115,7 +120,12 @@ public class ContentServiceImpl implements ContentService {
return getArticle(entity.getClass(), entity.getId(), slug, locale, true); return getArticle(entity.getClass(), entity.getId(), slug, locale, true);
} }
@Override @Override
public Article getArticleBySlugAndLang(String slug, String lang) {
return articleRepository.findBySlugAndLang(slug, lang);
}
@Override
@Cacheable(value = "contentcache", key = "'article-' + #clazz.name + '-' + #id + '-' + #slug + '-' + #locale.language + '-' + #useDefault") @Cacheable(value = "contentcache", key = "'article-' + #clazz.name + '-' + #id + '-' + #slug + '-' + #locale.language + '-' + #useDefault")
public Article getArticle(Class<?> clazz, Long id, String slug, Locale locale, boolean useDefault) { public Article getArticle(Class<?> clazz, Long id, String slug, Locale locale, boolean useDefault) {
Article article = articleRepository.findByClassPkAndTargetIdAndSlugAndLang(getClassPk(clazz), id, slug, locale.getLanguage()); Article article = articleRepository.findByClassPkAndTargetIdAndSlugAndLang(getClassPk(clazz), id, slug, locale.getLanguage());
......
...@@ -18,99 +18,188 @@ package org.genesys2.server.servlet.controller; ...@@ -18,99 +18,188 @@ package org.genesys2.server.servlet.controller;
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;
import org.genesys2.spring.RequestAttributeLocaleResolver;
import org.genesys2.spring.ResourceNotFoundException; import org.genesys2.spring.ResourceNotFoundException;
import org.genesys2.transifex.client.TransifexService;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import java.io.IOException;
import org.springframework.web.bind.annotation.RequestParam; import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;
@Controller @Controller
@RequestMapping("/content") @RequestMapping("/content")
public class ArticleController extends BaseController { public class ArticleController extends BaseController {
@Autowired @Autowired
private ContentService contentService; private ContentService contentService;
@RequestMapping @Autowired
@PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER')") private TransifexService transifexService;
public String list(ModelMap model, @RequestParam(value = "page", defaultValue = "1") int page) { @Autowired
model.addAttribute("pagedData", contentService.listArticles(new PageRequest(page - 1, 50, new Sort("slug")))); private RequestAttributeLocaleResolver localeResolver;
return "/content/index";
} @RequestMapping(value = "/postToTransifex/{slug}", method = RequestMethod.GET)
@PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER')")
@RequestMapping("{url:.+}") public String postTotransifex(@PathVariable("slug") String slug, Model model) {
public String view(ModelMap model, @PathVariable(value = "url") String slug) { Article article = contentService.getGlobalArticle(slug, getLocale());
_logger.debug("Viewing article " + slug); try {
transifexService.createXhtmlResource("article-" + slug, article.getTitle(), article.getBody());
final Article article = contentService.getGlobalArticle(slug, getLocale()); } catch (IOException e) {
if (article == null) { model.addAttribute("responseFromTransifex", "fail");
if (hasRole("ADMINISTRATOR")) { model.addAttribute("article", article);
return "redirect:/content/" + slug + "/edit"; e.printStackTrace();
} }
throw new ResourceNotFoundException(); model.addAttribute("responseFromTransifex", "resource added");
} model.addAttribute("article", article);
model.addAttribute("title", article.getTitle()); return "/content/article-edit";
model.addAttribute("article", article); }
return "/content/article"; @RequestMapping(value = "/deleteFromTransifex", method = RequestMethod.POST)
} @PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER')")
public String deleteFromtransifex(@RequestParam("articleSlug") String slug, Model model) {
@PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER')") Article article = contentService.getGlobalArticle(slug, getLocale());
@RequestMapping("{url}/edit") if (transifexService.deleteResource("article-" + slug)) {
public String edit(ModelMap model, @PathVariable(value = "url") String slug) { model.addAttribute("result", "deleted");
_logger.debug("Editing article " + slug); model.addAttribute("article", article);
} else {
Article article = contentService.getGlobalArticle(slug, getLocale(), false); model.addAttribute("result", "fail");
if (article == null) { model.addAttribute("article", article);
article = new Article(); }
article.setSlug(slug); return "/content/article-edit";
article.setLang(getLocale().getLanguage()); }
}
model.addAttribute("article", article); @RequestMapping(value = "/translate/{slug}/{lang}", method = RequestMethod.GET)
@PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER')")
return "/content/article-edit"; public String fetchFromtransifex(@PathVariable("slug") String slug, @PathVariable String lang, Model model) {
}
Article article = contentService.getGlobalArticle(slug, getLocale());
@PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER')")
@RequestMapping(value = "/save-article", method = { RequestMethod.POST }) JSONObject jsonObject;
public String createNewGlobalArticle(ModelMap model, @RequestParam("slug") String slug, @RequestParam("title") String title, JSONParser jsonParser = new JSONParser();
@RequestParam("body") String body) { String translatedResource = transifexService.getTranslatedResource("article-" + slug, new Locale(lang));
String content;
contentService.createGlobalArticle(slug, getLocale(), title, body); String title = null;
String body = null;
return "redirect:/content/" + slug;
} try {
jsonObject = (JSONObject) jsonParser.parse(translatedResource);
@PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER')") content = (String) jsonObject.get("content");
@RequestMapping(value = "/save-article", params = { "id" }, method = { RequestMethod.POST }) title = content.split("<title>")[1].split("</title>")[0];
public String saveExistingGlobalArticle(ModelMap model, @RequestParam("id") long id, @RequestParam("slug") String slug, body = content.split("<body>")[1].split("</body>")[0];
@RequestParam("title") String title, @RequestParam("body") String body) { } catch (ParseException e) {
e.printStackTrace();
contentService.updateArticle(id, slug, title, body); }
return "redirect:/content/" + slug; article.setTitle(title);
} article.setBody(body);
article.setLang(lang);
@RequestMapping(value = "/blurp/update-blurp", method = { RequestMethod.POST })
public String updateBlurp(ModelMap model, @RequestParam("id") long id, @RequestParam(required = false, value = "title") String title, model.addAttribute("article", article);
@RequestParam("body") String body) { return "/content/article-edit";
}
contentService.updateArticle(id, null, title, body);
@RequestMapping
return "redirect:/"; @PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER')")
} public String list(ModelMap model, @RequestParam(value = "page", defaultValue = "1") int page,
@RequestParam(value = "language", defaultValue = "") String lang) {
@RequestMapping(value = "/blurp/create-blurp", method = { RequestMethod.POST }) if (!lang.isEmpty()) {
public String createBlurp(ModelMap model, @RequestParam("clazz") String clazz, @RequestParam("entityId") long entityId, model.addAttribute("pagedData", contentService.listArticlesByLang(lang, new PageRequest(page - 1, 50, new Sort("slug"))));
@RequestParam(required = false, value = "title") String title, @RequestParam("body") String body) throws ClassNotFoundException { } else {
model.addAttribute("pagedData", contentService.listArticles(new PageRequest(page - 1, 50, new Sort("slug"))));
contentService.updateArticle(Class.forName(clazz), entityId, "blurp", title, body, getLocale()); }
return "redirect:/";
} //todo full name of locales
Map<String, String> locales = new TreeMap<>();
for (String language : localeResolver.getSupportedLocales()) {
locales.put(new Locale(language).getDisplayName(), language);
}
model.addAttribute("languages", locales);
return "/content/index";
}
@RequestMapping("{url:.+}")
public String view(ModelMap model, @PathVariable(value = "url") String slug) {
_logger.debug("Viewing article " + slug);
final Article article = contentService.getGlobalArticle(slug, getLocale());
if (article == null) {
if (hasRole("ADMINISTRATOR")) {
return "redirect:/content/" + slug + "/edit";
}
throw new ResourceNotFoundException();
}
model.addAttribute("title", article.getTitle());
model.addAttribute("article", article);
return "/content/article";
}
@PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER')")
@RequestMapping("{url}/edit/{language}")
public String edit(ModelMap model, @PathVariable(value = "url") String slug,
@PathVariable("language") String language) {
_logger.debug("Editing article " + slug);
Article article = contentService.getArticleBySlugAndLang(slug, language);
if (article == null) {
article = new Article();
article.setSlug(slug);
article.setLang(getLocale().getLanguage());
}
model.addAttribute("article", article);
return "/content/article-edit";
}
@PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER')")
@RequestMapping(value = "/save-article", method = {RequestMethod.POST})
public String createNewGlobalArticle(ModelMap model, @RequestParam("slug") String slug, @RequestParam("title") String title,
@RequestParam("body") String body) {
contentService.createGlobalArticle(slug, getLocale(), title, body);
return "redirect:/content/" + slug;
}
@PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER')")
@RequestMapping(value = "/save-article", params = {"id"}, method = {RequestMethod.POST})
public String saveExistingGlobalArticle(ModelMap model, @RequestParam("id") long id, @RequestParam("slug") String slug,
@RequestParam("title") String title, @RequestParam("body") String body) {
contentService.updateArticle(id, slug, title, body);
return "redirect:/content/" + slug;
}
@RequestMapping(value = "/blurp/update-blurp", method = {RequestMethod.POST})
public String updateBlurp(ModelMap model, @RequestParam("id") long id, @RequestParam(required = false, value = "title") String title,
@RequestParam("body") String body) {
contentService.updateArticle(id, null, title, body);
return "redirect:/";
}
@RequestMapping(value = "/blurp/create-blurp", method = {RequestMethod.POST})
public String createBlurp(ModelMap model, @RequestParam("clazz") String clazz, @RequestParam("entityId") long entityId,
@RequestParam(required = false, value = "title") String title, @RequestParam("body") String body) throws ClassNotFoundException {
contentService.updateArticle(Class.forName(clazz), entityId, "blurp", title, body, getLocale());
return "redirect:/";
}
} }
/**
* Copyright 2014 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
package org.genesys2.server.servlet.controller.transifex; package org.genesys2.server.servlet.controller.transifex;
import java.io.IOException;
import java.util.Locale;
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;
import org.genesys2.server.servlet.controller.BaseController; import org.genesys2.server.servlet.controller.BaseController;
import org.genesys2.transifex.client.TransifexService; import org.genesys2.transifex.client.TransifexService;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.HttpClientErrorException; import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
/** import java.util.List;
* Transifex web hook listener. import java.util.Locale;
* TODO Move other (non-hook) methods to ArticleController!
*
* @author matijaobreza
*
*/
@Controller @Controller
@RequestMapping(value = "/transifex") @RequestMapping(value = "/transifex")
public class TransifexAPIController extends BaseController { public class TransifexAPIController extends BaseController {
@Autowired @Autowired
private ContentService contentService; private ContentService contentService;
@Autowired @Autowired
private TransifexService transifexService; private TransifexService transifexService;
@Value("${transifex.content.template}") @Value("${transifex.project}")
private String contentTemplate; private String projectSlug;
@Value("${transifex.min.translated}") @Value("${transifex.username}")
private int transifexMinTranslated; private String trasifexUserName;
@Value("${transifex.hook.key}") @Value("${transifex.password}")
private Object transifexHookKey; private String transifexPassord;
@RequestMapping(value = "/deleteContent/{slug}") @Value("${transifex.base.api.url}")
public String deleteResource(@PathVariable String slug, Model model) { private String baseApiURL;
Article article = contentService.getGlobalArticle(slug, getLocale());
@Value("${transifex.content.template}")
if (articleExists(article)) { private String contentTemplate;
if (transifexService.deleteResource("article-".concat(article.getSlug()))) {
model.addAttribute("result", "deleted ok"); @Value("${transifex.min.translated}")
} private int transifexMinTranslated;
} else {
model.addAttribute("result", "not exists"); /**
} * Use "magic" SHA1 hash value just for some security purposes
model.addAttribute("title", article.getTitle()); * <p/>
model.addAttribute("article", article); * Note: the very same value should be in Transifex preferences
return "/content/article-edit"; *
} * @see classpath:spring/spring-security.xml
*/
/** @RequestMapping(value = "/hooks/40874cca86ca396169a5f4e6ebf6e4bf7199c4e7", method = RequestMethod.POST)
* Use "magic" SHA1 hash value just for some security purposes public void webHookHandle(@RequestParam(value = "project") String projectSlug,
* @RequestParam(value = "resource") String resource,
* Note: the very same value should be in Transifex preferences @RequestParam(value = "language") String language,