mirror of
https://github.com/AdguardTeam/AdGuardHome.git
synced 2025-12-20 01:11:03 +08:00
scripts: revert master
This commit is contained in:
@@ -1,9 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -22,12 +20,6 @@ import (
|
||||
"github.com/AdguardTeam/golibs/syncutil"
|
||||
)
|
||||
|
||||
const (
|
||||
jsonMessageKey = "message"
|
||||
jsonIndentPrefix = ""
|
||||
jsonIndentString = " "
|
||||
)
|
||||
|
||||
// download and save all translations.
|
||||
func (c *twoskyClient) download(ctx context.Context, l *slog.Logger) (err error) {
|
||||
var numWorker int
|
||||
@@ -48,29 +40,6 @@ func (c *twoskyClient) download(ctx context.Context, l *slog.Logger) (err error)
|
||||
usage("count must be positive")
|
||||
}
|
||||
|
||||
// download locales from AdGuard Home crowdin project
|
||||
if err = c.downloadTo(ctx, l, localesDir, defaultBaseFile, numWorker); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// download services from AdGuard Hostlist Registry crowdin project
|
||||
c.projectID = hostlistRegistryProjectID
|
||||
if err = c.downloadTo(ctx, l, servicesLocalesDir, servicesBaseFile, numWorker); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// downloads and saves all translations to the specified outputDir
|
||||
// using the specified baseFile name.
|
||||
func (c *twoskyClient) downloadTo(
|
||||
ctx context.Context,
|
||||
l *slog.Logger,
|
||||
outputDir string,
|
||||
baseFile string,
|
||||
numWorker int,
|
||||
) (err error) {
|
||||
downloadURI := c.uri.JoinPath("download")
|
||||
|
||||
wg := &sync.WaitGroup{}
|
||||
@@ -83,9 +52,7 @@ func (c *twoskyClient) downloadTo(
|
||||
client: &http.Client{
|
||||
Timeout: 10 * time.Second,
|
||||
},
|
||||
uriCh: uriCh,
|
||||
outputDir: outputDir,
|
||||
baseFile: baseFile,
|
||||
uriCh: uriCh,
|
||||
}
|
||||
|
||||
for range numWorker {
|
||||
@@ -93,7 +60,7 @@ func (c *twoskyClient) downloadTo(
|
||||
}
|
||||
|
||||
for _, lang := range c.langs {
|
||||
uri := translationURL(downloadURI, baseFile, c.projectID, lang)
|
||||
uri := translationURL(downloadURI, defaultBaseFile, c.projectID, lang)
|
||||
|
||||
uriCh <- uri
|
||||
}
|
||||
@@ -106,65 +73,8 @@ func (c *twoskyClient) downloadTo(
|
||||
return nil
|
||||
}
|
||||
|
||||
// extracts the "message" values into a flat map and returns the result
|
||||
// formatted with consistent JSON indentation
|
||||
func normalizeServicesJSON(data []byte) ([]byte, error) {
|
||||
unwrapped, err := extractMessagesJSON(data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("normalize services json: extraction failed: %w", err)
|
||||
}
|
||||
|
||||
indented, err := indentJSON(unwrapped)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("normalize services json: indentation failed: %w", err)
|
||||
}
|
||||
|
||||
return indented, nil
|
||||
}
|
||||
|
||||
// converts a wrapped services JSON of shape
|
||||
// {"key": {"message": "..."}} into a flat {"key": "..."}
|
||||
func extractMessagesJSON(input []byte) ([]byte, error) {
|
||||
var wrapped map[string]map[string]any
|
||||
if err := json.Unmarshal(input, &wrapped); err != nil {
|
||||
return nil, fmt.Errorf("extract json: unmarshal wrapped payload: %w", err)
|
||||
}
|
||||
|
||||
flattened := make(map[string]string, len(wrapped))
|
||||
for key, inner := range wrapped {
|
||||
rawValue, ok := inner[jsonMessageKey]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("extract json: missing %q field for key %q", jsonMessageKey, key)
|
||||
}
|
||||
|
||||
message, ok := rawValue.(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("extract json: %q field for key %q is not a string", jsonMessageKey, key)
|
||||
}
|
||||
|
||||
flattened[key] = message
|
||||
}
|
||||
|
||||
result, err := json.Marshal(flattened)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("extract json: marshal flattened map: %w", err)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// formats JSON using the configured prefix and indent
|
||||
func indentJSON(data []byte) (b []byte, err error) {
|
||||
var buffer bytes.Buffer
|
||||
|
||||
err = json.Indent(&buffer, data, jsonIndentPrefix, jsonIndentString)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("indent json: formatting failed: %w", err)
|
||||
}
|
||||
|
||||
return buffer.Bytes(), nil
|
||||
}
|
||||
|
||||
// printFailedLocales prints sorted list of failed downloads, if any. l and
|
||||
// failed must not be nil.
|
||||
func printFailedLocales(
|
||||
ctx context.Context,
|
||||
l *slog.Logger,
|
||||
@@ -188,13 +98,11 @@ func printFailedLocales(
|
||||
// received from the channel to download translations and save them to files.
|
||||
// Failures are stored in the failed map. All fields must not be nil.
|
||||
type downloadWorker struct {
|
||||
ctx context.Context
|
||||
l *slog.Logger
|
||||
failed *syncutil.Map[string, struct{}]
|
||||
client *http.Client
|
||||
uriCh <-chan *url.URL
|
||||
outputDir string
|
||||
baseFile string
|
||||
ctx context.Context
|
||||
l *slog.Logger
|
||||
failed *syncutil.Map[string, struct{}]
|
||||
client *http.Client
|
||||
uriCh <-chan *url.URL
|
||||
}
|
||||
|
||||
// run handles the channel of URLs, one by one. It returns when the channel is
|
||||
@@ -204,7 +112,7 @@ func (w *downloadWorker) run() {
|
||||
q := uri.Query()
|
||||
code := q.Get("language")
|
||||
|
||||
err := saveToFile(w.ctx, w.l, w.client, uri, code, w.outputDir, w.baseFile)
|
||||
err := saveToFile(w.ctx, w.l, w.client, uri, code)
|
||||
if err != nil {
|
||||
w.l.ErrorContext(w.ctx, "download worker", slogutil.KeyError, err)
|
||||
w.failed.Store(code, struct{}{})
|
||||
@@ -220,22 +128,13 @@ func saveToFile(
|
||||
client *http.Client,
|
||||
uri *url.URL,
|
||||
code string,
|
||||
outputDir string,
|
||||
baseFile string,
|
||||
) (err error) {
|
||||
data, err := getTranslation(ctx, l, client, uri.String())
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting translation %q: %s", code, err)
|
||||
}
|
||||
|
||||
if baseFile == servicesBaseFile {
|
||||
data, err = normalizeServicesJSON(data)
|
||||
if err != nil {
|
||||
return fmt.Errorf("normalize services JSON for %q: %w", code, err)
|
||||
}
|
||||
}
|
||||
|
||||
name := filepath.Join(outputDir, code+".json")
|
||||
name := filepath.Join(localesDir, code+".json")
|
||||
err = os.WriteFile(name, data, 0o664)
|
||||
if err != nil {
|
||||
return fmt.Errorf("writing file: %s", err)
|
||||
|
||||
@@ -26,15 +26,12 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
twoskyConfFile = "./.twosky.json"
|
||||
localesDir = "./client/src/__locales"
|
||||
servicesLocalesDir = "./client/src/__locales-services"
|
||||
defaultBaseFile = "en.json"
|
||||
servicesBaseFile = "services.json"
|
||||
defaultProjectID = "home"
|
||||
hostlistRegistryProjectID = "hostlists-registry"
|
||||
srcDir = "./client/src"
|
||||
twoskyURI = "https://twosky.int.agrd.dev/api/v1"
|
||||
twoskyConfFile = "./.twosky.json"
|
||||
localesDir = "./client/src/__locales"
|
||||
defaultBaseFile = "en.json"
|
||||
defaultProjectID = "home"
|
||||
srcDir = "./client/src"
|
||||
twoskyURI = "https://twosky.int.agrd.dev/api/v1"
|
||||
|
||||
readLimit = 1 * 1024 * 1024
|
||||
uploadTimeout = 20 * time.Second
|
||||
@@ -116,7 +113,7 @@ Commands:
|
||||
summary
|
||||
Print summary.
|
||||
download [-n <count>]
|
||||
Download translations (both app and services). count is a number of concurrent downloads.
|
||||
Download translations. count is a number of concurrent downloads.
|
||||
unused
|
||||
Print unused strings.
|
||||
upload
|
||||
|
||||
Reference in New Issue
Block a user