mirror of
https://github.com/OwO-Network/DeepLX.git
synced 2025-04-19 14:13:24 +00:00
Compare commits
19 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
4cee0f3031 | ||
|
cbc3c1be51 | ||
|
84792ead81 | ||
|
0a9ff6b582 | ||
|
d1dbfcc1e5 | ||
|
2400139a8d | ||
|
26a9003b13 | ||
|
85fd738f3e | ||
|
de9888ca5f | ||
|
bbfb808793 | ||
|
4a77cbf30e | ||
|
2d8b84e2c8 | ||
|
1c8beb8a87 | ||
|
f2fa90208d | ||
|
b04139e89d | ||
|
44b6c2915f | ||
|
b89751f78f | ||
|
1f62d85b60 | ||
|
547c735b1f |
2
.github/workflows/ci.yaml
vendored
2
.github/workflows/ci.yaml
vendored
@ -15,7 +15,7 @@ jobs:
|
|||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v4
|
uses: actions/setup-go@v4
|
||||||
with:
|
with:
|
||||||
go-version: '1.23.2'
|
go-version: '1.24.2'
|
||||||
|
|
||||||
- name: Install golint
|
- name: Install golint
|
||||||
run: go install golang.org/x/lint/golint@latest
|
run: go install golang.org/x/lint/golint@latest
|
||||||
|
2
.github/workflows/release.yaml
vendored
2
.github/workflows/release.yaml
vendored
@ -15,7 +15,7 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/setup-go@v4
|
- uses: actions/setup-go@v4
|
||||||
with:
|
with:
|
||||||
go-version: "1.23.2"
|
go-version: "1.24.2"
|
||||||
|
|
||||||
- run: bash .cross_compile.sh
|
- run: bash .cross_compile.sh
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
FROM golang:1.23.2 AS builder
|
FROM golang:1.24.2 AS builder
|
||||||
WORKDIR /go/src/github.com/OwO-Network/DeepLX
|
WORKDIR /go/src/github.com/OwO-Network/DeepLX
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN go get -d -v ./
|
RUN go get -d -v ./
|
||||||
|
16
README.md
16
README.md
@ -2,7 +2,7 @@
|
|||||||
* @Author: Vincent Young
|
* @Author: Vincent Young
|
||||||
* @Date: 2022-10-18 07:32:29
|
* @Date: 2022-10-18 07:32:29
|
||||||
* @LastEditors: Vincent Yang
|
* @LastEditors: Vincent Yang
|
||||||
* @LastEditTime: 2024-04-23 00:50:43
|
* @LastEditTime: 2024-11-30 19:48:00
|
||||||
* @FilePath: /DeepLX/README.md
|
* @FilePath: /DeepLX/README.md
|
||||||
* @Telegram: https://t.me/missuo
|
* @Telegram: https://t.me/missuo
|
||||||
*
|
*
|
||||||
@ -12,18 +12,16 @@
|
|||||||
[![GitHub Workflow][1]](https://github.com/OwO-Network/DeepLX/actions)
|
[![GitHub Workflow][1]](https://github.com/OwO-Network/DeepLX/actions)
|
||||||
[![Go Version][2]](https://github.com/OwO-Network/DeepLX/blob/main/go.mod)
|
[![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)
|
[![Go Report][3]](https://goreportcard.com/badge/github.com/OwO-Network/DeepLX)
|
||||||
[![Maintainability][4]](https://codeclimate.com/github/OwO-Network/DeepLX/maintainability)
|
[![GitHub License][4]](https://github.com/OwO-Network/DeepLX/blob/main/LICENSE)
|
||||||
[![GitHub License][5]](https://github.com/OwO-Network/DeepLX/blob/main/LICENSE)
|
[![Docker Pulls][5]](https://hub.docker.com/r/missuo/deeplx)
|
||||||
[![Docker Pulls][6]](https://hub.docker.com/r/missuo/deeplx)
|
[![Releases][6]](https://github.com/OwO-Network/DeepLX/releases)
|
||||||
[![Releases][7]](https://github.com/OwO-Network/DeepLX/releases)
|
|
||||||
|
|
||||||
[1]: https://img.shields.io/github/actions/workflow/status/OwO-Network/DeepLX/release.yaml?logo=github
|
[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
|
[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
|
[3]: https://goreportcard.com/badge/github.com/OwO-Network/DeepLX
|
||||||
[4]: https://api.codeclimate.com/v1/badges/b5b30239174fc6603aca/maintainability
|
[4]: https://img.shields.io/github/license/OwO-Network/DeepLX
|
||||||
[5]: 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/docker/pulls/missuo/deeplx?logo=docker
|
[6]: https://img.shields.io/github/v/release/OwO-Network/DeepLX?logo=smartthings
|
||||||
[7]: https://img.shields.io/github/v/release/OwO-Network/DeepLX?logo=smartthings
|
|
||||||
|
|
||||||
## How to use
|
## How to use
|
||||||
|
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
version: '3.8'
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
deeplx:
|
deeplx:
|
||||||
image: ghcr.io/owo-network/deeplx:latest
|
image: ghcr.io/owo-network/deeplx:latest
|
||||||
@ -8,4 +6,4 @@ services:
|
|||||||
- "1188:1188"
|
- "1188:1188"
|
||||||
# environment:
|
# environment:
|
||||||
# - TOKEN=helloworld
|
# - TOKEN=helloworld
|
||||||
# - DL_SESSION=xxxxxx
|
# - DL_SESSION=xxxxxx
|
||||||
|
30
go.mod
30
go.mod
@ -1,12 +1,13 @@
|
|||||||
module github.com/OwO-Network/DeepLX
|
module github.com/OwO-Network/DeepLX
|
||||||
|
|
||||||
go 1.23.2
|
go 1.23.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/abadojack/whatlanggo v1.0.1
|
github.com/abadojack/whatlanggo v1.0.1
|
||||||
github.com/andybalholm/brotli v1.0.5
|
github.com/andybalholm/brotli v1.1.0
|
||||||
github.com/gin-contrib/cors v1.6.0
|
github.com/gin-contrib/cors v1.6.0
|
||||||
github.com/gin-gonic/gin v1.9.1
|
github.com/gin-gonic/gin v1.9.1
|
||||||
|
github.com/imroc/req/v3 v3.48.0
|
||||||
github.com/tidwall/gjson v1.14.3
|
github.com/tidwall/gjson v1.14.3
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -14,29 +15,44 @@ require (
|
|||||||
github.com/bytedance/sonic v1.11.2 // indirect
|
github.com/bytedance/sonic v1.11.2 // indirect
|
||||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
|
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
|
||||||
github.com/chenzhuoyu/iasm v0.9.1 // indirect
|
github.com/chenzhuoyu/iasm v0.9.1 // indirect
|
||||||
|
github.com/cloudflare/circl v1.4.0 // indirect
|
||||||
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||||
github.com/go-playground/locales v0.14.1 // indirect
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
github.com/go-playground/validator/v10 v10.19.0 // indirect
|
github.com/go-playground/validator/v10 v10.19.0 // indirect
|
||||||
|
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
|
||||||
github.com/goccy/go-json v0.10.2 // indirect
|
github.com/goccy/go-json v0.10.2 // indirect
|
||||||
|
github.com/google/pprof v0.0.0-20240910150728-a0b0bb1d4134 // indirect
|
||||||
|
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||||
|
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
github.com/klauspost/compress v1.17.9 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||||
github.com/kr/text v0.2.0 // indirect
|
github.com/kr/text v0.2.0 // indirect
|
||||||
github.com/leodido/go-urn v1.4.0 // indirect
|
github.com/leodido/go-urn v1.4.0 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // 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/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
|
github.com/onsi/ginkgo/v2 v2.20.2 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.1.1 // indirect
|
github.com/pelletier/go-toml/v2 v2.1.1 // indirect
|
||||||
|
github.com/quic-go/qpack v0.5.1 // indirect
|
||||||
|
github.com/quic-go/quic-go v0.48.2 // indirect
|
||||||
|
github.com/refraction-networking/utls v1.6.7 // indirect
|
||||||
github.com/tidwall/match v1.1.1 // indirect
|
github.com/tidwall/match v1.1.1 // indirect
|
||||||
github.com/tidwall/pretty v1.2.0 // indirect
|
github.com/tidwall/pretty v1.2.0 // indirect
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||||
|
go.uber.org/mock v0.4.0 // indirect
|
||||||
golang.org/x/arch v0.7.0 // indirect
|
golang.org/x/arch v0.7.0 // indirect
|
||||||
golang.org/x/crypto v0.21.0 // indirect
|
golang.org/x/crypto v0.35.0 // indirect
|
||||||
golang.org/x/net v0.23.0 // indirect
|
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect
|
||||||
golang.org/x/sys v0.18.0 // indirect
|
golang.org/x/mod v0.21.0 // indirect
|
||||||
golang.org/x/text v0.14.0 // indirect
|
golang.org/x/net v0.36.0 // indirect
|
||||||
google.golang.org/protobuf v1.33.0 // indirect
|
golang.org/x/sync v0.11.0 // indirect
|
||||||
|
golang.org/x/sys v0.30.0 // indirect
|
||||||
|
golang.org/x/text v0.22.0 // indirect
|
||||||
|
golang.org/x/tools v0.25.0 // indirect
|
||||||
|
google.golang.org/protobuf v1.34.1 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
72
go.sum
72
go.sum
@ -1,7 +1,7 @@
|
|||||||
github.com/abadojack/whatlanggo v1.0.1 h1:19N6YogDnf71CTHm3Mp2qhYfkRdyvbgwWdd2EPxJRG4=
|
github.com/abadojack/whatlanggo v1.0.1 h1:19N6YogDnf71CTHm3Mp2qhYfkRdyvbgwWdd2EPxJRG4=
|
||||||
github.com/abadojack/whatlanggo v1.0.1/go.mod h1:66WiQbSbJBIlOZMsvbKe5m6pzQovxCH9B/K8tQB2uoc=
|
github.com/abadojack/whatlanggo v1.0.1/go.mod h1:66WiQbSbJBIlOZMsvbKe5m6pzQovxCH9B/K8tQB2uoc=
|
||||||
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
|
||||||
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
|
||||||
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||||
github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM=
|
github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM=
|
||||||
github.com/bytedance/sonic v1.11.2 h1:ywfwo0a/3j9HR8wsYGWsIWl2mvRsI950HyoxiBERw5A=
|
github.com/bytedance/sonic v1.11.2 h1:ywfwo0a/3j9HR8wsYGWsIWl2mvRsI950HyoxiBERw5A=
|
||||||
@ -13,6 +13,8 @@ github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpV
|
|||||||
github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
|
github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
|
||||||
github.com/chenzhuoyu/iasm v0.9.1 h1:tUHQJXo3NhBqw6s33wkGn9SP3bvrWLdlVIJ3hQBL7P0=
|
github.com/chenzhuoyu/iasm v0.9.1 h1:tUHQJXo3NhBqw6s33wkGn9SP3bvrWLdlVIJ3hQBL7P0=
|
||||||
github.com/chenzhuoyu/iasm v0.9.1/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
|
github.com/chenzhuoyu/iasm v0.9.1/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
|
||||||
|
github.com/cloudflare/circl v1.4.0 h1:BV7h5MgrktNzytKmWjpOtdYrf0lkkbF8YMlBGPhJQrY=
|
||||||
|
github.com/cloudflare/circl v1.4.0/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
@ -25,6 +27,8 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE
|
|||||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||||
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
|
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
|
||||||
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
|
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
|
||||||
|
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||||
|
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
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/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 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||||
@ -33,13 +37,26 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn
|
|||||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||||
github.com/go-playground/validator/v10 v10.19.0 h1:ol+5Fu+cSq9JD7SoSqe04GMI92cbn0+wvQ3bZ8b/AU4=
|
github.com/go-playground/validator/v10 v10.19.0 h1:ol+5Fu+cSq9JD7SoSqe04GMI92cbn0+wvQ3bZ8b/AU4=
|
||||||
github.com/go-playground/validator/v10 v10.19.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
github.com/go-playground/validator/v10 v10.19.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||||
|
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||||
|
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/google/pprof v0.0.0-20240910150728-a0b0bb1d4134 h1:c5FlPPgxOn7kJz3VoPLkQYQXGBS3EklQ4Zfi57uOuqQ=
|
||||||
|
github.com/google/pprof v0.0.0-20240910150728-a0b0bb1d4134/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
||||||
|
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
|
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||||
|
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
|
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||||
|
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||||
|
github.com/imroc/req/v3 v3.48.0 h1:IYuMGetuwLzOOTzDCquDqs912WNwpsPK0TBXWPIvoqg=
|
||||||
|
github.com/imroc/req/v3 v3.48.0/go.mod h1:weam9gmyb00QnOtu6HXSnk44dNFkIUQb5QdMx13FeUU=
|
||||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
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/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
|
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||||
|
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||||
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
|
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
|
||||||
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||||
@ -57,10 +74,20 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
|
|||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
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 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
|
github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4=
|
||||||
|
github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag=
|
||||||
|
github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
|
||||||
|
github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
|
||||||
github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI=
|
github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI=
|
||||||
github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
|
||||||
|
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
|
||||||
|
github.com/quic-go/quic-go v0.48.2 h1:wsKXZPeGWpMpCGSWqOcqpW2wZYic/8T3aqiOID0/KWE=
|
||||||
|
github.com/quic-go/quic-go v0.48.2/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs=
|
||||||
|
github.com/refraction-networking/utls v1.6.7 h1:zVJ7sP1dJx/WtVuITug3qYUq034cDq9B2MR1K67ULZM=
|
||||||
|
github.com/refraction-networking/utls v1.6.7/go.mod h1:BC3O4vQzye5hqpmDTWUqi4P5DDhzJfkV1tdqtawQIH0=
|
||||||
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
|
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
|
||||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
@ -71,8 +98,9 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
|||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
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.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
|
||||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/tidwall/gjson v1.14.3 h1:9jvXn7olKEHU1S9vwoMGliaT8jq1vJ7IH/n9zD9Dnlw=
|
github.com/tidwall/gjson v1.14.3 h1:9jvXn7olKEHU1S9vwoMGliaT8jq1vJ7IH/n9zD9Dnlw=
|
||||||
github.com/tidwall/gjson v1.14.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
github.com/tidwall/gjson v1.14.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||||
@ -83,23 +111,33 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS
|
|||||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||||
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
||||||
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||||
|
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
|
||||||
|
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
|
||||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||||
golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc=
|
golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc=
|
||||||
golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||||
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
|
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
|
||||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||||
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
|
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk=
|
||||||
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY=
|
||||||
|
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
|
||||||
|
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||||
|
golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA=
|
||||||
|
golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I=
|
||||||
|
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
|
||||||
|
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE=
|
||||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg=
|
||||||
|
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
|
||||||
|
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
|
261
main.go
261
main.go
@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* @Author: Vincent Yang
|
* @Author: Vincent Yang
|
||||||
* @Date: 2023-07-01 21:45:34
|
* @Date: 2023-07-01 21:45:34
|
||||||
* @LastEditors: Vincent Yang
|
* @LastEditors: Jason Lyu
|
||||||
* @LastEditTime: 2024-11-01 13:04:50
|
* @LastEditTime: 2025-04-08 13:45:00
|
||||||
* @FilePath: /DeepLX/main.go
|
* @FilePath: /DeepLX/main.go
|
||||||
* @Telegram: https://t.me/missuo
|
* @Telegram: https://t.me/missuo
|
||||||
* @GitHub: https://github.com/missuo
|
* @GitHub: https://github.com/missuo
|
||||||
@ -14,268 +14,21 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
translate "github.com/OwO-Network/DeepLX/translate"
|
|
||||||
"github.com/gin-contrib/cors"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
|
||||||
|
"github.com/OwO-Network/DeepLX/service"
|
||||||
)
|
)
|
||||||
|
|
||||||
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 main() {
|
func main() {
|
||||||
cfg := initConfig()
|
cfg := service.InitConfig()
|
||||||
|
|
||||||
fmt.Printf("DeepL X has been successfully launched! Listening on %v:%v\n", cfg.IP, cfg.Port)
|
fmt.Printf("DeepL X has been successfully launched! Listening on %v:%v\n", cfg.IP, cfg.Port)
|
||||||
fmt.Println("Developed by sjlleo <i@leo.moe> and missuo <me@missuo.me>.")
|
fmt.Println("Developed by sjlleo <i@leo.moe> and missuo <me@missuo.me>.")
|
||||||
|
|
||||||
// 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.")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setting the application to release mode
|
// Setting the application to release mode
|
||||||
gin.SetMode(gin.ReleaseMode)
|
gin.SetMode(gin.ReleaseMode)
|
||||||
r := gin.Default()
|
|
||||||
r.Use(cors.Default())
|
|
||||||
|
|
||||||
// Defining the root endpoint which returns the project details
|
app := service.Router(cfg)
|
||||||
r.GET("/", func(c *gin.Context) {
|
app.Run(fmt.Sprintf("%v:%v", cfg.IP, cfg.Port))
|
||||||
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",
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
r.Run(fmt.Sprintf("%v:%v", cfg.IP, cfg.Port))
|
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* @Author: Vincent Yang
|
* @Author: Vincent Yang
|
||||||
* @Date: 2024-04-23 00:39:03
|
* @Date: 2024-04-23 00:39:03
|
||||||
* @LastEditors: Vincent Yang
|
* @LastEditors: Jason Lyu
|
||||||
* @LastEditTime: 2024-09-17 19:34:32
|
* @LastEditTime: 2025-04-08 13:45:00
|
||||||
* @FilePath: /DeepLX/config.go
|
* @FilePath: /DeepLX/config.go
|
||||||
* @Telegram: https://t.me/missuo
|
* @Telegram: https://t.me/missuo
|
||||||
* @GitHub: https://github.com/missuo
|
* @GitHub: https://github.com/missuo
|
||||||
@ -10,7 +10,7 @@
|
|||||||
* Copyright © 2024 by Vincent, All Rights Reserved.
|
* Copyright © 2024 by Vincent, All Rights Reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
@ -26,7 +26,7 @@ type Config struct {
|
|||||||
Proxy string
|
Proxy string
|
||||||
}
|
}
|
||||||
|
|
||||||
func initConfig() *Config {
|
func InitConfig() *Config {
|
||||||
cfg := &Config{
|
cfg := &Config{
|
||||||
IP: "0.0.0.0",
|
IP: "0.0.0.0",
|
||||||
Port: 1188,
|
Port: 1188,
|
275
service/service.go
Normal file
275
service/service.go
Normal file
@ -0,0 +1,275 @@
|
|||||||
|
/*
|
||||||
|
* @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
|
||||||
|
}
|
@ -2,7 +2,7 @@
|
|||||||
* @Author: Vincent Young
|
* @Author: Vincent Young
|
||||||
* @Date: 2024-09-16 11:59:24
|
* @Date: 2024-09-16 11:59:24
|
||||||
* @LastEditors: Vincent Yang
|
* @LastEditors: Vincent Yang
|
||||||
* @LastEditTime: 2024-11-01 23:19:11
|
* @LastEditTime: 2025-04-08 14:26:33
|
||||||
* @FilePath: /DeepLX/translate/translate.go
|
* @FilePath: /DeepLX/translate/translate.go
|
||||||
* @Telegram: https://t.me/missuo
|
* @Telegram: https://t.me/missuo
|
||||||
* @GitHub: https://github.com/missuo
|
* @GitHub: https://github.com/missuo
|
||||||
@ -14,120 +14,92 @@ package translate
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"compress/flate"
|
||||||
|
"compress/gzip"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/abadojack/whatlanggo"
|
||||||
|
"github.com/imroc/req/v3"
|
||||||
|
|
||||||
"github.com/andybalholm/brotli"
|
"github.com/andybalholm/brotli"
|
||||||
"github.com/tidwall/gjson"
|
"github.com/tidwall/gjson"
|
||||||
)
|
)
|
||||||
|
|
||||||
const baseURL = "https://www2.deepl.com/jsonrpc"
|
|
||||||
|
|
||||||
// makeRequest makes an HTTP request to DeepL API
|
// makeRequest makes an HTTP request to DeepL API
|
||||||
func makeRequest(postData *PostData, urlMethod string, proxyURL string, dlSession string) (gjson.Result, error) {
|
func makeRequest(postData *PostData, proxyURL string, dlSession string) (gjson.Result, error) {
|
||||||
urlFull := fmt.Sprintf("%s?client=chrome-extension,1.28.0&method=%s", baseURL, urlMethod)
|
urlFull := "https://www2.deepl.com/jsonrpc"
|
||||||
|
|
||||||
postStr := formatPostString(postData)
|
postStr := formatPostString(postData)
|
||||||
req, err := http.NewRequest("POST", urlFull, bytes.NewReader([]byte(postStr)))
|
|
||||||
if err != nil {
|
// Create a new req client
|
||||||
return gjson.Result{}, err
|
client := req.C().SetTLSFingerprintRandomized()
|
||||||
|
|
||||||
|
// Set headers
|
||||||
|
headers := http.Header{
|
||||||
|
"Content-Type": []string{"application/json"},
|
||||||
|
"User-Agent": []string{"DeepL/1627620 CFNetwork/3826.500.62.2.1 Darwin/24.4.0"},
|
||||||
|
"Accept": []string{"*/*"},
|
||||||
|
"X-App-Os-Name": []string{"iOS"},
|
||||||
|
"X-App-Os-Version": []string{"18.4.0"},
|
||||||
|
"Accept-Language": []string{"en-US,en;q=0.9"},
|
||||||
|
"Accept-Encoding": []string{"gzip, deflate, br"}, // Keep this!
|
||||||
|
"X-App-Device": []string{"iPhone16,2"},
|
||||||
|
"Referer": []string{"https://www.deepl.com/"},
|
||||||
|
"X-Product": []string{"translator"},
|
||||||
|
"X-App-Build": []string{"1627620"},
|
||||||
|
"X-App-Version": []string{"25.1"},
|
||||||
}
|
}
|
||||||
|
|
||||||
if dlSession != "" {
|
if dlSession != "" {
|
||||||
req.Header = http.Header{
|
headers.Set("Cookie", "dl_session="+dlSession)
|
||||||
"Accept": []string{"*/*"},
|
|
||||||
"Accept-Language": []string{"en-US,en;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh-HK;q=0.6,zh;q=0.5"},
|
|
||||||
"Authorization": []string{"None"},
|
|
||||||
"Cache-Control": []string{"no-cache"},
|
|
||||||
"Content-Type": []string{"application/json"},
|
|
||||||
"DNT": []string{"1"},
|
|
||||||
"Origin": []string{"chrome-extension://cofdbpoegempjloogbagkncekinflcnj"},
|
|
||||||
"Pragma": []string{"no-cache"},
|
|
||||||
"Priority": []string{"u=1, i"},
|
|
||||||
"Referer": []string{"https://www.deepl.com/"},
|
|
||||||
"Sec-Fetch-Dest": []string{"empty"},
|
|
||||||
"Sec-Fetch-Mode": []string{"cors"},
|
|
||||||
"Sec-Fetch-Site": []string{"none"},
|
|
||||||
"Sec-GPC": []string{"1"},
|
|
||||||
"User-Agent": []string{"DeepLBrowserExtension/1.28.0 Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"},
|
|
||||||
"Cookie": []string{"dl_session=" + dlSession},
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
req.Header = http.Header{
|
|
||||||
"Accept": []string{"*/*"},
|
|
||||||
"Accept-Language": []string{"en-US,en;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh-HK;q=0.6,zh;q=0.5"},
|
|
||||||
"Authorization": []string{"None"},
|
|
||||||
"Cache-Control": []string{"no-cache"},
|
|
||||||
"Content-Type": []string{"application/json"},
|
|
||||||
"DNT": []string{"1"},
|
|
||||||
"Origin": []string{"chrome-extension://cofdbpoegempjloogbagkncekinflcnj"},
|
|
||||||
"Pragma": []string{"no-cache"},
|
|
||||||
"Priority": []string{"u=1, i"},
|
|
||||||
"Referer": []string{"https://www.deepl.com/"},
|
|
||||||
"Sec-Fetch-Dest": []string{"empty"},
|
|
||||||
"Sec-Fetch-Mode": []string{"cors"},
|
|
||||||
"Sec-Fetch-Site": []string{"none"},
|
|
||||||
"Sec-GPC": []string{"1"},
|
|
||||||
"User-Agent": []string{"DeepLBrowserExtension/1.28.0 Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36"},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup client with proxy if provided
|
// Set proxy if provided
|
||||||
var client *http.Client
|
|
||||||
if proxyURL != "" {
|
if proxyURL != "" {
|
||||||
proxy, err := url.Parse(proxyURL)
|
proxy, err := url.Parse(proxyURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return gjson.Result{}, err
|
return gjson.Result{}, err
|
||||||
}
|
}
|
||||||
client = &http.Client{Transport: &http.Transport{Proxy: http.ProxyURL(proxy)}}
|
client.SetProxyURL(proxy.String())
|
||||||
} else {
|
|
||||||
client = &http.Client{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := client.Do(req)
|
// Make the request
|
||||||
|
r := client.R()
|
||||||
|
r.Headers = headers
|
||||||
|
resp, err := r.
|
||||||
|
SetBody(bytes.NewReader([]byte(postStr))).
|
||||||
|
Post(urlFull)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return gjson.Result{}, err
|
return gjson.Result{}, err
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
var bodyReader io.Reader
|
var bodyReader io.Reader
|
||||||
if resp.Header.Get("Content-Encoding") == "br" {
|
contentEncoding := resp.Header.Get("Content-Encoding")
|
||||||
|
switch contentEncoding {
|
||||||
|
case "br":
|
||||||
bodyReader = brotli.NewReader(resp.Body)
|
bodyReader = brotli.NewReader(resp.Body)
|
||||||
} else {
|
case "gzip":
|
||||||
|
bodyReader, err = gzip.NewReader(resp.Body) // Use gzip.NewReader
|
||||||
|
if err != nil {
|
||||||
|
return gjson.Result{}, fmt.Errorf("failed to create gzip reader: %w", err)
|
||||||
|
}
|
||||||
|
case "deflate": // Less common, but good to handle
|
||||||
|
bodyReader = flate.NewReader(resp.Body)
|
||||||
|
default:
|
||||||
bodyReader = resp.Body
|
bodyReader = resp.Body
|
||||||
}
|
}
|
||||||
|
|
||||||
body, err := io.ReadAll(bodyReader)
|
body, err := io.ReadAll(bodyReader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return gjson.Result{}, err
|
return gjson.Result{}, fmt.Errorf("failed to read response body: %w", err)
|
||||||
}
|
}
|
||||||
return gjson.ParseBytes(body), nil
|
return gjson.ParseBytes(body), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// splitText splits the input text for translation
|
|
||||||
func splitText(text string, tagHandling bool, proxyURL string, dlSession string) (gjson.Result, error) {
|
|
||||||
postData := &PostData{
|
|
||||||
Jsonrpc: "2.0",
|
|
||||||
Method: "LMT_split_text",
|
|
||||||
ID: getRandomNumber(),
|
|
||||||
Params: Params{
|
|
||||||
CommonJobParams: CommonJobParams{
|
|
||||||
Mode: "translate",
|
|
||||||
},
|
|
||||||
Lang: Lang{
|
|
||||||
LangUserSelected: "auto",
|
|
||||||
},
|
|
||||||
Texts: []string{text},
|
|
||||||
TextType: map[bool]string{true: "richtext", false: "plaintext"}[tagHandling || isRichText(text)],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
return makeRequest(postData, "LMT_split_text", proxyURL, dlSession)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TranslateByDeepLX performs translation using DeepL API
|
// TranslateByDeepLX performs translation using DeepL API
|
||||||
func TranslateByDeepLX(sourceLang, targetLang, text string, tagHandling string, proxyURL string, dlSession string) (DeepLXTranslationResult, error) {
|
func TranslateByDeepLX(sourceLang, targetLang, text string, tagHandling string, proxyURL string, dlSession string) (DeepLXTranslationResult, error) {
|
||||||
if text == "" {
|
if text == "" {
|
||||||
@ -137,148 +109,182 @@ func TranslateByDeepLX(sourceLang, targetLang, text string, tagHandling string,
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Split text first
|
if tagHandling == "" {
|
||||||
splitResult, err := splitText(text, tagHandling == "html" || tagHandling == "xml", proxyURL, dlSession)
|
tagHandling = "plaintext"
|
||||||
if err != nil {
|
|
||||||
return DeepLXTranslationResult{
|
|
||||||
Code: http.StatusServiceUnavailable,
|
|
||||||
Message: err.Error(),
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get detected language if source language is auto
|
// Split text by newlines and store them for later reconstruction
|
||||||
if sourceLang == "auto" || sourceLang == "" {
|
textParts := strings.Split(text, "\n")
|
||||||
sourceLang = strings.ToLower(splitResult.Get("result.lang.detected").String())
|
var translatedParts []string
|
||||||
}
|
var allAlternatives [][]string // Store alternatives for each part
|
||||||
|
|
||||||
// Prepare jobs from split result
|
for _, part := range textParts {
|
||||||
var jobs []Job
|
if strings.TrimSpace(part) == "" {
|
||||||
chunks := splitResult.Get("result.texts.0.chunks").Array()
|
translatedParts = append(translatedParts, "")
|
||||||
for idx, chunk := range chunks {
|
allAlternatives = append(allAlternatives, []string{""})
|
||||||
sentence := chunk.Get("sentences.0")
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
// Handle context
|
// Get detected language if source language is auto
|
||||||
contextBefore := []string{}
|
if sourceLang == "auto" || sourceLang == "" {
|
||||||
contextAfter := []string{}
|
sourceLang = strings.ToUpper(whatlanggo.DetectLang(part).Iso6391())
|
||||||
if idx > 0 {
|
|
||||||
contextBefore = []string{chunks[idx-1].Get("sentences.0.text").String()}
|
|
||||||
}
|
|
||||||
if idx < len(chunks)-1 {
|
|
||||||
contextAfter = []string{chunks[idx+1].Get("sentences.0.text").String()}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prepare jobs from split result
|
||||||
|
var jobs []Job
|
||||||
|
|
||||||
jobs = append(jobs, Job{
|
jobs = append(jobs, Job{
|
||||||
Kind: "default",
|
Kind: "default",
|
||||||
PreferredNumBeams: 4,
|
PreferredNumBeams: 4,
|
||||||
RawEnContextBefore: contextBefore,
|
RawEnContextBefore: []string{},
|
||||||
RawEnContextAfter: contextAfter,
|
RawEnContextAfter: []string{},
|
||||||
Sentences: []Sentence{{
|
Sentences: []Sentence{{
|
||||||
Prefix: sentence.Get("prefix").String(),
|
Prefix: "",
|
||||||
Text: sentence.Get("text").String(),
|
Text: text,
|
||||||
ID: idx + 1,
|
ID: 0,
|
||||||
}},
|
}},
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
hasRegionalVariant := false
|
hasRegionalVariant := false
|
||||||
targetLangCode := targetLang
|
targetLangCode := targetLang
|
||||||
targetLangParts := strings.Split(targetLang, "-")
|
targetLangParts := strings.Split(targetLang, "-")
|
||||||
if len(targetLangParts) > 1 {
|
if len(targetLangParts) > 1 {
|
||||||
targetLangCode = targetLangParts[0]
|
targetLangCode = targetLangParts[0]
|
||||||
hasRegionalVariant = true
|
hasRegionalVariant = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare translation request
|
// Prepare translation request
|
||||||
id := getRandomNumber()
|
id := getRandomNumber()
|
||||||
|
|
||||||
postData := &PostData{
|
postData := &PostData{
|
||||||
Jsonrpc: "2.0",
|
|
||||||
Method: "LMT_handle_jobs",
|
|
||||||
ID: id,
|
|
||||||
Params: Params{
|
|
||||||
CommonJobParams: CommonJobParams{
|
|
||||||
Mode: "translate",
|
|
||||||
},
|
|
||||||
Lang: Lang{
|
|
||||||
SourceLangComputed: strings.ToUpper(sourceLang),
|
|
||||||
TargetLang: strings.ToUpper(targetLangCode),
|
|
||||||
},
|
|
||||||
Jobs: jobs,
|
|
||||||
Priority: 1,
|
|
||||||
Timestamp: getTimeStamp(getICount(text)),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if hasRegionalVariant {
|
|
||||||
postData = &PostData{
|
|
||||||
Jsonrpc: "2.0",
|
Jsonrpc: "2.0",
|
||||||
Method: "LMT_handle_jobs",
|
Method: "LMT_handle_jobs",
|
||||||
ID: id,
|
ID: id,
|
||||||
Params: Params{
|
Params: Params{
|
||||||
CommonJobParams: CommonJobParams{
|
CommonJobParams: CommonJobParams{
|
||||||
Mode: "translate",
|
Mode: "translate",
|
||||||
RegionalVariant: map[bool]string{true: targetLang, false: ""}[hasRegionalVariant],
|
Formality: "undefined",
|
||||||
|
TranscribeAs: "romanize",
|
||||||
|
AdvancedMode: false,
|
||||||
|
TextType: tagHandling,
|
||||||
|
WasSpoken: false,
|
||||||
},
|
},
|
||||||
Lang: Lang{
|
Lang: Lang{
|
||||||
SourceLangComputed: strings.ToUpper(sourceLang),
|
SourceLangUserSelected: "auto",
|
||||||
TargetLang: strings.ToUpper(targetLangCode),
|
TargetLang: strings.ToUpper(targetLangCode),
|
||||||
|
SourceLangComputed: strings.ToUpper(sourceLang),
|
||||||
},
|
},
|
||||||
Jobs: jobs,
|
Jobs: jobs,
|
||||||
Priority: 1,
|
Timestamp: getTimeStamp(getICount(part)),
|
||||||
Timestamp: getTimeStamp(getICount(text)),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Make translation request
|
if hasRegionalVariant {
|
||||||
result, err := makeRequest(postData, "LMT_handle_jobs", proxyURL, dlSession)
|
postData = &PostData{
|
||||||
if err != nil {
|
Jsonrpc: "2.0",
|
||||||
return DeepLXTranslationResult{
|
Method: "LMT_handle_jobs",
|
||||||
Code: http.StatusServiceUnavailable,
|
ID: id,
|
||||||
Message: err.Error(),
|
Params: Params{
|
||||||
}, nil
|
CommonJobParams: CommonJobParams{
|
||||||
}
|
Mode: "translate",
|
||||||
|
Formality: "undefined",
|
||||||
|
TranscribeAs: "romanize",
|
||||||
|
AdvancedMode: false,
|
||||||
|
TextType: tagHandling,
|
||||||
|
WasSpoken: false,
|
||||||
|
RegionalVariant: targetLang,
|
||||||
|
},
|
||||||
|
Lang: Lang{
|
||||||
|
SourceLangUserSelected: "auto",
|
||||||
|
TargetLang: strings.ToUpper(targetLangCode),
|
||||||
|
SourceLangComputed: strings.ToUpper(sourceLang),
|
||||||
|
},
|
||||||
|
Jobs: jobs,
|
||||||
|
Timestamp: getTimeStamp(getICount(part)),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Process translation results
|
// Make translation request
|
||||||
var alternatives []string
|
result, err := makeRequest(postData, proxyURL, dlSession)
|
||||||
var translatedText string
|
if err != nil {
|
||||||
|
return DeepLXTranslationResult{
|
||||||
|
Code: http.StatusServiceUnavailable,
|
||||||
|
Message: err.Error(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
translations := result.Get("result.translations").Array()
|
// Process translation results
|
||||||
if len(translations) > 0 {
|
var partTranslation string
|
||||||
// Get alternatives
|
var partAlternatives []string
|
||||||
numBeams := len(translations[0].Get("beams").Array())
|
|
||||||
for i := 0; i < numBeams; i++ {
|
translations := result.Get("result.translations").Array()
|
||||||
var altText string
|
if len(translations) > 0 {
|
||||||
|
// Process main translation
|
||||||
for _, translation := range translations {
|
for _, translation := range translations {
|
||||||
beams := translation.Get("beams").Array()
|
partTranslation += translation.Get("beams.0.sentences.0.text").String() + " "
|
||||||
if i < len(beams) {
|
}
|
||||||
altText += beams[i].Get("sentences.0.text").String()
|
partTranslation = strings.TrimSpace(partTranslation)
|
||||||
|
|
||||||
|
// Process alternatives
|
||||||
|
numBeams := len(translations[0].Get("beams").Array())
|
||||||
|
for i := 1; i < numBeams; i++ { // Start from 1 since 0 is the main translation
|
||||||
|
var altText string
|
||||||
|
for _, translation := range translations {
|
||||||
|
beams := translation.Get("beams").Array()
|
||||||
|
if i < len(beams) {
|
||||||
|
altText += beams[i].Get("sentences.0.text").String() + " "
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if altText != "" {
|
||||||
|
partAlternatives = append(partAlternatives, strings.TrimSpace(altText))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if altText != "" {
|
|
||||||
alternatives = append(alternatives, altText)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get main translation
|
if partTranslation == "" {
|
||||||
for _, translation := range translations {
|
return DeepLXTranslationResult{
|
||||||
translatedText += translation.Get("beams.0.sentences.0.text").String() + " "
|
Code: http.StatusServiceUnavailable,
|
||||||
|
Message: "Translation failed",
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
translatedText = strings.TrimSpace(translatedText)
|
|
||||||
|
translatedParts = append(translatedParts, partTranslation)
|
||||||
|
allAlternatives = append(allAlternatives, partAlternatives)
|
||||||
}
|
}
|
||||||
|
|
||||||
if translatedText == "" {
|
// Join all translated parts with newlines
|
||||||
return DeepLXTranslationResult{
|
translatedText := strings.Join(translatedParts, "\n")
|
||||||
Code: http.StatusServiceUnavailable,
|
|
||||||
Message: "Translation failed",
|
// Combine alternatives with proper newline handling
|
||||||
}, nil
|
var combinedAlternatives []string
|
||||||
|
maxAlts := 0
|
||||||
|
for _, alts := range allAlternatives {
|
||||||
|
if len(alts) > maxAlts {
|
||||||
|
maxAlts = len(alts)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create combined alternatives preserving line structure
|
||||||
|
for i := 0; i < maxAlts; i++ {
|
||||||
|
var altParts []string
|
||||||
|
for j, alts := range allAlternatives {
|
||||||
|
if i < len(alts) {
|
||||||
|
altParts = append(altParts, alts[i])
|
||||||
|
} else if len(translatedParts[j]) == 0 {
|
||||||
|
altParts = append(altParts, "") // Keep empty lines
|
||||||
|
} else {
|
||||||
|
altParts = append(altParts, translatedParts[j]) // Use main translation if no alternative
|
||||||
|
}
|
||||||
|
}
|
||||||
|
combinedAlternatives = append(combinedAlternatives, strings.Join(altParts, "\n"))
|
||||||
}
|
}
|
||||||
|
|
||||||
return DeepLXTranslationResult{
|
return DeepLXTranslationResult{
|
||||||
Code: http.StatusOK,
|
Code: http.StatusOK,
|
||||||
ID: id,
|
ID: getRandomNumber(), // Using new ID for the complete translation
|
||||||
Data: translatedText,
|
Data: translatedText,
|
||||||
Alternatives: alternatives,
|
Alternatives: combinedAlternatives,
|
||||||
SourceLang: sourceLang,
|
SourceLang: sourceLang,
|
||||||
TargetLang: targetLang,
|
TargetLang: targetLang,
|
||||||
Method: map[bool]string{true: "Pro", false: "Free"}[dlSession != ""],
|
Method: map[bool]string{true: "Pro", false: "Free"}[dlSession != ""],
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* @Author: Vincent Young
|
* @Author: Vincent Young
|
||||||
* @Date: 2024-09-16 11:59:24
|
* @Date: 2024-09-16 11:59:24
|
||||||
* @LastEditors: Vincent Yang
|
* @LastEditors: Vincent Yang
|
||||||
* @LastEditTime: 2024-11-01 23:18:56
|
* @LastEditTime: 2025-03-01 04:16:07
|
||||||
* @FilePath: /DeepLX/translate/types.go
|
* @FilePath: /DeepLX/translate/types.go
|
||||||
* @Telegram: https://t.me/missuo
|
* @Telegram: https://t.me/missuo
|
||||||
* @GitHub: https://github.com/missuo
|
* @GitHub: https://github.com/missuo
|
||||||
@ -14,14 +14,19 @@ package translate
|
|||||||
|
|
||||||
// Lang represents the language settings for translation
|
// Lang represents the language settings for translation
|
||||||
type Lang struct {
|
type Lang struct {
|
||||||
SourceLangComputed string `json:"source_lang_computed,omitempty"`
|
SourceLangUserSelected string `json:"source_lang_user_selected"` // Can be "auto"
|
||||||
TargetLang string `json:"target_lang"`
|
TargetLang string `json:"target_lang"`
|
||||||
LangUserSelected string `json:"lang_user_selected,omitempty"`
|
SourceLangComputed string `json:"source_lang_computed,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommonJobParams represents common parameters for translation jobs
|
// CommonJobParams represents common parameters for translation jobs
|
||||||
type CommonJobParams struct {
|
type CommonJobParams struct {
|
||||||
|
Formality string `json:"formality"` // Can be "undefined"
|
||||||
|
TranscribeAs string `json:"transcribe_as"`
|
||||||
Mode string `json:"mode"`
|
Mode string `json:"mode"`
|
||||||
|
WasSpoken bool `json:"wasSpoken"`
|
||||||
|
AdvancedMode bool `json:"advancedMode"`
|
||||||
|
TextType string `json:"textType"`
|
||||||
RegionalVariant string `json:"regionalVariant,omitempty"`
|
RegionalVariant string `json:"regionalVariant,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,10 +50,7 @@ type Job struct {
|
|||||||
type Params struct {
|
type Params struct {
|
||||||
CommonJobParams CommonJobParams `json:"commonJobParams"`
|
CommonJobParams CommonJobParams `json:"commonJobParams"`
|
||||||
Lang Lang `json:"lang"`
|
Lang Lang `json:"lang"`
|
||||||
Texts []string `json:"texts,omitempty"`
|
Jobs []Job `json:"jobs"`
|
||||||
TextType string `json:"textType,omitempty"`
|
|
||||||
Jobs []Job `json:"jobs,omitempty"`
|
|
||||||
Priority int `json:"priority,omitempty"`
|
|
||||||
Timestamp int64 `json:"timestamp"`
|
Timestamp int64 `json:"timestamp"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,25 +62,6 @@ type PostData struct {
|
|||||||
Params Params `json:"params"`
|
Params Params `json:"params"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// SplitTextResponse represents the response from text splitting
|
|
||||||
type SplitTextResponse struct {
|
|
||||||
Jsonrpc string `json:"jsonrpc"`
|
|
||||||
ID int64 `json:"id"`
|
|
||||||
Result struct {
|
|
||||||
Lang struct {
|
|
||||||
Detected string `json:"detected"`
|
|
||||||
} `json:"lang"`
|
|
||||||
Texts []struct {
|
|
||||||
Chunks []struct {
|
|
||||||
Sentences []struct {
|
|
||||||
Prefix string `json:"prefix"`
|
|
||||||
Text string `json:"text"`
|
|
||||||
} `json:"sentences"`
|
|
||||||
} `json:"chunks"`
|
|
||||||
} `json:"texts"`
|
|
||||||
} `json:"result"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// TranslationResponse represents the response from translation
|
// TranslationResponse represents the response from translation
|
||||||
type TranslationResponse struct {
|
type TranslationResponse struct {
|
||||||
Jsonrpc string `json:"jsonrpc"`
|
Jsonrpc string `json:"jsonrpc"`
|
||||||
@ -86,23 +69,34 @@ type TranslationResponse struct {
|
|||||||
Result struct {
|
Result struct {
|
||||||
Translations []struct {
|
Translations []struct {
|
||||||
Beams []struct {
|
Beams []struct {
|
||||||
Sentences []struct {
|
Sentences []SentenceResponse `json:"sentences"`
|
||||||
Text string `json:"text"`
|
NumSymbols int `json:"num_symbols"`
|
||||||
} `json:"sentences"`
|
RephraseVariant struct { // Added rephrase_variant
|
||||||
|
Name string `json:"name"`
|
||||||
|
} `json:"rephrase_variant"`
|
||||||
} `json:"beams"`
|
} `json:"beams"`
|
||||||
|
Quality string `json:"quality"` // Added quality
|
||||||
} `json:"translations"`
|
} `json:"translations"`
|
||||||
SourceLang string `json:"source_lang"`
|
TargetLang string `json:"target_lang"`
|
||||||
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"`
|
} `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
|
// DeepLXTranslationResult represents the final translation result
|
||||||
type DeepLXTranslationResult struct {
|
type DeepLXTranslationResult struct {
|
||||||
Code int `json:"code"`
|
Code int `json:"code"`
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
Message string `json:"message,omitempty"`
|
Message string `json:"message,omitempty"`
|
||||||
Data string `json:"data"`
|
Data string `json:"data"` // The primary translated text
|
||||||
Alternatives []string `json:"alternatives"`
|
Alternatives []string `json:"alternatives"` // Other possible translations
|
||||||
SourceLang string `json:"source_lang"`
|
SourceLang string `json:"source_lang"`
|
||||||
TargetLang string `json:"target_lang"`
|
TargetLang string `json:"target_lang"`
|
||||||
Method string `json:"method"`
|
Method string `json:"method"`
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* @Author: Vincent Young
|
* @Author: Vincent Young
|
||||||
* @Date: 2024-09-16 11:59:24
|
* @Date: 2024-09-16 11:59:24
|
||||||
* @LastEditors: Vincent Yang
|
* @LastEditors: Vincent Yang
|
||||||
* @LastEditTime: 2024-11-01 00:39:32
|
* @LastEditTime: 2025-04-08 14:27:21
|
||||||
* @FilePath: /DeepLX/translate/utils.go
|
* @FilePath: /DeepLX/translate/utils.go
|
||||||
* @Telegram: https://t.me/missuo
|
* @Telegram: https://t.me/missuo
|
||||||
* @GitHub: https://github.com/missuo
|
* @GitHub: https://github.com/missuo
|
||||||
@ -55,8 +55,3 @@ func formatPostString(postData *PostData) string {
|
|||||||
|
|
||||||
return postStr
|
return postStr
|
||||||
}
|
}
|
||||||
|
|
||||||
// isRichText checks if text contains HTML-like tags
|
|
||||||
func isRichText(text string) bool {
|
|
||||||
return strings.Contains(text, "<") && strings.Contains(text, ">")
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user