refactor!: rename project from DeepLX to DLX

Rebrand in response to a trademark report regarding the DEEPL mark.
Renames the Go module path, exported symbols, binary, systemd/launchd
services, Docker images, and CI artifacts; adds a trademark disclaimer
to the README and removes screenshots containing DeepL branding.

BREAKING CHANGE: Go module path is now github.com/OwO-Network/DLX.
translate.TranslateByDeepLX is now translate.TranslateByDLX and
DeepLXTranslationResult is now DLXTranslationResult. The release
binaries, systemd service, and Docker images are renamed from
deeplx to dlx.
This commit is contained in:
Vincent Yang 2026-07-08 08:53:32 -07:00
parent 88a00874c8
commit 515752fe25
No known key found for this signature in database
GPG Key ID: F9D66A5FEA75787E
19 changed files with 137 additions and 105 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: /DeepLX/.cross_compile.sh
# @FilePath: /DLX/.cross_compile.sh
# @Telegram: https://t.me/missuo
#
# Copyright © 2022 by Vincent, All Rights Reserved.
###
set -e
DIST_PREFIX="deeplx"
DIST_PREFIX="dlx"
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/deeplx
DOCKER_IMAGE_NAME: missuo/dlx
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/deeplx_${GOOS}_${GOARCH}"
BINARY="dist/dlx_${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: deeplx_${{ matrix.goos }}_${{ matrix.goarch }}
name: dlx_${{ matrix.goos }}_${{ matrix.goarch }}
path: dist/*
if-no-files-found: error

3
.gitignore vendored
View File

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

View File

@ -1,13 +1,13 @@
FROM golang:1.25 AS builder
WORKDIR /go/src/github.com/OwO-Network/DeepLX
WORKDIR /go/src/github.com/OwO-Network/DLX
COPY . .
RUN go get -d -v ./
RUN CGO_ENABLED=0 go build -a -installsuffix cgo -o deeplx .
RUN CGO_ENABLED=0 go build -a -installsuffix cgo -o dlx .
FROM alpine:latest
WORKDIR /app
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
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
EXPOSE 1188
ENTRYPOINT ["/app/deeplx"]
ENTRYPOINT ["/app/dlx"]

View File

@ -2,32 +2,63 @@
* @Author: Vincent Young
* @Date: 2022-10-18 07:32:29
* @LastEditors: Vincent Yang
* @LastEditTime: 2024-11-30 19:48:00
* @FilePath: /DeepLX/README.md
* @LastEditTime: 2026-07-08 00:00:00
* @FilePath: /DLX/README.md
* @Telegram: https://t.me/missuo
*
* Copyright © 2022 by Vincent, All Rights Reserved.
-->
[![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)
# DLX
[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
[![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)
## How to use
[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
> \[!TIP]
>
> Learn more about [📘 Using DeepLX](https://deeplx.owo.network) by checking it out.
> [!IMPORTANT]
> **Disclaimer:** DLX is an independent, open-source project. 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.
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"}'
```
## Discussion Group
[Telegram Group](https://t.me/+8KDGHKJCxEVkNzll)
@ -36,12 +67,12 @@
### Contributors
<a href="https://github.com/OwO-Network/DeepLX/graphs/contributors">
<img src="https://contrib.rocks/image?repo=OwO-Network/DeepLX&anon=0" />
<a href="https://github.com/OwO-Network/DLX/graphs/contributors">
<img src="https://contrib.rocks/image?repo=OwO-Network/DLX&anon=0" />
</a>
## Activity
![Alt](https://repobeats.axiom.co/api/embed/5f473f85db27cb30028a2f3db7a560f3577a4860.svg "Repobeats analytics image")
## 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)
[MIT](LICENSE)

View File

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

View File

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

2
go.mod
View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 287 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 592 KiB

View File

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

View File

@ -3,7 +3,7 @@
* @Date: 2023-07-01 21:45:34
* @LastEditors: Jason Lyu
* @LastEditTime: 2025-04-08 13:45:00
* @FilePath: /DeepLX/main.go
* @FilePath: /DLX/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/DeepLX/service"
"github.com/OwO-Network/DLX/service"
)
func main() {
cfg := service.InitConfig()
fmt.Printf("DeepL X has been successfully launched! Listening on %v:%v\n", cfg.IP, cfg.Port)
fmt.Printf("DLX 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.deeplx</string>
<string>me.missuo.dlx</string>
<key>KeepAlive</key>
<true/>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/deeplx</string>
<string>/usr/local/bin/dlx</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: /DeepLX/config.go
* @FilePath: /DLX/service/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: /DeepLX/main.go
* @FilePath: /DLX/service/service.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/DeepLX/translate"
"github.com/OwO-Network/DLX/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": "DeepL Free API, Developed by sjlleo and missuo. Go to /translate with POST. http://github.com/OwO-Network/DeepLX",
"message": "DLX Translation API, Developed by sjlleo and missuo. Go to /translate with POST. https://github.com/OwO-Network/DLX",
})
})
@ -131,7 +131,7 @@ func Router(cfg *Config) *gin.Engine {
return
}
result, err := translate.TranslateByDeepLX(sourceLang, targetLang, translateText, tagHandling, proxyURL, "")
result, err := translate.TranslateByDLX(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.TranslateByDeepLX(sourceLang, targetLang, translateText, tagHandling, proxyURL, dlSession)
result, err := translate.TranslateByDLX(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.TranslateByDeepLX("", targetLang, translateText, "", proxyURL, "")
result, err := translate.TranslateByDLX("", 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: /DeepLX/translate/translate.go
* @FilePath: /DLX/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
}
// TranslateByDeepLX performs translation via the DeepL oneshot endpoint.
// TranslateByDLX 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 TranslateByDeepLX(sourceLang, targetLang, text string, tagHandling string, proxyURL string, dlSession string) (DeepLXTranslationResult, error) {
func TranslateByDLX(sourceLang, targetLang, text string, tagHandling string, proxyURL string, dlSession string) (DLXTranslationResult, error) {
if text == "" {
return DeepLXTranslationResult{
return DLXTranslationResult{
Code: http.StatusNotFound,
Message: "No text to translate",
}, nil
@ -396,21 +396,21 @@ func TranslateByDeepLX(sourceLang, targetLang, text string, tagHandling string,
resolvedTarget, err := resolveTargetLang(targetLang)
if err != nil {
return DeepLXTranslationResult{
return DLXTranslationResult{
Code: http.StatusBadRequest,
Message: err.Error(),
}, nil
}
resolvedSource, err := resolveSourceLang(sourceLang)
if err != nil {
return DeepLXTranslationResult{
return DLXTranslationResult{
Code: http.StatusBadRequest,
Message: err.Error(),
}, nil
}
if n := utf8.RuneCountInString(text); n > maxFreeTextLength {
return DeepLXTranslationResult{
return DLXTranslationResult{
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 TranslateByDeepLX(sourceLang, targetLang, text string, tagHandling string,
// 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 DeepLXTranslationResult{
return DLXTranslationResult{
ID: id,
Code: http.StatusGatewayTimeout,
Message: fmt.Sprintf("upstream DeepL request timed out after %s", oneshotTimeout),
}, nil
}
return DeepLXTranslationResult{
return DLXTranslationResult{
ID: id,
Code: http.StatusServiceUnavailable,
Message: err.Error(),
@ -460,13 +460,13 @@ func TranslateByDeepLX(sourceLang, targetLang, text string, tagHandling string,
case http.StatusOK:
// fall through to body parsing
case http.StatusTooManyRequests:
return DeepLXTranslationResult{
return DLXTranslationResult{
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 DeepLXTranslationResult{
return DLXTranslationResult{
ID: id,
Code: http.StatusServiceUnavailable,
Message: fmt.Sprintf("request failed with status code: %d", status),
@ -475,7 +475,7 @@ func TranslateByDeepLX(sourceLang, targetLang, text string, tagHandling string,
translations := result.Get("translations").Array()
if len(translations) == 0 {
return DeepLXTranslationResult{
return DLXTranslationResult{
ID: id,
Code: http.StatusServiceUnavailable,
Message: "Translation failed",
@ -484,7 +484,7 @@ func TranslateByDeepLX(sourceLang, targetLang, text string, tagHandling string,
mainText := translations[0].Get("text").String()
if mainText == "" {
return DeepLXTranslationResult{
return DLXTranslationResult{
ID: id,
Code: http.StatusServiceUnavailable,
Message: "Translation failed",
@ -495,7 +495,7 @@ func TranslateByDeepLX(sourceLang, targetLang, text string, tagHandling string,
sourceLang = strings.ToUpper(detected)
}
return DeepLXTranslationResult{
return DLXTranslationResult{
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: /DeepLX/translate/types.go
* @FilePath: /DLX/translate/types.go
* @Telegram: https://t.me/missuo
* @GitHub: https://github.com/missuo
*
@ -12,11 +12,11 @@
package translate
// DeepLXTranslationResult is the public response shape consumed by the HTTP
// DLXTranslationResult 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 DeepLXTranslationResult struct {
type DLXTranslationResult 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_deeplx() {
echo -e "${green}Starting DeepLX uninstallation...${plain}"
uninstall_dlx() {
echo -e "${green}Starting DLX uninstallation...${plain}"
# 1. Stop and disable the DeepLX service
if systemctl is-active --quiet deeplx; then
echo -e "${yellow}Stopping DeepLX service...${plain}"
systemctl stop deeplx
# 1. Stop and disable the DLX service
if systemctl is-active --quiet dlx; then
echo -e "${yellow}Stopping DLX service...${plain}"
systemctl stop dlx
else
echo -e "${yellow}DeepLX service is not running or not found.${plain}"
echo -e "${yellow}DLX service is not running or not found.${plain}"
fi
if systemctl is-enabled --quiet deeplx; then
echo -e "${yellow}Disabling DeepLX service from starting on boot...${plain}"
systemctl disable deeplx
if systemctl is-enabled --quiet dlx; then
echo -e "${yellow}Disabling DLX service from starting on boot...${plain}"
systemctl disable dlx
else
echo -e "${yellow}DeepLX service is not enabled.${plain}"
echo -e "${yellow}DLX service is not enabled.${plain}"
fi
# 2. Remove the systemd service file
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
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
systemctl daemon-reload
echo -e "${green}Systemd daemon reloaded.${plain}"
else
echo -e "${yellow}DeepLX systemd service file not found, skipping removal.${plain}"
echo -e "${yellow}DLX systemd service file not found, skipping removal.${plain}"
fi
# 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
# 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
else
echo -e "${yellow}DeepLX executable not found, skipping removal.${plain}"
echo -e "${yellow}DLX executable not found, skipping removal.${plain}"
fi
echo -e "${green}DeepLX uninstallation complete.${plain}"
echo -e "${green}DLX uninstallation complete.${plain}"
echo -e "${green}If you wish to reinstall, please run the install script again.${plain}"
}
uninstall_deeplx
uninstall_dlx