From e580fb57a29ec3c3f3e180b20cfa6ec28687689b Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Sun, 20 Jul 2025 22:18:57 +0300 Subject: 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 --- internal/batch/doc.go | 4 ++ internal/batch/processor.go | 94 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 internal/batch/doc.go create mode 100644 internal/batch/processor.go (limited to 'internal/batch') diff --git a/internal/batch/doc.go b/internal/batch/doc.go new file mode 100644 index 0000000..33f3b19 --- /dev/null +++ b/internal/batch/doc.go @@ -0,0 +1,4 @@ +// Package batch handles batch processing of Bulgarian words from files. +// It supports reading word lists with optional translations in the format: +// "bulgarian_word" or "bulgarian_word = english_translation" +package batch diff --git a/internal/batch/processor.go b/internal/batch/processor.go new file mode 100644 index 0000000..75a38aa --- /dev/null +++ b/internal/batch/processor.go @@ -0,0 +1,94 @@ +package batch + +import ( + "fmt" + "os" + "strings" +) + +// WordEntry represents a word with optional translation +type WordEntry struct { + Bulgarian string + Translation string +} + +// ReadBatchFile reads words from a file and returns WordEntry slice +// Supports formats: +// - Bulgarian word only: "ябълка" +// - With translation: "ябълка = apple" +func ReadBatchFile(filename string) ([]WordEntry, error) { + content, err := os.ReadFile(filename) + if err != nil { + return nil, fmt.Errorf("failed to read batch file: %w", err) + } + + var entries []WordEntry + lines := string(content) + + for _, line := range splitLines(lines) { + if line = trimSpace(line); line != "" { + // Check if line contains '=' for bulgarian = english format + if strings.Contains(line, "=") { + parts := strings.SplitN(line, "=", 2) + if len(parts) == 2 { + bulgarian := strings.TrimSpace(parts[0]) + english := strings.TrimSpace(parts[1]) + if bulgarian != "" { + entries = append(entries, WordEntry{ + Bulgarian: bulgarian, + Translation: english, + }) + } + } + } else { + // Just a bulgarian word + entries = append(entries, WordEntry{ + Bulgarian: line, + Translation: "", + }) + } + } + } + + return entries, nil +} + +// splitLines splits a string by newlines +func splitLines(s string) []string { + var lines []string + current := "" + for _, r := range s { + if r == '\n' { + lines = append(lines, current) + current = "" + } else if r != '\r' { + current += string(r) + } + } + if current != "" { + lines = append(lines, current) + } + return lines +} + +// trimSpace trims whitespace from string +func trimSpace(s string) string { + start := 0 + end := len(s) + + // Trim from start + for start < end && isSpace(rune(s[start])) { + start++ + } + + // Trim from end + for end > start && isSpace(rune(s[end-1])) { + end-- + } + + return s[start:end] +} + +func isSpace(r rune) bool { + return r == ' ' || r == '\t' || r == '\n' || r == '\r' +} -- cgit v1.2.3