commit
9ee5379c38
@ -0,0 +1,41 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<classpath>
|
||||||
|
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="optional" value="true"/>
|
||||||
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
|
<attribute name="optional" value="true"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="optional" value="true"/>
|
||||||
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
|
<attribute name="test" value="true"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
|
<attribute name="test" value="true"/>
|
||||||
|
<attribute name="optional" value="true"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-21">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
|
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="output" path="target/classes"/>
|
||||||
|
</classpath>
|
||||||
@ -0,0 +1 @@
|
|||||||
|
/target/
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>translator</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.wst.common.project.facet.core.builder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.wst.validation.validationbuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
|
||||||
|
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
|
||||||
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
|
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||||
|
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
|
||||||
|
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<classpath>
|
||||||
|
<classpathentry excluding="**/node_modules/*|**/*.min.js|**/bower_components/*" kind="src" path="src/main/webapp"/>
|
||||||
|
<classpathentry kind="src" path="target/m2e-wtp/web-resources"/>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.WebProject">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="hide" value="true"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
|
||||||
|
<classpathentry kind="output" path=""/>
|
||||||
|
</classpath>
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
eclipse.preferences.version=1
|
||||||
|
encoding//src/main/java=UTF-8
|
||||||
|
encoding//src/main/resources=UTF-8
|
||||||
|
encoding/<project>=UTF-8
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
eclipse.preferences.version=1
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.methodParameters=generate
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.targetPlatform=21
|
||||||
|
org.eclipse.jdt.core.compiler.compliance=21
|
||||||
|
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||||
|
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
|
||||||
|
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||||
|
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
|
||||||
|
org.eclipse.jdt.core.compiler.release=enabled
|
||||||
|
org.eclipse.jdt.core.compiler.source=21
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
activeProfiles=
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
resolveWorkspaceProjects=true
|
||||||
|
version=1
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
|
||||||
|
<wb-module deploy-name="translator-2.0.0">
|
||||||
|
<wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
|
||||||
|
<wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
|
||||||
|
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
|
||||||
|
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
|
||||||
|
<property name="context-root" value="translator"/>
|
||||||
|
<property name="java-output-path" value="/translator/target/classes"/>
|
||||||
|
</wb-module>
|
||||||
|
</project-modules>
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<faceted-project>
|
||||||
|
<fixed facet="wst.jsdt.web"/>
|
||||||
|
<installed facet="java" version="21"/>
|
||||||
|
<installed facet="jst.web" version="6.0"/>
|
||||||
|
<installed facet="wst.jsdt.web" version="1.0"/>
|
||||||
|
</faceted-project>
|
||||||
@ -0,0 +1 @@
|
|||||||
|
org.eclipse.wst.jsdt.launching.baseBrowserLibrary
|
||||||
@ -0,0 +1 @@
|
|||||||
|
Window
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
disabled=06target
|
||||||
|
eclipse.preferences.version=1
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
version: '3.9'
|
||||||
|
services:
|
||||||
|
mariadb:
|
||||||
|
image: mariadb:11
|
||||||
|
environment:
|
||||||
|
MYSQL_DATABASE: translator
|
||||||
|
MYSQL_USER: translator
|
||||||
|
MYSQL_PASSWORD: translator
|
||||||
|
MYSQL_ROOT_PASSWORD: root
|
||||||
|
volumes: ["./sql:/docker-entrypoint-initdb.d"]
|
||||||
|
tomcat:
|
||||||
|
build: docker
|
||||||
|
ports: ['8080:8080']
|
||||||
|
depends_on: [mariadb]
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
FROM eclipse-temurin:21-jre
|
||||||
|
RUN apt-get update && apt-get install -y python3-pip && pip install argostranslate && argos-translate-cli --download de en
|
||||||
|
COPY target/translator.war /app.war
|
||||||
|
EXPOSE 8080
|
||||||
|
CMD ["java","-jar","/app.war"]
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>de.example</groupId>
|
||||||
|
<artifactId>translator</artifactId>
|
||||||
|
<version>2.0.0</version>
|
||||||
|
<packaging>war</packaging>
|
||||||
|
<properties><java.version>21</java.version></properties>
|
||||||
|
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.2.5</version></parent>
|
||||||
|
<dependencies>
|
||||||
|
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
|
||||||
|
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency>
|
||||||
|
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency>
|
||||||
|
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency>
|
||||||
|
<dependency><groupId>org.mariadb.jdbc</groupId><artifactId>mariadb-java-client</artifactId><scope>runtime</scope></dependency>
|
||||||
|
<dependency><groupId>com.github.ben-manes.caffeine</groupId><artifactId>caffeine</artifactId></dependency>
|
||||||
|
</dependencies></project>
|
||||||
@ -0,0 +1 @@
|
|||||||
|
CREATE DATABASE IF NOT EXISTS translator;
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
package de.example.translator;
|
||||||
|
|
||||||
|
import org.springframework.boot.*;
|
||||||
|
import org.springframework.boot.autoconfigure.*;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class TranslatorApplication {
|
||||||
|
public static void main(String[] a) {
|
||||||
|
SpringApplication.run(TranslatorApplication.class, a);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
package de.example.translator.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.*;
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.web.*;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class SecurityConfig {
|
||||||
|
@Bean
|
||||||
|
SecurityFilterChain f(HttpSecurity h) throws Exception {
|
||||||
|
h.csrf(c -> c.disable())
|
||||||
|
.authorizeHttpRequests(a -> a.requestMatchers("/admin").authenticated().anyRequest().permitAll())
|
||||||
|
.httpBasic();
|
||||||
|
return h.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
package de.example.translator.controller;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.*;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import de.example.translator.repository.*;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class AdminController {
|
||||||
|
private final TranslationLogRepository r;
|
||||||
|
|
||||||
|
public AdminController(TranslationLogRepository r) {
|
||||||
|
this.r = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/admin")
|
||||||
|
public String a(Model m) {
|
||||||
|
m.addAttribute("logs", r.findAll());
|
||||||
|
return "admin";
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package de.example.translator.controller;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import java.util.*;
|
||||||
|
import de.example.translator.service.*;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api")
|
||||||
|
public class TranslationController {
|
||||||
|
private final TranslationService s;
|
||||||
|
|
||||||
|
public TranslationController(TranslationService s) {
|
||||||
|
this.s = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/translate")
|
||||||
|
public String t(@RequestParam String from, @RequestParam String to, @RequestParam String text) {
|
||||||
|
return s.translate(from, to, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/batch")
|
||||||
|
public List<String> b(@RequestParam String from, @RequestParam String to, @RequestBody List<String> texts) {
|
||||||
|
return s.batch(from, to, texts);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
package de.example.translator.entity;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import java.time.*;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class TranslationLog {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
public Long id;
|
||||||
|
public String sourceLang;
|
||||||
|
public String targetLang;
|
||||||
|
@Column(columnDefinition = "TEXT")
|
||||||
|
public String sourceText;
|
||||||
|
@Column(columnDefinition = "TEXT")
|
||||||
|
public String translatedText;
|
||||||
|
public LocalDateTime createdAt = LocalDateTime.now();
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
package de.example.translator.repository;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.*;
|
||||||
|
import de.example.translator.entity.*;
|
||||||
|
|
||||||
|
public interface TranslationLogRepository extends JpaRepository<TranslationLog, Long> {
|
||||||
|
}
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
package de.example.translator.service;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.*;
|
||||||
|
import com.github.benmanes.caffeine.cache.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.io.*;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.stream.*;
|
||||||
|
import de.example.translator.repository.*;
|
||||||
|
import de.example.translator.entity.*;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class TranslationService {
|
||||||
|
private final TranslationLogRepository r;
|
||||||
|
private final Cache<String, String> cache = Caffeine.newBuilder().maximumSize(1000).build();
|
||||||
|
|
||||||
|
public TranslationService(TranslationLogRepository r) {
|
||||||
|
this.r = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String translate(String f, String t, String x) {
|
||||||
|
String k = f + t + x;
|
||||||
|
return cache.get(k, kk -> {
|
||||||
|
String tr = argos(f, t, x);
|
||||||
|
TranslationLog l = new TranslationLog();
|
||||||
|
l.sourceLang = f;
|
||||||
|
l.targetLang = t;
|
||||||
|
l.sourceText = x;
|
||||||
|
l.translatedText = tr;
|
||||||
|
r.save(l);
|
||||||
|
return tr;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> batch(String f, String t, List<String> xs) {
|
||||||
|
return xs.stream().map(x -> translate(f, t, x)).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String argos(String f, String t, String x) {
|
||||||
|
try {
|
||||||
|
Process p = new ProcessBuilder("argos-translate", "--from-lang", f, "--to-lang", t, "--text", x).start();
|
||||||
|
return new BufferedReader(new InputStreamReader(p.getInputStream(), StandardCharsets.UTF_8)).lines()
|
||||||
|
.collect(Collectors.joining());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
spring:
|
||||||
|
datasource:
|
||||||
|
url: jdbc:mariadb://mariadb:3306/translator
|
||||||
|
username: translator
|
||||||
|
password: translator
|
||||||
|
jpa:
|
||||||
|
hibernate:
|
||||||
|
ddl-auto: update
|
||||||
|
show-sql: false
|
||||||
|
server:
|
||||||
|
port: 8080
|
||||||
|
api:
|
||||||
|
key: secret123
|
||||||
@ -0,0 +1 @@
|
|||||||
|
<html><body><h2>Translation Logs</h2><table border=1><tr><th>ID</th><th>From</th><th>To</th><th>Text</th><th>Result</th></tr><tr th:each="l:${logs}"><td th:text="${l.id}"/><td th:text="${l.sourceLang}"/><td th:text="${l.targetLang}"/><td th:text="${l.sourceText}"/><td th:text="${l.translatedText}"/></tr></table></body></html>
|
||||||
Loading…
Reference in new issue