diff --git a/internal/dav/infuse.go b/internal/dav/infuse.go
new file mode 100644
index 0000000..cfdfc7d
--- /dev/null
+++ b/internal/dav/infuse.go
@@ -0,0 +1,83 @@
+package dav
+
+import (
+ "bytes"
+ "fmt"
+ "sort"
+ "strings"
+
+ "github.com/debridmediamanager/zurg/internal/config"
+ "github.com/debridmediamanager/zurg/internal/torrent"
+ "github.com/debridmediamanager/zurg/pkg/dav"
+ "github.com/debridmediamanager/zurg/pkg/logutil"
+)
+
+func HandleInfuseListDirectories(torMgr *torrent.TorrentManager) ([]byte, error) {
+ var buf bytes.Buffer
+ buf.WriteString("")
+ directories := torMgr.DirectoryMap.Keys()
+ sort.Strings(directories)
+ for _, directory := range directories {
+ if strings.HasPrefix(directory, "int__") {
+ continue
+ }
+ buf.WriteString(dav.BaseDirectory(directory, ""))
+ }
+ buf.WriteString("")
+ return buf.Bytes(), nil
+}
+
+func HandleInfuseListTorrents(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)
+ }
+
+ var buf bytes.Buffer
+ buf.WriteString("")
+ torrentNames := torrents.Keys()
+ sort.Strings(torrentNames)
+ for _, torrentName := range torrentNames {
+ tor, ok := torrents.Get(torrentName)
+ if !ok || tor.AllInProgress() {
+ continue
+ }
+ buf.WriteString(dav.BaseDirectory(tor.AccessKey, tor.LatestAdded))
+ }
+ buf.WriteString("")
+ return buf.Bytes(), nil
+}
+
+func HandleInfuseListFiles(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)
+ }
+ tor, ok := torrents.Get(torrentName)
+ if !ok {
+ return nil, fmt.Errorf("cannot find torrent %s", torrentName)
+ }
+
+ dirCfg := torMgr.Config.(*config.ZurgConfigV1).GetDirectoryConfig(directory)
+ biggestFileSize := int64(0)
+ if dirCfg.OnlyShowTheBiggestFile {
+ biggestFileSize = tor.ComputeBiggestFileSize()
+ }
+
+ var buf bytes.Buffer
+ buf.WriteString("")
+ filenames := tor.SelectedFiles.Keys()
+ sort.Strings(filenames)
+ for _, filename := range filenames {
+ file, ok := tor.SelectedFiles.Get(filename)
+ if !ok || !strings.HasPrefix(file.Link, "http") {
+ continue
+ }
+ if dirCfg.OnlyShowTheBiggestFile && file.Bytes < biggestFileSize {
+ continue
+ }
+ buf.WriteString(dav.File(filename, file.Bytes, file.Ended))
+ }
+ buf.WriteString("")
+ return buf.Bytes(), nil
+}
diff --git a/internal/router/router.go b/internal/router/router.go
index 24e8c9c..3c02173 100644
--- a/internal/router/router.go
+++ b/internal/router/router.go
@@ -42,13 +42,13 @@ func ApplyRouteTable(router *httprouter.Router, getfile *universal.GetFile, torM
// dav router
router.GET("/dav/:directory/:torrent/:file", zr.universalDownloadFileHandler)
- router.GET("/dav/:directory/:torrent/", zr.propfindTorrentHandler)
- router.GET("/dav/:directory/", zr.propfindDirectoryHandler)
- router.GET("/dav/", zr.propfindRootHandler)
- // PROPFIND routes
router.Handle("PROPFIND", "/dav/:directory/:torrent/", zr.propfindTorrentHandler)
router.Handle("PROPFIND", "/dav/:directory/", zr.propfindDirectoryHandler)
router.Handle("PROPFIND", "/dav/", zr.propfindRootHandler)
+ // extras
+ router.GET("/dav/:directory/:torrent/", zr.propfindTorrentHandler)
+ router.GET("/dav/:directory/", zr.propfindDirectoryHandler)
+ router.GET("/dav/", zr.propfindRootHandler)
// DELETE routes
router.DELETE("/dav/:directory/:torrent/:file", zr.deleteFileHandler)
router.DELETE("/dav/:directory/:torrent/", zr.deleteTorrentHandler)
@@ -56,9 +56,14 @@ func ApplyRouteTable(router *httprouter.Router, getfile *universal.GetFile, torM
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)
+ // infuse routes
+ router.GET("/infuse/:directory/:torrent/:file", zr.universalDownloadFileHandler)
+ router.Handle("PROPFIND", "/infuse/:directory/:torrent/", zr.propfindInfuseTorrentHandler)
+ router.Handle("PROPFIND", "/infuse/:directory/", zr.propfindInfuseDirectoryHandler)
+ router.Handle("PROPFIND", "/infuse/", zr.propfindInfuseRootHandler)
+
// Global OPTIONS route
router.GlobalOPTIONS = http.HandlerFunc(zr.globalOptionsHandler)
@@ -70,8 +75,8 @@ func ApplyRouteTable(router *httprouter.Router, getfile *universal.GetFile, torM
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)
+ zr.log.Debugf("Method not allowed: %s %s %v", req.Method, req.URL, req.Header)
+ http.Error(resp, "Method not allowed", http.StatusMethodNotAllowed)
})
}
@@ -127,6 +132,42 @@ func (zr *ZurgRouter) propfindFileHandler(resp http.ResponseWriter, req *http.Re
resp.Write(out)
}
+func (zr *ZurgRouter) propfindInfuseTorrentHandler(resp http.ResponseWriter, req *http.Request, params httprouter.Params) {
+ directory := params.ByName("directory")
+ torrentName := params.ByName("torrent")
+ out, err := dav.HandleInfuseListFiles(directory, torrentName, zr.torMgr, zr.log)
+ if err != nil {
+ http.Error(resp, "Not Found", http.StatusNotFound)
+ return
+ }
+ resp.Header().Set("Content-Type", "text/xml; charset=\"utf-8\"")
+ resp.WriteHeader(http.StatusOK)
+ resp.Write(out)
+}
+
+func (zr *ZurgRouter) propfindInfuseDirectoryHandler(resp http.ResponseWriter, req *http.Request, params httprouter.Params) {
+ directory := params.ByName("directory")
+ out, err := dav.HandleInfuseListTorrents(directory, zr.torMgr, zr.log)
+ if err != nil {
+ http.Error(resp, "Not Found", http.StatusNotFound)
+ return
+ }
+ resp.Header().Set("Content-Type", "text/xml; charset=\"utf-8\"")
+ resp.WriteHeader(http.StatusOK)
+ resp.Write(out)
+}
+
+func (zr *ZurgRouter) propfindInfuseRootHandler(resp http.ResponseWriter, req *http.Request, params httprouter.Params) {
+ out, err := dav.HandleInfuseListDirectories(zr.torMgr)
+ if err != nil {
+ http.Error(resp, "Not Found", http.StatusNotFound)
+ return
+ }
+ 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")