Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Genesys PGR
Genesys Backend
Commits
f1cf8d1b
Commit
f1cf8d1b
authored
Oct 23, 2014
by
Alexander Basov
Committed by
Matija Obreza
Nov 10, 2014
Browse files
Moved Transifex code to TransifexServiceImpl
Added TransifexClientTest to see behavior of their API
parent
9a0714d4
Changes
5
Hide whitespace changes
Inline
Side-by-side
pom.xml
View file @
f1cf8d1b
...
...
@@ -64,6 +64,7 @@
<oval.version>
1.81
</oval.version>
<jackson.version>
2.2.1
</jackson.version>
<jaxb-api.version>
2.1
</jaxb-api.version>
<!--Container -->
<jetty.version>
9.1.2.v20140210
</jetty.version>
...
...
@@ -302,11 +303,17 @@
<version>
${oval.version}
</version>
</dependency>
<!--<dependency> -->
<!--<groupId>com.fasterxml.jackson.core</groupId> -->
<!--<artifactId>jackson-databind</artifactId> -->
<!--<version>${jackson.version}</version> -->
<!--</dependency> -->
<dependency>
<groupId>
com.fasterxml.jackson.core
</groupId>
<artifactId>
jackson-databind
</artifactId>
<version>
${jackson.version}
</version>
</dependency>
<dependency>
<groupId>
javax.xml.bind
</groupId>
<artifactId>
jaxb-api
</artifactId>
<version>
${jaxb-api.version}
</version>
<scope>
runtime
</scope>
</dependency>
<!--Jetty -->
...
...
@@ -508,7 +515,20 @@
<artifactId>
urlrewritefilter
</artifactId>
<version>
4.0.4
</version>
</dependency>
</dependencies>
<dependency>
<groupId>
org.apache.commons
</groupId>
<artifactId>
commons-lang3
</artifactId>
<version>
3.3.2
</version>
</dependency>
<!--dom4j-->
<dependency>
<groupId>
dom4j
</groupId>
<artifactId>
dom4j
</artifactId>
<version>
1.6.1
</version>
</dependency>
</dependencies>
<build>
<plugins>
...
...
src/main/java/org/genesys2/server/model/impl/Article.java
View file @
f1cf8d1b
...
...
@@ -16,20 +16,12 @@
package
org.genesys2.server.model.impl
;
import
java.util.Calendar
;
import
javax.persistence.Column
;
import
javax.persistence.Entity
;
import
javax.persistence.JoinColumn
;
import
javax.persistence.Lob
;
import
javax.persistence.ManyToOne
;
import
javax.persistence.Table
;
import
javax.persistence.Temporal
;
import
javax.persistence.TemporalType
;
import
org.genesys2.server.model.AuditedModel
;
import
org.hibernate.annotations.Type
;
import
javax.persistence.*
;
import
java.util.Calendar
;
@Entity
@Table
(
name
=
"article"
)
public
class
Article
extends
AuditedModel
{
...
...
@@ -61,6 +53,8 @@ public class Article extends AuditedModel {
@Column
(
length
=
100000
)
private
String
body
;
private
boolean
transifexed
=
true
;
@Temporal
(
TemporalType
.
TIMESTAMP
)
private
Calendar
postDate
;
...
...
@@ -119,4 +113,12 @@ public class Article extends AuditedModel {
public
void
setLang
(
String
lang
)
{
this
.
lang
=
lang
;
}
public
boolean
isTransifexed
()
{
return
transifexed
;
}
public
void
setTransifexed
(
boolean
transifexed
)
{
this
.
transifexed
=
transifexed
;
}
}
src/main/java/org/genesys2/server/servlet/controller/transifex/TransifexAPIController.java
0 → 100644
View file @
f1cf8d1b
package
org.genesys2.server.servlet.controller.transifex
;
import
org.apache.commons.codec.binary.Base64
;
import
org.dom4j.Document
;
import
org.dom4j.DocumentException
;
import
org.dom4j.DocumentHelper
;
import
org.dom4j.io.HTMLWriter
;
import
org.dom4j.io.OutputFormat
;
import
org.genesys2.server.model.impl.Article
;
import
org.genesys2.server.service.ContentService
;
import
org.genesys2.server.servlet.controller.BaseController
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.core.io.FileSystemResource
;
import
org.springframework.core.io.Resource
;
import
org.springframework.http.*
;
import
org.springframework.stereotype.Controller
;
import
org.springframework.ui.Model
;
import
org.springframework.util.LinkedMultiValueMap
;
import
org.springframework.util.MultiValueMap
;
import
org.springframework.web.bind.annotation.PathVariable
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestMethod
;
import
org.springframework.web.bind.annotation.RequestParam
;
import
org.springframework.web.client.HttpClientErrorException
;
import
org.springframework.web.client.RestTemplate
;
import
java.io.File
;
import
java.io.FileWriter
;
import
java.io.IOException
;
@Controller
@RequestMapping
(
value
=
"/transifex"
)
public
class
TransifexAPIController
extends
BaseController
{
@Autowired
private
ContentService
contentService
;
@Value
(
"${transifex.project}"
)
private
String
projectSlug
;
@Value
(
"${transifex.username}"
)
private
String
trasifexUserName
;
@Value
(
"${transifex.password}"
)
private
String
transifexPassord
;
@Value
(
"${transifex.min.translated}"
)
private
String
minTranslatedValue
;
@Value
(
"${transifex.base.api.url}"
)
private
String
baseApiURL
;
private
RestTemplate
template
;
private
HttpHeaders
headers
;
@RequestMapping
(
value
=
"/deleteContent/{slug}"
)
public
String
deleteResource
(
@PathVariable
String
slug
,
Model
model
)
{
//make authentication for Transifex
basicAuthentication
();
Article
article
=
contentService
.
getGlobalArticle
(
slug
,
getLocale
());
//
if
(
resourceExists
(
article
))
{
StringBuilder
url
=
new
StringBuilder
();
url
.
append
(
"project/"
);
url
.
append
(
projectSlug
);
url
.
append
(
"/resource/"
);
url
.
append
(
"article-"
);
url
.
append
(
article
.
getSlug
());
HttpEntity
<
String
>
request
=
new
HttpEntity
<>(
headers
);
ResponseEntity
<
String
>
response
=
template
.
exchange
(
baseApiURL
+
url
,
HttpMethod
.
DELETE
,
request
,
String
.
class
);
if
(
response
.
getStatusCode
().
value
()
==
204
){
model
.
addAttribute
(
"result"
,
"deleted ok"
);
}
}
model
.
addAttribute
(
"title"
,
article
.
getTitle
());
model
.
addAttribute
(
"article"
,
article
);
return
"/content/article-edit"
;
}
@RequestMapping
(
value
=
"/hooks"
,
method
=
RequestMethod
.
POST
)
public
void
webHookHandle
(
@RequestParam
(
value
=
"project"
)
String
projectSlug
,
@RequestParam
(
value
=
"resource"
)
String
resource
,
@RequestParam
(
value
=
"language"
)
String
language
,
@RequestParam
(
value
=
"translated"
)
int
translated
){
System
.
out
.
println
(
projectSlug
+
" done \n"
);
}
@RequestMapping
(
value
=
"/translate/{slug}/{lang}"
,
method
=
RequestMethod
.
GET
)
public
String
translateArticles
(
@PathVariable
String
lang
,
@PathVariable
String
slug
,
Model
model
)
throws
DocumentException
{
//make authentication for Transifex
basicAuthentication
();
//Extract article from database we need
Article
article
=
contentService
.
getGlobalArticle
(
slug
,
getLocale
());
StringBuilder
url
=
new
StringBuilder
();
url
.
append
(
"project/"
);
url
.
append
(
projectSlug
);
url
.
append
(
"/resource/"
);
url
.
append
(
"article-"
);
url
.
append
(
slug
);
url
.
append
(
"/translation/"
);
url
.
append
(
lang
);
url
.
append
(
"/?file"
);
HttpEntity
<
String
>
request
=
new
HttpEntity
<>(
headers
);
ResponseEntity
<
String
>
response
=
template
.
exchange
(
baseApiURL
+
url
,
HttpMethod
.
GET
,
request
,
String
.
class
);
String
title
=
response
.
getBody
().
split
(
"<title>"
)[
1
].
split
(
"</title>"
)[
0
];
String
body
=
response
.
getBody
().
split
(
"<body>"
)[
1
].
split
(
"</body>"
)[
0
];
article
.
setTitle
(
title
);
article
.
setBody
(
body
);
contentService
.
updateArticle
(
article
.
getId
(),
article
.
getSlug
(),
article
.
getTitle
(),
article
.
getBody
());
model
.
addAttribute
(
"title"
,
article
.
getTitle
());
model
.
addAttribute
(
"article"
,
article
);
return
"/content/article-edit"
;
}
@RequestMapping
(
value
=
"/postContent/{slug}"
)
public
String
postResourceToTransifex
(
@PathVariable
String
slug
,
Model
model
)
throws
IOException
,
DocumentException
{
//We want to sent .xhtml file to transifex, for this we use dom4j
//Make the authentication for Transifex
basicAuthentication
();
//Extract article from database we need
Article
article
=
contentService
.
getGlobalArticle
(
slug
,
getLocale
(),
false
);
//Create temporary file articleSlug.xhtml
String
filePath
=
"/home/alexander/Downloads/"
+
article
.
getSlug
()+
".xhtml"
;
File
xhtmlFile
=
new
File
(
filePath
);
xhtmlFile
.
createNewFile
();
//Create dom4j document witch will be containing xhtml content
Document
xhtmlDocument
;
//Define xhtml output format for HTMLWriter
OutputFormat
outputFormat
=
OutputFormat
.
createPrettyPrint
();
outputFormat
.
setXHTML
(
true
);
HTMLWriter
writer
=
new
HTMLWriter
(
new
FileWriter
(
xhtmlFile
),
outputFormat
);
if
(!
resourceExists
(
article
))
{
//We will request like MULTIPART_FORM_DATA
headers
.
setContentType
(
MediaType
.
MULTIPART_FORM_DATA
);
//This is template our xhtml
String
content
=
"<html xmlns=\"http://www.w3.org/1999/xhtml\"> \n"
+
" <head> \n"
+
"<meta http-equiv=\"CONTENT-TYPE\" content=\"text/html; charset=utf8\"/> \n"
+
"<title>"
+
article
.
getTitle
()+
"</title> \n"
+
" </head> \n"
+
" <body>"
+
article
.
getBody
()+
"</body> \n"
+
"</html>"
;
//Parse String content and write it into articleSlug.xhtml file
xhtmlDocument
=
DocumentHelper
.
parseText
(
content
);
writer
.
write
(
xhtmlDocument
);
writer
.
flush
();
//Create Multi value map with all necessary information for request
MultiValueMap
<
String
,
Object
>
map
=
new
LinkedMultiValueMap
<>();
map
.
add
(
"slug"
,
"article-"
+
slug
);
map
.
add
(
"name"
,
article
.
getTitle
());
map
.
add
(
"i18n_type"
,
"XHTML"
);
Resource
resource
=
new
FileSystemResource
(
filePath
);
map
.
add
(
"content"
,
resource
);
//Create our request entity
HttpEntity
<
MultiValueMap
<
String
,
Object
>>
request
=
new
HttpEntity
<>(
map
,
headers
);
model
.
addAttribute
(
"title"
,
article
.
getTitle
());
model
.
addAttribute
(
"article"
,
article
);
StringBuilder
url
=
new
StringBuilder
();
url
.
append
(
"project/"
);
url
.
append
(
projectSlug
);
url
.
append
(
"/resources/"
);
try
{
//Send our post request(with .xhtml file) to Transifex
template
.
postForLocation
(
baseApiURL
+
url
,
request
);
model
.
addAttribute
(
"responseFromTransifex"
,
"Resource added"
);
}
catch
(
HttpClientErrorException
e
)
{
model
.
addAttribute
(
"responseFromTransifex"
,
"fail"
);
}
//After all operations, temporary .xhtml file is deleted
xhtmlFile
.
delete
();
}
return
"/content/article-edit"
;
}
//Transifex requires Basic HTTP authentication!
//This method make authentication for Transifex
public
void
basicAuthentication
()
{
template
=
new
RestTemplate
();
headers
=
new
HttpHeaders
();
String
trasifexCreds
=
trasifexUserName
+
":"
+
transifexPassord
;
byte
[]
transifexCredsBytes
=
trasifexCreds
.
getBytes
();
byte
[]
base64CredsBytes
=
Base64
.
encodeBase64
(
transifexCredsBytes
);
String
base64Creds
=
new
String
(
base64CredsBytes
);
headers
.
add
(
"Authorization"
,
"Basic "
+
base64Creds
);
}
//This method verify if article already exists in Transifex
public
boolean
resourceExists
(
Article
resource
)
{
//make authentication for Transifex
basicAuthentication
();
StringBuilder
url
=
new
StringBuilder
();
url
.
append
(
"project/"
);
url
.
append
(
projectSlug
);
url
.
append
(
"/resource/"
);
url
.
append
(
"article-"
);
url
.
append
(
resource
.
getSlug
());
ResponseEntity
<
String
>
response
;
HttpEntity
<
String
>
request
=
new
HttpEntity
<>(
headers
);
try
{
response
=
template
.
exchange
(
baseApiURL
+
url
,
HttpMethod
.
GET
,
request
,
String
.
class
);
}
catch
(
HttpClientErrorException
e
)
{
return
false
;
}
return
response
.
getStatusCode
().
value
()
==
200
;
}
}
src/main/resources/spring/spring.properties
View file @
f1cf8d1b
...
...
@@ -125,3 +125,9 @@ cache.tileserver.eviction-policy=LRU
# Connection to Elasticsearch
elasticsearch.url
=
http://localhost:9200/
transifex.project
=
genesys-dev
transifex.username
=
Alexandr19011990
transifex.password
=
Alexandr19011990
transifex.min.translated
=
80
transifex.base.api.url
=
https://www.transifex.com/api/2/
src/main/webapp/WEB-INF/jsp/content/article-edit.jsp
View file @
f1cf8d1b
<!DOCTYPE html>
<%@include
file=
"/WEB-INF/jsp/init.jsp"
%>
<%@include
file=
"/WEB-INF/jsp/init.jsp"
%>
<html>
<head>
<title>
${title}
</title>
<title>
${title}
</title>
</head>
<body>
<h1>
<spring:message
code=
"article.edit-article"
/>
</h1>
<form
role=
"form"
class=
""
action=
"
<c:url
value=
"/content/save-article"
/>
"
method=
"post"
>
<c:if
test=
"
${
article
.
id
ne
null
}
"
>
<input
type=
"hidden"
name=
"id"
value=
"${article.id}"
/>
</c:if>
<div
class=
"form-group"
>
<label
for=
"article-slug"
class=
"control-label"
><spring:message
code=
"article.slug"
/></label>
<div
class=
"controls"
>
<input
type=
"text"
id=
"article-slug"
name=
"slug"
value=
"
<c:out
value=
"
${
article
.
slug
}
"
/>
"
class=
"span9 form-control required"
/>
</div>
</div>
<div
class=
"form-group"
>
<label
for=
"article-title"
class=
"control-label"
><spring:message
code=
"article.title"
/></label>
<div
class=
"controls"
>
<input
type=
"text"
id=
"article-title"
name=
"title"
value=
"
<c:out
value=
"
${
article
.
title
}
"
/>
"
class=
"span9 form-control required"
/>
</div>
</div>
<div
class=
"form-group"
>
<label
for=
"article-body"
class=
"control-label"
><spring:message
code=
"article.body"
/></label>
<div
class=
"controls"
>
<textarea
id=
"article-body"
name=
"body"
class=
"span9 required form-control html-editor"
><c:out
value=
"
${
article
.
body
}
"
escapeXml=
"false"
/></textarea>
</div>
</div>
<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>
<content
tag=
"javascript"
>
<script
type=
"text/javascript"
src=
"/html/js/tinymce/tinymce.min.js"
></script>
<script
type=
"text/javascript"
>
jQuery
(
document
).
ready
(
function
()
{
if
(
window
.
location
.
hash
==
'
#raw
'
)
{
}
else
{
tinyMCE
.
init
({
selector
:
"
.html-editor
"
,
menubar
:
false
,
statusbar
:
false
,
height
:
200
,
plugins
:
"
link autolink code
"
,
directionality
:
document
.
dir
,
<h1>
<spring:message
code=
"article.edit-article"
/>
</h1>
<div
class=
"form-group"
>
<div>
${responseFromTransifex}
</div>
<a
href=
"
<c:url
value=
"/transifex/postContent/${article.slug}"
/>
"
class=
"btn btn-default"
>
Post to Transifex
</a>
</div>
<div
class=
"form-group"
>
<div>
${result}
</div>
<a
href=
"
<c:url
value=
"/transifex/deleteContent/${article.slug}"
/>
"
class=
"btn btn-default"
>
Delete from
Transifex
</a>
</div>
<div
class=
"form-group"
>
<div
class=
"dropdown"
>
<a
href=
"#"
class=
"dropdown-toggle"
data-toggle=
"dropdown"
><c:out
value=
"Transifex's translate"
/>
<b
class=
"caret"
></b></a>
<ul
class=
"dropdown-menu"
role=
"menu"
>
<li><a
href=
"${pageContext.request.contextPath}/transifex/translate/${article.slug}/${"
en
"}"
>
English
</a></li>
<li><a
href=
"${pageContext.request.contextPath}/transifex/translate/${article.slug}/${"
es
"}"
>
Spanish
</a></li>
<li><a
href=
"${pageContext.request.contextPath}/transifex/translate/${article.slug}/${"
ar
"}"
>
Arabic
</a></li>
<li><a
href=
"${pageContext.request.contextPath}/transifex/translate/${article.slug}/${"
zh
"}"
>
Chinese
</a></li>
<li><a
href=
"${pageContext.request.contextPath}/transifex/translate/${article.slug}/${"
fr
"}"
>
French
</a></li>
<li><a
href=
"${pageContext.request.contextPath}/transifex/translate/${article.slug}/${"
de
"}"
>
German
</a></li>
<li><a
href=
"${pageContext.request.contextPath}/transifex/translate/${article.slug}/${"
fa
"}"
>
Persian
</a></li>
<li><a
href=
"${pageContext.request.contextPath}/transifex/translate/${article.slug}/${"
ru
"}"
>
Russian
</a></li>
</ul>
</div>
</div>
<form
role=
"form"
class=
""
action=
"
<c:url
value=
"/content/save-article"
/>
"
method=
"post"
>
<c:if
test=
"
${
article
.
id
ne
null
}
"
>
<input
type=
"hidden"
name=
"id"
value=
"${article.id}"
/>
</c:if>
<div
class=
"form-group"
>
<label
for=
"article-slug"
class=
"control-label"
><spring:message
code=
"article.slug"
/></label>
<div
class=
"controls"
>
<input
type=
"text"
id=
"article-slug"
name=
"slug"
value=
"
<c:out
value=
"
${
article
.
slug
}
"
/>
"
class=
"span9 form-control required"
/>
</div>
</div>
<div
class=
"form-group"
>
<label
for=
"article-title"
class=
"control-label"
><spring:message
code=
"article.title"
/></label>
<div
class=
"controls"
>
<input
type=
"text"
id=
"article-title"
name=
"title"
value=
"
<c:out
value=
"
${
article
.
title
}
"
/>
"
class=
"span9 form-control required"
/>
</div>
</div>
<div
class=
"form-group"
>
<label
for=
"article-body"
class=
"control-label"
><spring:message
code=
"article.body"
/></label>
<div
class=
"controls"
>
<textarea
id=
"article-body"
name=
"body"
class=
"span9 required form-control html-editor"
><c:out
value=
"
${
article
.
body
}
"
escapeXml=
"false"
/></textarea>
</div>
</div>
<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>
<content
tag=
"javascript"
>
<script
type=
"text/javascript"
src=
"/html/js/tinymce/tinymce.min.js"
></script>
<script
type=
"text/javascript"
>
jQuery
(
document
).
ready
(
function
()
{
if
(
window
.
location
.
hash
==
'
#raw
'
)
{
}
else
{
tinyMCE
.
init
({
selector
:
"
.html-editor
"
,
menubar
:
false
,
statusbar
:
false
,
height
:
200
,
plugins
:
"
link autolink code
"
,
directionality
:
document
.
dir
,
convert_urls
:
false
});
}
});
</script>
});
}
});
</script>
</content>
</body>
</html>
\ No newline at end of file
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment