refactor
This commit is contained in:
parent
aedc4a4518
commit
9b0e2ed6dc
15 changed files with 693 additions and 540 deletions
137
internal/converter/converter.go
Normal file
137
internal/converter/converter.go
Normal file
|
@ -0,0 +1,137 @@
|
|||
package converter
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"sub-cli/internal/format/lrc"
|
||||
"sub-cli/internal/format/srt"
|
||||
"sub-cli/internal/model"
|
||||
)
|
||||
|
||||
// ErrUnsupportedFormat is returned when trying to convert to/from an unsupported format
|
||||
var ErrUnsupportedFormat = errors.New("unsupported format")
|
||||
|
||||
// Convert converts a file from one format to another
|
||||
func Convert(sourceFile, targetFile string) error {
|
||||
sourceFmt := strings.TrimPrefix(filepath.Ext(sourceFile), ".")
|
||||
targetFmt := strings.TrimPrefix(filepath.Ext(targetFile), ".")
|
||||
|
||||
switch sourceFmt {
|
||||
case "lrc":
|
||||
return convertFromLRC(sourceFile, targetFile, targetFmt)
|
||||
case "srt":
|
||||
return convertFromSRT(sourceFile, targetFile, targetFmt)
|
||||
default:
|
||||
return fmt.Errorf("%w: %s", ErrUnsupportedFormat, sourceFmt)
|
||||
}
|
||||
}
|
||||
|
||||
// convertFromLRC converts an LRC file to another format
|
||||
func convertFromLRC(sourceFile, targetFile, targetFmt string) error {
|
||||
sourceLyrics, err := lrc.Parse(sourceFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error parsing source LRC file: %w", err)
|
||||
}
|
||||
|
||||
switch targetFmt {
|
||||
case "txt":
|
||||
return lrcToTxt(sourceLyrics, targetFile)
|
||||
case "srt":
|
||||
return lrcToSRT(sourceLyrics, targetFile)
|
||||
case "lrc":
|
||||
return lrc.Generate(sourceLyrics, targetFile)
|
||||
default:
|
||||
return fmt.Errorf("%w: %s", ErrUnsupportedFormat, targetFmt)
|
||||
}
|
||||
}
|
||||
|
||||
// convertFromSRT converts an SRT file to another format
|
||||
func convertFromSRT(sourceFile, targetFile, targetFmt string) error {
|
||||
entries, err := srt.Parse(sourceFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error parsing source SRT file: %w", err)
|
||||
}
|
||||
|
||||
switch targetFmt {
|
||||
case "txt":
|
||||
return srtToTxt(entries, targetFile)
|
||||
case "lrc":
|
||||
lyrics := srt.ConvertToLyrics(entries)
|
||||
return lrc.Generate(lyrics, targetFile)
|
||||
case "srt":
|
||||
return srt.Generate(entries, targetFile)
|
||||
default:
|
||||
return fmt.Errorf("%w: %s", ErrUnsupportedFormat, targetFmt)
|
||||
}
|
||||
}
|
||||
|
||||
// lrcToTxt converts LRC lyrics to a plain text file
|
||||
func lrcToTxt(lyrics model.Lyrics, targetFile string) error {
|
||||
file, err := os.Create(targetFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating target file: %w", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
for _, content := range lyrics.Content {
|
||||
if _, err := fmt.Fprintln(file, content); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// lrcToSRT converts LRC lyrics to an SRT file
|
||||
func lrcToSRT(lyrics model.Lyrics, targetFile string) error {
|
||||
var entries []model.SRTEntry
|
||||
|
||||
for i, content := range lyrics.Content {
|
||||
if i >= len(lyrics.Timeline) {
|
||||
break
|
||||
}
|
||||
|
||||
startTime := lyrics.Timeline[i]
|
||||
endTime := startTime
|
||||
|
||||
// If there's a next timeline entry, use it for end time
|
||||
// Otherwise add a few seconds to the start time
|
||||
if i+1 < len(lyrics.Timeline) {
|
||||
endTime = lyrics.Timeline[i+1]
|
||||
} else {
|
||||
endTime.Seconds += 3
|
||||
}
|
||||
|
||||
entry := model.SRTEntry{
|
||||
Number: i + 1,
|
||||
StartTime: startTime,
|
||||
EndTime: endTime,
|
||||
Content: content,
|
||||
}
|
||||
|
||||
entries = append(entries, entry)
|
||||
}
|
||||
|
||||
return srt.Generate(entries, targetFile)
|
||||
}
|
||||
|
||||
// srtToTxt converts SRT entries to a plain text file
|
||||
func srtToTxt(entries []model.SRTEntry, targetFile string) error {
|
||||
file, err := os.Create(targetFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating target file: %w", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
for _, entry := range entries {
|
||||
if _, err := fmt.Fprintln(file, entry.Content); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue