mirror of
https://github.com/OwO-Network/DeepLX.git
synced 2025-07-26 20:33:25 +00:00
Compare commits
5 Commits
e9b5dedc43
...
f172f59fb6
Author | SHA1 | Date | |
---|---|---|---|
|
f172f59fb6 | ||
|
29ac0e1589 | ||
|
dce5ccd029 | ||
|
56755a1b92 | ||
|
a9a5a914b6 |
12
Dockerfile
12
Dockerfile
@ -1,14 +1,6 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
FROM golang:1.22 AS builder
|
||||
FROM golang:1.23.1 AS builder
|
||||
WORKDIR /go/src/github.com/OwO-Network/DeepLX
|
||||
COPY main.go ./
|
||||
COPY types.go ./
|
||||
COPY utils.go ./
|
||||
COPY config.go ./
|
||||
COPY translate.go ./
|
||||
COPY go.mod ./
|
||||
COPY go.sum ./
|
||||
COPY . .
|
||||
RUN go get -d -v ./
|
||||
RUN CGO_ENABLED=0 go build -a -installsuffix cgo -o deeplx .
|
||||
|
||||
|
23
config.go
23
config.go
@ -1,8 +1,8 @@
|
||||
/*
|
||||
* @Author: Vincent Yang
|
||||
* @Date: 2024-04-23 00:39:03
|
||||
* @LastEditors: Vincent Yang
|
||||
* @LastEditTime: 2024-06-18 02:40:52
|
||||
* @LastEditors: Vincent Young
|
||||
* @LastEditTime: 2024-09-16 12:02:15
|
||||
* @FilePath: /DeepLX/config.go
|
||||
* @Telegram: https://t.me/missuo
|
||||
* @GitHub: https://github.com/missuo
|
||||
@ -14,10 +14,19 @@ package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"os"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
IP string
|
||||
Port int
|
||||
Token string
|
||||
AuthKey string
|
||||
DlSession string
|
||||
Proxy string
|
||||
}
|
||||
|
||||
func initConfig() *Config {
|
||||
cfg := &Config{
|
||||
IP: "0.0.0.0",
|
||||
@ -54,14 +63,6 @@ func initConfig() *Config {
|
||||
}
|
||||
}
|
||||
|
||||
// DeepL Official Authentication key flag
|
||||
flag.StringVar(&cfg.AuthKey, "authkey", "", "The authentication key for DeepL API")
|
||||
if cfg.AuthKey == "" {
|
||||
if authKey, ok := os.LookupEnv("AUTHKEY"); ok {
|
||||
cfg.AuthKey = authKey
|
||||
}
|
||||
}
|
||||
|
||||
// HTTP Proxy flag
|
||||
flag.StringVar(&cfg.Proxy, "proxy", "", "set the proxy URL for HTTP requests")
|
||||
if cfg.Proxy == "" {
|
||||
|
2
go.mod
2
go.mod
@ -1,6 +1,6 @@
|
||||
module github.com/OwO-Network/DeepLX
|
||||
|
||||
go 1.22
|
||||
go 1.23.1
|
||||
|
||||
require (
|
||||
github.com/abadojack/whatlanggo v1.0.1
|
||||
|
39
main.go
39
main.go
@ -1,14 +1,15 @@
|
||||
/*
|
||||
* @Author: Vincent Yang
|
||||
* @Date: 2023-07-01 21:45:34
|
||||
* @LastEditors: Vincent Yang
|
||||
* @LastEditTime: 2024-09-15 02:00:23
|
||||
* @LastEditors: Vincent Young
|
||||
* @LastEditTime: 2024-09-16 12:12:35
|
||||
* @FilePath: /DeepLX/main.go
|
||||
* @Telegram: https://t.me/missuo
|
||||
* @GitHub: https://github.com/missuo
|
||||
*
|
||||
* Copyright © 2024 by Vincent, All Rights Reserved.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
@ -19,6 +20,7 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
translate "github.com/OwO-Network/DeepLX/translate"
|
||||
"github.com/gin-contrib/cors"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@ -57,6 +59,20 @@ func authMiddleware(cfg *Config) gin.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
cfg := initConfig()
|
||||
|
||||
@ -81,9 +97,6 @@ func main() {
|
||||
if cfg.Token != "" {
|
||||
fmt.Println("Access token is set.")
|
||||
}
|
||||
if cfg.AuthKey != "" {
|
||||
fmt.Println("DeepL Official Authentication key is set.")
|
||||
}
|
||||
|
||||
// Setting the application to release mode
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
@ -108,7 +121,6 @@ func main() {
|
||||
translateText := req.TransText
|
||||
tagHandling := req.TagHandling
|
||||
|
||||
authKey := cfg.AuthKey
|
||||
proxyURL := cfg.Proxy
|
||||
|
||||
if tagHandling != "" && tagHandling != "html" && tagHandling != "xml" {
|
||||
@ -119,7 +131,7 @@ func main() {
|
||||
return
|
||||
}
|
||||
|
||||
result, err := translateByDeepLX(sourceLang, targetLang, translateText, tagHandling, authKey, proxyURL)
|
||||
result, err := translate.TranslateByDeepLX(sourceLang, targetLang, translateText, tagHandling, proxyURL)
|
||||
if err != nil {
|
||||
log.Fatalf("Translation failed: %s", err)
|
||||
}
|
||||
@ -183,7 +195,7 @@ func main() {
|
||||
return
|
||||
}
|
||||
|
||||
result, err := translateByDeepLXPro(sourceLang, targetLang, translateText, tagHandling, dlSession, proxyURL)
|
||||
result, err := translate.TranslateByDeepLXPro(sourceLang, targetLang, translateText, tagHandling, dlSession, proxyURL)
|
||||
if err != nil {
|
||||
log.Fatalf("Translation failed: %s", err)
|
||||
}
|
||||
@ -209,17 +221,8 @@ func main() {
|
||||
|
||||
// Free API endpoint, Consistent with the official API format
|
||||
r.POST("/v2/translate", authMiddleware(cfg), func(c *gin.Context) {
|
||||
authorizationHeader := c.GetHeader("Authorization")
|
||||
var authKey string
|
||||
proxyURL := cfg.Proxy
|
||||
|
||||
if strings.HasPrefix(authorizationHeader, "DeepL-Auth-Key") {
|
||||
parts := strings.Split(authorizationHeader, " ")
|
||||
if len(parts) >= 2 && strings.HasSuffix(parts[len(parts)-1], ":fx") {
|
||||
authKey = parts[len(parts)-1]
|
||||
}
|
||||
}
|
||||
|
||||
var translateText string
|
||||
var targetLang string
|
||||
|
||||
@ -244,7 +247,7 @@ func main() {
|
||||
targetLang = jsonData.TargetLang
|
||||
}
|
||||
|
||||
result, err := translateByDeepLX("", targetLang, translateText, "", authKey, proxyURL)
|
||||
result, err := translate.TranslateByDeepLX("", targetLang, translateText, "", proxyURL)
|
||||
if err != nil {
|
||||
log.Fatalf("Translation failed: %s", err)
|
||||
}
|
||||
|
@ -1,4 +1,16 @@
|
||||
package main
|
||||
/*
|
||||
* @Author: Vincent Young
|
||||
* @Date: 2024-09-16 11:59:24
|
||||
* @LastEditors: Vincent Young
|
||||
* @LastEditTime: 2024-09-16 12:09:37
|
||||
* @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"
|
||||
@ -47,71 +59,7 @@ func initDeepLXData(sourceLang string, targetLang string) *PostData {
|
||||
}
|
||||
}
|
||||
|
||||
func translateByOfficialAPI(text string, sourceLang string, targetLang string, authKey string, proxyURL string) (string, error) {
|
||||
freeURL := "https://api-free.deepl.com/v2/translate"
|
||||
textArray := strings.Split(text, "\n")
|
||||
|
||||
payload := PayloadAPI{
|
||||
Text: textArray,
|
||||
TargetLang: targetLang,
|
||||
SourceLang: sourceLang,
|
||||
}
|
||||
|
||||
payloadBytes, err := json.Marshal(payload)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", freeURL, bytes.NewBuffer(payloadBytes))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
req.Header.Set("Authorization", "DeepL-Auth-Key "+authKey)
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
var client *http.Client
|
||||
if proxyURL != "" {
|
||||
proxy, err := url.Parse(proxyURL)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
transport := &http.Transport{
|
||||
Proxy: http.ProxyURL(proxy),
|
||||
}
|
||||
client = &http.Client{Transport: transport}
|
||||
} else {
|
||||
client = &http.Client{}
|
||||
}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Parsing the response
|
||||
var translationResponse TranslationResponse
|
||||
err = json.Unmarshal(body, &translationResponse)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Concatenating the translations
|
||||
var sb strings.Builder
|
||||
for _, translation := range translationResponse.Translations {
|
||||
sb.WriteString(translation.Text)
|
||||
}
|
||||
|
||||
return sb.String(), nil
|
||||
}
|
||||
|
||||
func translateByDeepLX(sourceLang string, targetLang string, translateText string, tagHandling string, authKey string, proxyURL string) (DeepLXTranslationResult, error) {
|
||||
func TranslateByDeepLX(sourceLang string, targetLang string, translateText string, tagHandling string, proxyURL string) (DeepLXTranslationResult, error) {
|
||||
id := getRandomNumber()
|
||||
if sourceLang == "" {
|
||||
lang := whatlanggo.DetectLang(translateText)
|
||||
@ -233,36 +181,13 @@ func translateByDeepLX(sourceLang string, targetLang string, translateText strin
|
||||
Message: "Invalid target language",
|
||||
}, nil
|
||||
}
|
||||
|
||||
if resp.StatusCode == http.StatusTooManyRequests && authKey != "" {
|
||||
authKeyArray := strings.Split(authKey, ",")
|
||||
for _, authKey := range authKeyArray {
|
||||
validity, err := checkUsageAuthKey(authKey)
|
||||
if err != nil {
|
||||
continue
|
||||
} else {
|
||||
if validity {
|
||||
translatedText, err := translateByOfficialAPI(translateText, sourceLang, targetLang, authKey, proxyURL)
|
||||
if err != nil {
|
||||
if resp.StatusCode == http.StatusTooManyRequests {
|
||||
return DeepLXTranslationResult{
|
||||
Code: http.StatusTooManyRequests,
|
||||
Message: "Too Many Requests",
|
||||
}, nil
|
||||
}
|
||||
return DeepLXTranslationResult{
|
||||
Code: http.StatusOK,
|
||||
Message: "Success",
|
||||
ID: 1000000,
|
||||
Data: translatedText,
|
||||
SourceLang: sourceLang,
|
||||
TargetLang: targetLang,
|
||||
Method: "Official API",
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
var alternatives []string
|
||||
res.Get("result.texts.0.alternatives").ForEach(func(key, value gjson.Result) bool {
|
||||
alternatives = append(alternatives, value.Get("text").String())
|
||||
@ -286,13 +211,8 @@ func translateByDeepLX(sourceLang string, targetLang string, translateText strin
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
return DeepLXTranslationResult{
|
||||
Code: http.StatusServiceUnavailable,
|
||||
Message: "Uknown error",
|
||||
}, nil
|
||||
}
|
||||
|
||||
func translateByDeepLXPro(sourceLang string, targetLang string, translateText string, tagHandling string, dlSession string, proxyURL string) (DeepLXTranslationResult, error) {
|
||||
func TranslateByDeepLXPro(sourceLang string, targetLang string, translateText string, tagHandling string, dlSession string, proxyURL string) (DeepLXTranslationResult, error) {
|
||||
id := getRandomNumber()
|
||||
if sourceLang == "" {
|
||||
lang := whatlanggo.DetectLang(translateText)
|
@ -1,24 +1,16 @@
|
||||
/*
|
||||
* @Author: Vincent Yang
|
||||
* @Date: 2024-03-20 15:43:57
|
||||
* @LastEditors: Vincent Yang
|
||||
* @LastEditTime: 2024-09-15 01:54:05
|
||||
* @FilePath: /DeepLX/types.go
|
||||
* @Author: Vincent Young
|
||||
* @Date: 2024-09-16 11:59:24
|
||||
* @LastEditors: Vincent Young
|
||||
* @LastEditTime: 2024-09-16 12:06:36
|
||||
* @FilePath: /DeepLX/translate/types.go
|
||||
* @Telegram: https://t.me/missuo
|
||||
* @GitHub: https://github.com/missuo
|
||||
*
|
||||
* Copyright © 2024 by Vincent, All Rights Reserved.
|
||||
*/
|
||||
package main
|
||||
|
||||
type Config struct {
|
||||
IP string
|
||||
Port int
|
||||
Token string
|
||||
AuthKey string
|
||||
DlSession string
|
||||
Proxy string
|
||||
}
|
||||
package translate
|
||||
|
||||
type Lang struct {
|
||||
SourceLangUserSelected string `json:"source_lang_user_selected"`
|
||||
@ -52,20 +44,6 @@ type PostData struct {
|
||||
Params Params `json:"params"`
|
||||
}
|
||||
|
||||
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"`
|
||||
}
|
||||
|
||||
type Translation struct {
|
||||
Text string `json:"text"`
|
||||
}
|
40
translate/utils.go
Normal file
40
translate/utils.go
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* @Author: Vincent Young
|
||||
* @Date: 2024-09-16 11:59:24
|
||||
* @LastEditors: Vincent Young
|
||||
* @LastEditTime: 2024-09-16 12:06:44
|
||||
* @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 (
|
||||
"math/rand"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func getICount(translateText string) int64 {
|
||||
return int64(strings.Count(translateText, "i"))
|
||||
}
|
||||
|
||||
func getRandomNumber() int64 {
|
||||
src := rand.NewSource(time.Now().UnixNano())
|
||||
rng := rand.New(src)
|
||||
num := rng.Int63n(99999) + 8300000
|
||||
return num * 1000
|
||||
}
|
||||
|
||||
func getTimeStamp(iCount int64) int64 {
|
||||
ts := time.Now().UnixMilli()
|
||||
if iCount != 0 {
|
||||
iCount = iCount + 1
|
||||
return ts - ts%iCount + iCount
|
||||
} else {
|
||||
return ts
|
||||
}
|
||||
}
|
72
utils.go
72
utils.go
@ -1,72 +0,0 @@
|
||||
/*
|
||||
* @Author: Vincent Yang
|
||||
* @Date: 2024-04-23 00:17:27
|
||||
* @LastEditors: Vincent Yang
|
||||
* @LastEditTime: 2024-04-23 00:17:29
|
||||
* @FilePath: /DeepLX/utils.go
|
||||
* @Telegram: https://t.me/missuo
|
||||
* @GitHub: https://github.com/missuo
|
||||
*
|
||||
* Copyright © 2024 by Vincent, All Rights Reserved.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func getICount(translateText string) int64 {
|
||||
return int64(strings.Count(translateText, "i"))
|
||||
}
|
||||
|
||||
func getRandomNumber() int64 {
|
||||
src := rand.NewSource(time.Now().UnixNano())
|
||||
rng := rand.New(src)
|
||||
num := rng.Int63n(99999) + 8300000
|
||||
return num * 1000
|
||||
}
|
||||
|
||||
func getTimeStamp(iCount int64) int64 {
|
||||
ts := time.Now().UnixMilli()
|
||||
if iCount != 0 {
|
||||
iCount = iCount + 1
|
||||
return ts - ts%iCount + iCount
|
||||
} else {
|
||||
return ts
|
||||
}
|
||||
}
|
||||
|
||||
func checkUsageAuthKey(authKey string) (bool, error) {
|
||||
url := "https://api-free.deepl.com/v2/usage"
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
req.Header.Add("Authorization", "DeepL-Auth-Key "+authKey)
|
||||
|
||||
client := &http.Client{}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
var response DeepLUsageResponse
|
||||
err = json.Unmarshal(body, &response)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return response.CharacterCount < 499900, nil
|
||||
}
|
Loading…
Reference in New Issue
Block a user