Compare commits

..

No commits in common. "770f63bca90bef1612b352022b1ecea2e9e082da" and "88a00874c89d279f5a8acdf1d43db01f39fb0b35" have entirely different histories.

19 changed files with 105 additions and 143 deletions

View File

@ -4,14 +4,14 @@
# @Date: 2022-10-20 02:19:06
# @LastEditors: Vincent Yang
# @LastEditTime: 2024-03-20 16:52:40
# @FilePath: /DLX/.cross_compile.sh
# @FilePath: /DeepLX/.cross_compile.sh
# @Telegram: https://t.me/missuo
#
# Copyright © 2022 by Vincent, All Rights Reserved.
###
set -e
DIST_PREFIX="dlx"
DIST_PREFIX="deeplx"
DEBUG_MODE=${2}
TARGET_DIR="dist"
PLATFORMS="darwin/amd64 darwin/arm64 linux/386 linux/amd64 linux/arm64 linux/mips openbsd/amd64 openbsd/arm64 freebsd/amd64 freebsd/arm64 windows/386 windows/amd64"

View File

@ -8,7 +8,7 @@ on:
- 'v*'
env:
DOCKER_IMAGE_NAME: missuo/dlx
DOCKER_IMAGE_NAME: missuo/deeplx
GHCR_IMAGE_NAME: ${{ github.repository }}
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}

View File

@ -41,7 +41,7 @@ jobs:
CGO_ENABLED: "0"
run: |
mkdir -p dist
BINARY="dist/dlx_${GOOS}_${GOARCH}"
BINARY="dist/deeplx_${GOOS}_${GOARCH}"
if [ "${GOOS}" = "windows" ]; then
BINARY="${BINARY}.exe"
fi
@ -50,7 +50,7 @@ jobs:
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: dlx_${{ matrix.goos }}_${{ matrix.goarch }}
name: deeplx_${{ matrix.goos }}_${{ matrix.goarch }}
path: dist/*
if-no-files-found: error

3
.gitignore vendored
View File

@ -1,5 +1,4 @@
DLX
dlx
DeepLX
# macOS Finder metadata
.DS_Store

View File

@ -1,13 +1,13 @@
FROM golang:1.25 AS builder
WORKDIR /go/src/github.com/OwO-Network/DLX
WORKDIR /go/src/github.com/OwO-Network/DeepLX
COPY . .
RUN go get -d -v ./
RUN CGO_ENABLED=0 go build -a -installsuffix cgo -o dlx .
RUN CGO_ENABLED=0 go build -a -installsuffix cgo -o deeplx .
FROM alpine:latest
WORKDIR /app
RUN addgroup -S dlx && adduser -h /app -G dlx -SH dlx
USER dlx:dlx
COPY --from=builder --chown=dlx:dlx /go/src/github.com/OwO-Network/DLX/dlx /app/dlx
RUN addgroup -S deeplx && adduser -h /app -G deeplx -SH deeplx
USER deeplx:deeplx
COPY --from=builder --chown=deeplx:deeplx /go/src/github.com/OwO-Network/DeepLX/deeplx /app/deeplx
EXPOSE 1188
ENTRYPOINT ["/app/dlx"]
ENTRYPOINT ["/app/deeplx"]

View File

@ -2,69 +2,32 @@
* @Author: Vincent Young
* @Date: 2022-10-18 07:32:29
* @LastEditors: Vincent Yang
* @LastEditTime: 2026-07-08 00:00:00
* @FilePath: /DLX/README.md
* @LastEditTime: 2024-11-30 19:48:00
* @FilePath: /DeepLX/README.md
* @Telegram: https://t.me/missuo
*
* Copyright © 2022 by Vincent, All Rights Reserved.
-->
# DLX
[![GitHub Workflow][1]](https://github.com/OwO-Network/DeepLX/actions)
[![Go Version][2]](https://github.com/OwO-Network/DeepLX/blob/main/go.mod)
[![Go Report][3]](https://goreportcard.com/badge/github.com/OwO-Network/DeepLX)
[![GitHub License][4]](https://github.com/OwO-Network/DeepLX/blob/main/LICENSE)
[![Docker Pulls][5]](https://hub.docker.com/r/missuo/deeplx)
[![Releases][6]](https://github.com/OwO-Network/DeepLX/releases)
[![GitHub Workflow][1]](https://github.com/OwO-Network/DLX/actions)
[![Go Version][2]](https://github.com/OwO-Network/DLX/blob/main/go.mod)
[![Go Report][3]](https://goreportcard.com/badge/github.com/OwO-Network/DLX)
[![GitHub License][4]](https://github.com/OwO-Network/DLX/blob/main/LICENSE)
[![Docker Pulls][5]](https://hub.docker.com/r/missuo/dlx)
[![Releases][6]](https://github.com/OwO-Network/DLX/releases)
[1]: https://img.shields.io/github/actions/workflow/status/OwO-Network/DeepLX/release.yaml?logo=github
[2]: https://img.shields.io/github/go-mod/go-version/OwO-Network/DeepLX?logo=go
[3]: https://goreportcard.com/badge/github.com/OwO-Network/DeepLX
[4]: https://img.shields.io/github/license/OwO-Network/DeepLX
[5]: https://img.shields.io/docker/pulls/missuo/deeplx?logo=docker
[6]: https://img.shields.io/github/v/release/OwO-Network/DeepLX?logo=smartthings
[1]: https://img.shields.io/github/actions/workflow/status/OwO-Network/DLX/release.yaml?logo=github
[2]: https://img.shields.io/github/go-mod/go-version/OwO-Network/DLX?logo=go
[3]: https://goreportcard.com/badge/github.com/OwO-Network/DLX
[4]: https://img.shields.io/github/license/OwO-Network/DLX
[5]: https://img.shields.io/docker/pulls/missuo/dlx?logo=docker
[6]: https://img.shields.io/github/v/release/OwO-Network/DLX?logo=smartthings
## How to use
> [!IMPORTANT]
> **Disclaimer:** DLX is an independent, open-source project. It is **not** an official DeepL product, and it is **not** affiliated with, endorsed by, or sponsored by DeepL SE in any way. "DeepL" is a registered trademark of DeepL SE. Any reference to DeepL in this repository is made solely to describe interoperability with the DeepL translation service.
## Why was this project renamed?
In July 2026, we received a trademark notice forwarded by GitHub Trust & Safety, submitted on behalf of DeepL SE. The notice stated that this project's former name, "DeepLX", contained the registered trademark "DeepL" and might cause confusion about whether the project is authorized or endorsed by DeepL SE.
It never was, and it never claimed to be. To resolve the matter and remove any possible confusion, we renamed the repository to **DLX** and removed DeepL branding from the project. To state it plainly one more time: **this project is not an official DeepL project and has no relationship with DeepL SE whatsoever.**
DLX is a self-hosted translation API server written in Go. It exposes a simple HTTP API on port `1188`.
## Usage
### Docker
```bash
docker run -d -p 1188:1188 ghcr.io/owo-network/dlx:latest
```
Or use the provided [`compose.yaml`](compose.yaml):
```bash
docker compose up -d
```
### Binary
Download the binary for your platform from [Releases](https://github.com/OwO-Network/DLX/releases) and run it:
```bash
./dlx
```
### Translate
```bash
curl -X POST http://localhost:1188/translate \
-H "Content-Type: application/json" \
-d '{"text": "Hello, world!", "source_lang": "EN", "target_lang": "ZH"}'
```
> \[!TIP]
>
> Learn more about [📘 Using DeepLX](https://deeplx.owo.network) by checking it out.
## Discussion Group
[Telegram Group](https://t.me/+8KDGHKJCxEVkNzll)
@ -73,12 +36,12 @@ curl -X POST http://localhost:1188/translate \
### Contributors
<a href="https://github.com/OwO-Network/DLX/graphs/contributors">
<img src="https://contrib.rocks/image?repo=OwO-Network/DLX&anon=0" />
<a href="https://github.com/OwO-Network/DeepLX/graphs/contributors">
<img src="https://contrib.rocks/image?repo=OwO-Network/DeepLX&anon=0" />
</a>
## Activity
![Alt](https://repobeats.axiom.co/api/embed/5f473f85db27cb30028a2f3db7a560f3577a4860.svg "Repobeats analytics image")
## License
[MIT](LICENSE)
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FOwO-Network%2FDeepLX.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2FOwO-Network%2FDeepLX?ref=badge_large)

View File

@ -1,6 +1,6 @@
services:
dlx:
image: ghcr.io/owo-network/dlx:latest
deeplx:
image: ghcr.io/owo-network/deeplx:latest
restart: always
ports:
- "1188:1188"

View File

@ -1,12 +1,12 @@
[Unit]
Description=DLX Service
Description=DeepLX Service
After=network.target
[Service]
Type=simple
Restart=always
WorkingDirectory=/usr/bin/
ExecStart=/usr/bin/dlx
ExecStart=/usr/bin/deeplx
[Install]
WantedBy=multi-user.target

2
go.mod
View File

@ -1,4 +1,4 @@
module github.com/OwO-Network/DLX
module github.com/OwO-Network/DeepLX
go 1.25.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 592 KiB

View File

@ -1,21 +1,21 @@
###
# @Author: Vincent Young
# @Date: 2023-02-12 09:53:21
# @LastEditors: Vincent Yang
# @LastEditTime: 2026-07-08 00:00:00
# @FilePath: /DLX/install.sh
# @LastEditors: Vincent Young
# @LastEditTime: 2023-02-12 10:01:57
# @FilePath: /DeepLX/install.sh
# @Telegram: https://t.me/missuo
#
# Copyright © 2023 by Vincent, All Rights Reserved.
###
#
# Copyright © 2023 by Vincent, All Rights Reserved.
###
install_dlx(){
last_version=$(curl -Ls "https://api.github.com/repos/OwO-Network/DLX/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
install_deeplx(){
last_version=$(curl -Ls "https://api.github.com/repos/OwO-Network/DeepLX/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
if [[ ! -n "$last_version" ]]; then
echo -e "${red}Failed to detect DLX version, probably due to exceeding Github API limitations.${plain}"
echo -e "${red}Failed to detect DeepLX version, probably due to exceeding Github API limitations.${plain}"
exit 1
fi
echo -e "DLX latest version: ${last_version}, Start install..."
echo -e "DeepLX latest version: ${last_version}, Start install..."
arch=$(uname -m)
case "${arch}" in
@ -29,13 +29,13 @@ install_dlx(){
;;
esac
wget -q -N --no-check-certificate -O /usr/bin/dlx https://github.com/OwO-Network/DLX/releases/download/${last_version}/dlx_linux_${file_arch}
wget -q -N --no-check-certificate -O /usr/bin/deeplx https://github.com/OwO-Network/DeepLX/releases/download/${last_version}/deeplx_linux_${file_arch}
chmod +x /usr/bin/dlx
wget -q -N --no-check-certificate -O /etc/systemd/system/dlx.service https://raw.githubusercontent.com/OwO-Network/DLX/main/dlx.service
chmod +x /usr/bin/deeplx
wget -q -N --no-check-certificate -O /etc/systemd/system/deeplx.service https://raw.githubusercontent.com/OwO-Network/DeepLX/main/deeplx.service
systemctl daemon-reload
systemctl enable dlx
systemctl start dlx
systemctl enable deeplx
systemctl start deeplx
echo -e "Installed successfully, listening at 0.0.0.0:1188"
}
install_dlx
install_deeplx

View File

@ -3,7 +3,7 @@
* @Date: 2023-07-01 21:45:34
* @LastEditors: Jason Lyu
* @LastEditTime: 2025-04-08 13:45:00
* @FilePath: /DLX/main.go
* @FilePath: /DeepLX/main.go
* @Telegram: https://t.me/missuo
* @GitHub: https://github.com/missuo
*
@ -17,13 +17,13 @@ import (
"github.com/gin-gonic/gin"
"github.com/OwO-Network/DLX/service"
"github.com/OwO-Network/DeepLX/service"
)
func main() {
cfg := service.InitConfig()
fmt.Printf("DLX has been successfully launched! Listening on %v:%v\n", cfg.IP, cfg.Port)
fmt.Printf("DeepL X has been successfully launched! Listening on %v:%v\n", cfg.IP, cfg.Port)
fmt.Println("Developed by sjlleo <i@leo.moe> and missuo <me@missuo.me>.")
// Setting the application to release mode

View File

@ -3,12 +3,12 @@
<plist version="1.0">
<dict>
<key>Label</key>
<string>me.missuo.dlx</string>
<string>me.missuo.deeplx</string>
<key>KeepAlive</key>
<true/>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/dlx</string>
<string>/usr/local/bin/deeplx</string>
</array>
<key>RunAtLoad</key>
<true/>

View File

@ -3,7 +3,7 @@
* @Date: 2024-04-23 00:39:03
* @LastEditors: Jason Lyu
* @LastEditTime: 2025-04-08 13:45:00
* @FilePath: /DLX/service/config.go
* @FilePath: /DeepLX/config.go
* @Telegram: https://t.me/missuo
* @GitHub: https://github.com/missuo
*

View File

@ -3,7 +3,7 @@
* @Date: 2023-07-01 21:45:34
* @LastEditors: Jason Lyu
* @LastEditTime: 2025-04-08 13:45:00
* @FilePath: /DLX/service/service.go
* @FilePath: /DeepLX/main.go
* @Telegram: https://t.me/missuo
* @GitHub: https://github.com/missuo
*
@ -23,7 +23,7 @@ import (
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
"github.com/OwO-Network/DLX/translate"
"github.com/OwO-Network/DeepLX/translate"
)
func authMiddleware(cfg *Config) gin.HandlerFunc {
@ -101,7 +101,7 @@ func Router(cfg *Config) *gin.Engine {
r.GET("/", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": http.StatusOK,
"message": "DLX Translation API, Developed by sjlleo and missuo. Go to /translate with POST. https://github.com/OwO-Network/DLX",
"message": "DeepL Free API, Developed by sjlleo and missuo. Go to /translate with POST. http://github.com/OwO-Network/DeepLX",
})
})
@ -131,7 +131,7 @@ func Router(cfg *Config) *gin.Engine {
return
}
result, err := translate.TranslateByDLX(sourceLang, targetLang, translateText, tagHandling, proxyURL, "")
result, err := translate.TranslateByDeepLX(sourceLang, targetLang, translateText, tagHandling, proxyURL, "")
if err != nil {
log.Printf("Translation failed: %s", err)
c.JSON(http.StatusInternalServerError, gin.H{
@ -206,7 +206,7 @@ func Router(cfg *Config) *gin.Engine {
return
}
result, err := translate.TranslateByDLX(sourceLang, targetLang, translateText, tagHandling, proxyURL, dlSession)
result, err := translate.TranslateByDeepLX(sourceLang, targetLang, translateText, tagHandling, proxyURL, dlSession)
if err != nil {
log.Printf("Translation failed: %s", err)
c.JSON(http.StatusInternalServerError, gin.H{
@ -263,7 +263,7 @@ func Router(cfg *Config) *gin.Engine {
targetLang = jsonData.TargetLang
}
result, err := translate.TranslateByDLX("", targetLang, translateText, "", proxyURL, "")
result, err := translate.TranslateByDeepLX("", targetLang, translateText, "", proxyURL, "")
if err != nil {
log.Printf("Translation failed: %s", err)
c.JSON(http.StatusInternalServerError, gin.H{

View File

@ -3,7 +3,7 @@
* @Date: 2024-09-16 11:59:24
* @LastEditors: Vincent Yang
* @LastEditTime: 2026-05-22 00:00:00
* @FilePath: /DLX/translate/translate.go
* @FilePath: /DeepLX/translate/translate.go
* @Telegram: https://t.me/missuo
* @GitHub: https://github.com/missuo
*
@ -382,13 +382,13 @@ func callOneshot(endpoint string, body []byte, bearerToken, proxyURL string) (gj
return gjson.ParseBytes(raw), resp.StatusCode, nil
}
// TranslateByDLX performs translation via the DeepL oneshot endpoint.
// TranslateByDeepLX performs translation via the DeepL oneshot endpoint.
// Passing dlSession switches to the Pro endpoint; the value is sent
// verbatim as the Bearer token (i.e. it must be an OAuth access token,
// not the legacy dl_session cookie).
func TranslateByDLX(sourceLang, targetLang, text string, tagHandling string, proxyURL string, dlSession string) (DLXTranslationResult, error) {
func TranslateByDeepLX(sourceLang, targetLang, text string, tagHandling string, proxyURL string, dlSession string) (DeepLXTranslationResult, error) {
if text == "" {
return DLXTranslationResult{
return DeepLXTranslationResult{
Code: http.StatusNotFound,
Message: "No text to translate",
}, nil
@ -396,21 +396,21 @@ func TranslateByDLX(sourceLang, targetLang, text string, tagHandling string, pro
resolvedTarget, err := resolveTargetLang(targetLang)
if err != nil {
return DLXTranslationResult{
return DeepLXTranslationResult{
Code: http.StatusBadRequest,
Message: err.Error(),
}, nil
}
resolvedSource, err := resolveSourceLang(sourceLang)
if err != nil {
return DLXTranslationResult{
return DeepLXTranslationResult{
Code: http.StatusBadRequest,
Message: err.Error(),
}, nil
}
if n := utf8.RuneCountInString(text); n > maxFreeTextLength {
return DLXTranslationResult{
return DeepLXTranslationResult{
Code: http.StatusRequestEntityTooLarge,
Message: fmt.Sprintf("text exceeds maximum length: %d characters (anonymous oneshot limit is %d)", n, maxFreeTextLength),
}, nil
@ -443,13 +443,13 @@ func TranslateByDLX(sourceLang, targetLang, text string, tagHandling string, pro
// took too long" from other 503 failure modes (DNS, TLS, etc.).
var ue *url.Error
if errors.Is(err, context.DeadlineExceeded) || (errors.As(err, &ue) && ue.Timeout()) {
return DLXTranslationResult{
return DeepLXTranslationResult{
ID: id,
Code: http.StatusGatewayTimeout,
Message: fmt.Sprintf("upstream DeepL request timed out after %s", oneshotTimeout),
}, nil
}
return DLXTranslationResult{
return DeepLXTranslationResult{
ID: id,
Code: http.StatusServiceUnavailable,
Message: err.Error(),
@ -460,13 +460,13 @@ func TranslateByDLX(sourceLang, targetLang, text string, tagHandling string, pro
case http.StatusOK:
// fall through to body parsing
case http.StatusTooManyRequests:
return DLXTranslationResult{
return DeepLXTranslationResult{
ID: id,
Code: http.StatusTooManyRequests,
Message: "too many requests, your IP has been blocked by DeepL temporarily, please don't request it frequently in a short time",
}, nil
default:
return DLXTranslationResult{
return DeepLXTranslationResult{
ID: id,
Code: http.StatusServiceUnavailable,
Message: fmt.Sprintf("request failed with status code: %d", status),
@ -475,7 +475,7 @@ func TranslateByDLX(sourceLang, targetLang, text string, tagHandling string, pro
translations := result.Get("translations").Array()
if len(translations) == 0 {
return DLXTranslationResult{
return DeepLXTranslationResult{
ID: id,
Code: http.StatusServiceUnavailable,
Message: "Translation failed",
@ -484,7 +484,7 @@ func TranslateByDLX(sourceLang, targetLang, text string, tagHandling string, pro
mainText := translations[0].Get("text").String()
if mainText == "" {
return DLXTranslationResult{
return DeepLXTranslationResult{
ID: id,
Code: http.StatusServiceUnavailable,
Message: "Translation failed",
@ -495,7 +495,7 @@ func TranslateByDLX(sourceLang, targetLang, text string, tagHandling string, pro
sourceLang = strings.ToUpper(detected)
}
return DLXTranslationResult{
return DeepLXTranslationResult{
Code: http.StatusOK,
ID: id,
Data: mainText,

View File

@ -3,7 +3,7 @@
* @Date: 2024-09-16 11:59:24
* @LastEditors: Vincent Yang
* @LastEditTime: 2026-05-22 00:00:00
* @FilePath: /DLX/translate/types.go
* @FilePath: /DeepLX/translate/types.go
* @Telegram: https://t.me/missuo
* @GitHub: https://github.com/missuo
*
@ -12,11 +12,11 @@
package translate
// DLXTranslationResult is the public response shape consumed by the HTTP
// DeepLXTranslationResult is the public response shape consumed by the HTTP
// handlers in the service package. The structure predates the migration to
// the oneshot endpoint; Alternatives is now always empty because oneshot does
// not return alternative translations, and ID is synthesized from time.
type DLXTranslationResult struct {
type DeepLXTranslationResult struct {
Code int `json:"code"`
ID int64 `json:"id"`
Message string `json:"message,omitempty"`

View File

@ -12,44 +12,44 @@ if [[ $EUID -ne 0 ]]; then
exit 1
fi
uninstall_dlx() {
echo -e "${green}Starting DLX uninstallation...${plain}"
uninstall_deeplx() {
echo -e "${green}Starting DeepLX uninstallation...${plain}"
# 1. Stop and disable the DLX service
if systemctl is-active --quiet dlx; then
echo -e "${yellow}Stopping DLX service...${plain}"
systemctl stop dlx
# 1. Stop and disable the DeepLX service
if systemctl is-active --quiet deeplx; then
echo -e "${yellow}Stopping DeepLX service...${plain}"
systemctl stop deeplx
else
echo -e "${yellow}DLX service is not running or not found.${plain}"
echo -e "${yellow}DeepLX service is not running or not found.${plain}"
fi
if systemctl is-enabled --quiet dlx; then
echo -e "${yellow}Disabling DLX service from starting on boot...${plain}"
systemctl disable dlx
if systemctl is-enabled --quiet deeplx; then
echo -e "${yellow}Disabling DeepLX service from starting on boot...${plain}"
systemctl disable deeplx
else
echo -e "${yellow}DLX service is not enabled.${plain}"
echo -e "${yellow}DeepLX service is not enabled.${plain}"
fi
# 2. Remove the systemd service file
if [ -f /etc/systemd/system/dlx.service ]; then
echo -e "${yellow}Removing DLX systemd service file (/etc/systemd/system/dlx.service)...${plain}"
rm -f /etc/systemd/system/dlx.service
if [ -f /etc/systemd/system/deeplx.service ]; then
echo -e "${yellow}Removing DeepLX systemd service file (/etc/systemd/system/deeplx.service)...${plain}"
rm -f /etc/systemd/system/deeplx.service
systemctl daemon-reload
echo -e "${green}Systemd daemon reloaded.${plain}"
else
echo -e "${yellow}DLX systemd service file not found, skipping removal.${plain}"
echo -e "${yellow}DeepLX systemd service file not found, skipping removal.${plain}"
fi
# 3. Remove the DLX executable
if [ -f /usr/bin/dlx ]; then
echo -e "${yellow}Removing DLX executable (/usr/bin/dlx)...${plain}"
rm -f /usr/bin/dlx
# 3. Remove the DeepLX executable
if [ -f /usr/bin/deeplx ]; then
echo -e "${yellow}Removing DeepLX executable (/usr/bin/deeplx)...${plain}"
rm -f /usr/bin/deeplx
else
echo -e "${yellow}DLX executable not found, skipping removal.${plain}"
echo -e "${yellow}DeepLX executable not found, skipping removal.${plain}"
fi
echo -e "${green}DLX uninstallation complete.${plain}"
echo -e "${green}DeepLX uninstallation complete.${plain}"
echo -e "${green}If you wish to reinstall, please run the install script again.${plain}"
}
uninstall_dlx
uninstall_deeplx