feat: only accept video files and subtitles of known formats

This commit is contained in:
Simon Ding
2024-11-20 12:03:56 +08:00
parent c833f6fab6
commit 7b6dba1afe
9 changed files with 164 additions and 34 deletions

View File

@@ -20,8 +20,10 @@ const (
SettingMovieNamingFormat = "movie_naming_format"
SettingProwlarrInfo = "prowlarr_info"
SettingTvSizeLimiter = "tv_size_limiter"
SettingMovieSizeLimiter = "movie_size_limiter"
SettingTvSizeLimiter = "tv_size_limiter"
SettingMovieSizeLimiter = "movie_size_limiter"
SettingAcceptedVideoFormats = "accepted_video_formats"
SettingAcceptedSubtitleFormats = "accepted_subtitle_formats"
)
const (
@@ -44,6 +46,17 @@ const (
const DefaultNamingFormat = "{{.NameCN}} {{.NameEN}} {{if .Year}} ({{.Year}}) {{end}}"
//https://en.wikipedia.org/wiki/Video_file_format
var defaultAcceptedVideoFormats = []string{
".webm", ".mkv", ".flv", ".vob", ".ogv", ".ogg", ".drc", ".mng", ".avi", ".mts", ".m2ts",".ts",
".mov", ".qt", ".wmv", ".yuv", ".rm", ".rmvb", ".viv", ".amv", ".mp4", ".m4p", ".m4v",
".mpg", ".mp2", ".mpeg", ".mpe", ".mpv", ".m2v", ".m4v",
".svi", ".3gp", ".3g2", ".nsv",
}
var defaultAcceptedSubtitleFormats = []string{
".ass", ".srt",".vtt", ".webvtt", ".sub",
}
type NamingInfo struct {
NameCN string
NameEN string

View File

@@ -709,3 +709,53 @@ func (c *Client) SaveProwlarrSetting(se *ProwlarrSetting) error {
}
return c.SetSetting(SettingProwlarrInfo, string(data))
}
func (c *Client) getAcceptedFormats(key string) ([]string, error) {
v := c.GetSetting(key)
if v == "" {
return nil, nil
}
var res []string
err := json.Unmarshal([]byte(v), &res)
return res, err
}
func (c *Client) setAcceptedFormats(key string, v []string) error {
data, err := json.Marshal(v)
if err != nil {
return err
}
return c.SetSetting(key, string(data))
}
func (c *Client) GetAcceptedVideoFormats() ([]string, error) {
res, err := c.getAcceptedFormats(SettingAcceptedVideoFormats)
if err != nil {
return nil, err
}
if res == nil {
return defaultAcceptedVideoFormats, nil
}
return res, nil
}
func (c *Client) SetAcceptedVideoFormats(key string, v []string) error {
return c.setAcceptedFormats(SettingAcceptedVideoFormats, v)
}
func (c *Client) GetAcceptedSubtitleFormats() ([]string, error) {
res, err := c.getAcceptedFormats(SettingAcceptedSubtitleFormats)
if err != nil {
return nil, err
}
if res== nil {
return defaultAcceptedSubtitleFormats, nil
}
return res, nil
}
func (c *Client) SetAcceptedSubtitleFormats(key string, v []string) error {
return c.setAcceptedFormats(SettingAcceptedSubtitleFormats, v)
}

View File

@@ -10,20 +10,22 @@ import (
"github.com/gabriel-vasile/mimetype"
)
func NewAlist(cfg *alist.Config, dir string) (*Alist, error) {
func NewAlist(cfg *alist.Config, dir string, videoFormats []string, subtitleFormats []string) (*Alist, error) {
cl := alist.New(cfg)
_, err := cl.Login()
if err != nil {
return nil, err
}
return &Alist{baseDir: dir, cfg: cfg, client: cl}, nil
return &Alist{baseDir: dir, cfg: cfg, client: cl, videoFormats: videoFormats, subtitleFormats: subtitleFormats}, nil
}
type Alist struct {
baseDir string
cfg *alist.Config
client *alist.Client
progresser func() float64
baseDir string
cfg *alist.Config
client *alist.Client
progresser func() float64
videoFormats []string
subtitleFormats []string
}
func (a *Alist) Move(src, dest string) error {
@@ -34,7 +36,7 @@ func (a *Alist) Move(src, dest string) error {
}
func (a *Alist) Copy(src, dest string) error {
b, err := NewBase(src)
b, err := NewBase(src, a.videoFormats, a.subtitleFormats)
if err != nil {
return err
}

View File

@@ -7,10 +7,12 @@ import (
"path/filepath"
"polaris/log"
"polaris/pkg/utils"
"strings"
"github.com/gabriel-vasile/mimetype"
"github.com/pkg/errors"
)
type Storage interface {
Move(src, dest string) error
Copy(src, dest string) error
@@ -20,22 +22,66 @@ type Storage interface {
UploadProgress() float64
}
type uploadFunc func(destPath string, destInfo fs.FileInfo, srcReader io.Reader, mimeType *mimetype.MIME) error
type Base struct {
src string
totalSize int64
uploadedSize int64
src string
videoFormats []string
subtitleFormats []string
totalSize int64
uploadedSize int64
}
func NewBase(src string) (*Base, error) {
b := &Base{src: src}
func NewBase(src string, videoFormats []string, subtitleFormats []string) (*Base, error) {
b := &Base{src: src, videoFormats: videoFormats, subtitleFormats: subtitleFormats}
err := b.calculateSize()
return b, err
}
func (b *Base) checkVideoFilesExist() bool {
if len(b.videoFormats) == 0 { // do not check
return true
}
hasVideo := false
filepath.Walk(b.src, func(path string, info fs.FileInfo, err error) error {
ext := filepath.Ext(strings.ToLower(info.Name()))
for _, f := range b.videoFormats {
if f == ext {
hasVideo = true
}
}
return nil
})
return hasVideo
}
func (b *Base) isFileNeeded(name string) bool {
ext := filepath.Ext(strings.ToLower(name))
if len(b.videoFormats) == 0 {
return true
} else {
for _, f := range b.videoFormats {
if f == ext {
return true
}
}
}
if len(b.subtitleFormats) > 0 {
for _, f := range b.subtitleFormats {
if f == ext {
return true
}
}
}
return false
}
func (b *Base) Upload(destDir string, tryLink, detectMime, changeMediaHash bool, upload uploadFunc, mkdir func(string) error) error {
if !b.checkVideoFilesExist() {
return errors.Errorf("no video file")
}
os.MkdirAll(destDir, os.ModePerm)
targetBase := filepath.Join(destDir, filepath.Base(b.src)) //文件的场景,要加上文件名, move filename ./dir/
@@ -61,6 +107,10 @@ func (b *Base) Upload(destDir string, tryLink, detectMime, changeMediaHash bool,
if info.IsDir() {
mkdir(destName)
} else { //is file
if !b.isFileNeeded(info.Name()) {
log.Debugf("file is not needed, skip: %s", info.Name())
return nil
}
if tryLink {
if err := os.Link(path, destName); err == nil {
return nil //link success
@@ -116,12 +166,11 @@ func (b *Base) calculateSize() error {
}
func (b *Base) Progress() float64 {
return float64(b.uploadedSize)/float64(b.totalSize)
return float64(b.uploadedSize) / float64(b.totalSize)
}
type progressReader struct {
R io.Reader
R io.Reader
Add func(int)
}
@@ -129,4 +178,4 @@ func (pr *progressReader) Read(p []byte) (int, error) {
n, err := pr.R.Read(p)
pr.Add(n)
return n, err
}
}

View File

@@ -11,18 +11,19 @@ import (
"github.com/pkg/errors"
)
func NewLocalStorage(dir string) (*LocalStorage, error) {
func NewLocalStorage(dir string, videoFormats []string, subtitleFormats []string) (*LocalStorage, error) {
os.MkdirAll(dir, 0655)
return &LocalStorage{dir: dir}, nil
return &LocalStorage{dir: dir, videoFormats: videoFormats, subtitleFormats: subtitleFormats}, nil
}
type LocalStorage struct {
dir string
dir string
videoFormats []string
subtitleFormats []string
}
func (l *LocalStorage) Copy(src, destDir string) error {
b, err := NewBase(src)
b, err := NewBase(src, l.videoFormats, l.subtitleFormats)
if err != nil {
return err
}
@@ -69,4 +70,4 @@ func (l *LocalStorage) WriteFile(name string, data []byte) error {
func (l *LocalStorage) UploadProgress() float64 {
return 0
}
}

View File

@@ -16,10 +16,12 @@ type WebdavStorage struct {
fs *gowebdav.Client
dir string
changeMediaHash bool
progresser func() float64
progresser func() float64
videoFormats []string
subtitleFormats []string
}
func NewWebdavStorage(url, user, password, path string, changeMediaHash bool) (*WebdavStorage, error) {
func NewWebdavStorage(url, user, password, path string, changeMediaHash bool, videoFormats []string, subtitleFormats []string) (*WebdavStorage, error) {
c := gowebdav.NewClient(url, user, password)
if err := c.Connect(); err != nil {
return nil, errors.Wrap(err, "connect webdav")
@@ -27,11 +29,13 @@ func NewWebdavStorage(url, user, password, path string, changeMediaHash bool) (*
return &WebdavStorage{
fs: c,
dir: path,
videoFormats: videoFormats,
subtitleFormats: subtitleFormats,
}, nil
}
func (w *WebdavStorage) Copy(local, remoteDir string) error {
b, err := NewBase(local)
b, err := NewBase(local, w.videoFormats, w.subtitleFormats)
if err != nil {
return err
}
@@ -80,4 +84,4 @@ func (w *WebdavStorage) UploadProgress() float64 {
return 0
}
return w.progresser()
}
}

2
server/core/fliters.go Normal file
View File

@@ -0,0 +1,2 @@
package core

View File

@@ -203,11 +203,20 @@ func (c *Client) getStorage(storageId int, mediaType media.MediaType) (storage.S
if mediaType == media.MediaTypeMovie {
targetPath = st.MoviePath
}
videoFormats, err := c.db.GetAcceptedVideoFormats()
if err != nil {
log.Warnf("get accepted video format error: %v", err)
}
subtitleFormats, err := c.db.GetAcceptedSubtitleFormats()
if err != nil {
log.Warnf("get accepted subtitle format error: %v", err)
}
switch st.Implementation {
case storage1.ImplementationLocal:
storageImpl1, err := storage.NewLocalStorage(targetPath)
storageImpl1, err := storage.NewLocalStorage(targetPath, videoFormats, subtitleFormats)
if err != nil {
return nil, errors.Wrap(err, "new local")
}
@@ -215,14 +224,14 @@ func (c *Client) getStorage(storageId int, mediaType media.MediaType) (storage.S
case storage1.ImplementationWebdav:
ws := st.ToWebDavSetting()
storageImpl1, err := storage.NewWebdavStorage(ws.URL, ws.User, ws.Password, targetPath, ws.ChangeFileHash == "true")
storageImpl1, err := storage.NewWebdavStorage(ws.URL, ws.User, ws.Password, targetPath, ws.ChangeFileHash == "true", videoFormats, subtitleFormats)
if err != nil {
return nil, errors.Wrap(err, "new webdav")
}
return storageImpl1, nil
case storage1.ImplementationAlist:
cfg := st.ToWebDavSetting()
storageImpl1, err := storage.NewAlist(&alist.Config{URL: cfg.URL, Username: cfg.User, Password: cfg.Password}, targetPath)
storageImpl1, err := storage.NewAlist(&alist.Config{URL: cfg.URL, Username: cfg.User, Password: cfg.Password}, targetPath, videoFormats, subtitleFormats)
if err != nil {
return nil, errors.Wrap(err, "alist")
}

View File

@@ -30,7 +30,7 @@ func (s *Server) AddStorage(c *gin.Context) (interface{}, error) {
if in.Implementation == "webdav" {
//test webdav
wd := in.ToWebDavSetting()
st, err := storage.NewWebdavStorage(wd.URL, wd.User, wd.Password, in.TvPath, false)
st, err := storage.NewWebdavStorage(wd.URL, wd.User, wd.Password, in.TvPath, false, nil, nil)
if err != nil {
return nil, errors.Wrap(err, "new webdav")
}
@@ -43,7 +43,7 @@ func (s *Server) AddStorage(c *gin.Context) (interface{}, error) {
}
} else if in.Implementation == "alist" {
cfg := in.ToAlistSetting()
_, err := storage.NewAlist(&alist.Config{URL: cfg.URL, Username: cfg.User, Password: cfg.Password}, in.TvPath)
_, err := storage.NewAlist(&alist.Config{URL: cfg.URL, Username: cfg.User, Password: cfg.Password}, in.TvPath, nil, nil)
if err != nil {
return nil, errors.Wrap(err, "alist")
}