mirror of
https://github.com/OwO-Network/DeepLX.git
synced 2025-04-18 13:43:24 +00:00
Compare commits
3 Commits
2d8b84e2c8
...
de9888ca5f
Author | SHA1 | Date | |
---|---|---|---|
|
de9888ca5f | ||
|
bbfb808793 | ||
|
4a77cbf30e |
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.4'
|
go-version: '1.23.5'
|
||||||
|
|
||||||
- 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.4"
|
go-version: "1.23.5"
|
||||||
|
|
||||||
- run: bash .cross_compile.sh
|
- run: bash .cross_compile.sh
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
FROM golang:1.23.4 AS builder
|
FROM golang:1.23.5 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 ./
|
||||||
|
4
go.mod
4
go.mod
@ -1,6 +1,6 @@
|
|||||||
module github.com/OwO-Network/DeepLX
|
module github.com/OwO-Network/DeepLX
|
||||||
|
|
||||||
go 1.23.4
|
go 1.23.5
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/abadojack/whatlanggo v1.0.1
|
github.com/abadojack/whatlanggo v1.0.1
|
||||||
@ -48,7 +48,7 @@ require (
|
|||||||
golang.org/x/crypto v0.31.0 // indirect
|
golang.org/x/crypto v0.31.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect
|
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect
|
||||||
golang.org/x/mod v0.21.0 // indirect
|
golang.org/x/mod v0.21.0 // indirect
|
||||||
golang.org/x/net v0.29.0 // indirect
|
golang.org/x/net v0.33.0 // indirect
|
||||||
golang.org/x/sync v0.10.0 // indirect
|
golang.org/x/sync v0.10.0 // indirect
|
||||||
golang.org/x/sys v0.28.0 // indirect
|
golang.org/x/sys v0.28.0 // indirect
|
||||||
golang.org/x/text v0.21.0 // indirect
|
golang.org/x/text v0.21.0 // indirect
|
||||||
|
4
go.sum
4
go.sum
@ -122,8 +122,8 @@ golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWB
|
|||||||
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY=
|
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 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
|
||||||
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||||
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
|
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
|
||||||
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
|
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||||
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
||||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
golang.org/x/sync v0.10.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=
|
||||||
|
@ -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-12-03 11:23:23
|
* @LastEditTime: 2025-01-20 17:09:59
|
||||||
* @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
|
||||||
@ -126,87 +126,79 @@ func TranslateByDeepLX(sourceLang, targetLang, text string, tagHandling string,
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Split text first
|
// Split text by newlines and store them for later reconstruction
|
||||||
splitResult, err := splitText(text, tagHandling == "html" || tagHandling == "xml", proxyURL, dlSession)
|
textParts := strings.Split(text, "\n")
|
||||||
if err != nil {
|
var translatedParts []string
|
||||||
return DeepLXTranslationResult{
|
var allAlternatives [][]string // Store alternatives for each part
|
||||||
Code: http.StatusServiceUnavailable,
|
|
||||||
Message: err.Error(),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get detected language if source language is auto
|
for _, part := range textParts {
|
||||||
if sourceLang == "auto" || sourceLang == "" {
|
if strings.TrimSpace(part) == "" {
|
||||||
sourceLang = strings.ToUpper(whatlanggo.DetectLang(text).Iso6391())
|
translatedParts = append(translatedParts, "")
|
||||||
}
|
allAlternatives = append(allAlternatives, []string{""})
|
||||||
|
continue
|
||||||
// Prepare jobs from split result
|
|
||||||
var jobs []Job
|
|
||||||
chunks := splitResult.Get("result.texts.0.chunks").Array()
|
|
||||||
for idx, chunk := range chunks {
|
|
||||||
sentence := chunk.Get("sentences.0")
|
|
||||||
|
|
||||||
// Handle context
|
|
||||||
contextBefore := []string{}
|
|
||||||
contextAfter := []string{}
|
|
||||||
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()}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jobs = append(jobs, Job{
|
// Split text first
|
||||||
Kind: "default",
|
splitResult, err := splitText(part, tagHandling == "html" || tagHandling == "xml", proxyURL, dlSession)
|
||||||
PreferredNumBeams: 4,
|
if err != nil {
|
||||||
RawEnContextBefore: contextBefore,
|
return DeepLXTranslationResult{
|
||||||
RawEnContextAfter: contextAfter,
|
Code: http.StatusServiceUnavailable,
|
||||||
Sentences: []Sentence{{
|
Message: err.Error(),
|
||||||
Prefix: sentence.Get("prefix").String(),
|
}, nil
|
||||||
Text: sentence.Get("text").String(),
|
}
|
||||||
ID: idx + 1,
|
|
||||||
}},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
hasRegionalVariant := false
|
// Get detected language if source language is auto
|
||||||
targetLangCode := targetLang
|
if sourceLang == "auto" || sourceLang == "" {
|
||||||
targetLangParts := strings.Split(targetLang, "-")
|
sourceLang = strings.ToUpper(whatlanggo.DetectLang(part).Iso6391())
|
||||||
if len(targetLangParts) > 1 {
|
}
|
||||||
targetLangCode = targetLangParts[0]
|
|
||||||
hasRegionalVariant = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare translation request
|
// Prepare jobs from split result
|
||||||
id := getRandomNumber()
|
var jobs []Job
|
||||||
|
chunks := splitResult.Get("result.texts.0.chunks").Array()
|
||||||
|
for idx, chunk := range chunks {
|
||||||
|
sentence := chunk.Get("sentences.0")
|
||||||
|
|
||||||
postData := &PostData{
|
// Handle context
|
||||||
Jsonrpc: "2.0",
|
contextBefore := []string{}
|
||||||
Method: "LMT_handle_jobs",
|
contextAfter := []string{}
|
||||||
ID: id,
|
if idx > 0 {
|
||||||
Params: Params{
|
contextBefore = []string{chunks[idx-1].Get("sentences.0.text").String()}
|
||||||
CommonJobParams: CommonJobParams{
|
}
|
||||||
Mode: "translate",
|
if idx < len(chunks)-1 {
|
||||||
},
|
contextAfter = []string{chunks[idx+1].Get("sentences.0.text").String()}
|
||||||
Lang: Lang{
|
}
|
||||||
SourceLangComputed: strings.ToUpper(sourceLang),
|
|
||||||
TargetLang: strings.ToUpper(targetLangCode),
|
|
||||||
},
|
|
||||||
Jobs: jobs,
|
|
||||||
Priority: 1,
|
|
||||||
Timestamp: getTimeStamp(getICount(text)),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if hasRegionalVariant {
|
jobs = append(jobs, Job{
|
||||||
postData = &PostData{
|
Kind: "default",
|
||||||
|
PreferredNumBeams: 4,
|
||||||
|
RawEnContextBefore: contextBefore,
|
||||||
|
RawEnContextAfter: contextAfter,
|
||||||
|
Sentences: []Sentence{{
|
||||||
|
Prefix: sentence.Get("prefix").String(),
|
||||||
|
Text: sentence.Get("text").String(),
|
||||||
|
ID: idx + 1,
|
||||||
|
}},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
hasRegionalVariant := false
|
||||||
|
targetLangCode := targetLang
|
||||||
|
targetLangParts := strings.Split(targetLang, "-")
|
||||||
|
if len(targetLangParts) > 1 {
|
||||||
|
targetLangCode = targetLangParts[0]
|
||||||
|
hasRegionalVariant = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare translation request
|
||||||
|
id := getRandomNumber()
|
||||||
|
|
||||||
|
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],
|
|
||||||
},
|
},
|
||||||
Lang: Lang{
|
Lang: Lang{
|
||||||
SourceLangComputed: strings.ToUpper(sourceLang),
|
SourceLangComputed: strings.ToUpper(sourceLang),
|
||||||
@ -214,60 +206,111 @@ func TranslateByDeepLX(sourceLang, targetLang, text string, tagHandling string,
|
|||||||
},
|
},
|
||||||
Jobs: jobs,
|
Jobs: jobs,
|
||||||
Priority: 1,
|
Priority: 1,
|
||||||
Timestamp: getTimeStamp(getICount(text)),
|
Timestamp: getTimeStamp(getICount(part)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// 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",
|
||||||
|
RegionalVariant: map[bool]string{true: targetLang, false: ""}[hasRegionalVariant],
|
||||||
|
},
|
||||||
|
Lang: Lang{
|
||||||
|
SourceLangComputed: strings.ToUpper(sourceLang),
|
||||||
|
TargetLang: strings.ToUpper(targetLangCode),
|
||||||
|
},
|
||||||
|
Jobs: jobs,
|
||||||
|
Priority: 1,
|
||||||
|
Timestamp: getTimeStamp(getICount(part)),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Process translation results
|
// Make translation request
|
||||||
var alternatives []string
|
result, err := makeRequest(postData, "LMT_handle_jobs", 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 != ""],
|
||||||
|
Loading…
Reference in New Issue
Block a user