DeepLX/main.go

282 lines
7.0 KiB
Go
Raw Normal View History

2023-07-03 00:50:58 +08:00
/*
2024-03-21 04:41:44 +08:00
* @Author: Vincent Yang
2023-07-03 00:50:58 +08:00
* @Date: 2023-07-01 21:45:34
2024-11-01 12:43:57 +08:00
* @LastEditors: Vincent Yang
* @LastEditTime: 2024-11-01 13:04:50
2023-07-03 00:50:58 +08:00
* @FilePath: /DeepLX/main.go
* @Telegram: https://t.me/missuo
2024-03-21 04:41:44 +08:00
* @GitHub: https://github.com/missuo
2023-07-03 00:50:58 +08:00
*
2024-03-21 04:41:44 +08:00
* Copyright © 2024 by Vincent, All Rights Reserved.
2023-07-03 00:50:58 +08:00
*/
2024-09-17 00:08:13 +08:00
2022-10-17 13:51:22 +08:00
package main
import (
2023-02-12 09:23:04 +08:00
"fmt"
2022-10-17 13:51:22 +08:00
"log"
"net/http"
2024-06-18 03:09:20 +08:00
"net/url"
"os"
2022-10-17 13:51:22 +08:00
"strings"
2024-09-17 00:08:13 +08:00
translate "github.com/OwO-Network/DeepLX/translate"
2023-03-07 00:19:27 +08:00
"github.com/gin-contrib/cors"
2022-10-20 01:06:30 +08:00
"github.com/gin-gonic/gin"
2022-10-17 13:51:22 +08:00
)
2024-04-14 06:54:16 +08:00
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 {
2024-04-14 06:54:16 +08:00
c.JSON(http.StatusUnauthorized, gin.H{
"code": http.StatusUnauthorized,
"message": "Invalid access token",
})
c.Abort()
return
}
}
2024-04-14 06:54:16 +08:00
c.Next()
}
}
2024-09-17 00:08:13 +08:00
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"`
}
2022-10-20 01:06:30 +08:00
func main() {
2024-03-21 04:41:44 +08:00
cfg := initConfig()
2023-04-23 13:25:47 +08:00
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>.")
2023-02-12 09:23:04 +08:00
2024-06-18 03:09:20 +08:00
// 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),
}
}
2023-11-28 03:50:32 +08:00
if cfg.Token != "" {
fmt.Println("Access token is set.")
2023-10-29 10:48:58 +08:00
}
2023-11-28 01:03:32 +08:00
// Setting the application to release mode
2023-02-12 09:23:04 +08:00
gin.SetMode(gin.ReleaseMode)
2022-10-20 01:06:30 +08:00
r := gin.Default()
2023-03-07 00:19:27 +08:00
r.Use(cors.Default())
2022-10-20 01:06:30 +08:00
// Defining the root endpoint which returns the project details
2023-02-12 09:23:04 +08:00
r.GET("/", func(c *gin.Context) {
2023-12-09 08:02:25 +08:00
c.JSON(http.StatusOK, gin.H{
"code": http.StatusOK,
2023-11-20 08:26:07 +08:00
"message": "DeepL Free API, Developed by sjlleo and missuo. Go to /translate with POST. http://github.com/OwO-Network/DeepLX",
2022-10-20 01:06:30 +08:00
})
})
2022-11-10 02:23:14 +08:00
2024-04-23 12:50:11 +08:00
// Free API endpoint, No Pro Account required
2024-04-14 06:54:16 +08:00
r.POST("/translate", authMiddleware(cfg), func(c *gin.Context) {
2023-11-28 03:50:32 +08:00
req := PayloadFree{}
c.BindJSON(&req)
2023-11-28 03:50:32 +08:00
sourceLang := req.SourceLang
targetLang := req.TargetLang
translateText := req.TransText
2024-09-15 14:04:53 +08:00
tagHandling := req.TagHandling
2024-06-18 03:09:20 +08:00
proxyURL := cfg.Proxy
2024-09-15 14:04:53 +08:00
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, "")
2024-03-21 04:41:44 +08:00
if err != nil {
log.Fatalf("Translation failed: %s", err)
}
2024-03-21 04:41:44 +08:00
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 {
2024-03-21 04:41:44 +08:00
c.JSON(result.Code, gin.H{
"code": result.Code,
"message": result.Message,
})
}
2024-03-21 04:41:44 +08:00
})
2024-04-23 12:50:11 +08:00
// 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,
})
}
})
2024-04-23 12:50:11 +08:00
// Free API endpoint, Consistent with the official API format
2024-04-14 06:54:16 +08:00
r.POST("/v2/translate", authMiddleware(cfg), func(c *gin.Context) {
2024-06-18 03:09:20 +08:00
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, "")
2024-03-21 04:41:44 +08:00
if err != nil {
log.Fatalf("Translation failed: %s", err)
}
2024-03-21 04:41:44 +08:00
if result.Code == http.StatusOK {
c.JSON(http.StatusOK, gin.H{
"translations": []map[string]interface{}{
{
2024-03-21 04:41:44 +08:00
"detected_source_language": result.SourceLang,
"text": result.Data,
},
},
})
} else {
2024-03-21 04:41:44 +08:00
c.JSON(result.Code, gin.H{
"code": result.Code,
"message": result.Message,
})
2022-10-20 01:06:30 +08:00
}
})
// 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))
2022-10-17 13:51:22 +08:00
}