diff options
| author | Paul Buetow <paul@buetow.org> | 2025-07-20 22:18:57 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2025-07-20 22:18:57 +0300 |
| commit | e580fb57a29ec3c3f3e180b20cfa6ec28687689b (patch) | |
| tree | de74f04450b830268e4c1644a91acb9fd45c3802 /internal/translation | |
| parent | 9e3328a6aaefe4bd1aa0ec3e8bf6e93d6033180b (diff) | |
Refactor main.go into focused packages
- Reduced main.go from 961 lines to 89 lines (91% reduction)
- Created new packages for better separation of concerns:
- cli: Command-line interface setup and configuration
- processor: Core word processing logic and orchestration
- batch: Batch file processing functionality
- translation: Bulgarian to English translation services
- models: OpenAI model listing functionality
- phonetic: Phonetic information fetching
- Each package has clear documentation in doc.go files
- Improved testability and maintainability
- All existing functionality preserved
- All tests passing and build successful
Diffstat (limited to 'internal/translation')
| -rw-r--r-- | internal/translation/doc.go | 4 | ||||
| -rw-r--r-- | internal/translation/translator.go | 103 |
2 files changed, 107 insertions, 0 deletions
diff --git a/internal/translation/doc.go b/internal/translation/doc.go new file mode 100644 index 0000000..fac31ff --- /dev/null +++ b/internal/translation/doc.go @@ -0,0 +1,4 @@ +// Package translation provides Bulgarian to English translation services +// using the OpenAI API. It includes translation caching for batch operations +// and file persistence for translated words. +package translation diff --git a/internal/translation/translator.go b/internal/translation/translator.go new file mode 100644 index 0000000..ab3a879 --- /dev/null +++ b/internal/translation/translator.go @@ -0,0 +1,103 @@ +package translation + +import ( + "context" + "fmt" + "os" + "path/filepath" + "strings" + + "github.com/sashabaranov/go-openai" +) + +// Translator handles Bulgarian to English translation +type Translator struct { + apiKey string + client *openai.Client +} + +// NewTranslator creates a new translator instance +func NewTranslator(apiKey string) *Translator { + return &Translator{ + apiKey: apiKey, + client: openai.NewClient(apiKey), + } +} + +// TranslateWord translates a Bulgarian word to English +func (t *Translator) TranslateWord(word string) (string, error) { + if t.apiKey == "" { + return "", fmt.Errorf("OpenAI API key not found") + } + + ctx := context.Background() + + req := openai.ChatCompletionRequest{ + Model: openai.GPT4oMini, + Messages: []openai.ChatCompletionMessage{ + { + Role: openai.ChatMessageRoleUser, + Content: fmt.Sprintf("Translate the Bulgarian word '%s' to English. Respond with only the English translation, nothing else.", word), + }, + }, + MaxTokens: 50, + Temperature: 0.3, + } + + resp, err := t.client.CreateChatCompletion(ctx, req) + if err != nil { + return "", fmt.Errorf("OpenAI API error: %w", err) + } + + if len(resp.Choices) == 0 { + return "", fmt.Errorf("no translation returned") + } + + translation := strings.TrimSpace(resp.Choices[0].Message.Content) + return translation, nil +} + +// SaveTranslation saves the translation to a file in the word directory +func SaveTranslation(wordDir, word, translation string) error { + outputFile := filepath.Join(wordDir, "translation.txt") + content := fmt.Sprintf("%s = %s\n", word, translation) + + if err := os.WriteFile(outputFile, []byte(content), 0644); err != nil { + return fmt.Errorf("failed to write translation file: %w", err) + } + + return nil +} + +// TranslationCache stores translations in memory for batch operations +type TranslationCache struct { + translations map[string]string +} + +// NewTranslationCache creates a new translation cache +func NewTranslationCache() *TranslationCache { + return &TranslationCache{ + translations: make(map[string]string), + } +} + +// Add adds a translation to the cache +func (tc *TranslationCache) Add(word, translation string) { + tc.translations[word] = translation +} + +// Get retrieves a translation from the cache +func (tc *TranslationCache) Get(word string) (string, bool) { + translation, ok := tc.translations[word] + return translation, ok +} + +// GetAll returns all cached translations +func (tc *TranslationCache) GetAll() map[string]string { + // Return a copy to prevent external modification + result := make(map[string]string) + for k, v := range tc.translations { + result[k] = v + } + return result +} |
