diff options
| author | Paul Buetow <paul@buetow.org> | 2026-03-08 08:44:11 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-03-08 08:44:11 +0200 |
| commit | 6e2635afc69579fdc895d6b7890538ca98dabaae (patch) | |
| tree | 5db5aa603ab5ac3b372c2ac8512c84627fb063e1 | |
| parent | aa733f9a86b02d7b4d6edd8022a44e4ba417b24c (diff) | |
refactor(task-376): share audio attribution builder
| -rw-r--r-- | internal/audio/attribution.go | 49 | ||||
| -rw-r--r-- | internal/gui/generator.go | 21 | ||||
| -rw-r--r-- | internal/processor/processor.go | 25 |
3 files changed, 68 insertions, 27 deletions
diff --git a/internal/audio/attribution.go b/internal/audio/attribution.go new file mode 100644 index 0000000..80f2bc3 --- /dev/null +++ b/internal/audio/attribution.go @@ -0,0 +1,49 @@ +package audio + +import ( + "fmt" + "path/filepath" + "strings" + "time" +) + +// AttributionParams describes metadata included in OpenAI TTS attribution files. +type AttributionParams struct { + Word string + Model string + Voice string + Instruction string + ProcessedText string + Speed float64 + GeneratedAt time.Time +} + +// AttributionPath returns the sidecar attribution file path for a generated audio file. +func AttributionPath(audioFile string) string { + return strings.TrimSuffix(audioFile, filepath.Ext(audioFile)) + "_attribution.txt" +} + +// BuildOpenAIAttribution builds the attribution content for OpenAI-generated audio. +func BuildOpenAIAttribution(params AttributionParams) string { + var b strings.Builder + b.WriteString("Audio generated by OpenAI TTS\n\n") + fmt.Fprintf(&b, "Bulgarian word: %s\n", params.Word) + fmt.Fprintf(&b, "Model: %s\n", params.Model) + fmt.Fprintf(&b, "Voice: %s\n", params.Voice) + fmt.Fprintf(&b, "Speed: %.2f\n", params.Speed) + + if params.Instruction != "" { + fmt.Fprintf(&b, "\nVoice instructions:\n%s\n", params.Instruction) + } + if params.ProcessedText != "" { + fmt.Fprintf(&b, "\nProcessed text sent to TTS: %s\n", params.ProcessedText) + } + + generatedAt := params.GeneratedAt + if generatedAt.IsZero() { + generatedAt = time.Now() + } + fmt.Fprintf(&b, "\nGenerated at: %s\n", generatedAt.Format("2006-01-02 15:04:05")) + + return b.String() +} diff --git a/internal/gui/generator.go b/internal/gui/generator.go index 14f0f60..09ff534 100644 --- a/internal/gui/generator.go +++ b/internal/gui/generator.go @@ -367,20 +367,17 @@ func (a *Application) generateImagesWithPrompt(ctx context.Context, word string, // saveAudioAttribution saves attribution info for generated audio func (a *Application) saveAudioAttribution(word, audioFile, voice string, speed float64) error { - attribution := fmt.Sprintf("Audio generated by OpenAI TTS\n\n") - attribution += fmt.Sprintf("Bulgarian word: %s\n", word) - attribution += fmt.Sprintf("Model: %s\n", a.audioConfig.OpenAIModel) - attribution += fmt.Sprintf("Voice: %s\n", voice) - attribution += fmt.Sprintf("Speed: %.2f\n", speed) - - if a.audioConfig.OpenAIInstruction != "" { - attribution += fmt.Sprintf("\nVoice instructions:\n%s\n", a.audioConfig.OpenAIInstruction) - } - - attribution += fmt.Sprintf("\nGenerated at: %s\n", time.Now().Format("2006-01-02 15:04:05")) + attribution := audio.BuildOpenAIAttribution(audio.AttributionParams{ + Word: word, + Model: a.audioConfig.OpenAIModel, + Voice: voice, + Speed: speed, + Instruction: a.audioConfig.OpenAIInstruction, + GeneratedAt: time.Now(), + }) // Save to file - attrPath := strings.TrimSuffix(audioFile, filepath.Ext(audioFile)) + "_attribution.txt" + attrPath := audio.AttributionPath(audioFile) if err := os.WriteFile(attrPath, []byte(attribution), 0644); err != nil { return fmt.Errorf("failed to write audio attribution file: %w", err) } diff --git a/internal/processor/processor.go b/internal/processor/processor.go index 3b49cf0..d52ca53 100644 --- a/internal/processor/processor.go +++ b/internal/processor/processor.go @@ -728,17 +728,6 @@ func (p *Processor) isWordFullyProcessed(word string) bool { return true // All required files exist } func (p *Processor) saveAudioAttribution(word, audioFile string, config *audio.Config) error { - // Create attribution text - attribution := fmt.Sprintf("Audio generated by OpenAI TTS\n\n") - attribution += fmt.Sprintf("Bulgarian word: %s\n", word) - attribution += fmt.Sprintf("Model: %s\n", config.OpenAIModel) - attribution += fmt.Sprintf("Voice: %s\n", config.OpenAIVoice) - attribution += fmt.Sprintf("Speed: %.2f\n", config.OpenAISpeed) - - if config.OpenAIInstruction != "" { - attribution += fmt.Sprintf("\nVoice instructions:\n%s\n", config.OpenAIInstruction) - } - // Add preprocessing information cleanedWord := strings.TrimSpace(word) punctuationToRemove := []string{"!", "?", ".", ",", ";", ":", "\"", "'", "(", ")", "[", "]", "{", "}", "-", "—", "–"} @@ -746,12 +735,18 @@ func (p *Processor) saveAudioAttribution(word, audioFile string, config *audio.C cleanedWord = strings.ReplaceAll(cleanedWord, punct, "") } processedText := fmt.Sprintf("%s...", strings.TrimSpace(cleanedWord)) - attribution += fmt.Sprintf("\nProcessed text sent to TTS: %s\n", processedText) - - attribution += fmt.Sprintf("\nGenerated at: %s\n", time.Now().Format("2006-01-02 15:04:05")) + attribution := audio.BuildOpenAIAttribution(audio.AttributionParams{ + Word: word, + Model: config.OpenAIModel, + Voice: config.OpenAIVoice, + Speed: config.OpenAISpeed, + Instruction: config.OpenAIInstruction, + ProcessedText: processedText, + GeneratedAt: time.Now(), + }) // Save to file - attrPath := strings.TrimSuffix(audioFile, filepath.Ext(audioFile)) + "_attribution.txt" + attrPath := audio.AttributionPath(audioFile) if err := os.WriteFile(attrPath, []byte(attribution), 0644); err != nil { return fmt.Errorf("failed to write audio attribution file: %w", err) } |
