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 ================================================ [![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 ## 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 and missuo .") // 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 ================================================ Label me.missuo.deeplx KeepAlive ProgramArguments /usr/local/bin/deeplx RunAtLoad OnDemand LaunchOnlyOnce ================================================ 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