diff --git a/db/const.go b/db/const.go index a22ac5f..d49e886 100644 --- a/db/const.go +++ b/db/const.go @@ -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 diff --git a/db/db.go b/db/db.go index 8a94684..800c73a 100644 --- a/db/db.go +++ b/db/db.go @@ -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) +} \ No newline at end of file diff --git a/pkg/storage/alist.go b/pkg/storage/alist.go index f91b76a..ab6a371 100644 --- a/pkg/storage/alist.go +++ b/pkg/storage/alist.go @@ -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 } diff --git a/pkg/storage/base.go b/pkg/storage/base.go index cf3b5db..4df564d 100644 --- a/pkg/storage/base.go +++ b/pkg/storage/base.go @@ -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 -} \ No newline at end of file +} diff --git a/pkg/storage/local.go b/pkg/storage/local.go index b0042e1..c5a4b52 100644 --- a/pkg/storage/local.go +++ b/pkg/storage/local.go @@ -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 -} \ No newline at end of file +} diff --git a/pkg/storage/webdav.go b/pkg/storage/webdav.go index 00b31d4..a9b690f 100644 --- a/pkg/storage/webdav.go +++ b/pkg/storage/webdav.go @@ -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() -} \ No newline at end of file +} diff --git a/server/core/fliters.go b/server/core/fliters.go new file mode 100644 index 0000000..25dcb76 --- /dev/null +++ b/server/core/fliters.go @@ -0,0 +1,2 @@ +package core + diff --git a/server/core/integration.go b/server/core/integration.go index 87c2073..c0e02e2 100644 --- a/server/core/integration.go +++ b/server/core/integration.go @@ -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") } diff --git a/server/storage.go b/server/storage.go index fa8987d..0f6fc12 100644 --- a/server/storage.go +++ b/server/storage.go @@ -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") }