1
0
mirror of https://github.com/raseels-repos/golang-saas-starter-kit.git synced 2025-06-06 23:46:29 +02:00

197 lines
4.6 KiB
Go
Raw Normal View History

package main
import (
"flag"
"fmt"
"geeks-accelerator/oss/saas-starter-kit/tools/text-translator/internal/jsontranslator"
"io/ioutil"
"log"
"os"
"path/filepath"
"regexp"
"strings"
"github.com/PuerkitoBio/goquery"
)
const (
keyWordLengthLimit = 4
)
var (
inFile = flag.String("i", "", "source .gohtml file to extract text from")
outDir = flag.String("o", "", "output directory for translations")
locale = flag.String("l", "en", "locale of input file")
allowedCharsKeyRegex, _ = regexp.Compile("[^a-zA-Z0-9 ]+")
)
func main() {
flag.Parse()
flag.VisitAll(func(f *flag.Flag) {
if f.Value.String() == "" {
fmt.Printf("-%s flag is required\n", f.Name)
os.Exit(1)
}
})
s, err := os.Stat(*inFile)
if err != nil {
fmt.Printf("coudn't check if path is a file or directory: %v\n", err)
os.Exit(1)
}
if s.IsDir() {
filepath.Walk(*inFile, func(path string, info os.FileInfo, err error) error {
if err != nil {
fmt.Printf("error while walking path: %v\n", err)
os.Exit(1)
}
if !info.IsDir() {
parseFile(path)
}
return nil
})
} else {
parseFile(*inFile)
}
}
func parseFile(path string) {
log.Printf("reading file %s\n", path)
b, err := ioutil.ReadFile(path)
if err != nil {
fmt.Printf("error while reading input file: %v\n", err)
os.Exit(1)
}
content := string(b)
_, name := filepath.Split(path)
filenameWithoutExt := strings.TrimRight(name, filepath.Ext(name))
translationFile := jsontranslator.JSONTranslation{Locale: *locale}
// Extract title and description
title, description := extractTitleAndDescription(content)
if title != "" {
translationFile.Items = append(translationFile.Items, jsontranslator.Translation{
Locale: *locale,
Key: fmt.Sprintf("%s-title", filenameWithoutExt),
Translation: title,
})
}
if description != "" {
translationFile.Items = append(translationFile.Items, jsontranslator.Translation{
Locale: *locale,
Key: fmt.Sprintf("%s-description", filenameWithoutExt),
Translation: description,
})
}
// Extract texts from html tags
extractedTexts := unique(extract(content, filenameWithoutExt))
for _, text := range extractedTexts {
key := makeKey(text, filenameWithoutExt)
translationFile.Items = append(translationFile.Items, jsontranslator.Translation{
Locale: *locale,
Key: key,
Translation: text,
})
}
err = jsontranslator.Save(*outDir, filenameWithoutExt+".json", []jsontranslator.JSONTranslation{translationFile})
if err != nil {
fmt.Printf("error while saving the extracted strings: %v\n", err)
os.Exit(1)
}
}
func extract(content string, keyPrefix string) []string {
var res []string
r := strings.NewReader(content)
doc, err := goquery.NewDocumentFromReader(r)
if err != nil {
log.Fatal(err)
}
f := func(text string) {
// Safemode: avoid contents that involve template actions
if strings.Index(text, "{{") != -1 {
return
}
if len(text) > 0 {
res = append(res, text)
}
}
// Extract <input> placeholder texts
doc.Find("input").Union(doc.Find("select")).Each(func(i int, input *goquery.Selection) {
if p, exists := input.Attr("placeholder"); exists {
f(p)
}
})
// Extract text from <p>, <a>, ... tags
simpleTags := []string{"p", "a", "h1", "h2", "h3", "h4", "h5", "h6", "button", "small", "label", "li"}
n := &goquery.Selection{}
for _, tag := range simpleTags {
n = n.Union(doc.Find(tag))
}
n.Each(func(i int, n *goquery.Selection) {
if n.Children().Length() == 0 {
f(n.Text())
}
})
return res
}
func extractTitleAndDescription(content string) (title, description string) {
idxStart := strings.Index(content, `{{define "title"}}`)
if idxStart >= 0 {
idxEnd := strings.Index(content, `{{end}}`)
if idxEnd >= 0 {
title = content[idxStart+18 : idxEnd]
content = content[idxEnd+7:]
}
}
idxStart = strings.Index(content, `{{define "description"}}`)
if idxStart >= 0 {
idxEnd := strings.Index(content, `{{end}}`)
if idxEnd >= 0 {
description = content[idxStart+24 : idxEnd]
}
}
return
}
func makeKey(text, prefix string) string {
text = strings.TrimSpace(text)
key := allowedCharsKeyRegex.ReplaceAllString(text, "")
key = strings.ToLower(key)
split := strings.SplitN(key, " ", keyWordLengthLimit+1)
limit := len(split)
if limit > keyWordLengthLimit {
limit = keyWordLengthLimit
}
key = strings.Join(split[:limit], "-")
key = fmt.Sprintf("%s-%s", prefix, key)
return key
}
func unique(lst []string) []string {
keys := make(map[string]struct{})
list := []string{}
for _, s := range lst {
if _, exist := keys[s]; !exist {
keys[s] = struct{}{}
list = append(list, s)
}
}
return list
}