diff --git a/db/db.go b/db/db.go index a05cb83..46f1de5 100644 --- a/db/db.go +++ b/db/db.go @@ -311,11 +311,12 @@ type LocalDirSetting struct { } type WebdavSetting struct { - URL string `json:"url"` - TvPath string `json:"tv_path"` - MoviePath string `json:"movie_path"` - User string `json:"user"` - Password string `json:"password"` + URL string `json:"url"` + TvPath string `json:"tv_path"` + MoviePath string `json:"movie_path"` + User string `json:"user"` + Password string `json:"password"` + ChangeFileHash string `json:"change_file_hash"` } func (c *Client) AddStorage(st *StorageInfo) error { diff --git a/pkg/storage/webdav.go b/pkg/storage/webdav.go index 7d7089f..632bde7 100644 --- a/pkg/storage/webdav.go +++ b/pkg/storage/webdav.go @@ -7,6 +7,7 @@ import ( "path/filepath" "polaris/log" "polaris/pkg/gowebdav" + "polaris/pkg/utils" "github.com/gabriel-vasile/mimetype" "github.com/pkg/errors" @@ -15,9 +16,10 @@ import ( type WebdavStorage struct { fs *gowebdav.Client dir string + changeMediaHash bool } -func NewWebdavStorage(url, user, password, path string) (*WebdavStorage, error) { +func NewWebdavStorage(url, user, password, path string, changeMediaHash bool) (*WebdavStorage, error) { c := gowebdav.NewClient(url, user, password) if err := c.Connect(); err != nil { return nil, errors.Wrap(err, "connect webdav") @@ -53,6 +55,11 @@ func (w *WebdavStorage) Move(local, remote string) error { // } } else { //is file + if w.changeMediaHash { + if err := utils.ChangeFileHash(path); err != nil { + log.Errorf("change file %v hash error: %v", path, err) + } + } if f, err := os.OpenFile(path, os.O_RDONLY, 0666); err != nil { return errors.Wrapf(err, "read file %v", path) } else { //open success diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 3b1b412..7fcde68 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -1,6 +1,7 @@ package utils import ( + "os" "regexp" "strconv" "strings" @@ -146,3 +147,16 @@ func AvailableSpace(dir string) uint64 { unix.Statfs(dir, &stat) return stat.Bavail * uint64(stat.Bsize) } + +func ChangeFileHash(name string) error { + f, err := os.OpenFile(name, os.O_APPEND|os.O_WRONLY, 0655) + if err != nil { + return errors.Wrap(err, "open file") + } + defer f.Close() + _, err = f.Write([]byte("\000")) + if err != nil { + return errors.Wrap(err, "write file") + } + return nil +} diff --git a/server/scheduler.go b/server/scheduler.go index ab2fcbe..18dfbb4 100644 --- a/server/scheduler.go +++ b/server/scheduler.go @@ -101,7 +101,7 @@ func (s *Server) moveCompletedTask(id int) (err1 error) { if series.MediaType == media.MediaTypeMovie { targetPath = ws.MoviePath } - storageImpl, err := storage.NewWebdavStorage(ws.URL, ws.User, ws.Password, targetPath) + storageImpl, err := storage.NewWebdavStorage(ws.URL, ws.User, ws.Password, targetPath, ws.ChangeFileHash == "true") if err != nil { return errors.Wrap(err, "new webdav") } @@ -162,7 +162,7 @@ func (s *Server) checkDownloadedSeriesFiles(m *ent.Media) error { case storage1.ImplementationWebdav: ws := st.ToWebDavSetting() targetPath := ws.TvPath - storageImpl1, err := storage.NewWebdavStorage(ws.URL, ws.User, ws.Password, targetPath) + storageImpl1, err := storage.NewWebdavStorage(ws.URL, ws.User, ws.Password, targetPath, ws.ChangeFileHash == "true") if err != nil { return errors.Wrap(err, "new webdav") } diff --git a/ui/lib/providers/settings.dart b/ui/lib/providers/settings.dart index f047f4f..3da910b 100644 --- a/ui/lib/providers/settings.dart +++ b/ui/lib/providers/settings.dart @@ -258,7 +258,12 @@ class StorageSettingData extends AutoDisposeAsyncNotifier> { class Storage { Storage( - {this.id, this.name, this.implementation, this.settings, this.isDefault}); + {this.id, + this.name, + this.implementation, + this.settings, + this.isDefault, + }); final int? id; final String? name; diff --git a/ui/lib/system_settings.dart b/ui/lib/system_settings.dart index b03e5b4..63d2b7f 100644 --- a/ui/lib/system_settings.dart +++ b/ui/lib/system_settings.dart @@ -386,12 +386,15 @@ class _SystemSettingsPageState extends ConsumerState { var urlController = TextEditingController(); var userController = TextEditingController(); var passController = TextEditingController(); + bool enablingChangeFileHash = false; if (s.settings != null) { tvPathController.text = s.settings!["tv_path"] ?? ""; moviePathController.text = s.settings!["movie_path"] ?? ""; urlController.text = s.settings!["url"] ?? ""; userController.text = s.settings!["user"] ?? ""; passController.text = s.settings!["password"] ?? ""; + enablingChangeFileHash = + s.settings!["change_file_hash"] == "true" ? true : false; } String selectImpl = s.implementation == null ? "local" : s.implementation!; @@ -419,7 +422,7 @@ class _SystemSettingsPageState extends ConsumerState { ), selectImpl != "local" ? Column( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ TextField( decoration: const InputDecoration(labelText: "Webdav地址"), @@ -433,6 +436,14 @@ class _SystemSettingsPageState extends ConsumerState { decoration: const InputDecoration(labelText: "密码"), controller: passController, ), + CheckboxListTile( + title: const Text("上传时更改文件哈希", style: TextStyle(fontSize: 14),), + value: enablingChangeFileHash, + onChanged: (v) { + setState(() { + enablingChangeFileHash = v??false; + }); + }), ], ) : Container(), @@ -456,7 +467,8 @@ class _SystemSettingsPageState extends ConsumerState { "movie_path": moviePathController.text, "url": urlController.text, "user": userController.text, - "password": passController.text + "password": passController.text, + "change_file_hash": enablingChangeFileHash ? "true" : "false" }, )); }