feat: movie also requires suggested dir

This commit is contained in:
Simon Ding
2024-07-30 10:50:40 +08:00
parent ba532d406a
commit 2c8c715540
5 changed files with 71 additions and 65 deletions

View File

@@ -26,10 +26,20 @@ type LocalStorage struct {
dir string dir string
} }
func (l *LocalStorage) Move(src, dest string) error { func (l *LocalStorage) Move(src, destDir string) error {
targetDir := filepath.Join(l.dir, dest) os.MkdirAll(filepath.Join(l.dir, destDir), os.ModePerm)
os.MkdirAll(filepath.Dir(targetDir), os.ModePerm)
err := filepath.Walk(src, func(path string, info fs.FileInfo, err error) error { targetBase := filepath.Join(l.dir, destDir, filepath.Base(src)) //文件的场景,要加上文件名, move filename ./dir/
info, err := os.Stat(src)
if err != nil {
return errors.Wrap(err, "read source dir")
}
if info.IsDir() { //如果是路径,则只移动路径里面的文件,不管当前路径, 行为类似 move dirname/* target_dir/
targetBase = filepath.Join(l.dir, destDir)
}
err = filepath.Walk(src, func(path string, info fs.FileInfo, err error) error {
if err != nil { if err != nil {
return err return err
} }
@@ -37,7 +47,7 @@ func (l *LocalStorage) Move(src, dest string) error {
if err != nil { if err != nil {
return errors.Wrapf(err, "relation between %s and %s", src, path) return errors.Wrapf(err, "relation between %s and %s", src, path)
} }
destName := filepath.Join(targetDir, rel) destName := filepath.Join(targetBase, rel)
if info.IsDir() { if info.IsDir() {
os.Mkdir(destName, os.ModePerm) os.Mkdir(destName, os.ModePerm)

View File

@@ -30,13 +30,20 @@ func NewWebdavStorage(url, user, password, path string, changeMediaHash bool) (*
}, nil }, nil
} }
func (w *WebdavStorage) Move(local, remote string) error { func (w *WebdavStorage) Move(local, remoteDir string) error {
remoteBase := filepath.Join(w.dir,remote) remoteBase := filepath.Join(w.dir,remoteDir, filepath.Base(local))
info, err := os.Stat(local)
if err != nil {
return errors.Wrap(err, "read source dir")
}
if info.IsDir() { //如果是路径,则只移动路径里面的文件,不管当前路径, 行为类似 move dirname/* target_dir/
remoteBase = filepath.Join(w.dir, remoteDir)
}
//log.Infof("remove all content in %s", remoteBase) //log.Infof("remove all content in %s", remoteBase)
//w.fs.RemoveAll(remoteBase) //w.fs.RemoveAll(remoteBase)
err := filepath.Walk(local, func(path string, info fs.FileInfo, err error) error { err = filepath.Walk(local, func(path string, info fs.FileInfo, err error) error {
if err != nil { if err != nil {
return errors.Wrapf(err, "read file %v", path) return errors.Wrapf(err, "read file %v", path)
} }

View File

@@ -128,18 +128,10 @@ func (s *Server) moveCompletedTask(id int) (err1 error) {
stImpl = storageImpl stImpl = storageImpl
} }
if r.EpisodeID == 0 {
//season package download
if err := stImpl.Move(filepath.Join(s.db.GetDownloadDir(), torrent.Name()), r.TargetDir); err != nil {
return errors.Wrap(err, "move file")
} //如果种子是路径,则会把路径展开,只移动文件,类似 move dir/* dir2/, 如果种子是文件,则会直接移动文件,类似 move file dir/
if err := stImpl.Move(filepath.Join(s.db.GetDownloadDir(), torrent.Name()), r.TargetDir); err != nil {
} else { return errors.Wrap(err, "move file")
if err := stImpl.Move(filepath.Join(s.db.GetDownloadDir(), torrent.Name()), filepath.Join(r.TargetDir, torrent.Name())); err != nil {
return errors.Wrap(err, "move file")
}
} }
log.Infof("move downloaded files to target dir success, file: %v, target dir: %v", torrent.Name(), r.TargetDir) log.Infof("move downloaded files to target dir success, file: %v, target dir: %v", torrent.Name(), r.TargetDir)

View File

@@ -60,7 +60,7 @@ type addWatchlistIn struct {
TmdbID int `json:"tmdb_id" binding:"required"` TmdbID int `json:"tmdb_id" binding:"required"`
StorageID int `json:"storage_id" ` StorageID int `json:"storage_id" `
Resolution string `json:"resolution" binding:"required"` Resolution string `json:"resolution" binding:"required"`
Folder string `json:"folder"` Folder string `json:"folder" binding:"required"`
DownloadHistoryEpisodes bool `json:"download_history_episodes"` //for tv DownloadHistoryEpisodes bool `json:"download_history_episodes"` //for tv
} }
@@ -187,7 +187,7 @@ func (s *Server) AddMovie2Watchlist(c *gin.Context) (interface{}, error) {
AirDate: detail.ReleaseDate, AirDate: detail.ReleaseDate,
Resolution: media.Resolution(in.Resolution), Resolution: media.Resolution(in.Resolution),
StorageID: in.StorageID, StorageID: in.StorageID,
TargetDir: "./", TargetDir: in.Folder,
}, []int{epid}) }, []int{epid})
if err != nil { if err != nil {
return nil, errors.Wrap(err, "add to list") return nil, errors.Wrap(err, "add to list")

View File

@@ -30,13 +30,15 @@ class _SearchPageState extends ConsumerState<SearchPage> {
List<Widget> res = searchList.when( List<Widget> res = searchList.when(
data: (data) { data: (data) {
if (data.isEmpty) { if (data.isEmpty) {
return [Container( return [
height: MediaQuery.of(context).size.height * 0.6, Container(
alignment: Alignment.center, height: MediaQuery.of(context).size.height * 0.6,
child: const Text( alignment: Alignment.center,
"啥都没有...", child: const Text(
style: TextStyle(fontSize: 16), "啥都没有...",
))]; style: TextStyle(fontSize: 16),
))
];
} }
var cards = List<Widget>.empty(growable: true); var cards = List<Widget>.empty(growable: true);
for (final item in data) { for (final item in data) {
@@ -202,44 +204,39 @@ class _SearchPageState extends ConsumerState<SearchPage> {
}); });
}, },
), ),
item.mediaType == "tv" name.when(
? name.when( data: (s) {
data: (s) { return storageSelected == 0
return storageSelected == 0 ? const Text("")
? const Text("") : () {
: () { final storage = v
final storage = v .where((e) =>
.where((e) => e.id == storageSelected)
e.id == .first;
storageSelected) final path = item.mediaType ==
.first; "tv"
final path = storage ? storage.settings!["tv_path"]
.settings!["tv_path"]; : storage
.settings!["movie_path"];
pathController.text = s; pathController.text = s;
return SizedBox( return SizedBox(
//width: 300, //width: 300,
child: TextField( child: TextField(
controller: controller: pathController,
pathController, decoration: InputDecoration(
decoration: labelText: "存储路径",
InputDecoration( prefix: Text(path)),
labelText: ),
"存储路径", );
prefix: }();
Text(path)), },
), error: (error, stackTrace) =>
); Text("$error"),
}(); loading: () => const MyProgressIndicator(
}, size: 20,
error: (error, stackTrace) => ),
Text("$error"), ),
loading: () =>
const MyProgressIndicator(
size: 20,
),
)
: Text(""),
item.mediaType == "tv" item.mediaType == "tv"
? SizedBox( ? SizedBox(
width: 250, width: 250,