diff --git a/internal/dav/listing.go b/internal/dav/listing.go index cba0942..5b4f8fc 100644 --- a/internal/dav/listing.go +++ b/internal/dav/listing.go @@ -11,7 +11,7 @@ import ( "github.com/debridmediamanager/zurg/pkg/logutil" ) -func HandleListDirectories(torMgr *torrent.TorrentManager) (*string, error) { +func HandleListDirectories(torMgr *torrent.TorrentManager) ([]byte, error) { davDoc := "" davDoc += dav.BaseDirectory("", "") directories := torMgr.DirectoryMap.Keys() @@ -23,10 +23,10 @@ func HandleListDirectories(torMgr *torrent.TorrentManager) (*string, error) { davDoc += dav.Directory(directory, "") } davDoc += "" - return &davDoc, nil + return []byte(davDoc), nil } -func HandleListTorrents(directory string, torMgr *torrent.TorrentManager, log *logutil.Logger) (*string, error) { +func HandleListTorrents(directory string, torMgr *torrent.TorrentManager, log *logutil.Logger) ([]byte, error) { torrents, ok := torMgr.DirectoryMap.Get(directory) if !ok { return nil, fmt.Errorf("cannot find directory %s", directory) @@ -48,10 +48,10 @@ func HandleListTorrents(directory string, torMgr *torrent.TorrentManager, log *l davDoc += dav.Directory(tor.AccessKey, tor.LatestAdded) } davDoc += "" - return &davDoc, nil + return []byte(davDoc), nil } -func HandleListFiles(directory, torrentName string, torMgr *torrent.TorrentManager, log *logutil.Logger) (*string, error) { +func HandleListFiles(directory, torrentName string, torMgr *torrent.TorrentManager, log *logutil.Logger) ([]byte, error) { torrents, ok := torMgr.DirectoryMap.Get(directory) if !ok { return nil, fmt.Errorf("cannot find directory %s", directory) @@ -72,5 +72,24 @@ func HandleListFiles(directory, torrentName string, torMgr *torrent.TorrentManag davDoc += dav.File(filename, file.Bytes, file.Ended) } davDoc += "" - return &davDoc, nil + return []byte(davDoc), nil +} + +func HandlePropfindFile(directory, torrentName, fileName string, torMgr *torrent.TorrentManager, log *logutil.Logger) ([]byte, error) { + torrents, ok := torMgr.DirectoryMap.Get(directory) + if !ok { + return nil, fmt.Errorf("cannot find directory %s", directory) + } + tor, ok := torrents.Get(torrentName) + if !ok { + return nil, fmt.Errorf("cannot find torrent %s", torrentName) + } + file, ok := tor.SelectedFiles.Get(fileName) + if !ok || !strings.HasPrefix(file.Link, "http") { + return nil, fmt.Errorf("cannot find file %s", fileName) + } + davDoc := "" + dav.BaseDirectory(filepath.Join(directory, tor.AccessKey), tor.LatestAdded) + davDoc += dav.File(fileName, file.Bytes, file.Ended) + davDoc += "" + return []byte(davDoc), nil } diff --git a/internal/dav/rename.go b/internal/dav/rename.go new file mode 100644 index 0000000..d41d8ab --- /dev/null +++ b/internal/dav/rename.go @@ -0,0 +1,41 @@ +package dav + +import ( + "fmt" + + "github.com/debridmediamanager/zurg/internal/torrent" +) + +func HandleRenameTorrent(directory, torrentName, newName string, torMgr *torrent.TorrentManager) error { + torrents, ok := torMgr.DirectoryMap.Get(directory) + if !ok { + return fmt.Errorf("cannot find directory %s", directory) + } + torrent, ok := torrents.Get(torrentName) + if !ok { + return fmt.Errorf("cannot find torrent %s", torrentName) + } + torrents.Remove(torrentName) + torrents.Set(newName, torrent) + torrent.AccessKey = newName + return nil +} + +func HandleRenameFile(directory, torrentName, fileName, newName string, torMgr *torrent.TorrentManager) error { + torrents, ok := torMgr.DirectoryMap.Get(directory) + if !ok { + return fmt.Errorf("cannot find directory %s", directory) + } + torrent, ok := torrents.Get(torrentName) + if !ok { + return fmt.Errorf("cannot find torrent %s", torrentName) + } + file, ok := torrent.SelectedFiles.Get(fileName) + if !ok { + return fmt.Errorf("cannot find file %s", fileName) + } + torrent.SelectedFiles.Remove(torrentName) + torrent.SelectedFiles.Set(newName, file) + file.Path = newName + return nil +} diff --git a/internal/router/router.go b/internal/router/router.go index 3d8da38..c030645 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -4,6 +4,7 @@ import ( "fmt" "net/http" "os" + "path/filepath" "runtime" "strings" @@ -55,6 +56,12 @@ func ApplyRouteTable(router *httprouter.Router, getfile *universal.GetFile, torM // DELETE routes router.DELETE("/dav/:directory/:torrent/:file", zr.deleteFileHandler) router.DELETE("/dav/:directory/:torrent/", zr.deleteTorrentHandler) + // rename sequence + router.Handle("PROPFIND", "/dav/:directory/:torrent/:file", zr.propfindFileHandler) + router.Handle("MKCOL", "/dav/:directory/:torrent/", zr.mkcolTorrentHandler) + router.Handle("MOVE", "/dav/:directory/:torrent/:file", zr.moveFileHandler) + // MOVE routes + router.Handle("MOVE", "/dav/:directory/:torrent/", zr.moveTorrentHandler) // Global OPTIONS route router.GlobalOPTIONS = http.HandlerFunc(zr.globalOptionsHandler) @@ -65,6 +72,11 @@ func ApplyRouteTable(router *httprouter.Router, getfile *universal.GetFile, torM // logs route router.GET("/logs", zr.logsHandler) router.GET("/logs/", zr.logsHandler) + + router.MethodNotAllowed = http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { + zr.log.Debugf("Method Not Allowed: %s %s %v", req.Method, req.URL, req.Header) + http.Error(resp, "Method Not Allowed", http.StatusMethodNotAllowed) + }) } func (zr *ZurgRouter) httpTorrentDirectoryHandler(resp http.ResponseWriter, req *http.Request, params httprouter.Params) { @@ -103,6 +115,22 @@ func (zr *ZurgRouter) httpRootHandler(resp http.ResponseWriter, req *http.Reques fmt.Fprint(resp, *out) } +func (zr *ZurgRouter) propfindFileHandler(resp http.ResponseWriter, req *http.Request, params httprouter.Params) { + directory := params.ByName("directory") + torrentName := params.ByName("torrent") + fileName := params.ByName("file") + out, err := dav.HandlePropfindFile(directory, torrentName, fileName, zr.torMgr, zr.log) + if err != nil { + fmt.Println(">>>>>>>>>>>>>>>>>>>. not found", err) + http.Error(resp, "Not Found", http.StatusNotFound) + return + } + fmt.Println(">>>>>>>>>>>>>>>>>>>. found yey") + resp.Header().Set("Content-Type", "text/xml; charset=\"utf-8\"") + resp.WriteHeader(http.StatusOK) + resp.Write(out) +} + func (zr *ZurgRouter) propfindTorrentHandler(resp http.ResponseWriter, req *http.Request, params httprouter.Params) { directory := params.ByName("directory") torrentName := params.ByName("torrent") @@ -113,7 +141,7 @@ func (zr *ZurgRouter) propfindTorrentHandler(resp http.ResponseWriter, req *http } resp.Header().Set("Content-Type", "text/xml; charset=\"utf-8\"") resp.WriteHeader(http.StatusOK) - fmt.Fprint(resp, *out) + resp.Write(out) } func (zr *ZurgRouter) propfindDirectoryHandler(resp http.ResponseWriter, req *http.Request, params httprouter.Params) { @@ -125,7 +153,7 @@ func (zr *ZurgRouter) propfindDirectoryHandler(resp http.ResponseWriter, req *ht } resp.Header().Set("Content-Type", "text/xml; charset=\"utf-8\"") resp.WriteHeader(http.StatusOK) - fmt.Fprint(resp, *out) + resp.Write(out) } func (zr *ZurgRouter) propfindRootHandler(resp http.ResponseWriter, req *http.Request, params httprouter.Params) { @@ -136,7 +164,7 @@ func (zr *ZurgRouter) propfindRootHandler(resp http.ResponseWriter, req *http.Re } resp.Header().Set("Content-Type", "text/xml; charset=\"utf-8\"") resp.WriteHeader(http.StatusOK) - fmt.Fprint(resp, *out) + resp.Write(out) } func (zr *ZurgRouter) deleteFileHandler(resp http.ResponseWriter, req *http.Request, params httprouter.Params) { @@ -160,6 +188,39 @@ func (zr *ZurgRouter) deleteTorrentHandler(resp http.ResponseWriter, req *http.R resp.WriteHeader(http.StatusNoContent) } +func (zr *ZurgRouter) mkcolTorrentHandler(resp http.ResponseWriter, req *http.Request, params httprouter.Params) { + fmt.Println(">>>>>>>>>>>>>>>>>>> mkcolTorrentHandler") + resp.WriteHeader(http.StatusNoContent) +} + +func (zr *ZurgRouter) moveFileHandler(resp http.ResponseWriter, req *http.Request, params httprouter.Params) { + directory := params.ByName("directory") + torrentName := params.ByName("torrent") + fileName := params.ByName("file") + newName := req.Header.Get("Destination") + newName = filepath.Base(newName) + fmt.Println(">>>>>>>>>>>>>>>>>>> moveFileHandler", fileName, ">>>>>>>>", newName) + if dav.HandleRenameFile(directory, torrentName, fileName, newName, zr.torMgr) != nil { + fmt.Println(">>>>>>>>>>>>>>>>>>> moveFileHandler not found") + http.Error(resp, "Not Found", http.StatusNotFound) + return + } + fmt.Println(">>>>>>>>>>>>>>>>>>> moveFileHandler yay") + resp.WriteHeader(http.StatusNoContent) +} + +func (zr *ZurgRouter) moveTorrentHandler(resp http.ResponseWriter, req *http.Request, params httprouter.Params) { + directory := params.ByName("directory") + torrentName := params.ByName("torrent") + newName := req.Header.Get("Destination") + newName = filepath.Base(newName) + if dav.HandleRenameTorrent(directory, torrentName, newName, zr.torMgr) != nil { + http.Error(resp, "Not Found", http.StatusNotFound) + return + } + resp.WriteHeader(http.StatusNoContent) +} + func (zr *ZurgRouter) globalOptionsHandler(resp http.ResponseWriter, req *http.Request) { resp.WriteHeader(http.StatusOK) }