summaryrefslogtreecommitdiff
path: root/internal/translation
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2025-07-20 22:18:57 +0300
committerPaul Buetow <paul@buetow.org>2025-07-20 22:18:57 +0300
commite580fb57a29ec3c3f3e180b20cfa6ec28687689b (patch)
treede74f04450b830268e4c1644a91acb9fd45c3802 /internal/translation
parent9e3328a6aaefe4bd1aa0ec3e8bf6e93d6033180b (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.go4
-rw-r--r--internal/translation/translator.go103
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
+}