master
VogelT 2 months ago
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>

1
.gitignore vendored

@ -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,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…
Cancel
Save