diff --git a/pkg/storage/alist.go b/pkg/storage/alist.go index ab6a371c..579d601c 100644 --- a/pkg/storage/alist.go +++ b/pkg/storage/alist.go @@ -72,3 +72,7 @@ func (a *Alist) UploadProgress() float64 { } return a.progresser() } + +func (a *Alist) RemoveAll(path string) error { + return nil +} \ No newline at end of file diff --git a/pkg/storage/base.go b/pkg/storage/base.go index 7721491f..d2f35c47 100644 --- a/pkg/storage/base.go +++ b/pkg/storage/base.go @@ -20,6 +20,7 @@ type Storage interface { ReadFile(string) ([]byte, error) WriteFile(string, []byte) error UploadProgress() float64 + RemoveAll(path string) error } type uploadFunc func(destPath string, destInfo fs.FileInfo, srcReader io.Reader, mimeType *mimetype.MIME) error diff --git a/pkg/storage/local.go b/pkg/storage/local.go index c5a4b52f..2b8f7524 100644 --- a/pkg/storage/local.go +++ b/pkg/storage/local.go @@ -71,3 +71,7 @@ func (l *LocalStorage) WriteFile(name string, data []byte) error { func (l *LocalStorage) UploadProgress() float64 { return 0 } + +func (i *LocalStorage) RemoveAll(path string) error { + return os.RemoveAll(path) +} \ No newline at end of file diff --git a/pkg/storage/webdav.go b/pkg/storage/webdav.go index a9b690fe..493040ee 100644 --- a/pkg/storage/webdav.go +++ b/pkg/storage/webdav.go @@ -85,3 +85,7 @@ func (w *WebdavStorage) UploadProgress() float64 { } return w.progresser() } + +func (w *WebdavStorage) RemoveAll(path string) error { + return w.fs.RemoveAll(path) +} diff --git a/server/core/importlist.go b/server/core/importlist.go index eec7084b..2c0bbe18 100644 --- a/server/core/importlist.go +++ b/server/core/importlist.go @@ -323,7 +323,7 @@ func (c *Client) AddMovie2Watchlist(in AddWatchlistIn) (interface{}, error) { } func (c *Client) checkMovieFolder(m *ent.Media) error { - var storageImpl, err = c.getStorage(m.StorageID, media.MediaTypeMovie) + var storageImpl, err = c.GetStorage(m.StorageID, media.MediaTypeMovie) if err != nil { return err } diff --git a/server/core/integration.go b/server/core/integration.go index c0e02e27..f38f0331 100644 --- a/server/core/integration.go +++ b/server/core/integration.go @@ -35,7 +35,7 @@ func (c *Client) writeNfoFile(historyId int) error { } if md.MediaType == media.MediaTypeTv { //tvshow.nfo - st, err := c.getStorage(md.StorageID, media.MediaTypeTv) + st, err := c.GetStorage(md.StorageID, media.MediaTypeTv) if err != nil { return errors.Wrap(err, "get storage") } @@ -70,7 +70,7 @@ func (c *Client) writeNfoFile(historyId int) error { } } else if md.MediaType == media.MediaTypeMovie { //movie.nfo - st, err := c.getStorage(md.StorageID, media.MediaTypeMovie) + st, err := c.GetStorage(md.StorageID, media.MediaTypeMovie) if err != nil { return errors.Wrap(err, "get storage") } @@ -122,7 +122,7 @@ func (c *Client) writePlexmatch(historyId int) error { if series.MediaType != media.MediaTypeTv { //.plexmatch only support tv series return nil } - st, err := c.getStorage(series.StorageID, media.MediaTypeTv) + st, err := c.GetStorage(series.StorageID, media.MediaTypeTv) if err != nil { return errors.Wrap(err, "get storage") } @@ -197,7 +197,7 @@ func (c *Client) nfoSupportEnabled() bool { return c.db.GetSetting(db.SettingNfoSupportEnabled) == "true" } -func (c *Client) getStorage(storageId int, mediaType media.MediaType) (storage.Storage, error) { +func (c *Client) GetStorage(storageId int, mediaType media.MediaType) (storage.Storage, error) { st := c.db.GetStorage(storageId) targetPath := st.TvPath if mediaType == media.MediaTypeMovie { diff --git a/server/core/scheduler.go b/server/core/scheduler.go index 2da3bd3c..42d6d1a8 100644 --- a/server/core/scheduler.go +++ b/server/core/scheduler.go @@ -203,7 +203,7 @@ func (c *Client) moveCompletedTask(id int) (err1 error) { } st := c.db.GetStorage(series.StorageID) log.Infof("move task files to target dir: %v", r.TargetDir) - stImpl, err := c.getStorage(st.ID, series.MediaType) + stImpl, err := c.GetStorage(st.ID, series.MediaType) if err != nil { return err } @@ -243,7 +243,7 @@ func (c *Client) CheckDownloadedSeriesFiles(m *ent.Media) error { } log.Infof("check files in directory: %s", m.TargetDir) - var storageImpl, err = c.getStorage(m.StorageID, media.MediaTypeTv) + var storageImpl, err = c.GetStorage(m.StorageID, media.MediaTypeTv) if err != nil { return err } diff --git a/server/watchlist.go b/server/watchlist.go index 3b572a18..75de5885 100644 --- a/server/watchlist.go +++ b/server/watchlist.go @@ -10,6 +10,7 @@ import ( "polaris/log" "polaris/server/core" "strconv" + "strings" "github.com/gin-gonic/gin" "github.com/pkg/errors" @@ -170,9 +171,30 @@ func (s *Server) DeleteFromWatchlist(c *gin.Context) (interface{}, error) { if err != nil { return nil, errors.Wrap(err, "convert") } + + deleteFiles := c.Query("delete_files") + if strings.ToLower(deleteFiles) == "true" { + //will delete local media file + log.Infof("will delete local media files for %d", id) + m, err := s.db.GetMedia(id) + if err != nil { + log.Warnf("get media: %v", err) + } else { + st, err := s.core.GetStorage(m.StorageID, m.MediaType) + if err != nil { + log.Warnf("get storage error: %v", err) + } else { + if err := st.RemoveAll(m.TargetDir); err != nil { + log.Warnf("remove all : %v", err) + } + } + } + } + if err := s.db.DeleteMedia(id); err != nil { return nil, errors.Wrap(err, "delete db") } os.RemoveAll(filepath.Join(db.ImgPath, ids)) //delete image related + return "success", nil } diff --git a/ui/lib/providers/series_details.dart b/ui/lib/providers/series_details.dart index 5a6b35ac..977941b2 100644 --- a/ui/lib/providers/series_details.dart +++ b/ui/lib/providers/series_details.dart @@ -24,9 +24,9 @@ class SeriesDetailData return SeriesDetails.fromJson(rsp.data); } - Future delete() async { - final dio = await APIs.getDio(); - var resp = await dio.delete("${APIs.seriesDetailUrl}$id"); + Future delete(bool removeFiles ) async { + final dio = APIs.getDio(); + var resp = await dio.delete("${APIs.seriesDetailUrl}$id", queryParameters: {"delete_files": removeFiles}); var rsp = ServerResponse.fromJson(resp.data); if (rsp.code != 0) { throw rsp.message; diff --git a/ui/lib/widgets/detail_card.dart b/ui/lib/widgets/detail_card.dart index efa2127a..e52d4d6f 100644 --- a/ui/lib/widgets/detail_card.dart +++ b/ui/lib/widgets/detail_card.dart @@ -193,13 +193,25 @@ class _DetailCardState extends ConsumerState { } Future showConfirmDialog(BuildContext oriContext) { + var deleteFiles = false; return showDialog( context: context, barrierDismissible: true, builder: (BuildContext context) { return AlertDialog( - title: const Text("确认删除:"), - content: Text("${widget.details.name}"), + title: const Text("确认删除"), + content: StatefulBuilder(builder: (context, setState) { + return CheckboxListTile( + value: deleteFiles, + title: Text("删除媒体文件"), + onChanged: (v) { + setState( + () { + deleteFiles = v!; + }, + ); + }); + }), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(), @@ -209,7 +221,7 @@ class _DetailCardState extends ConsumerState { ref .read(mediaDetailsProvider(widget.details.id.toString()) .notifier) - .delete() + .delete(deleteFiles) .then((v) { if (oriContext.mounted) { oriContext.go(widget.details.mediaType == "tv"