273 lines
5.9 KiB
Go
273 lines
5.9 KiB
Go
package task_pack_release
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"slices"
|
|
"strings"
|
|
"text/template"
|
|
)
|
|
|
|
type NfoCreatorSettings struct {
|
|
Title string
|
|
Infos []*KeyValue
|
|
Notes string
|
|
}
|
|
|
|
type KeyValue struct {
|
|
Key string
|
|
Value string
|
|
}
|
|
|
|
type nfoTemplateData struct {
|
|
Title1 string
|
|
Title2 string
|
|
Infos []string
|
|
Notes []string
|
|
}
|
|
|
|
func CreateNfo(dstPath string, settings *NfoCreatorSettings) (string, error) {
|
|
maxAllowedWidth := 65
|
|
|
|
// Prepare
|
|
nfoTemplateData := &nfoTemplateData{}
|
|
|
|
// Handle the title
|
|
title := strings.ReplaceAll(settings.Title, " ", ".")
|
|
title = strings.ReplaceAll(title, "(", "")
|
|
title = strings.ReplaceAll(title, ")", "")
|
|
title = strings.ReplaceAll(title, ",", "")
|
|
title = strings.ReplaceAll(title, "&", "")
|
|
title = strings.ReplaceAll(title, "..", ".")
|
|
nfoTemplateData.Title1 = title
|
|
nfoTemplateData.Title2 = ""
|
|
if len(title) > maxAllowedWidth {
|
|
splitIndex := strings.LastIndexAny(title[:maxAllowedWidth], ".-")
|
|
nfoTemplateData.Title1 = title[:splitIndex]
|
|
nfoTemplateData.Title2 = title[splitIndex:]
|
|
}
|
|
nfoTemplateData.Title1 = fmt.Sprintf("%-*s", maxAllowedWidth, nfoTemplateData.Title1)
|
|
nfoTemplateData.Title2 = fmt.Sprintf("%-*s", maxAllowedWidth, nfoTemplateData.Title2)
|
|
|
|
// Handle Infos
|
|
maxKey := slices.MaxFunc(settings.Infos, func(a, b *KeyValue) int {
|
|
if len(a.Key) < len(b.Key) {
|
|
return -1
|
|
} else if len(a.Key) > len(b.Key) {
|
|
return 1
|
|
}
|
|
return 0
|
|
})
|
|
maxKeyLen := len(maxKey.Key)
|
|
for _, info := range settings.Infos {
|
|
nfoTemplateData.Infos = append(nfoTemplateData.Infos, fmt.Sprintf("%-*s : %-*s", maxKeyLen, info.Key, maxAllowedWidth-maxKeyLen-3, info.Value))
|
|
}
|
|
|
|
// Handle Notes
|
|
noteLines := strings.SplitSeq(settings.Notes, "\n")
|
|
for note := range noteLines {
|
|
if len(note) > maxAllowedWidth {
|
|
splitIndex := strings.LastIndexAny(note[:maxAllowedWidth], " ")
|
|
nfoTemplateData.Notes = append(nfoTemplateData.Notes, fmt.Sprintf("%-*s", maxAllowedWidth, note[:splitIndex]))
|
|
nfoTemplateData.Notes = append(nfoTemplateData.Notes, fmt.Sprintf("%-*s", maxAllowedWidth, note[splitIndex+1:]))
|
|
} else {
|
|
nfoTemplateData.Notes = append(nfoTemplateData.Notes, fmt.Sprintf("%-*s", maxAllowedWidth, note))
|
|
}
|
|
}
|
|
|
|
// Parse the template file
|
|
t1, err := template.New("info.nfo.tmpl").ParseFiles("./task_pack_release/info.nfo.tmpl")
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
// Execute the template to a memory buffer
|
|
var buf bytes.Buffer
|
|
if err := t1.Execute(&buf, nfoTemplateData); err != nil {
|
|
return "", err
|
|
}
|
|
|
|
// Convert the buffer to string
|
|
content := buf.String()
|
|
|
|
os.MkdirAll(dstPath, os.ModePerm)
|
|
nfoFilePath := filepath.Join(dstPath, fmt.Sprintf("%s.nfo", title))
|
|
if err := os.WriteFile(nfoFilePath, []byte(content), os.ModePerm); err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return nfoFilePath, nil
|
|
}
|
|
|
|
const (
|
|
WebDL = "WEB-DL"
|
|
DvdRip = "DVDRip"
|
|
Bluray = "BluRay"
|
|
Dvd = "DVD"
|
|
YouTube = "YouTube"
|
|
)
|
|
|
|
type TitleBuilder struct {
|
|
title string
|
|
season string
|
|
language string
|
|
quality string
|
|
resolution string
|
|
codec string
|
|
version string
|
|
dubbed bool
|
|
dualLanguage bool
|
|
enhanced bool
|
|
complete bool
|
|
extras bool
|
|
year string
|
|
episodes string
|
|
}
|
|
|
|
// Constructor
|
|
func NewTitleBuilder(title string) *TitleBuilder {
|
|
return &TitleBuilder{title: title}
|
|
}
|
|
|
|
func (t *TitleBuilder) Year(value int) *TitleBuilder {
|
|
t.year = fmt.Sprintf("(%d)", value)
|
|
return t
|
|
}
|
|
|
|
func (t *TitleBuilder) Season(value int) *TitleBuilder {
|
|
t.season = fmt.Sprintf("S%02d", value)
|
|
return t
|
|
}
|
|
|
|
func (t *TitleBuilder) EpisodeRange(first, last int) *TitleBuilder {
|
|
t.episodes = fmt.Sprintf("E%02d-E%02d", first, last)
|
|
return t
|
|
}
|
|
|
|
func (t *TitleBuilder) German() *TitleBuilder {
|
|
t.language = "German"
|
|
return t
|
|
}
|
|
|
|
func (t *TitleBuilder) Complete() *TitleBuilder {
|
|
t.complete = true
|
|
return t
|
|
}
|
|
|
|
func (t *TitleBuilder) Dubbed() *TitleBuilder {
|
|
t.dubbed = true
|
|
return t
|
|
}
|
|
|
|
func (t *TitleBuilder) Dual() *TitleBuilder {
|
|
t.dualLanguage = true
|
|
return t
|
|
}
|
|
|
|
func (t *TitleBuilder) Enhanced() *TitleBuilder {
|
|
t.enhanced = true
|
|
return t
|
|
}
|
|
|
|
func (t *TitleBuilder) Extras() *TitleBuilder {
|
|
t.extras = true
|
|
return t
|
|
}
|
|
|
|
func (t *TitleBuilder) WebDL() *TitleBuilder {
|
|
t.quality = WebDL
|
|
return t
|
|
}
|
|
|
|
func (t *TitleBuilder) DVDRip() *TitleBuilder {
|
|
t.quality = DvdRip
|
|
return t
|
|
}
|
|
|
|
func (t *TitleBuilder) Bluray() *TitleBuilder {
|
|
t.quality = Bluray
|
|
return t
|
|
}
|
|
|
|
func (t *TitleBuilder) R480() *TitleBuilder {
|
|
t.resolution = "480p"
|
|
return t
|
|
}
|
|
|
|
func (t *TitleBuilder) R576() *TitleBuilder {
|
|
t.resolution = "576p"
|
|
return t
|
|
}
|
|
|
|
func (t *TitleBuilder) R720p() *TitleBuilder {
|
|
t.resolution = "720p"
|
|
return t
|
|
}
|
|
|
|
func (t *TitleBuilder) R1080p() *TitleBuilder {
|
|
t.resolution = "1080p"
|
|
return t
|
|
}
|
|
|
|
func (t *TitleBuilder) X264() *TitleBuilder {
|
|
t.codec = "x264"
|
|
return t
|
|
}
|
|
|
|
func (t *TitleBuilder) ReleaseVersion(version string) *TitleBuilder {
|
|
t.version = fmt.Sprintf("v%s", version)
|
|
return t
|
|
}
|
|
|
|
func (t *TitleBuilder) Build() string {
|
|
var sb strings.Builder
|
|
|
|
// Replace German umlauts
|
|
title := strings.NewReplacer(
|
|
"ö", "oe",
|
|
"ä", "ae",
|
|
"ü", "ue",
|
|
).Replace(t.title)
|
|
|
|
sb.WriteString(title)
|
|
addIfTrue(&sb, t.extras, "Extras")
|
|
addIfNotEmpty(&sb, t.year, false)
|
|
hasSeason := addIfNotEmpty(&sb, t.season, false)
|
|
addIfNotEmpty(&sb, t.episodes, hasSeason)
|
|
addIfTrue(&sb, t.complete, "Complete")
|
|
addIfNotEmpty(&sb, t.language, false)
|
|
addIfTrue(&sb, t.dubbed, "Dubbed")
|
|
addIfTrue(&sb, t.dualLanguage, "DL")
|
|
addIfNotEmpty(&sb, t.quality, false)
|
|
addIfNotEmpty(&sb, t.resolution, false)
|
|
addIfTrue(&sb, t.enhanced, "Enhanced")
|
|
addIfNotEmpty(&sb, t.codec, false)
|
|
addIfNotEmpty(&sb, t.version, false)
|
|
|
|
sb.WriteString("-Roemer")
|
|
|
|
return sb.String()
|
|
}
|
|
|
|
func addIfNotEmpty(sb *strings.Builder, value string, skipDot bool) bool {
|
|
if strings.TrimSpace(value) != "" {
|
|
if !skipDot {
|
|
sb.WriteString(".")
|
|
}
|
|
sb.WriteString(value)
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func addIfTrue(sb *strings.Builder, value bool, text string) bool {
|
|
if value {
|
|
sb.WriteString(".")
|
|
sb.WriteString(text)
|
|
return true
|
|
}
|
|
return false
|
|
}
|