diff --git a/cmd/zurg/main.go b/cmd/zurg/main.go index 3b4345d..d731138 100644 --- a/cmd/zurg/main.go +++ b/cmd/zurg/main.go @@ -52,7 +52,7 @@ func main() { log.Errorf("Server panic: %v\n", r) } }() - log.Infof("Starting server on %s\n", addr) + log.Infof("Starting server on %s", addr) if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Panicf("Failed to start server: %v", err) } @@ -65,7 +65,7 @@ func main() { log.Errorf("Mount panic: %v\n", r) } }() - log.Infof("Mounting on %s\n", mountPoint) + log.Infof("Mounting on %s", mountPoint) if err := zfs.Mount(mountPoint); err != nil { log.Panicf("Failed to mount: %v", err) } diff --git a/internal/config/load.go b/internal/config/load.go index c57b04d..5b6a404 100644 --- a/internal/config/load.go +++ b/internal/config/load.go @@ -27,7 +27,7 @@ func LoadZurgConfig(filename string) (ConfigInterface, error) { rlog := logutil.NewLogger() log := rlog.Named("config") - log.Debug("Loading config file", filename) + log.Debug("Loading config file ", filename) content, err := os.ReadFile(filename) if err != nil { return nil, err diff --git a/internal/config/v1.go b/internal/config/v1.go index f9f0d55..a199854 100644 --- a/internal/config/v1.go +++ b/internal/config/v1.go @@ -10,14 +10,10 @@ import ( ) func loadV1Config(content []byte) (*ZurgConfigV1, error) { - rlog := logutil.NewLogger() - log := rlog.Named("config") - var configV1 ZurgConfigV1 if err := yaml.Unmarshal(content, &configV1); err != nil { return nil, err } - log.Debug("V1 config loaded successfully") return &configV1, nil } @@ -27,13 +23,9 @@ func (z *ZurgConfigV1) GetVersion() string { } func (z *ZurgConfigV1) GetDirectories() []string { - rlog := logutil.NewLogger() - log := rlog.Named("config") - rootDirectories := make([]string, len(z.Directories)) i := 0 for directory := range z.Directories { - log.Debug("Adding to rootDirectories", directory) rootDirectories[i] = directory i++ } @@ -41,12 +33,9 @@ func (z *ZurgConfigV1) GetDirectories() []string { } func (z *ZurgConfigV1) GetGroupMap() map[string][]string { - // Obtain a new sugared logger instance rlog := logutil.NewLogger() log := rlog.Named("config") - log.Debug("Starting to build the group map from directories") - var groupMap = make(map[string][]string) var groupOrderMap = make(map[string]int) // To store GroupOrder for each directory @@ -54,7 +43,7 @@ func (z *ZurgConfigV1) GetGroupMap() map[string][]string { for directory, val := range z.Directories { groupMap[val.Group] = append(groupMap[val.Group], directory) groupOrderMap[directory] = val.GroupOrder - log.Debugf("Added directory to group: %s, group: %s, groupOrder: %d", directory, val.Group, val.GroupOrder) + log.Debugf("Added directory to group: %s, group: %s, order: %d", directory, val.Group, val.GroupOrder) } // Sort the slice based on GroupOrder and then directory name for deterministic order @@ -66,7 +55,7 @@ func (z *ZurgConfigV1) GetGroupMap() map[string][]string { return groupOrderMap[dirs[i]] < groupOrderMap[dirs[j]] }) groupMap[group] = dirs - log.Debugf("Sorted directories within a group: %s, sortedDirectories: %v", group, dirs) + log.Debugf("Sorted directories within a group: %s %v", group, dirs) } // Return a deep copy of the map diff --git a/internal/dav/listing.go b/internal/dav/listing.go index 5637b56..3d18ef8 100644 --- a/internal/dav/listing.go +++ b/internal/dav/listing.go @@ -3,7 +3,6 @@ package dav import ( "encoding/xml" "fmt" - "log" "net/http" "path" "strings" @@ -11,10 +10,14 @@ import ( "github.com/debridmediamanager.com/zurg/internal/config" "github.com/debridmediamanager.com/zurg/internal/torrent" "github.com/debridmediamanager.com/zurg/pkg/dav" + "github.com/debridmediamanager.com/zurg/pkg/logutil" "github.com/hashicorp/golang-lru/v2/expirable" ) func HandlePropfindRequest(w http.ResponseWriter, r *http.Request, t *torrent.TorrentManager, c config.ConfigInterface, cache *expirable.LRU[string, string]) { + rlog := logutil.NewLogger() + log := rlog.Named("dav") + requestPath := path.Clean(r.URL.Path) requestPath = strings.Trim(requestPath, "/") @@ -38,13 +41,13 @@ func HandlePropfindRequest(w http.ResponseWriter, r *http.Request, t *torrent.To case len(filteredSegments) == 2: output, err = handleSingleTorrent(requestPath, w, r, t) default: - log.Println("Not Found", r.Method, requestPath) + log.Errorf("Request %s %s not found", r.Method, requestPath) writeHTTPError(w, "Not Found", http.StatusNotFound) return } if err != nil { - log.Printf("Error processing request: %v\n", err) + log.Errorf("Error processing request: %v", err) writeHTTPError(w, "Server error", http.StatusInternalServerError) return } diff --git a/internal/dav/util.go b/internal/dav/util.go index d1670f1..b57303e 100644 --- a/internal/dav/util.go +++ b/internal/dav/util.go @@ -1,7 +1,6 @@ package dav import ( - "log" "time" ) @@ -9,7 +8,6 @@ import ( func convertRFC3339toRFC1123(input string) string { t, err := time.Parse(time.RFC3339, input) if err != nil { - log.Println("Conversion error", err) return "" } return t.Format("Mon, 02 Jan 2006 15:04:05 GMT") diff --git a/internal/http/listing.go b/internal/http/listing.go index 6013a4d..cdd23f2 100644 --- a/internal/http/listing.go +++ b/internal/http/listing.go @@ -2,7 +2,6 @@ package http import ( "fmt" - "log" "net/http" "net/url" "path" @@ -10,10 +9,14 @@ import ( "github.com/debridmediamanager.com/zurg/internal/config" "github.com/debridmediamanager.com/zurg/internal/torrent" + "github.com/debridmediamanager.com/zurg/pkg/logutil" "github.com/hashicorp/golang-lru/v2/expirable" ) func HandleDirectoryListing(w http.ResponseWriter, r *http.Request, t *torrent.TorrentManager, c config.ConfigInterface, cache *expirable.LRU[string, string]) { + rlog := logutil.NewLogger() + log := rlog.Named("http") + requestPath := path.Clean(r.URL.Path) if data, exists := cache.Get(requestPath); exists { @@ -35,13 +38,13 @@ func HandleDirectoryListing(w http.ResponseWriter, r *http.Request, t *torrent.T case len(filteredSegments) == 3: output, err = handleSingleTorrent(requestPath, w, r, t) default: - log.Println("Not Found (http)", r.Method, requestPath, len(filteredSegments)) + log.Errorf("Request %s %s not found", r.Method, requestPath) writeHTTPError(w, "Not Found", http.StatusNotFound) return } if err != nil { - log.Printf("Error processing request: %v\n", err) + log.Errorf("Error processing request: %v", err) writeHTTPError(w, "Server error", http.StatusInternalServerError) return } diff --git a/internal/net/router.go b/internal/net/router.go index 18acffa..1c5f4fc 100644 --- a/internal/net/router.go +++ b/internal/net/router.go @@ -1,7 +1,6 @@ package net import ( - "log" "net/http" "path" "strings" @@ -11,11 +10,15 @@ import ( intHttp "github.com/debridmediamanager.com/zurg/internal/http" "github.com/debridmediamanager.com/zurg/internal/torrent" "github.com/debridmediamanager.com/zurg/internal/universal" + "github.com/debridmediamanager.com/zurg/pkg/logutil" "github.com/hashicorp/golang-lru/v2/expirable" ) // Router creates a WebDAV router func Router(mux *http.ServeMux, c config.ConfigInterface, t *torrent.TorrentManager, cache *expirable.LRU[string, string]) { + rlog := logutil.NewLogger() + log := rlog.Named("net") + mux.HandleFunc("/http/", func(w http.ResponseWriter, r *http.Request) { switch r.Method { case http.MethodGet: @@ -30,7 +33,7 @@ func Router(mux *http.ServeMux, c config.ConfigInterface, t *torrent.TorrentMana universal.HandleHeadRequest(w, r, t, c, cache) default: - log.Println("Method not implemented", r.Method) + log.Errorf("Request %s %s not supported yet", r.Method, r.URL.Path) http.Error(w, "Method not implemented", http.StatusMethodNotAllowed) } }) @@ -47,7 +50,7 @@ func Router(mux *http.ServeMux, c config.ConfigInterface, t *torrent.TorrentMana w.WriteHeader(http.StatusOK) default: - log.Println("Method not implemented", r.Method, r.URL.Path) + log.Errorf("Request %s %s not supported yet", r.Method, r.URL.Path) http.Error(w, "Method not implemented", http.StatusMethodNotAllowed) } }) diff --git a/internal/torrent/hooks.go b/internal/torrent/hooks.go index 79ea0bf..9015f24 100644 --- a/internal/torrent/hooks.go +++ b/internal/torrent/hooks.go @@ -3,10 +3,10 @@ package torrent import ( "bytes" "fmt" - "log" "os/exec" "github.com/debridmediamanager.com/zurg/internal/config" + "github.com/debridmediamanager.com/zurg/pkg/logutil" ) type ScriptExecutor struct { @@ -30,15 +30,18 @@ func (se *ScriptExecutor) Execute() (string, error) { } func OnLibraryUpdateHook(config config.ConfigInterface) { + rlog := logutil.NewLogger() + log := rlog.Named("hooks") + executor := &ScriptExecutor{ Script: config.GetOnLibraryUpdate(), } output, err := executor.Execute() if err != nil { - log.Printf("Failed to execute hook on_library_update:\n%v\n", err) + log.Errorf("Failed to execute hook on_library_update: %v", err) return } if output != "" { - log.Printf("Output of hook on_library_update:\n%s\n", output) + log.Infof("Output of hook on_library_update:\n%s", output) } } diff --git a/internal/torrent/manager.go b/internal/torrent/manager.go index 4106d4a..afa3b2c 100644 --- a/internal/torrent/manager.go +++ b/internal/torrent/manager.go @@ -3,7 +3,6 @@ package torrent import ( "encoding/gob" "fmt" - "log" "math" "os" "strings" @@ -11,8 +10,10 @@ import ( "time" "github.com/debridmediamanager.com/zurg/internal/config" + "github.com/debridmediamanager.com/zurg/pkg/logutil" "github.com/debridmediamanager.com/zurg/pkg/realdebrid" "github.com/hashicorp/golang-lru/v2/expirable" + "go.uber.org/zap" ) type TorrentManager struct { @@ -26,6 +27,7 @@ type TorrentManager struct { directoryMap map[string][]string processedTorrents map[string][]string mu *sync.Mutex + log *zap.SugaredLogger } // NewTorrentManager creates a new torrent manager @@ -40,16 +42,14 @@ func NewTorrentManager(config config.ConfigInterface, cache *expirable.LRU[strin directoryMap: make(map[string][]string), processedTorrents: make(map[string][]string), mu: &sync.Mutex{}, + log: logutil.NewLogger().Named("manager"), } // Initialize torrents for the first time - log.Println("Initializing torrents") t.mu.Lock() - log.Println("Fetching torrents") t.torrents = t.getFreshListFromAPI() t.checksum = t.getChecksum() t.mu.Unlock() - log.Println("Finished fetching torrents") // log.Println("First checksum", t.checksum) @@ -162,13 +162,13 @@ func (t *TorrentManager) getChecksum() string { totalCount = torrentsResp.totalCount case count = <-countChan: case err := <-errChan: - log.Printf("Error: %v\n", err) + t.log.Errorf("Checksum API Error: %v\n", err) return "" } } if len(torrents) == 0 { - log.Println("Huh, no torrents returned") + t.log.Error("Huh, no torrents returned") return "" } @@ -178,7 +178,7 @@ func (t *TorrentManager) getChecksum() string { // startRefreshJob periodically refreshes the torrents func (t *TorrentManager) startRefreshJob() { - log.Println("Starting periodic refresh") + t.log.Info("Starting periodic refresh") for { <-time.After(time.Duration(t.config.GetRefreshEverySeconds()) * time.Second) @@ -221,7 +221,7 @@ func (t *TorrentManager) startRefreshJob() { func (t *TorrentManager) getFreshListFromAPI() []Torrent { torrents, _, err := realdebrid.GetTorrents(t.config.GetToken(), 0) if err != nil { - log.Printf("Cannot get torrents: %v\n", err) + t.log.Errorf("Cannot get torrents: %v\n", err) return nil } @@ -244,7 +244,7 @@ func (t *TorrentManager) getFreshListFromAPI() []Torrent { } } - log.Printf("Fetched %d torrents", len(torrentsV2)) + t.log.Infof("Fetched %d torrents", len(torrentsV2)) return torrentsV2 } @@ -267,10 +267,10 @@ func (t *TorrentManager) addMoreInfo(torrent *Torrent) { return } - // log.Println("Getting info for", torrent.ID) + // t.log.Println("Getting info for", torrent.ID) info, err := realdebrid.GetTorrentInfo(t.config.GetToken(), torrent.ID) if err != nil { - log.Printf("Cannot get info: %v\n", err) + t.log.Errorf("Cannot get info: %v\n", err) return } @@ -298,19 +298,21 @@ func (t *TorrentManager) addMoreInfo(torrent *Torrent) { }) } if len(selectedFiles) > len(info.Links) && info.Progress == 100 { - log.Printf("Some links has expired for %s, %s: %d selected but only %d link(s)\n", info.ID, info.Name, len(selectedFiles), len(info.Links)) + t.log.Debugf("Some links has expired for %s %s: %d selected but only %d link(s)", info.ID, info.Name, len(selectedFiles), len(info.Links)) // chaotic file means RD will not output the desired file selection // e.g. even if we select just a single mkv, it will output a rar var isChaotic bool selectedFiles, isChaotic = t.organizeChaos(info, selectedFiles) if isChaotic { - log.Println("This torrent is unfixable, it's always returning an unstreamable link, ignoring", info.ID, info.Name) + t.log.Infof("Torrent %s %s is unfixable, it's always returning an unstreamable link, ignoring", info.ID, info.Name) + t.log.Debugf("You can try fixing it yourself magnet:?xt=urn:btih:%s", info.Hash) } else { if len(streamableFiles) > 1 { - log.Println("Marking for repair", info.ID, info.Name) + t.log.Infof("Torrent %s %s marked for repair", info.ID, info.Name) forRepair = true } else { - log.Println("This torrent is unfixable, the lone streamable link has expired, ignoring", info.ID, info.ID) + t.log.Infof("Torrent %s %s is unfixable, the lone streamable link has expired, ignoring", info.ID, info.Name) + t.log.Debugf("You can try fixing it yourself magnet:?xt=urn:btih:%s", info.Hash) } } } else { @@ -352,7 +354,6 @@ func (t *TorrentManager) mapToDirectories() { // for every group, iterate over every torrent // and then sprinkle/distribute the torrents to the directories of the group for group, directories := range groupMap { - log.Printf("Processing directory group '%s', sequence: %s\n", group, strings.Join(directories, " > ")) counter := make(map[string]int) for i := range t.torrents { // don't process torrents that are already mapped if it is not the first run @@ -398,15 +399,14 @@ func (t *TorrentManager) mapToDirectories() { sum += count } if sum > 0 { - log.Printf("Directory group processed: %s %v %d\n", group, counter, sum) + t.log.Infof("Group processing completed: %s %v total: %d", group, counter, sum) } else { - log.Println("No new additions to directory group", group) + t.log.Info("No new additions to directory group", group) } } default: - log.Println("Unknown config version") + t.log.Error("Unknown config version") } - log.Println("Finished mapping to directories") } // getByID returns a torrent by its ID @@ -424,7 +424,7 @@ func (t *TorrentManager) writeToFile(torrent *Torrent) { filePath := fmt.Sprintf("data/%s.bin", torrent.ID) file, err := os.Create(filePath) if err != nil { - log.Fatalf("Failed creating file: %s", err) + t.log.Fatalf("Failed creating file: %s", err) return } defer file.Close() @@ -468,14 +468,14 @@ func (t *TorrentManager) repairAll(wg *sync.WaitGroup) { wg.Wait() for _, torrent := range t.torrents { if torrent.ForRepair { - log.Println("Issues were detected on", torrent.Name, "; fixing...") + t.log.Infof("Issues were detected on %s %s; fixing...", torrent.ID, torrent.Name) t.repair(torrent.ID, torrent.SelectedFiles, true) } if len(torrent.Links) == 0 && torrent.Progress == 100 { // If the torrent has no links // and already processing repair // delete it! - log.Println("Deleting", torrent.Name, "as it has no links") + t.log.Infof("Deleting broken torrent %s %s as it doesn't contain any files", torrent.ID, torrent.Name) realdebrid.DeleteTorrent(t.config.GetToken(), torrent.ID) } } @@ -496,7 +496,7 @@ func (t *TorrentManager) repair(torrentID string, selectedFiles []File, tryReins } } if found { - log.Println("Repair in progress, skipping", torrentID) + t.log.Infof("Repair in progress, skipping %s", torrentID) return } @@ -519,16 +519,16 @@ func (t *TorrentManager) repair(torrentID string, selectedFiles []File, tryReins } } if len(missingFiles) == 0 { - log.Println(torrent.Name, "is already repaired") + t.log.Infof("Torrent %s %s is already repaired", torrent.ID, torrent.Name) return } // then we repair it! - log.Println("Repairing torrent", torrentID) + t.log.Infof("Repairing torrent %s %s", torrent.ID, torrent.Name) // check if we can still add more downloads proceed := t.canCapacityHandle() if !proceed { - log.Println("Cannot add more torrents, exiting") + t.log.Error("Cannot add more torrents, exiting") return } @@ -556,8 +556,7 @@ func (t *TorrentManager) repair(torrentID string, selectedFiles []File, tryReins // we will download 1 extra streamable file to force a redownload of the missing files // or if there's only 1 missing file, we will download 1 more to prevent a rename missingFilesPlus1 := strings.Join(getFileIDs(missingFiles), ",") - missingFilesPlus1 += fmt.Sprintf(",%d", otherStreamableFileIDs[0]) - log.Println("Trying to reinsert with 1 extra file", missingFilesPlus1) + t.log.Infof("Redownloading %d missing files", len(missingFiles)) t.reinsertTorrent(torrent, missingFilesPlus1, false) } else if len(selectedFiles) > 1 { // if not, last resort: add only the missing files but do it in 2 batches @@ -565,25 +564,28 @@ func (t *TorrentManager) repair(torrentID string, selectedFiles []File, tryReins missingFiles1 := strings.Join(getFileIDs(missingFiles[:half]), ",") missingFiles2 := strings.Join(getFileIDs(missingFiles[half:]), ",") if missingFiles1 != "" { - log.Println("Trying to reinsert with 1/2 batches", missingFiles1) + t.log.Infof("Redownloading %d missing files; batch 1 of 2", len(missingFiles1)) t.reinsertTorrent(torrent, missingFiles1, false) } if missingFiles2 != "" { - log.Println("Trying to reinsert with 2/2 batches", missingFiles2) + t.log.Infof("Redownloading %d missing files; batch 2 of 2", len(missingFiles2)) t.reinsertTorrent(torrent, missingFiles2, false) + } else { + t.log.Info("No other missing files left to reinsert") } } else { - log.Println("Cannot repair as the single link cached in RD for this torrent is already broken", torrent.ID, torrent.Name) + t.log.Infof("Torrent %s %s is unfixable as the only link cached in RD is already broken", torrent.ID, torrent.Name) + t.log.Debugf("You can try fixing it yourself magnet:?xt=urn:btih:%s", torrent.Hash) return } - log.Println("Waiting for downloads to finish") + t.log.Info("Waiting for downloads to finish") } } func (t *TorrentManager) reinsertTorrent(torrent *Torrent, missingFiles string, deleteIfFailed bool) bool { // if missingFiles is not provided, look for missing files if missingFiles == "" { - log.Println("Reinserting whole torrent", torrent.Name) + t.log.Info("Redownloading whole torrent", torrent.Name) var selection string for _, file := range torrent.SelectedFiles { selection += fmt.Sprintf("%d,", file.ID) @@ -594,20 +596,18 @@ func (t *TorrentManager) reinsertTorrent(torrent *Torrent, missingFiles string, if len(selection) > 0 { missingFiles = selection[:len(selection)-1] } - } else { - log.Printf("Reinserting %d missing files for %s", len(strings.Split(missingFiles, ",")), torrent.Name) } - // reinsert torrent + // redownload torrent resp, err := realdebrid.AddMagnetHash(t.config.GetToken(), torrent.Hash) if err != nil { - log.Printf("Cannot reinsert torrent: %v\n", err) + t.log.Errorf("Cannot redownload torrent: %v", err) return false } newTorrentID := resp.ID err = realdebrid.SelectTorrentFiles(t.config.GetToken(), newTorrentID, missingFiles) if err != nil { - log.Printf("Cannot select files on reinserted torrent: %v\n", err) + t.log.Errorf("Cannot start redownloading: %v", err) } if deleteIfFailed { @@ -619,7 +619,7 @@ func (t *TorrentManager) reinsertTorrent(torrent *Torrent, missingFiles string, // see if the torrent is ready info, err := realdebrid.GetTorrentInfo(t.config.GetToken(), newTorrentID) if err != nil { - log.Printf("Cannot get info on reinserted torrent: %v\n", err) + t.log.Errorf("Cannot get info on redownloaded torrent: %v", err) if deleteIfFailed { realdebrid.DeleteTorrent(t.config.GetToken(), newTorrentID) } @@ -628,17 +628,17 @@ func (t *TorrentManager) reinsertTorrent(torrent *Torrent, missingFiles string, time.Sleep(1 * time.Second) if info.Progress != 100 { - log.Printf("Torrent is not cached anymore, %d%%\n", info.Progress) + t.log.Infof("Torrent is not cached anymore so we have to wait until completion, currently %d%%", info.Progress) realdebrid.DeleteTorrent(t.config.GetToken(), newTorrentID) return false } if len(info.Links) != len(torrent.SelectedFiles) { - log.Printf("It doesn't fix the problem, got %d links but we need %d\n", len(info.Links), len(torrent.SelectedFiles)) + t.log.Infof("It didn't fix the issue, only got %d files but we need %d, undoing", len(info.Links), len(torrent.SelectedFiles)) realdebrid.DeleteTorrent(t.config.GetToken(), newTorrentID) return false } - log.Println("Reinsertion successful, deleting old torrent") + t.log.Info("Redownload successful, deleting old torrent") realdebrid.DeleteTorrent(t.config.GetToken(), torrent.ID) } return true @@ -713,9 +713,9 @@ func (t *TorrentManager) canCapacityHandle() bool { for { count, err := realdebrid.GetActiveTorrentCount(t.config.GetToken()) if err != nil { - log.Printf("Cannot get active torrent count: %v\n", err) + t.log.Errorf("Cannot get active downloads count: %v", err) if retryCount >= maxRetries { - log.Println("Max retries reached. Exiting.") + t.log.Error("Max retries reached. Exiting.") return false } delay := time.Duration(math.Pow(2, float64(retryCount))) * baseDelay @@ -728,12 +728,12 @@ func (t *TorrentManager) canCapacityHandle() bool { } if count.DownloadingCount < count.MaxNumberOfTorrents { - log.Printf("We can still add a new torrent, %d/%d\n", count.DownloadingCount, count.MaxNumberOfTorrents) + t.log.Infof("We can still add a new torrent, we have capacity for %d more", count.MaxNumberOfTorrents-count.DownloadingCount) return true } if retryCount >= maxRetries { - log.Println("Max retries reached. Exiting.") + t.log.Error("Max retries reached, exiting") return false } delay := time.Duration(math.Pow(2, float64(retryCount))) * baseDelay diff --git a/internal/universal/get.go b/internal/universal/get.go index 41eef1f..775d113 100644 --- a/internal/universal/get.go +++ b/internal/universal/get.go @@ -2,7 +2,6 @@ package universal import ( "io" - "log" "net/http" "path" "path/filepath" @@ -13,12 +12,17 @@ import ( intHttp "github.com/debridmediamanager.com/zurg/internal/http" "github.com/debridmediamanager.com/zurg/internal/torrent" "github.com/debridmediamanager.com/zurg/pkg/davextra" + "github.com/debridmediamanager.com/zurg/pkg/logutil" "github.com/debridmediamanager.com/zurg/pkg/realdebrid" "github.com/hashicorp/golang-lru/v2/expirable" + "go.uber.org/zap" ) // HandleGetRequest handles a GET request universally for both WebDAV and HTTP func HandleGetRequest(w http.ResponseWriter, r *http.Request, t *torrent.TorrentManager, c config.ConfigInterface, cache *expirable.LRU[string, string]) { + rlog := logutil.NewLogger() + log := rlog.Named("uniget") + requestPath := path.Clean(r.URL.Path) isDav := true if strings.Contains(requestPath, "/http") { @@ -39,7 +43,7 @@ func HandleGetRequest(w http.ResponseWriter, r *http.Request, t *torrent.Torrent return } if data, exists := cache.Get(requestPath); exists { - streamFileToResponse(data, w, r, c.GetNetworkBufferSize()) + streamFileToResponse(data, w, r, c.GetNetworkBufferSize(), log) return } @@ -49,7 +53,7 @@ func HandleGetRequest(w http.ResponseWriter, r *http.Request, t *torrent.Torrent torrents := t.FindAllTorrentsWithName(baseDirectory, torrentName) if torrents == nil { - log.Println("Cannot find torrent", requestPath) + log.Errorf("Cannot find torrent %s in the directory %s", requestPath, baseDirectory) http.Redirect(w, r, "https://send.nukes.wtf/tDeTd0", http.StatusFound) return } @@ -57,13 +61,13 @@ func HandleGetRequest(w http.ResponseWriter, r *http.Request, t *torrent.Torrent filenameV2, linkFragment := davextra.ExtractLinkFragment(filename) torrent, file := getFile(torrents, filenameV2, linkFragment) if file == nil { - log.Println("Cannot find file (get)", requestPath) + log.Errorf("Cannot find file from path %s", requestPath) http.Error(w, "Cannot find file", http.StatusNotFound) return } if file.Link == "" { - log.Println("Link not found (get)", filename) - http.Error(w, "Cannot find file", http.StatusNotFound) + // This is a dead file, serve an alternate file + log.Errorf("File %s is no longer available", filename) return } link := file.Link @@ -74,7 +78,7 @@ func HandleGetRequest(w http.ResponseWriter, r *http.Request, t *torrent.Torrent resp := realdebrid.RetryUntilOk(unrestrictFn) if resp == nil { if !file.Unavailable { - log.Println("Cannot unrestrict link", link, filenameV2) + log.Errorf("Cannot unrestrict file %s %s", filenameV2, link) t.HideTheFile(torrent, file) } http.Redirect(w, r, "https://send.nukes.wtf/tDeTd0", http.StatusFound) @@ -83,19 +87,19 @@ func HandleGetRequest(w http.ResponseWriter, r *http.Request, t *torrent.Torrent actualExt := filepath.Ext(resp.Filename) expectedExt := filepath.Ext(filenameV2) if actualExt != expectedExt { - log.Println("File extension mismatch", resp.Filename, filenameV2) + log.Errorf("File extension mismatch: %s and %s", filenameV2, resp.Filename) } else { - log.Println("Filename mismatch", resp.Filename, filenameV2) + log.Errorf("Filename mismatch: %s and %s", filenameV2, resp.Filename) } } cache.Add(requestPath, resp.Download) - streamFileToResponse(resp.Download, w, r, c.GetNetworkBufferSize()) + streamFileToResponse(resp.Download, w, r, c.GetNetworkBufferSize(), log) } -func streamFileToResponse(url string, w http.ResponseWriter, r *http.Request, bufferSize int) { +func streamFileToResponse(url string, w http.ResponseWriter, r *http.Request, bufferSize int, log *zap.SugaredLogger) { req, err := http.NewRequest(http.MethodGet, url, nil) if err != nil { - log.Println("Error creating new request:", err) + log.Errorf("Error creating new request %v", err) http.Redirect(w, r, "https://send.nukes.wtf/ARjVWb", http.StatusFound) return } @@ -108,14 +112,14 @@ func streamFileToResponse(url string, w http.ResponseWriter, r *http.Request, bu resp, err := http.DefaultClient.Do(req) if err != nil { - log.Println("Error downloading file:", err) + log.Errorf("Error downloading file %v", err) http.Redirect(w, r, "https://send.nukes.wtf/TB2u2n", http.StatusFound) return } defer resp.Body.Close() if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusPartialContent { - log.Printf("Received a non-OK status code: %d", resp.StatusCode) + log.Errorf("Received a nonOK status code %d", resp.StatusCode) http.Redirect(w, r, "https://send.nukes.wtf/b5AiON", http.StatusFound) return } diff --git a/internal/universal/head.go b/internal/universal/head.go index c902b8b..58c452a 100644 --- a/internal/universal/head.go +++ b/internal/universal/head.go @@ -2,7 +2,6 @@ package universal import ( "fmt" - "log" "net/http" "path" "path/filepath" @@ -11,10 +10,14 @@ import ( "github.com/debridmediamanager.com/zurg/internal/config" "github.com/debridmediamanager.com/zurg/internal/torrent" "github.com/debridmediamanager.com/zurg/pkg/davextra" + "github.com/debridmediamanager.com/zurg/pkg/logutil" "github.com/hashicorp/golang-lru/v2/expirable" ) func HandleHeadRequest(w http.ResponseWriter, r *http.Request, t *torrent.TorrentManager, c config.ConfigInterface, cache *expirable.LRU[string, string]) { + rlog := logutil.NewLogger() + log := rlog.Named("unihead") + requestPath := path.Clean(r.URL.Path) requestPath = strings.Replace(requestPath, "/http", "", 1) if requestPath == "/favicon.ico" { @@ -24,7 +27,7 @@ func HandleHeadRequest(w http.ResponseWriter, r *http.Request, t *torrent.Torren segments := strings.Split(requestPath, "/") // If there are less than 3 segments, return an error or adjust as needed if len(segments) < 4 { - log.Println("Method not implemented", r.Method, r.URL.Path) + log.Errorf("Request %s %s not supported yet", r.Method, r.URL.Path) http.Error(w, "Method not implemented", http.StatusMethodNotAllowed) return } @@ -45,7 +48,7 @@ func HandleHeadRequest(w http.ResponseWriter, r *http.Request, t *torrent.Torren torrents := t.FindAllTorrentsWithName(baseDirectory, torrentName) if torrents == nil { - log.Println("Cannot find torrent", requestPath) + log.Errorf("Cannot find torrent %s in the directory %s", requestPath, baseDirectory) http.Error(w, "Cannot find file", http.StatusNotFound) return } @@ -53,12 +56,13 @@ func HandleHeadRequest(w http.ResponseWriter, r *http.Request, t *torrent.Torren filenameV2, linkFragment := davextra.ExtractLinkFragment(filename) _, file := getFile(torrents, filenameV2, linkFragment) if file == nil { - log.Println("Cannot find file (head)", requestPath) + log.Errorf("Cannot find file from path %s", requestPath) http.Error(w, "Cannot find file", http.StatusNotFound) return } if file.Link == "" { - log.Println("Link not found (head)", filename) + // This is a dead file, serve an alternate file + log.Errorf("File %s is no longer available", filename) http.Error(w, "Cannot find file", http.StatusNotFound) return }