diff --git a/cmd/lingualeo/lingualeo.go b/cmd/lingualeo/lingualeo.go index e517ecd..b25238d 100644 --- a/cmd/lingualeo/lingualeo.go +++ b/cmd/lingualeo/lingualeo.go @@ -4,10 +4,8 @@ import ( "context" "os" "os/signal" - "sync" "syscall" - "github.com/trezorg/lingualeo/pkg/api" "github.com/trezorg/lingualeo/pkg/messages" "github.com/trezorg/lingualeo/pkg/translator" "github.com/trezorg/lingualeo/pkg/utils" @@ -33,21 +31,6 @@ func main() { } }() - var wg sync.WaitGroup - wg.Add(1) - soundChan, addWordChan, resultsChan := args.Process(ctx, &wg) - if args.Sound { - wg.Add(1) - go args.Pronounce(ctx, soundChan, &wg) - } - if args.Add { - wg.Add(1) - go args.AddToDictionary(ctx, addWordChan, &wg) - } - - for result := range api.OrResultDone(ctx, resultsChan) { - result.PrintTranslation() - } - - wg.Wait() + args.TranslateWithReverseRussian(ctx) + } diff --git a/go.mod b/go.mod index d130129..0cd8b82 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/trezorg/lingualeo -go 1.14 +go 1.16 require ( github.com/BurntSushi/toml v0.3.1 diff --git a/pkg/api/items.go b/pkg/api/items.go index 86a709a..b4eef0d 100644 --- a/pkg/api/items.go +++ b/pkg/api/items.go @@ -22,7 +22,7 @@ func (bit *convertibleBoolean) UnmarshalJSON(data []byte) error { return nil } -//Result API result insterface +//Result API result interface type Result interface { GetWord() string Error() string @@ -44,7 +44,7 @@ type apiError struct { ErrorCode int `json:"error_code"` } -//Word transale word structure +//Word translates word structure type Word struct { ID int `json:"id"` Votes int `json:"votes"` @@ -68,7 +68,7 @@ func opResultFromBody(word string, body string) OpResult { } } -//TranslationResult represets API response +//TranslationResult represents API response type TranslationResult struct { Word string `json:"-"` Words []string `json:"-"` @@ -120,12 +120,12 @@ func (result *TranslationResult) SetWord(word string) { result.Word = word } -//GetTranslate returns transalation for a word +//GetTranslate returns translation for a word func (result *TranslationResult) GetTranslate() []string { return result.Words } -//SetTranslate sets custom transaltion for a word +//SetTranslate sets custom translation for a word func (result *TranslationResult) SetTranslate(translates []string, replace bool) { if replace { result.Words = utils.Unique(translates) @@ -134,12 +134,12 @@ func (result *TranslationResult) SetTranslate(translates []string, replace bool) } } -//GetSoundURLs retuns sound urls to promounciate +//GetSoundURLs returns sound urls to pronounce func (result *TranslationResult) GetSoundURLs() []string { return []string{result.SoundURL} } -//InDictionary chel either workd is already has been added into the dictionary +//InDictionary checks either word is already has been added into the dictionary func (result *TranslationResult) InDictionary() bool { if bool(result.Exists) { return true @@ -156,7 +156,7 @@ func (result *TranslationResult) Error() string { return result.ErrorMsg } -//IsRussian either word in in Russian langualge +//IsRussian either word in in Russian language func (result *TranslationResult) IsRussian() bool { return result.Transcription == "" } diff --git a/pkg/translator/args.go b/pkg/translator/args.go index 5c98516..3ccb53f 100644 --- a/pkg/translator/args.go +++ b/pkg/translator/args.go @@ -79,8 +79,8 @@ func prepareCliArgs(version string) Lingualeo { return fmt.Errorf("there are no words to translate") } args.Words = utils.Unique(c.Args().Slice()) - args.Translate = translate.Value() - if args.Add && len(args.Translate) > 0 && len(args.Words) > 1 { + args.Translation = translate.Value() + if args.Add && len(args.Translation) > 0 && len(args.Words) > 1 { return fmt.Errorf("you should add only one word with custom transcation") } return nil @@ -191,6 +191,12 @@ func prepareCliArgs(version string) Lingualeo { Usage: "Log pretty print", Destination: &args.LogPrettyPrint, }, + &cli.BoolFlag{ + Name: "reverse-translate", + Aliases: []string{"rt"}, + Usage: "Reverse translate russian words", + Destination: &args.ReverseTranslate, + }, } app.Commands = []*cli.Command{ { @@ -352,6 +358,9 @@ func (args *Lingualeo) mergeConfigs(a *Lingualeo) { if a.LogPrettyPrint { args.LogPrettyPrint = a.LogPrettyPrint } + if a.ReverseTranslate { + args.ReverseTranslate = a.ReverseTranslate + } if a.TranslateReplace { args.TranslateReplace = a.TranslateReplace } diff --git a/pkg/translator/items.go b/pkg/translator/items.go index 6754b58..e861c06 100644 --- a/pkg/translator/items.go +++ b/pkg/translator/items.go @@ -8,7 +8,7 @@ type Lingualeo struct { Config string Player string `yaml:"player" json:"player" toml:"player"` Words []string - Translate []string + Translation []string Force bool `yaml:"force" json:"force" toml:"force"` Add bool `yaml:"add" json:"add" toml:"add"` TranslateReplace bool `yaml:"translate_replace" json:"translate_replace" toml:"translate_replace"` @@ -17,5 +17,6 @@ type Lingualeo struct { DownloadSoundFile bool `yaml:"download" json:"download" toml:"download"` LogLevel string `yaml:"log_level" json:"log_level" toml:"log_level"` LogPrettyPrint bool `yaml:"log_pretty_print" json:"log_pretty_print" toml:"log_pretty_print"` + ReverseTranslate bool `yaml:"reverse_translate" json:"reverse_translate" toml:"reverse_translate"` API api.Translator } diff --git a/pkg/translator/linguleo.go b/pkg/translator/linguleo.go index 3382437..baf5987 100644 --- a/pkg/translator/linguleo.go +++ b/pkg/translator/linguleo.go @@ -94,8 +94,8 @@ func (args *Lingualeo) translateWords(ctx context.Context) <-chan api.OpResult { func (args *Lingualeo) prepareResultToAdd(result *api.Result) bool { if !(*result).InDictionary() || args.Force { // Custom translation - if len(args.Translate) > 0 { - (*result).SetTranslate(args.Translate, args.TranslateReplace) + if len(args.Translation) > 0 { + (*result).SetTranslate(args.Translation, args.TranslateReplace) } return true } @@ -194,3 +194,50 @@ func (args *Lingualeo) Process(ctx context.Context, wg *sync.WaitGroup) (<-chan return soundChan, addWordChan, resultsChan } + +func (args *Lingualeo) translateToChan(ctx context.Context) chan api.Result { + var wg sync.WaitGroup + wg.Add(1) + soundChan, addWordChan, resultsChan := args.Process(ctx, &wg) + if args.Sound { + wg.Add(1) + go args.Pronounce(ctx, soundChan, &wg) + } + if args.Add { + wg.Add(1) + go args.AddToDictionary(ctx, addWordChan, &wg) + } + + ch := make(chan api.Result, len(args.Words)) + + go func() { + defer close(ch) + for result := range api.OrResultDone(ctx, resultsChan) { + result.PrintTranslation() + ch <- result + } + wg.Wait() + }() + + return ch + +} + +func (args *Lingualeo) TranslateWithReverseRussian(ctx context.Context) { + //TranslateWithReverseRussian translates russian words, + //gets english translations and translates them once more + results := args.translateToChan(ctx) + var englishWords []string + for result := range results { + for _, word := range result.GetTranslate() { + if args.ReverseTranslate && utils.IsEnglishWord(word) { + englishWords = append(englishWords, word) + } + } + } + if len(englishWords) > 0 { + args.Words = englishWords + for range args.translateToChan(ctx) { + } + } +} diff --git a/pkg/utils/testing/utils_test.go b/pkg/utils/testing/utils_test.go index b758939..0a67f66 100644 --- a/pkg/utils/testing/utils_test.go +++ b/pkg/utils/testing/utils_test.go @@ -17,7 +17,13 @@ func TestInsertIntoSlice(t *testing.T) { } func TestCheckEitherCommandIsAvailableOnSystem(t *testing.T) { - assert.Equal(t, true, utils.IsCommandAvailable("bash -c 'oops'")) - assert.Equal(t, true, utils.IsCommandAvailable("bash")) - assert.Equal(t, false, utils.IsCommandAvailable("xxxxxxxxxxx")) + assert.True(t, utils.IsCommandAvailable("bash -c 'oops'")) + assert.True(t, utils.IsCommandAvailable("bash")) + assert.False(t, utils.IsCommandAvailable("xxxxxxxxxxx")) +} + +func TestRussianWord(t *testing.T) { + assert.True(t, utils.IsRussianWord("гном")) + assert.True(t, utils.IsRussianWord("гном1")) + assert.False(t, utils.IsRussianWord("test")) } diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 09e9495..96eb4c0 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -115,3 +115,21 @@ func Capitalize(s string) string { } return "" } + +func IsRussianWord(s string) bool { + for _, symbol := range s { + if !(unicode.Is(unicode.Cyrillic, symbol) || unicode.Is(unicode.Number, symbol)) { + return false + } + } + return true +} + +func IsEnglishWord(s string) bool { + for _, symbol := range s { + if !(unicode.Is(unicode.Latin, symbol) || unicode.Is(unicode.Number, symbol)) { + return false + } + } + return true +}