Files
zurg/internal/router/router.go
2023-11-30 23:08:16 +01:00

203 lines
7.1 KiB
Go

package router
import (
"encoding/json"
"fmt"
"net/http"
"github.com/debridmediamanager/zurg/internal/config"
"github.com/debridmediamanager/zurg/internal/dav"
intHttp "github.com/debridmediamanager/zurg/internal/http"
"github.com/debridmediamanager/zurg/internal/torrent"
"github.com/debridmediamanager/zurg/internal/universal"
"github.com/debridmediamanager/zurg/internal/version"
"github.com/debridmediamanager/zurg/pkg/realdebrid"
"github.com/julienschmidt/httprouter"
"go.uber.org/zap"
)
type ZurgRouter struct {
getfile *universal.GetFile
torMgr *torrent.TorrentManager
cfg config.ConfigInterface
api *realdebrid.RealDebrid
log *zap.SugaredLogger
}
func ApplyRouteTable(router *httprouter.Router, getfile *universal.GetFile, torMgr *torrent.TorrentManager, cfg config.ConfigInterface, api *realdebrid.RealDebrid, log *zap.SugaredLogger) {
zr := &ZurgRouter{
getfile: getfile,
torMgr: torMgr,
cfg: cfg,
api: api,
log: log,
}
// http router
router.GET("/http/:directory/:torrent/:file", zr.universalDownloadFileHandler)
router.GET("/http/:directory/:torrent/", zr.httpTorrentDirectoryHandler)
router.GET("/http/:directory/", zr.httpDirectoryHandler)
router.GET("/http/", zr.httpRootHandler)
// HEAD route
router.HEAD("/http/:directory/:torrent/:file", zr.headFileHandler)
// 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)
// DELETE routes
router.DELETE("/dav/:directory/:torrent/:file", zr.deleteFileHandler)
router.DELETE("/dav/:directory/:torrent/", zr.deleteTorrentHandler)
// Global OPTIONS route
router.GlobalOPTIONS = http.HandlerFunc(zr.globalOptionsHandler)
// root route
router.GET("/", zr.rootHandler)
}
func (zr *ZurgRouter) httpTorrentDirectoryHandler(resp http.ResponseWriter, req *http.Request, params httprouter.Params) {
directory := params.ByName("directory")
torrentName := params.ByName("torrent")
out, err := intHttp.HandleListFiles(directory, torrentName, zr.torMgr, zr.log)
if err != nil {
http.Error(resp, "Not Found", http.StatusNotFound)
return
}
resp.Header().Set("Content-Type", "text/html; charset=\"utf-8\"")
resp.WriteHeader(http.StatusOK)
fmt.Fprint(resp, *out)
}
func (zr *ZurgRouter) httpDirectoryHandler(resp http.ResponseWriter, req *http.Request, params httprouter.Params) {
directory := params.ByName("directory")
out, err := intHttp.HandleListTorrents(directory, zr.torMgr, zr.log)
if err != nil {
http.Error(resp, "Not Found", http.StatusNotFound)
return
}
resp.Header().Set("Content-Type", "text/html; charset=\"utf-8\"")
resp.WriteHeader(http.StatusOK)
fmt.Fprint(resp, *out)
}
func (zr *ZurgRouter) httpRootHandler(resp http.ResponseWriter, req *http.Request, params httprouter.Params) {
out, err := intHttp.HandleListDirectories(zr.torMgr)
if err != nil {
http.Error(resp, "Not Found", http.StatusNotFound)
return
}
resp.Header().Set("Content-Type", "text/html; charset=\"utf-8\"")
resp.WriteHeader(http.StatusOK)
fmt.Fprint(resp, *out)
}
func (zr *ZurgRouter) propfindTorrentHandler(resp http.ResponseWriter, req *http.Request, params httprouter.Params) {
directory := params.ByName("directory")
torrentName := params.ByName("torrent")
out, err := dav.HandleListFiles(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)
fmt.Fprint(resp, *out)
}
func (zr *ZurgRouter) propfindDirectoryHandler(resp http.ResponseWriter, req *http.Request, params httprouter.Params) {
directory := params.ByName("directory")
out, err := dav.HandleListTorrents(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)
fmt.Fprint(resp, *out)
}
func (zr *ZurgRouter) propfindRootHandler(resp http.ResponseWriter, req *http.Request, params httprouter.Params) {
out, err := dav.HandleListDirectories(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)
fmt.Fprint(resp, *out)
}
func (zr *ZurgRouter) deleteFileHandler(resp http.ResponseWriter, req *http.Request, params httprouter.Params) {
directory := params.ByName("directory")
torrentName := params.ByName("torrent")
fileName := params.ByName("file")
if dav.HandleDeleteFile(directory, torrentName, fileName, zr.torMgr) != nil {
http.Error(resp, "Not Found", http.StatusNotFound)
return
}
resp.WriteHeader(http.StatusNoContent)
}
func (zr *ZurgRouter) deleteTorrentHandler(resp http.ResponseWriter, req *http.Request, params httprouter.Params) {
directory := params.ByName("directory")
torrentName := params.ByName("torrent")
if dav.HandleDeleteTorrent(directory, torrentName, 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)
}
func (zr *ZurgRouter) universalDownloadFileHandler(resp http.ResponseWriter, req *http.Request, params httprouter.Params) {
directory := params.ByName("directory")
torrentName := params.ByName("torrent")
fileName := params.ByName("file")
zr.getfile.HandleGetRequest(directory, torrentName, fileName, resp, req, zr.torMgr, zr.cfg, zr.log)
}
func (zr *ZurgRouter) headFileHandler(resp http.ResponseWriter, req *http.Request, params httprouter.Params) {
directory := params.ByName("directory")
torrentName := params.ByName("torrent")
fileName := params.ByName("file")
universal.HandleHeadRequest(directory, torrentName, fileName, resp, req, zr.torMgr, zr.log)
}
// Create a struct to hold the data
type RootResponse struct {
Version string `json:"zurg"`
BuiltAt string `json:"built_at"`
GitCommit string `json:"git_commit"`
GoVersion string `json:"go_version"`
UserInfo *realdebrid.User `json:"user_info"`
}
func (zr *ZurgRouter) rootHandler(resp http.ResponseWriter, req *http.Request, params httprouter.Params) {
userInfo, err := zr.api.GetUserInformation()
if err != nil {
// Handle the error appropriately
http.Error(resp, err.Error(), http.StatusInternalServerError)
return
}
response := RootResponse{
Version: version.GetVersion(),
BuiltAt: version.GetBuiltAt(),
GitCommit: version.GetGitCommit(),
GoVersion: version.GetGoVersion(),
UserInfo: userInfo,
}
if err := json.NewEncoder(resp).Encode(response); err != nil {
http.Error(resp, err.Error(), http.StatusInternalServerError)
}
}