mirror of https://github.com/stashapp/stash.git
107 lines
3.2 KiB
Go
107 lines
3.2 KiB
Go
package scene
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"golang.org/x/text/language"
|
|
|
|
"github.com/asticode/go-astisub"
|
|
"github.com/stashapp/stash/pkg/models"
|
|
)
|
|
|
|
var CaptionExts = []string{"vtt", "srt"} // in a case where vtt and srt files are both provided prioritize vtt file due to native support
|
|
|
|
// to be used for captions without a language code in the filename
|
|
// ISO 639-1 uses 2 or 3 a-z chars for codes so 00 is a safe non valid choise
|
|
// https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
|
|
const LangUnknown = "00"
|
|
|
|
// GetCaptionPath generates the path of a caption
|
|
// from a given file path, wanted language and caption sufffix
|
|
func GetCaptionPath(path, lang, suffix string) string {
|
|
ext := filepath.Ext(path)
|
|
fn := strings.TrimSuffix(path, ext)
|
|
captionExt := ""
|
|
if len(lang) == 0 || lang == LangUnknown {
|
|
captionExt = suffix
|
|
} else {
|
|
captionExt = lang + "." + suffix
|
|
}
|
|
return fn + "." + captionExt
|
|
}
|
|
|
|
// ReadSubs reads a captions file
|
|
func ReadSubs(path string) (*astisub.Subtitles, error) {
|
|
return astisub.OpenFile(path)
|
|
}
|
|
|
|
// IsValidLanguage checks whether the given string is a valid
|
|
// ISO 639 language code
|
|
func IsValidLanguage(lang string) bool {
|
|
_, err := language.ParseBase(lang)
|
|
return err == nil
|
|
}
|
|
|
|
// IsLangInCaptions returns true if lang is present
|
|
// in the captions
|
|
func IsLangInCaptions(lang string, ext string, captions []*models.SceneCaption) bool {
|
|
for _, caption := range captions {
|
|
if lang == caption.LanguageCode && ext == caption.CaptionType {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// GenerateCaptionCandidates generates a list of filenames with exts as extensions
|
|
// that can associated with the caption
|
|
func GenerateCaptionCandidates(captionPath string, exts []string) []string {
|
|
var candidates []string
|
|
|
|
basename := strings.TrimSuffix(captionPath, filepath.Ext(captionPath)) // caption filename without the extension
|
|
|
|
// a caption file can be something like scene_filename.srt or scene_filename.en.srt
|
|
// if a language code is present and valid remove it from the basename
|
|
languageExt := filepath.Ext(basename)
|
|
if len(languageExt) > 2 && IsValidLanguage(languageExt[1:]) {
|
|
basename = strings.TrimSuffix(basename, languageExt)
|
|
}
|
|
|
|
for _, ext := range exts {
|
|
candidates = append(candidates, basename+"."+ext)
|
|
}
|
|
|
|
return candidates
|
|
}
|
|
|
|
// GetCaptionsLangFromPath returns the language code from a given captions path
|
|
// If no valid language is present LangUknown is returned
|
|
func GetCaptionsLangFromPath(captionPath string) string {
|
|
langCode := LangUnknown
|
|
basename := strings.TrimSuffix(captionPath, filepath.Ext(captionPath)) // caption filename without the extension
|
|
languageExt := filepath.Ext(basename)
|
|
if len(languageExt) > 2 && IsValidLanguage(languageExt[1:]) {
|
|
langCode = languageExt[1:]
|
|
}
|
|
return langCode
|
|
}
|
|
|
|
// CleanCaptions removes non existent/accessible language codes from captions
|
|
func CleanCaptions(scenePath string, captions []*models.SceneCaption) (cleanedCaptions []*models.SceneCaption, changed bool) {
|
|
changed = false
|
|
for _, caption := range captions {
|
|
found := false
|
|
f := caption.Path(scenePath)
|
|
if _, er := os.Stat(f); er == nil {
|
|
cleanedCaptions = append(cleanedCaptions, caption)
|
|
found = true
|
|
}
|
|
if !found {
|
|
changed = true
|
|
}
|
|
}
|
|
return
|
|
}
|