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