Full Code of OwO-Network/DeepLX for AI

main 8d145722eba5 cached
22 files
43.5 KB
16.0k tokens
27 symbols
1 requests
Download .txt
Repository: OwO-Network/DeepLX
Branch: main
Commit: 8d145722eba5
Files: 22
Total size: 43.5 KB

Directory structure:
gitextract_wsz2ewjq/

├── .cross_compile.sh
├── .github/
│   ├── FUNDING.yaml
│   └── workflows/
│       ├── ci.yaml
│       ├── docker.yaml
│       └── release.yaml
├── .gitignore
├── Dockerfile
├── LICENSE
├── README.md
├── compose.yaml
├── deeplx.service
├── go.mod
├── go.sum
├── install.sh
├── main.go
├── me.missuo.deeplx.plist
├── service/
│   ├── config.go
│   └── service.go
├── translate/
│   ├── translate.go
│   ├── types.go
│   └── utils.go
└── uninstall.sh

================================================
FILE CONTENTS
================================================

================================================
FILE: .cross_compile.sh
================================================

###
 # @Author: Vincent Young
 # @Date: 2022-10-20 02:19:06
 # @LastEditors: Vincent Yang
 # @LastEditTime: 2024-03-20 16:52:40
 # @FilePath: /DeepLX/.cross_compile.sh
 # @Telegram: https://t.me/missuo
 # 
 # Copyright © 2022 by Vincent, All Rights Reserved. 
### 
set -e

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"

rm -rf ${TARGET_DIR}
mkdir ${TARGET_DIR}

for pl in ${PLATFORMS}; do
    export GOOS=$(echo ${pl} | cut -d'/' -f1)
    export GOARCH=$(echo ${pl} | cut -d'/' -f2)
    export TARGET=${TARGET_DIR}/${DIST_PREFIX}_${GOOS}_${GOARCH}
    if [ "${GOOS}" == "windows" ]; then
        export TARGET=${TARGET_DIR}/${DIST_PREFIX}_${GOOS}_${GOARCH}.exe
    fi

    echo "build => ${TARGET}"
    if [ "${DEBUG_MODE}" == "debug" ]; then
        CGO_ENABLED=0 go build -trimpath -gcflags "all=-N -l" -o ${TARGET} \
            -ldflags "-w -s" .
    else
        CGO_ENABLED=0 go build -trimpath -o ${TARGET} \
            -ldflags "-w -s" .
    fi
done


================================================
FILE: .github/FUNDING.yaml
================================================
github: [missuo]


================================================
FILE: .github/workflows/ci.yaml
================================================
on:
  push:
  pull_request:

name: CI

jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Code
        uses: actions/checkout@v3

      - name: Set up Go
        uses: actions/setup-go@v4
        with:
          go-version: '1.24.2'

      - name: Install golint
        run: go install golang.org/x/lint/golint@latest

      - name: Build
        run: go build ./...

      - name: Test
        run: go test ./...


================================================
FILE: .github/workflows/docker.yaml
================================================
name: Docker Image CI

on:
  push:
    branches:
      - dev
    tags:
      - 'v*'

env:
  DOCKER_IMAGE_NAME: missuo/deeplx
  GHCR_IMAGE_NAME: ${{ github.repository }}
  DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
  DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
  GHCR_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  GHCR_USERNAME: ${{ github.repository_owner }}

jobs:
  docker_build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v2
        with:
          platforms: all

      - name: Set up docker buildx
        id: buildx
        uses: docker/setup-buildx-action@v2
        with:
          version: latest

      - name: Login to DockerHub
        uses: docker/login-action@v2
        with:
          registry: docker.io
          username: ${{ env.DOCKER_USERNAME }}
          password: ${{ env.DOCKER_PASSWORD }}

      - name: Login to GHCR
        uses: docker/login-action@v2
        with:
          registry: ghcr.io
          username: ${{ env.GHCR_USERNAME }}
          password: ${{ env.GHCR_TOKEN }}

      - name: Docker meta
        id: meta
        uses: docker/metadata-action@v4
        with:
          # list of Docker images to use as base name for tags
          images: |
            docker.io/${{ env.DOCKER_IMAGE_NAME }}
            ghcr.io/${{ env.GHCR_IMAGE_NAME }}
          # generate Docker tags based on the following events/attributes
          tags: |
            type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/') }}
            type=pep440,pattern={{raw}},enable=${{ startsWith(github.ref, 'refs/tags/') }}
            type=raw,value=dev,enable=${{ github.ref == 'refs/heads/dev' }}

      - name: Build and push
        uses: docker/build-push-action@v3
        with:
          context: .
          platforms: linux/amd64,linux/arm64
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max


================================================
FILE: .github/workflows/release.yaml
================================================
on:
  push:
    tags:
      - 'v*'
  pull_request:

name: Release
jobs:
        
  Build:
    if: startsWith(github.ref, 'refs/tags/v')
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-go@v4
        with:
          go-version: "1.24.2"

      - run: bash .cross_compile.sh

      - name: Release
        uses: softprops/action-gh-release@v1
        with:
          draft: false
          generate_release_notes: true
          files: |
            dist/*


================================================
FILE: .gitignore
================================================
DeepLX

================================================
FILE: Dockerfile
================================================
FROM golang:1.25 AS builder
WORKDIR /go/src/github.com/OwO-Network/DeepLX
COPY . .
RUN go get -d -v ./
RUN CGO_ENABLED=0 go build -a -installsuffix cgo -o deeplx .

FROM alpine:latest
WORKDIR /app
COPY --from=builder /go/src/github.com/OwO-Network/DeepLX/deeplx /app/deeplx
CMD ["/app/deeplx"]


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2022 OwO Network Limited

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
<!--
 * @Author: Vincent Young
 * @Date: 2022-10-18 07:32:29
 * @LastEditors: Vincent Yang
 * @LastEditTime: 2024-11-30 19:48:00
 * @FilePath: /DeepLX/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)

[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

## How to use

> \[!TIP]
>
> Learn more about [📘 Using DeepLX](https://deeplx.owo.network) by checking it out.

## Discussion Group
[Telegram Group](https://t.me/+8KDGHKJCxEVkNzll)

## Acknowledgements

### Contributors

<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
[![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)


================================================
FILE: compose.yaml
================================================
services:
  deeplx:
    image: ghcr.io/owo-network/deeplx:latest
    restart: always
    ports:
      - "1188:1188"
    # environment:
      # - TOKEN=helloworld
      # - DL_SESSION=xxxxxx


================================================
FILE: deeplx.service
================================================
[Unit]
Description=DeepLX Service
After=network.target

[Service]
Type=simple
Restart=always
WorkingDirectory=/usr/bin/
ExecStart=/usr/bin/deeplx

[Install]
WantedBy=multi-user.target


================================================
FILE: go.mod
================================================
module github.com/OwO-Network/DeepLX

go 1.25.0

require (
	github.com/abadojack/whatlanggo v1.0.1
	github.com/andybalholm/brotli v1.2.0
	github.com/gin-contrib/cors v1.7.6
	github.com/gin-gonic/gin v1.11.0
	github.com/imroc/req/v3 v3.57.0
	github.com/tidwall/gjson v1.18.0
)

require (
	github.com/bytedance/gopkg v0.1.3 // indirect
	github.com/bytedance/sonic v1.15.0 // indirect
	github.com/bytedance/sonic/loader v0.5.0 // indirect
	github.com/cloudwego/base64x v0.1.6 // indirect
	github.com/gabriel-vasile/mimetype v1.4.13 // indirect
	github.com/gin-contrib/sse v1.1.0 // indirect
	github.com/go-playground/locales v0.14.1 // indirect
	github.com/go-playground/universal-translator v0.18.1 // indirect
	github.com/go-playground/validator/v10 v10.30.1 // indirect
	github.com/goccy/go-json v0.10.5 // indirect
	github.com/goccy/go-yaml v1.19.2 // indirect
	github.com/google/go-querystring v1.2.0 // indirect
	github.com/icholy/digest v1.1.0 // indirect
	github.com/json-iterator/go v1.1.12 // indirect
	github.com/klauspost/compress v1.18.4 // indirect
	github.com/klauspost/cpuid/v2 v2.3.0 // indirect
	github.com/leodido/go-urn v1.4.0 // indirect
	github.com/mattn/go-isatty v0.0.20 // indirect
	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
	github.com/modern-go/reflect2 v1.0.2 // indirect
	github.com/pelletier/go-toml/v2 v2.2.4 // indirect
	github.com/quic-go/qpack v0.6.0 // indirect
	github.com/quic-go/quic-go v0.57.1 // indirect
	github.com/refraction-networking/utls v1.8.2 // indirect
	github.com/tidwall/match v1.2.0 // indirect
	github.com/tidwall/pretty v1.2.1 // indirect
	github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
	github.com/ugorji/go/codec v1.3.1 // indirect
	golang.org/x/arch v0.24.0 // indirect
	golang.org/x/crypto v0.48.0 // indirect
	golang.org/x/net v0.51.0 // indirect
	golang.org/x/sys v0.41.0 // indirect
	golang.org/x/text v0.34.0 // indirect
	google.golang.org/protobuf v1.36.11 // indirect
)


================================================
FILE: go.sum
================================================
github.com/abadojack/whatlanggo v1.0.1 h1:19N6YogDnf71CTHm3Mp2qhYfkRdyvbgwWdd2EPxJRG4=
github.com/abadojack/whatlanggo v1.0.1/go.mod h1:66WiQbSbJBIlOZMsvbKe5m6pzQovxCH9B/K8tQB2uoc=
github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ=
github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=
github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M=
github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM=
github.com/bytedance/sonic v1.15.0 h1:/PXeWFaR5ElNcVE84U0dOHjiMHQOwNIx3K4ymzh/uSE=
github.com/bytedance/sonic v1.15.0/go.mod h1:tFkWrPz0/CUCLEF4ri4UkHekCIcdnkqXw9VduqpJh0k=
github.com/bytedance/sonic/loader v0.5.0 h1:gXH3KVnatgY7loH5/TkeVyXPfESoqSBSBEiDd5VjlgE=
github.com/bytedance/sonic/loader v0.5.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo=
github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M=
github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gabriel-vasile/mimetype v1.4.13 h1:46nXokslUBsAJE/wMsp5gtO500a4F3Nkz9Ufpk2AcUM=
github.com/gabriel-vasile/mimetype v1.4.13/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
github.com/gin-contrib/cors v1.7.6 h1:3gQ8GMzs1Ylpf70y8bMw4fVpycXIeX1ZemuSQIsnQQY=
github.com/gin-contrib/cors v1.7.6/go.mod h1:Ulcl+xN4jel9t1Ry8vqph23a60FwH9xVLd+3ykmTjOk=
github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=
github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk=
github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.30.1 h1:f3zDSN/zOma+w6+1Wswgd9fLkdwy06ntQJp0BBvFG0w=
github.com/go-playground/validator/v10 v10.30.1/go.mod h1:oSuBIQzuJxL//3MelwSLD5hc2Tu889bF0Idm9Dg26cM=
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM=
github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/go-querystring v1.2.0 h1:yhqkPbu2/OH+V9BfpCVPZkNmUXhb2gBxJArfhIxNtP0=
github.com/google/go-querystring v1.2.0/go.mod h1:8IFJqpSRITyJ8QhQ13bmbeMBDfmeEJZD5A0egEOmkqU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/icholy/digest v1.1.0 h1:HfGg9Irj7i+IX1o1QAmPfIBNu/Q5A5Tu3n/MED9k9H4=
github.com/icholy/digest v1.1.0/go.mod h1:QNrsSGQ5v7v9cReDI0+eyjsXGUoRSUZQHeQ5C4XLa0Y=
github.com/imroc/req/v3 v3.57.0 h1:LMTUjNRUybUkTPn8oJDq8Kg3JRBOBTcnDhKu7mzupKI=
github.com/imroc/req/v3 v3.57.0/go.mod h1:JL62ey1nvSLq81HORNcosvlf7SxZStONNqOprg0Pz00=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c=
github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=
github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII=
github.com/quic-go/quic-go v0.57.1 h1:25KAAR9QR8KZrCZRThWMKVAwGoiHIrNbT72ULHTuI10=
github.com/quic-go/quic-go v0.57.1/go.mod h1:ly4QBAjHA2VhdnxhojRsCUOeJwKYg+taDlos92xb1+s=
github.com/refraction-networking/utls v1.8.2 h1:j4Q1gJj0xngdeH+Ox/qND11aEfhpgoEvV+S9iJ2IdQo=
github.com/refraction-networking/utls v1.8.2/go.mod h1:jkSOEkLqn+S/jtpEHPOsVv/4V4EVnelwbMQl4vCWXAM=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/match v1.2.0 h1:0pt8FlkOwjN2fPt4bIl4BoNxb98gGHN2ObFEDkrfZnM=
github.com/tidwall/match v1.2.0/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.3.1 h1:waO7eEiFDwidsBN6agj1vJQ4AG7lh2yqXyOXqhgQuyY=
github.com/ugorji/go/codec v1.3.1/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
golang.org/x/arch v0.24.0 h1:qlJ3M9upxvFfwRM51tTg3Yl+8CP9vCC1E7vlFpgv99Y=
golang.org/x/arch v0.24.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A=
golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=
golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo=
golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=


================================================
FILE: install.sh
================================================
###
 # @Author: Vincent Young
 # @Date: 2023-02-12 09:53:21
 # @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. 
### 

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 DeepLX version, probably due to exceeding Github API limitations.${plain}"
        exit 1
    fi
    echo -e "DeepLX latest version: ${last_version}, Start install..."
    wget -q -N --no-check-certificate -O /usr/bin/deeplx https://github.com/OwO-Network/DeepLX/releases/download/${last_version}/deeplx_linux_amd64

    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 deeplx
    systemctl start deeplx
    echo -e "Installed successfully, listening at 0.0.0.0:1188"
}
install_deeplx


================================================
FILE: main.go
================================================
/*
 * @Author: Vincent Yang
 * @Date: 2023-07-01 21:45:34
 * @LastEditors: Jason Lyu
 * @LastEditTime: 2025-04-08 13:45:00
 * @FilePath: /DeepLX/main.go
 * @Telegram: https://t.me/missuo
 * @GitHub: https://github.com/missuo
 *
 * Copyright © 2024 by Vincent, All Rights Reserved.
 */

package main

import (
	"fmt"

	"github.com/gin-gonic/gin"

	"github.com/OwO-Network/DeepLX/service"
)

func main() {
	cfg := service.InitConfig()

	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
	gin.SetMode(gin.ReleaseMode)

	app := service.Router(cfg)
	app.Run(fmt.Sprintf("%v:%v", cfg.IP, cfg.Port))
}


================================================
FILE: me.missuo.deeplx.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Label</key>
	<string>me.missuo.deeplx</string>
	<key>KeepAlive</key>
	<true/>
	<key>ProgramArguments</key>
	<array>
		<string>/usr/local/bin/deeplx</string>
	</array>
	<key>RunAtLoad</key>
	<true/>
	<key>OnDemand</key>
	<false/>
	<key>LaunchOnlyOnce</key>
	<true/>
</dict>
</plist>


================================================
FILE: service/config.go
================================================
/*
 * @Author: Vincent Yang
 * @Date: 2024-04-23 00:39:03
 * @LastEditors: Jason Lyu
 * @LastEditTime: 2025-04-08 13:45:00
 * @FilePath: /DeepLX/config.go
 * @Telegram: https://t.me/missuo
 * @GitHub: https://github.com/missuo
 *
 * Copyright © 2024 by Vincent, All Rights Reserved.
 */

package service

import (
	"flag"
	"fmt"
	"os"
)

type Config struct {
	IP        string
	Port      int
	Token     string
	DlSession string
	Proxy     string
}

func InitConfig() *Config {
	cfg := &Config{
		IP:   "0.0.0.0",
		Port: 1188,
	}

	// IP flag
	if ip, ok := os.LookupEnv("IP"); ok && ip != "" {
		cfg.IP = ip
	}
	flag.StringVar(&cfg.IP, "ip", cfg.IP, "set up the IP address to bind to")
	flag.StringVar(&cfg.IP, "i", cfg.IP, "set up the IP address to bind to")

	// Port flag
	if port, ok := os.LookupEnv("PORT"); ok && port != "" {
		fmt.Sscanf(port, "%d", &cfg.Port)
	}
	flag.IntVar(&cfg.Port, "port", cfg.Port, "set up the port to listen on")
	flag.IntVar(&cfg.Port, "p", cfg.Port, "set up the port to listen on")

	// DL Session flag
	flag.StringVar(&cfg.DlSession, "s", "", "set the dl-session for /v1/translate endpoint")
	if cfg.DlSession == "" {
		if dlSession, ok := os.LookupEnv("DL_SESSION"); ok {
			cfg.DlSession = dlSession
		}
	}

	// Access token flag
	flag.StringVar(&cfg.Token, "token", "", "set the access token for /translate endpoint")
	if cfg.Token == "" {
		if token, ok := os.LookupEnv("TOKEN"); ok {
			cfg.Token = token
		}
	}

	// HTTP Proxy flag
	flag.StringVar(&cfg.Proxy, "proxy", "", "set the proxy URL for HTTP requests")
	if cfg.Proxy == "" {
		if proxy, ok := os.LookupEnv("PROXY"); ok {
			cfg.Proxy = proxy
		}
	}

	flag.Parse()
	return cfg
}


================================================
FILE: service/service.go
================================================
/*
 * @Author: Vincent Yang
 * @Date: 2023-07-01 21:45:34
 * @LastEditors: Jason Lyu
 * @LastEditTime: 2025-04-08 13:45:00
 * @FilePath: /DeepLX/main.go
 * @Telegram: https://t.me/missuo
 * @GitHub: https://github.com/missuo
 *
 * Copyright © 2024 by Vincent, All Rights Reserved.
 */

package service

import (
	"fmt"
	"log"
	"net/http"
	"net/url"
	"os"
	"strings"

	"github.com/gin-contrib/cors"
	"github.com/gin-gonic/gin"

	"github.com/OwO-Network/DeepLX/translate"
)

func authMiddleware(cfg *Config) gin.HandlerFunc {
	return func(c *gin.Context) {
		if cfg.Token != "" {
			providedTokenInQuery := c.Query("token")
			providedTokenInHeader := c.GetHeader("Authorization")

			// Compatability with the Bearer token format
			if providedTokenInHeader != "" {
				parts := strings.Split(providedTokenInHeader, " ")
				if len(parts) == 2 {
					if parts[0] == "Bearer" || parts[0] == "DeepL-Auth-Key" {
						providedTokenInHeader = parts[1]
					} else {
						providedTokenInHeader = ""
					}
				} else {
					providedTokenInHeader = ""
				}
			}

			if providedTokenInHeader != cfg.Token && providedTokenInQuery != cfg.Token {
				c.JSON(http.StatusUnauthorized, gin.H{
					"code":    http.StatusUnauthorized,
					"message": "Invalid access token",
				})
				c.Abort()
				return
			}
		}

		c.Next()
	}
}

type PayloadFree struct {
	TransText   string `json:"text"`
	SourceLang  string `json:"source_lang"`
	TargetLang  string `json:"target_lang"`
	TagHandling string `json:"tag_handling"`
}

type PayloadAPI struct {
	Text        []string `json:"text"`
	TargetLang  string   `json:"target_lang"`
	SourceLang  string   `json:"source_lang"`
	TagHandling string   `json:"tag_handling"`
}

func Router(cfg *Config) *gin.Engine {
	// Set Proxy
	proxyURL := os.Getenv("PROXY")
	if proxyURL == "" {
		proxyURL = cfg.Proxy
	}
	if proxyURL != "" {
		proxy, err := url.Parse(proxyURL)
		if err != nil {
			log.Fatalf("Failed to parse proxy URL: %v", err)
		}
		http.DefaultTransport = &http.Transport{
			Proxy: http.ProxyURL(proxy),
		}
	}

	if cfg.Token != "" {
		fmt.Println("Access token is set.")
	}

	r := gin.Default()
	r.Use(cors.Default())

	// Defining the root endpoint which returns the project details
	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",
		})
	})

	// Free API endpoint, No Pro Account required
	r.POST("/translate", authMiddleware(cfg), func(c *gin.Context) {
		req := PayloadFree{}
		c.BindJSON(&req)

		sourceLang := req.SourceLang
		targetLang := req.TargetLang
		translateText := req.TransText
		tagHandling := req.TagHandling

		proxyURL := cfg.Proxy

		if tagHandling != "" && tagHandling != "html" && tagHandling != "xml" {
			c.JSON(http.StatusBadRequest, gin.H{
				"code":    http.StatusBadRequest,
				"message": "Invalid tag_handling value. Allowed values are 'html' and 'xml'.",
			})
			return
		}

		result, err := translate.TranslateByDeepLX(sourceLang, targetLang, translateText, tagHandling, proxyURL, "")
		if err != nil {
			log.Fatalf("Translation failed: %s", err)
		}

		if result.Code == http.StatusOK {
			c.JSON(http.StatusOK, gin.H{
				"code":         http.StatusOK,
				"id":           result.ID,
				"data":         result.Data,
				"alternatives": result.Alternatives,
				"source_lang":  result.SourceLang,
				"target_lang":  result.TargetLang,
				"method":       result.Method,
			})
		} else {
			c.JSON(result.Code, gin.H{
				"code":    result.Code,
				"message": result.Message,
			})

		}
	})

	// Pro API endpoint, Pro Account required
	r.POST("/v1/translate", authMiddleware(cfg), func(c *gin.Context) {
		req := PayloadFree{}
		c.BindJSON(&req)

		sourceLang := req.SourceLang
		targetLang := req.TargetLang
		translateText := req.TransText
		tagHandling := req.TagHandling
		proxyURL := cfg.Proxy

		dlSession := cfg.DlSession

		if tagHandling != "" && tagHandling != "html" && tagHandling != "xml" {
			c.JSON(http.StatusBadRequest, gin.H{
				"code":    http.StatusBadRequest,
				"message": "Invalid tag_handling value. Allowed values are 'html' and 'xml'.",
			})
			return
		}

		cookie := c.GetHeader("Cookie")
		if cookie != "" {
			dlSession = strings.Replace(cookie, "dl_session=", "", -1)
		}

		if dlSession == "" {
			c.JSON(http.StatusUnauthorized, gin.H{
				"code":    http.StatusUnauthorized,
				"message": "No dl_session Found",
			})
			return
		} else if strings.Contains(dlSession, ".") {
			c.JSON(http.StatusUnauthorized, gin.H{
				"code":    http.StatusUnauthorized,
				"message": "Your account is not a Pro account. Please upgrade your account or switch to a different account.",
			})
			return
		}

		result, err := translate.TranslateByDeepLX(sourceLang, targetLang, translateText, tagHandling, proxyURL, dlSession)
		if err != nil {
			log.Fatalf("Translation failed: %s", err)
		}

		if result.Code == http.StatusOK {
			c.JSON(http.StatusOK, gin.H{
				"code":         http.StatusOK,
				"id":           result.ID,
				"data":         result.Data,
				"alternatives": result.Alternatives,
				"source_lang":  result.SourceLang,
				"target_lang":  result.TargetLang,
				"method":       result.Method,
			})
		} else {
			c.JSON(result.Code, gin.H{
				"code":    result.Code,
				"message": result.Message,
			})

		}
	})

	// Free API endpoint, Consistent with the official API format
	r.POST("/v2/translate", authMiddleware(cfg), func(c *gin.Context) {
		proxyURL := cfg.Proxy

		var translateText string
		var targetLang string

		translateText = c.PostForm("text")
		targetLang = c.PostForm("target_lang")

		if translateText == "" || targetLang == "" {
			var jsonData struct {
				Text       []string `json:"text"`
				TargetLang string   `json:"target_lang"`
			}

			if err := c.BindJSON(&jsonData); err != nil {
				c.JSON(http.StatusBadRequest, gin.H{
					"code":    http.StatusBadRequest,
					"message": "Invalid request payload",
				})
				return
			}

			translateText = strings.Join(jsonData.Text, "\n")
			targetLang = jsonData.TargetLang
		}

		result, err := translate.TranslateByDeepLX("", targetLang, translateText, "", proxyURL, "")
		if err != nil {
			log.Fatalf("Translation failed: %s", err)
		}

		if result.Code == http.StatusOK {
			c.JSON(http.StatusOK, gin.H{
				"translations": []map[string]interface{}{
					{
						"detected_source_language": result.SourceLang,
						"text":                     result.Data,
					},
				},
			})
		} else {
			c.JSON(result.Code, gin.H{
				"code":    result.Code,
				"message": result.Message,
			})
		}
	})

	// Catch-all route to handle undefined paths
	r.NoRoute(func(c *gin.Context) {
		c.JSON(http.StatusNotFound, gin.H{
			"code":    http.StatusNotFound,
			"message": "Path not found",
		})
	})

	return r
}


================================================
FILE: translate/translate.go
================================================
/*
 * @Author: Vincent Young
 * @Date: 2024-09-16 11:59:24
 * @LastEditors: Vincent Yang
 * @LastEditTime: 2025-07-13 23:09:49
 * @FilePath: /DeepLX/translate/translate.go
 * @Telegram: https://t.me/missuo
 * @GitHub: https://github.com/missuo
 *
 * Copyright © 2024 by Vincent, All Rights Reserved.
 */

package translate

import (
	"bytes"
	"compress/flate"
	"compress/gzip"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strings"

	"github.com/abadojack/whatlanggo"
	"github.com/imroc/req/v3"

	"github.com/andybalholm/brotli"
	"github.com/tidwall/gjson"
)

// makeRequestWithBody makes an HTTP request with pre-formatted body using minimal headers
func makeRequestWithBody(postStr string, proxyURL string, dlSession string) (gjson.Result, error) {
	urlFull := "https://www2.deepl.com/jsonrpc"

	// Create a new req client
	client := req.C().SetTLSFingerprintRandomized()

	// Set headers to simulate browser request
	headers := http.Header{
		"Content-Type":    []string{"application/json"},
		"Accept":          []string{"*/*"},
		"Accept-Language": []string{"en-US,en;q=0.9"},
		"Accept-Encoding": []string{"gzip, deflate, br, zstd"},
		"Origin":          []string{"https://www.deepl.com"},
		"Referer":         []string{"https://www.deepl.com/"},
		"Sec-Fetch-Dest":  []string{"empty"},
		"Sec-Fetch-Mode":  []string{"cors"},
		"Sec-Fetch-Site":  []string{"same-site"},
		"User-Agent":      []string{"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36 Edg/141.0.0.0"},
	}

	if dlSession != "" {
		headers.Set("Cookie", "dl_session="+dlSession)
	}

	// Set proxy if provided
	if proxyURL != "" {
		proxy, err := url.Parse(proxyURL)
		if err != nil {
			return gjson.Result{}, err
		}
		client.SetProxyURL(proxy.String())
	}

	// Make the request
	r := client.R()
	r.Headers = headers
	resp, err := r.
		SetBody(bytes.NewReader([]byte(postStr))).
		Post(urlFull)

	if err != nil {
		return gjson.Result{}, err
	}

	// Check for blocked status like TypeScript version
	if resp.StatusCode == 429 {
		return gjson.Result{}, fmt.Errorf("too many requests, your IP has been blocked by DeepL temporarily, please don't request it frequently in a short time")
	}

	// Check for other error status codes
	if resp.StatusCode != 200 {
		return gjson.Result{}, fmt.Errorf("request failed with status code: %d", resp.StatusCode)
	}

	var bodyReader io.Reader
	contentEncoding := resp.Header.Get("Content-Encoding")
	switch contentEncoding {
	case "br":
		bodyReader = brotli.NewReader(resp.Body)
	case "gzip":
		bodyReader, err = gzip.NewReader(resp.Body)
		if err != nil {
			return gjson.Result{}, fmt.Errorf("failed to create gzip reader: %w", err)
		}
	case "deflate":
		bodyReader = flate.NewReader(resp.Body)
	default:
		bodyReader = resp.Body
	}

	body, err := io.ReadAll(bodyReader)
	if err != nil {
		return gjson.Result{}, fmt.Errorf("failed to read response body: %w", err)
	}
	return gjson.ParseBytes(body), nil
}

// TranslateByDeepLX performs translation using DeepL API
func TranslateByDeepLX(sourceLang, targetLang, text string, tagHandling string, proxyURL string, dlSession string) (DeepLXTranslationResult, error) {
	if text == "" {
		return DeepLXTranslationResult{
			Code:    http.StatusNotFound,
			Message: "No text to translate",
		}, nil
	}

	// Get detected language if source language is auto
	if sourceLang == "auto" || sourceLang == "" {
		sourceLang = strings.ToUpper(whatlanggo.DetectLang(text).Iso6391())
	}

	// Prepare translation request using new LMT_handle_texts method
	id := getRandomNumber()
	iCount := getICount(text)
	timestamp := getTimeStamp(iCount)

	postData := &PostData{
		Jsonrpc: "2.0",
		Method:  "LMT_handle_texts",
		ID:      id,
		Params: Params{
			Splitting: "newlines",
			Lang: Lang{
				SourceLangUserSelected: sourceLang,
				TargetLang:             targetLang,
			},
			Texts: []TextItem{{
				Text:                text,
				RequestAlternatives: 3,
			}},
			Timestamp: timestamp,
		},
	}

	// Format and apply body manipulation method like TypeScript
	postStr := formatPostString(postData)
	postStr = handlerBodyMethod(id, postStr)

	// Make translation request
	result, err := makeRequestWithBody(postStr, proxyURL, dlSession)
	if err != nil {
		return DeepLXTranslationResult{
			Code:    http.StatusServiceUnavailable,
			Message: err.Error(),
		}, nil
	}

	// Process translation results using new format
	textsArray := result.Get("result.texts").Array()
	if len(textsArray) == 0 {
		return DeepLXTranslationResult{
			Code:    http.StatusServiceUnavailable,
			Message: "Translation failed",
		}, nil
	}

	// Get main translation
	mainText := textsArray[0].Get("text").String()
	if mainText == "" {
		return DeepLXTranslationResult{
			Code:    http.StatusServiceUnavailable,
			Message: "Translation failed",
		}, nil
	}

	// Get alternatives
	var alternatives []string
	alternativesArray := textsArray[0].Get("alternatives").Array()
	for _, alt := range alternativesArray {
		altText := alt.Get("text").String()
		if altText != "" {
			alternatives = append(alternatives, altText)
		}
	}

	// Get detected source language from response
	detectedLang := result.Get("result.lang").String()
	if detectedLang != "" {
		sourceLang = detectedLang
	}

	return DeepLXTranslationResult{
		Code:         http.StatusOK,
		ID:           id,
		Data:         mainText,
		Alternatives: alternatives,
		SourceLang:   sourceLang,
		TargetLang:   targetLang,
		Method:       map[bool]string{true: "Pro", false: "Free"}[dlSession != ""],
	}, nil
}


================================================
FILE: translate/types.go
================================================
/*
 * @Author: Vincent Young
 * @Date: 2024-09-16 11:59:24
 * @LastEditors: Vincent Yang
 * @LastEditTime: 2025-03-01 04:16:07
 * @FilePath: /DeepLX/translate/types.go
 * @Telegram: https://t.me/missuo
 * @GitHub: https://github.com/missuo
 *
 * Copyright © 2024 by Vincent, All Rights Reserved.
 */

package translate

// Lang represents the language settings for translation
type Lang struct {
	SourceLangUserSelected string `json:"source_lang_user_selected"` // Can be "auto"
	TargetLang             string `json:"target_lang"`
	SourceLangComputed     string `json:"source_lang_computed,omitempty"`
}

// CommonJobParams represents common parameters for translation jobs
type CommonJobParams struct {
	Formality       string `json:"formality"` // Can be "undefined"
	TranscribeAs    string `json:"transcribe_as"`
	Mode            string `json:"mode"`
	WasSpoken       bool   `json:"wasSpoken"`
	AdvancedMode    bool   `json:"advancedMode"`
	TextType        string `json:"textType"`
	RegionalVariant string `json:"regionalVariant,omitempty"`
}

// Sentence represents a sentence in the translation request
type Sentence struct {
	Prefix string `json:"prefix"`
	Text   string `json:"text"`
	ID     int    `json:"id"`
}

// Job represents a translation job
type Job struct {
	Kind               string     `json:"kind"`
	PreferredNumBeams  int        `json:"preferred_num_beams"`
	RawEnContextBefore []string   `json:"raw_en_context_before"`
	RawEnContextAfter  []string   `json:"raw_en_context_after"`
	Sentences          []Sentence `json:"sentences"`
}

// TextItem represents a text item for translation
type TextItem struct {
	Text                string `json:"text"`
	RequestAlternatives int    `json:"requestAlternatives"`
}

// Params represents parameters for translation requests
type Params struct {
	Splitting string     `json:"splitting"`
	Lang      Lang       `json:"lang"`
	Texts     []TextItem `json:"texts"`
	Timestamp int64      `json:"timestamp"`
}

// LegacyParams represents the old parameters structure for jobs (kept for compatibility)
type LegacyParams struct {
	CommonJobParams CommonJobParams `json:"commonJobParams"`
	Lang            Lang            `json:"lang"`
	Jobs            []Job           `json:"jobs"`
	Timestamp       int64           `json:"timestamp"`
}

// PostData represents the complete translation request
type PostData struct {
	Jsonrpc string `json:"jsonrpc"`
	Method  string `json:"method"`
	ID      int64  `json:"id"`
	Params  Params `json:"params"`
}

// TextResponse represents a single text response
type TextResponse struct {
	Text         string   `json:"text"`
	Alternatives []struct {
		Text string `json:"text"`
	} `json:"alternatives"`
}

// TranslationResponse represents the response from LMT_handle_texts
type TranslationResponse struct {
	Jsonrpc string `json:"jsonrpc"`
	ID      int64  `json:"id"`
	Result  struct {
		Lang  string          `json:"lang"`
		Texts []TextResponse  `json:"texts"`
	} `json:"result"`
}

// LegacyTranslationResponse represents the old response format (kept for compatibility)
type LegacyTranslationResponse struct {
	Jsonrpc string `json:"jsonrpc"`
	ID      int64  `json:"id"`
	Result  struct {
		Translations []struct {
			Beams []struct {
				Sentences       []SentenceResponse `json:"sentences"`
				NumSymbols      int                `json:"num_symbols"`
				RephraseVariant struct {           // Added rephrase_variant
					Name string `json:"name"`
				} `json:"rephrase_variant"`
			} `json:"beams"`
			Quality string `json:"quality"` // Added quality
		} `json:"translations"`
		TargetLang            string                 `json:"target_lang"`
		SourceLang            string                 `json:"source_lang"`
		SourceLangIsConfident bool                   `json:"source_lang_is_confident"`
		DetectedLanguages     map[string]interface{} `json:"detectedLanguages"` // Use interface{} for now
	} `json:"result"`
}

// SentenceResponse is a helper struct for the response sentences
type SentenceResponse struct {
	Text string `json:"text"`
	IDS  []int  `json:"ids"` // Added IDS
}

// DeepLXTranslationResult represents the final translation result
type DeepLXTranslationResult struct {
	Code         int      `json:"code"`
	ID           int64    `json:"id"`
	Message      string   `json:"message,omitempty"`
	Data         string   `json:"data"`         // The primary translated text
	Alternatives []string `json:"alternatives"` // Other possible translations
	SourceLang   string   `json:"source_lang"`
	TargetLang   string   `json:"target_lang"`
	Method       string   `json:"method"`
}


================================================
FILE: translate/utils.go
================================================
/*
 * @Author: Vincent Young
 * @Date: 2024-09-16 11:59:24
 * @LastEditors: Vincent Yang
 * @LastEditTime: 2025-04-08 14:27:21
 * @FilePath: /DeepLX/translate/utils.go
 * @Telegram: https://t.me/missuo
 * @GitHub: https://github.com/missuo
 *
 * Copyright © 2024 by Vincent, All Rights Reserved.
 */

package translate

import (
	"encoding/json"
	"math/rand"
	"strings"
	"time"
)

// getICount returns the number of 'i' characters in the text
func getICount(translateText string) int64 {
	return int64(strings.Count(translateText, "i"))
}

// getRandomNumber generates a random number for request ID
func getRandomNumber() int64 {
	src := rand.NewSource(time.Now().UnixNano())
	rng := rand.New(src)
	num := rng.Int63n(99999) + 100000
	return num * 1000
}

// getTimeStamp generates timestamp for request based on i count
func getTimeStamp(iCount int64) int64 {
	ts := time.Now().UnixMilli()
	if iCount != 0 {
		iCount = iCount + 1
		return ts - (ts % iCount) + iCount
	}
	return ts
}

// formatPostString formats the request JSON string with specific spacing rules
func formatPostString(postData *PostData) string {
	postBytes, _ := json.Marshal(postData)
	postStr := string(postBytes)
	return postStr
}

// handlerBodyMethod manipulates the request body based on random number calculation
func handlerBodyMethod(random int64, body string) string {
	calc := (random+5)%29 == 0 || (random+3)%13 == 0
	if calc {
		return strings.Replace(body, `"method":"`, `"method" : "`, 1)
	}
	return strings.Replace(body, `"method":"`, `"method": "`, 1)
}


================================================
FILE: uninstall.sh
================================================
#!/bin/bash

# Colors
red='\033[0;31m'
green='\033[0;32m'
yellow='\033[0;33m'
plain='\033[0m'

# Check for root privileges
if [[ $EUID -ne 0 ]]; then
    echo -e "${red}This script must be run as root.${plain}"
    exit 1
fi

uninstall_deeplx() {
    echo -e "${green}Starting DeepLX 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
    else
        echo -e "${yellow}DeepLX 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
    else
        echo -e "${yellow}DeepLX 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
        systemctl daemon-reload
        echo -e "${green}Systemd daemon reloaded.${plain}"
    else
        echo -e "${yellow}DeepLX 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
    else
        echo -e "${yellow}DeepLX executable not found, skipping removal.${plain}"
    fi

    echo -e "${green}DeepLX uninstallation complete.${plain}"
    echo -e "${green}If you wish to reinstall, please run the install script again.${plain}"
}

uninstall_deeplx
Download .txt
gitextract_wsz2ewjq/

├── .cross_compile.sh
├── .github/
│   ├── FUNDING.yaml
│   └── workflows/
│       ├── ci.yaml
│       ├── docker.yaml
│       └── release.yaml
├── .gitignore
├── Dockerfile
├── LICENSE
├── README.md
├── compose.yaml
├── deeplx.service
├── go.mod
├── go.sum
├── install.sh
├── main.go
├── me.missuo.deeplx.plist
├── service/
│   ├── config.go
│   └── service.go
├── translate/
│   ├── translate.go
│   ├── types.go
│   └── utils.go
└── uninstall.sh
Download .txt
SYMBOL INDEX (27 symbols across 6 files)

FILE: main.go
  function main (line 23) | func main() {

FILE: service/config.go
  type Config (line 21) | type Config struct
  function InitConfig (line 29) | func InitConfig() *Config {

FILE: service/service.go
  function authMiddleware (line 29) | func authMiddleware(cfg *Config) gin.HandlerFunc {
  type PayloadFree (line 63) | type PayloadFree struct
  type PayloadAPI (line 70) | type PayloadAPI struct
  function Router (line 77) | func Router(cfg *Config) *gin.Engine {

FILE: translate/translate.go
  function makeRequestWithBody (line 33) | func makeRequestWithBody(postStr string, proxyURL string, dlSession stri...
  function TranslateByDeepLX (line 111) | func TranslateByDeepLX(sourceLang, targetLang, text string, tagHandling ...

FILE: translate/types.go
  type Lang (line 16) | type Lang struct
  type CommonJobParams (line 23) | type CommonJobParams struct
  type Sentence (line 34) | type Sentence struct
  type Job (line 41) | type Job struct
  type TextItem (line 50) | type TextItem struct
  type Params (line 56) | type Params struct
  type LegacyParams (line 64) | type LegacyParams struct
  type PostData (line 72) | type PostData struct
  type TextResponse (line 80) | type TextResponse struct
  type TranslationResponse (line 88) | type TranslationResponse struct
  type LegacyTranslationResponse (line 98) | type LegacyTranslationResponse struct
  type SentenceResponse (line 120) | type SentenceResponse struct
  type DeepLXTranslationResult (line 126) | type DeepLXTranslationResult struct

FILE: translate/utils.go
  function getICount (line 23) | func getICount(translateText string) int64 {
  function getRandomNumber (line 28) | func getRandomNumber() int64 {
  function getTimeStamp (line 36) | func getTimeStamp(iCount int64) int64 {
  function formatPostString (line 46) | func formatPostString(postData *PostData) string {
  function handlerBodyMethod (line 53) | func handlerBodyMethod(random int64, body string) string {
Condensed preview — 22 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (49K chars).
[
  {
    "path": ".cross_compile.sh",
    "chars": 1134,
    "preview": "\n###\n # @Author: Vincent Young\n # @Date: 2022-10-20 02:19:06\n # @LastEditors: Vincent Yang\n # @LastEditTime: 2024-03-20 "
  },
  {
    "path": ".github/FUNDING.yaml",
    "chars": 17,
    "preview": "github: [missuo]\n"
  },
  {
    "path": ".github/workflows/ci.yaml",
    "chars": 456,
    "preview": "on:\n  push:\n  pull_request:\n\nname: CI\n\njobs:\n  build:\n    name: Build\n    runs-on: ubuntu-latest\n    steps:\n      - name"
  },
  {
    "path": ".github/workflows/docker.yaml",
    "chars": 2131,
    "preview": "name: Docker Image CI\n\non:\n  push:\n    branches:\n      - dev\n    tags:\n      - 'v*'\n\nenv:\n  DOCKER_IMAGE_NAME: missuo/de"
  },
  {
    "path": ".github/workflows/release.yaml",
    "chars": 507,
    "preview": "on:\n  push:\n    tags:\n      - 'v*'\n  pull_request:\n\nname: Release\njobs:\n        \n  Build:\n    if: startsWith(github.ref,"
  },
  {
    "path": ".gitignore",
    "chars": 6,
    "preview": "DeepLX"
  },
  {
    "path": "Dockerfile",
    "chars": 294,
    "preview": "FROM golang:1.25 AS builder\nWORKDIR /go/src/github.com/OwO-Network/DeepLX\nCOPY . .\nRUN go get -d -v ./\nRUN CGO_ENABLED=0"
  },
  {
    "path": "LICENSE",
    "chars": 1076,
    "preview": "MIT License\n\nCopyright (c) 2022 OwO Network Limited\n\nPermission is hereby granted, free of charge, to any person obtaini"
  },
  {
    "path": "README.md",
    "chars": 1861,
    "preview": "<!--\n * @Author: Vincent Young\n * @Date: 2022-10-18 07:32:29\n * @LastEditors: Vincent Yang\n * @LastEditTime: 2024-11-30 "
  },
  {
    "path": "compose.yaml",
    "chars": 190,
    "preview": "services:\n  deeplx:\n    image: ghcr.io/owo-network/deeplx:latest\n    restart: always\n    ports:\n      - \"1188:1188\"\n    "
  },
  {
    "path": "deeplx.service",
    "chars": 184,
    "preview": "[Unit]\nDescription=DeepLX Service\nAfter=network.target\n\n[Service]\nType=simple\nRestart=always\nWorkingDirectory=/usr/bin/\n"
  },
  {
    "path": "go.mod",
    "chars": 1980,
    "preview": "module github.com/OwO-Network/DeepLX\n\ngo 1.25.0\n\nrequire (\n\tgithub.com/abadojack/whatlanggo v1.0.1\n\tgithub.com/andybalho"
  },
  {
    "path": "go.sum",
    "chars": 10353,
    "preview": "github.com/abadojack/whatlanggo v1.0.1 h1:19N6YogDnf71CTHm3Mp2qhYfkRdyvbgwWdd2EPxJRG4=\ngithub.com/abadojack/whatlanggo v"
  },
  {
    "path": "install.sh",
    "chars": 1164,
    "preview": "###\n # @Author: Vincent Young\n # @Date: 2023-02-12 09:53:21\n # @LastEditors: Vincent Young\n # @LastEditTime: 2023-02-12 "
  },
  {
    "path": "main.go",
    "chars": 758,
    "preview": "/*\n * @Author: Vincent Yang\n * @Date: 2023-07-01 21:45:34\n * @LastEditors: Jason Lyu\n * @LastEditTime: 2025-04-08 13:45:"
  },
  {
    "path": "me.missuo.deeplx.plist",
    "chars": 459,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "service/config.go",
    "chars": 1678,
    "preview": "/*\n * @Author: Vincent Yang\n * @Date: 2024-04-23 00:39:03\n * @LastEditors: Jason Lyu\n * @LastEditTime: 2025-04-08 13:45:"
  },
  {
    "path": "service/service.go",
    "chars": 6876,
    "preview": "/*\n * @Author: Vincent Yang\n * @Date: 2023-07-01 21:45:34\n * @LastEditors: Jason Lyu\n * @LastEditTime: 2025-04-08 13:45:"
  },
  {
    "path": "translate/translate.go",
    "chars": 5543,
    "preview": "/*\n * @Author: Vincent Young\n * @Date: 2024-09-16 11:59:24\n * @LastEditors: Vincent Yang\n * @LastEditTime: 2025-07-13 23"
  },
  {
    "path": "translate/types.go",
    "chars": 4587,
    "preview": "/*\n * @Author: Vincent Young\n * @Date: 2024-09-16 11:59:24\n * @LastEditors: Vincent Yang\n * @LastEditTime: 2025-03-01 04"
  },
  {
    "path": "translate/utils.go",
    "chars": 1541,
    "preview": "/*\n * @Author: Vincent Young\n * @Date: 2024-09-16 11:59:24\n * @LastEditors: Vincent Yang\n * @LastEditTime: 2025-04-08 14"
  },
  {
    "path": "uninstall.sh",
    "chars": 1761,
    "preview": "#!/bin/bash\n\n# Colors\nred='\\033[0;31m'\ngreen='\\033[0;32m'\nyellow='\\033[0;33m'\nplain='\\033[0m'\n\n# Check for root privileg"
  }
]

About this extraction

This page contains the full source code of the OwO-Network/DeepLX GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 22 files (43.5 KB), approximately 16.0k tokens, and a symbol index with 27 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!