Reimplement deletes and marking files as broken
This commit is contained in:
@@ -29,14 +29,14 @@ func HandleDeleteFile(directory, torrentName, fileName string, torMgr *torrent.T
|
|||||||
return fmt.Errorf("cannot find torrent %s", torrentName)
|
return fmt.Errorf("cannot find torrent %s", torrentName)
|
||||||
}
|
}
|
||||||
file, ok := torrent.SelectedFiles.Get(fileName)
|
file, ok := torrent.SelectedFiles.Get(fileName)
|
||||||
if !ok {
|
if !ok || file.IsDeleted {
|
||||||
return fmt.Errorf("cannot find file %s", fileName)
|
return fmt.Errorf("cannot find file %s", fileName)
|
||||||
}
|
}
|
||||||
dirCfg := torMgr.Config.(*config.ZurgConfigV1).GetDirectoryConfig(directory)
|
dirCfg := torMgr.Config.(*config.ZurgConfigV1).GetDirectoryConfig(directory)
|
||||||
if dirCfg.OnlyShowTheBiggestFile {
|
if dirCfg.OnlyShowTheBiggestFile {
|
||||||
torMgr.Delete(torrentName, true)
|
torMgr.Delete(torrentName, true)
|
||||||
} else {
|
} else {
|
||||||
file.Link = "unselect"
|
file.IsDeleted = true
|
||||||
if torMgr.CheckDeletedStatus(torrent) {
|
if torMgr.CheckDeletedStatus(torrent) {
|
||||||
torMgr.Delete(torrentName, true)
|
torMgr.Delete(torrentName, true)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,8 +74,8 @@ func ServeFilesListForInfuse(directory, torrentName string, torMgr *torrent.Torr
|
|||||||
filenames := tor.SelectedFiles.Keys()
|
filenames := tor.SelectedFiles.Keys()
|
||||||
sort.Strings(filenames)
|
sort.Strings(filenames)
|
||||||
for _, filename := range filenames {
|
for _, filename := range filenames {
|
||||||
file, ok := tor.SelectedFiles.Get(filename)
|
file, _ := tor.SelectedFiles.Get(filename)
|
||||||
if !ok || !strings.HasPrefix(file.Link, "http") {
|
if file.IsDeleted {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if dirCfg.OnlyShowTheBiggestFile && file.Bytes < biggestFileSize {
|
if dirCfg.OnlyShowTheBiggestFile && file.Bytes < biggestFileSize {
|
||||||
@@ -104,7 +104,7 @@ func ServeDownloadsListForInfuse(torMgr *torrent.TorrentManager) ([]byte, error)
|
|||||||
sort.Strings(filenames)
|
sort.Strings(filenames)
|
||||||
for _, filename := range filenames {
|
for _, filename := range filenames {
|
||||||
download, ok := torMgr.DownloadMap.Get(filename)
|
download, ok := torMgr.DownloadMap.Get(filename)
|
||||||
if !ok || !strings.HasPrefix(download.Link, "http") {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
buf.WriteString(dav.File(download.Filename, download.Filesize, download.Generated))
|
buf.WriteString(dav.File(download.Filename, download.Filesize, download.Generated))
|
||||||
|
|||||||
@@ -78,8 +78,8 @@ func ServeFilesList(directory, torrentName string, torMgr *torrent.TorrentManage
|
|||||||
filenames := tor.SelectedFiles.Keys()
|
filenames := tor.SelectedFiles.Keys()
|
||||||
sort.Strings(filenames)
|
sort.Strings(filenames)
|
||||||
for _, filename := range filenames {
|
for _, filename := range filenames {
|
||||||
file, ok := tor.SelectedFiles.Get(filename)
|
file, _ := tor.SelectedFiles.Get(filename)
|
||||||
if !ok || !strings.HasPrefix(file.Link, "http") {
|
if file.IsDeleted {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if dirCfg.OnlyShowTheBiggestFile && file.Bytes < biggestFileSize {
|
if dirCfg.OnlyShowTheBiggestFile && file.Bytes < biggestFileSize {
|
||||||
@@ -107,7 +107,7 @@ func HandleSingleFile(directory, torrentName, fileName string, torMgr *torrent.T
|
|||||||
return nil, fmt.Errorf("cannot find torrent %s", torrentName)
|
return nil, fmt.Errorf("cannot find torrent %s", torrentName)
|
||||||
}
|
}
|
||||||
file, ok := tor.SelectedFiles.Get(fileName)
|
file, ok := tor.SelectedFiles.Get(fileName)
|
||||||
if !ok || !strings.HasPrefix(file.Link, "http") {
|
if !ok || file.IsDeleted {
|
||||||
return nil, fmt.Errorf("cannot find file %s", fileName)
|
return nil, fmt.Errorf("cannot find file %s", fileName)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +131,7 @@ func ServeDownloadsList(torMgr *torrent.TorrentManager) ([]byte, error) {
|
|||||||
sort.Strings(filenames)
|
sort.Strings(filenames)
|
||||||
for _, filename := range filenames {
|
for _, filename := range filenames {
|
||||||
download, ok := torMgr.DownloadMap.Get(filename)
|
download, ok := torMgr.DownloadMap.Get(filename)
|
||||||
if !ok || !strings.HasPrefix(download.Link, "http") {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
buf.WriteString(dav.File(download.Filename, download.Filesize, download.Generated))
|
buf.WriteString(dav.File(download.Filename, download.Filesize, download.Generated))
|
||||||
|
|||||||
@@ -31,11 +31,12 @@ func HandleRenameFile(directory, torrentName, fileName, newName string, torMgr *
|
|||||||
return fmt.Errorf("cannot find torrent %s", torrentName)
|
return fmt.Errorf("cannot find torrent %s", torrentName)
|
||||||
}
|
}
|
||||||
file, ok := torrent.SelectedFiles.Get(fileName)
|
file, ok := torrent.SelectedFiles.Get(fileName)
|
||||||
if !ok {
|
if !ok || file.IsDeleted {
|
||||||
return fmt.Errorf("cannot find file %s", fileName)
|
return fmt.Errorf("cannot find file %s", fileName)
|
||||||
}
|
}
|
||||||
torrent.SelectedFiles.Remove(torrentName)
|
oldName := torMgr.GetPath(file)
|
||||||
|
file.Rename = newName
|
||||||
torrent.SelectedFiles.Set(newName, file)
|
torrent.SelectedFiles.Set(newName, file)
|
||||||
file.Path = newName
|
torrent.SelectedFiles.Remove(oldName)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,8 +74,8 @@ func ServeFilesList(directory, torrentName string, torMgr *torrent.TorrentManage
|
|||||||
filenames := tor.SelectedFiles.Keys()
|
filenames := tor.SelectedFiles.Keys()
|
||||||
sort.Strings(filenames)
|
sort.Strings(filenames)
|
||||||
for _, filename := range filenames {
|
for _, filename := range filenames {
|
||||||
file, ok := tor.SelectedFiles.Get(filename)
|
file, _ := tor.SelectedFiles.Get(filename)
|
||||||
if !ok || !strings.HasPrefix(file.Link, "http") {
|
if file.IsDeleted {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if dirCfg.OnlyShowTheBiggestFile && file.Bytes < biggestFileSize {
|
if dirCfg.OnlyShowTheBiggestFile && file.Bytes < biggestFileSize {
|
||||||
@@ -104,7 +104,7 @@ func ServeDownloadsList(torMgr *torrent.TorrentManager) ([]byte, error) {
|
|||||||
sort.Strings(filenames)
|
sort.Strings(filenames)
|
||||||
for _, filename := range filenames {
|
for _, filename := range filenames {
|
||||||
download, ok := torMgr.DownloadMap.Get(filename)
|
download, ok := torMgr.DownloadMap.Get(filename)
|
||||||
if !ok || !strings.HasPrefix(download.Link, "http") {
|
if !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
filePath := filepath.Join(config.DOWNLOADS, url.PathEscape(filename))
|
filePath := filepath.Join(config.DOWNLOADS, url.PathEscape(filename))
|
||||||
|
|||||||
@@ -3,20 +3,20 @@ package torrent
|
|||||||
import cmap "github.com/orcaman/concurrent-map/v2"
|
import cmap "github.com/orcaman/concurrent-map/v2"
|
||||||
|
|
||||||
func (t *TorrentManager) CheckDeletedStatus(torrent *Torrent) bool {
|
func (t *TorrentManager) CheckDeletedStatus(torrent *Torrent) bool {
|
||||||
var unselectedIDs []int
|
var deletedIDs []int
|
||||||
torrent.SelectedFiles.IterCb(func(_ string, file *File) {
|
torrent.SelectedFiles.IterCb(func(_ string, file *File) {
|
||||||
if file.Link == "unselect" {
|
if file.IsDeleted {
|
||||||
unselectedIDs = append(unselectedIDs, file.ID)
|
deletedIDs = append(deletedIDs, file.ID)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if len(unselectedIDs) == torrent.SelectedFiles.Count() && len(unselectedIDs) > 0 {
|
if len(deletedIDs) == torrent.SelectedFiles.Count() && len(deletedIDs) > 0 {
|
||||||
return true
|
return true
|
||||||
} else if len(unselectedIDs) > 0 {
|
} else if len(deletedIDs) > 0 {
|
||||||
t.saveTorrentChangesToDisk(torrent, func(info *Torrent) {
|
t.saveTorrentChangesToDisk(torrent, func(info *Torrent) {
|
||||||
info.SelectedFiles.IterCb(func(_ string, file *File) {
|
info.SelectedFiles.IterCb(func(_ string, file *File) {
|
||||||
for _, unselectedID := range unselectedIDs {
|
for _, deletedID := range deletedIDs {
|
||||||
if file.ID == unselectedID {
|
if file.ID == deletedID {
|
||||||
file.Link = "unselect"
|
file.IsDeleted = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ type TorrentManager struct {
|
|||||||
DownloadCache cmap.ConcurrentMap[string, *realdebrid.Download]
|
DownloadCache cmap.ConcurrentMap[string, *realdebrid.Download]
|
||||||
DownloadMap cmap.ConcurrentMap[string, *realdebrid.Download]
|
DownloadMap cmap.ConcurrentMap[string, *realdebrid.Download]
|
||||||
fixers cmap.ConcurrentMap[string, *Torrent]
|
fixers cmap.ConcurrentMap[string, *Torrent]
|
||||||
deleteOnceDone mapset.Set[string]
|
|
||||||
allAccessKeys mapset.Set[string]
|
allAccessKeys mapset.Set[string]
|
||||||
latestState *LibraryState
|
latestState *LibraryState
|
||||||
requiredVersion string
|
requiredVersion string
|
||||||
@@ -56,7 +55,6 @@ func NewTorrentManager(cfg config.ConfigInterface, api *realdebrid.RealDebrid, w
|
|||||||
RefreshKillSwitch: make(chan struct{}, 1),
|
RefreshKillSwitch: make(chan struct{}, 1),
|
||||||
RepairKillSwitch: make(chan struct{}, 1),
|
RepairKillSwitch: make(chan struct{}, 1),
|
||||||
fixers: cmap.New[*Torrent](),
|
fixers: cmap.New[*Torrent](),
|
||||||
deleteOnceDone: mapset.NewSet[string](),
|
|
||||||
allAccessKeys: mapset.NewSet[string](),
|
allAccessKeys: mapset.NewSet[string](),
|
||||||
latestState: &LibraryState{},
|
latestState: &LibraryState{},
|
||||||
requiredVersion: "0.9.3-hotfix.3",
|
requiredVersion: "0.9.3-hotfix.3",
|
||||||
@@ -78,6 +76,7 @@ func NewTorrentManager(cfg config.ConfigInterface, api *realdebrid.RealDebrid, w
|
|||||||
|
|
||||||
// proxy
|
// proxy
|
||||||
func (t *TorrentManager) UnrestrictUntilOk(link string) *realdebrid.Download {
|
func (t *TorrentManager) UnrestrictUntilOk(link string) *realdebrid.Download {
|
||||||
|
// check if it's a valid link
|
||||||
if !strings.HasPrefix(link, "http") {
|
if !strings.HasPrefix(link, "http") {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -114,6 +113,9 @@ func (t *TorrentManager) GetKey(torrent *Torrent) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *TorrentManager) GetPath(file *File) string {
|
func (t *TorrentManager) GetPath(file *File) string {
|
||||||
|
if !t.Config.ShouldIgnoreRenames() && file.Rename != "" {
|
||||||
|
return file.Rename
|
||||||
|
}
|
||||||
if t.Config.ShouldExposeFullPath() {
|
if t.Config.ShouldExposeFullPath() {
|
||||||
filename := strings.TrimPrefix(file.Path, "/")
|
filename := strings.TrimPrefix(file.Path, "/")
|
||||||
filename = strings.ReplaceAll(filename, "/", " - ")
|
filename = strings.ReplaceAll(filename, "/", " - ")
|
||||||
|
|||||||
@@ -24,10 +24,8 @@ func (t *TorrentManager) refreshTorrents() []string {
|
|||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
allTorrents, _ := t.DirectoryMap.Get(INT_ALL)
|
allTorrents, _ := t.DirectoryMap.Get(INT_ALL)
|
||||||
doesNotExist := t.deleteOnceDone.Clone()
|
|
||||||
for i := range instances {
|
for i := range instances {
|
||||||
idx := i
|
idx := i
|
||||||
doesNotExist.Remove(instances[idx].ID) // remove if existing
|
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
_ = t.workerPool.Submit(func() {
|
_ = t.workerPool.Submit(func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
@@ -48,30 +46,6 @@ func (t *TorrentManager) refreshTorrents() []string {
|
|||||||
close(infoChan)
|
close(infoChan)
|
||||||
t.log.Infof("Fetched info for %d torrents", len(instances))
|
t.log.Infof("Fetched info for %d torrents", len(instances))
|
||||||
|
|
||||||
// delete expired fixers
|
|
||||||
doesNotExist.Each(func(fixerID string) bool {
|
|
||||||
t.fixers.Remove(fixerID)
|
|
||||||
t.deleteOnceDone.Remove(fixerID)
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
|
|
||||||
// ensure delete
|
|
||||||
infoCache, _ := t.DirectoryMap.Get(INT_INFO_CACHE)
|
|
||||||
for {
|
|
||||||
fixerToDel, ok := t.deleteOnceDone.Pop()
|
|
||||||
if !ok {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
torrent, exists := infoCache.Get(fixerToDel)
|
|
||||||
if exists && torrent.AnyInProgress() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
t.log.Debugf("Ensuring that torrent id=%s is deleted", fixerToDel)
|
|
||||||
t.Delete(t.GetKey(torrent), true)
|
|
||||||
t.Api.DeleteTorrent(fixerToDel)
|
|
||||||
infoCache.Remove(fixerToDel)
|
|
||||||
}
|
|
||||||
|
|
||||||
newlyFetchedKeys := mapset.NewSet[string]()
|
newlyFetchedKeys := mapset.NewSet[string]()
|
||||||
noInfoCount := 0
|
noInfoCount := 0
|
||||||
for info := range infoChan {
|
for info := range infoChan {
|
||||||
@@ -169,7 +143,7 @@ func (t *TorrentManager) getMoreInfo(rdTorrent realdebrid.Torrent) *Torrent {
|
|||||||
|
|
||||||
hasBrokenFiles := false
|
hasBrokenFiles := false
|
||||||
torrentFromFile.SelectedFiles.IterCb(func(filepath string, file *File) {
|
torrentFromFile.SelectedFiles.IterCb(func(filepath string, file *File) {
|
||||||
if !strings.HasPrefix(file.Link, "http") && file.Link != "unselect" {
|
if file.IsBroken && !file.IsDeleted {
|
||||||
hasBrokenFiles = true
|
hasBrokenFiles = true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -307,7 +281,6 @@ func (t *TorrentManager) mergeToMain(existing, toMerge *Torrent) Torrent {
|
|||||||
|
|
||||||
// the link can have the following values
|
// the link can have the following values
|
||||||
// 1. https://*** - the file is available
|
// 1. https://*** - the file is available
|
||||||
// 2. unselect - the file is deleted
|
|
||||||
// 3. empty - the file is not available
|
// 3. empty - the file is not available
|
||||||
mainTorrent.SelectedFiles.IterCb(func(key string, file *File) {
|
mainTorrent.SelectedFiles.IterCb(func(key string, file *File) {
|
||||||
if file.Link == "" {
|
if file.Link == "" {
|
||||||
@@ -320,7 +293,7 @@ func (t *TorrentManager) mergeToMain(existing, toMerge *Torrent) Torrent {
|
|||||||
older.SelectedFiles.IterCb(func(key string, file *File) {
|
older.SelectedFiles.IterCb(func(key string, file *File) {
|
||||||
if !mainTorrent.SelectedFiles.Has(key) {
|
if !mainTorrent.SelectedFiles.Has(key) {
|
||||||
mainTorrent.SelectedFiles.Set(key, file)
|
mainTorrent.SelectedFiles.Set(key, file)
|
||||||
} else if file.Link == "unselect" {
|
} else if file.IsDeleted {
|
||||||
mainTorrent.SelectedFiles.Set(key, file)
|
mainTorrent.SelectedFiles.Set(key, file)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ func (t *TorrentManager) repairAll(torrent *Torrent) {
|
|||||||
// check 1: for broken files
|
// check 1: for broken files
|
||||||
brokenFileIDs := mapset.NewSet[int]()
|
brokenFileIDs := mapset.NewSet[int]()
|
||||||
torrent.SelectedFiles.IterCb(func(_ string, file *File) {
|
torrent.SelectedFiles.IterCb(func(_ string, file *File) {
|
||||||
if !strings.HasPrefix(file.Link, "http") && file.Link != "unselect" {
|
if file.IsBroken && !file.IsDeleted {
|
||||||
brokenFileIDs.Add(file.ID)
|
brokenFileIDs.Add(file.ID)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -337,7 +337,6 @@ func (t *TorrentManager) redownloadTorrent(torrent *Torrent, selection string) (
|
|||||||
err = t.Api.SelectTorrentFiles(newTorrentID, selection)
|
err = t.Api.SelectTorrentFiles(newTorrentID, selection)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Api.DeleteTorrent(newTorrentID)
|
t.Api.DeleteTorrent(newTorrentID)
|
||||||
t.deleteOnceDone.Add(newTorrentID)
|
|
||||||
return nil, fmt.Errorf("cannot start redownloading: %v", err)
|
return nil, fmt.Errorf("cannot start redownloading: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -348,7 +347,6 @@ func (t *TorrentManager) redownloadTorrent(torrent *Torrent, selection string) (
|
|||||||
info, err := t.Api.GetTorrentInfo(newTorrentID)
|
info, err := t.Api.GetTorrentInfo(newTorrentID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Api.DeleteTorrent(newTorrentID)
|
t.Api.DeleteTorrent(newTorrentID)
|
||||||
t.deleteOnceDone.Add(newTorrentID)
|
|
||||||
return nil, fmt.Errorf("cannot get info on redownloaded torrent %s (id=%s) : %v", t.GetKey(torrent), newTorrentID, err)
|
return nil, fmt.Errorf("cannot get info on redownloaded torrent %s (id=%s) : %v", t.GetKey(torrent), newTorrentID, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,7 +362,6 @@ func (t *TorrentManager) redownloadTorrent(torrent *Torrent, selection string) (
|
|||||||
}
|
}
|
||||||
if !isOkStatus {
|
if !isOkStatus {
|
||||||
t.Api.DeleteTorrent(newTorrentID)
|
t.Api.DeleteTorrent(newTorrentID)
|
||||||
t.deleteOnceDone.Add(newTorrentID)
|
|
||||||
return nil, fmt.Errorf("the redownloaded torrent %s (id=%s) is in error state: %s", t.GetKey(torrent), newTorrentID, info.Status)
|
return nil, fmt.Errorf("the redownloaded torrent %s (id=%s) is in error state: %s", t.GetKey(torrent), newTorrentID, info.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -372,7 +369,6 @@ func (t *TorrentManager) redownloadTorrent(torrent *Torrent, selection string) (
|
|||||||
selectionCount := len(strings.Split(selection, ","))
|
selectionCount := len(strings.Split(selection, ","))
|
||||||
if info.Progress == 100 && len(info.Links) != selectionCount {
|
if info.Progress == 100 && len(info.Links) != selectionCount {
|
||||||
t.Api.DeleteTorrent(newTorrentID)
|
t.Api.DeleteTorrent(newTorrentID)
|
||||||
t.deleteOnceDone.Add(newTorrentID)
|
|
||||||
return nil, fmt.Errorf("it did not fix the issue for %s (id=%s), only got %d files but we need %d, undoing", t.GetKey(torrent), info.ID, len(info.Links), selectionCount)
|
return nil, fmt.Errorf("it did not fix the issue for %s (id=%s), only got %d files but we need %d, undoing", t.GetKey(torrent), info.ID, len(info.Links), selectionCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,13 +380,11 @@ func (t *TorrentManager) redownloadTorrent(torrent *Torrent, selection string) (
|
|||||||
for _, id := range oldTorrentIDs {
|
for _, id := range oldTorrentIDs {
|
||||||
torrent.DownloadedIDs.Remove(id)
|
torrent.DownloadedIDs.Remove(id)
|
||||||
t.Api.DeleteTorrent(id)
|
t.Api.DeleteTorrent(id)
|
||||||
t.deleteOnceDone.Add(id)
|
|
||||||
infoCache.Remove(id)
|
infoCache.Remove(id)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// it's a fixer
|
// it's a fixer
|
||||||
t.fixers.Set(newTorrentID, torrent)
|
t.fixers.Set(newTorrentID, torrent)
|
||||||
t.deleteOnceDone.Add(newTorrentID)
|
|
||||||
}
|
}
|
||||||
return info, nil
|
return info, nil
|
||||||
}
|
}
|
||||||
@@ -455,11 +449,11 @@ func (t *TorrentManager) markAsUnfixable(torrent *Torrent, reason string) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// getBrokenFiles returns the files that are not http links and not unselect
|
// getBrokenFiles returns the files that are not http links and not deleted
|
||||||
func getBrokenFiles(torrent *Torrent) []*File {
|
func getBrokenFiles(torrent *Torrent) []*File {
|
||||||
var brokenFiles []*File
|
var brokenFiles []*File
|
||||||
torrent.SelectedFiles.IterCb(func(_ string, file *File) {
|
torrent.SelectedFiles.IterCb(func(_ string, file *File) {
|
||||||
if !strings.HasPrefix(file.Link, "http") && file.Link != "unselect" {
|
if file.IsBroken && !file.IsDeleted {
|
||||||
brokenFiles = append(brokenFiles, file)
|
brokenFiles = append(brokenFiles, file)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -515,7 +509,6 @@ func (t *TorrentManager) handleFixers(fixer realdebrid.Torrent) *Torrent {
|
|||||||
if torrent == nil {
|
if torrent == nil {
|
||||||
t.log.Warnf("repair_method#2: Fixer for %s (id=%s) is done but torrent has been deleted, deleting fixer...", fixer.Name, fixer.ID)
|
t.log.Warnf("repair_method#2: Fixer for %s (id=%s) is done but torrent has been deleted, deleting fixer...", fixer.Name, fixer.ID)
|
||||||
t.Api.DeleteTorrent(fixer.ID)
|
t.Api.DeleteTorrent(fixer.ID)
|
||||||
t.deleteOnceDone.Add(fixer.ID)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -542,7 +535,6 @@ func (t *TorrentManager) handleFixers(fixer realdebrid.Torrent) *Torrent {
|
|||||||
} else {
|
} else {
|
||||||
t.log.Warnf("repair_method#2: Fixer is done but torrent %s is still broken; let's keep the fixer", t.GetKey(torrent))
|
t.log.Warnf("repair_method#2: Fixer is done but torrent %s is still broken; let's keep the fixer", t.GetKey(torrent))
|
||||||
t.Api.DeleteTorrent(info.ID)
|
t.Api.DeleteTorrent(info.ID)
|
||||||
t.deleteOnceDone.Add(fixer.ID)
|
|
||||||
return t.getMoreInfo(fixer)
|
return t.getMoreInfo(fixer)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -550,7 +542,6 @@ func (t *TorrentManager) handleFixers(fixer realdebrid.Torrent) *Torrent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
t.Api.DeleteTorrent(fixer.ID) // delete the fixer
|
t.Api.DeleteTorrent(fixer.ID) // delete the fixer
|
||||||
t.deleteOnceDone.Add(fixer.ID)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -154,4 +154,7 @@ type File struct {
|
|||||||
realdebrid.File
|
realdebrid.File
|
||||||
Ended string `json:"Ended"`
|
Ended string `json:"Ended"`
|
||||||
Link string `json:"Link"`
|
Link string `json:"Link"`
|
||||||
|
IsBroken bool `json:"IsBroken"`
|
||||||
|
IsDeleted bool `json:"IsDeleted"`
|
||||||
|
Rename string `json:"Rename"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,17 +27,11 @@ func CheckFile(directory, torrentName, fileName string, w http.ResponseWriter, r
|
|||||||
}
|
}
|
||||||
|
|
||||||
file, ok := torrent.SelectedFiles.Get(fileName)
|
file, ok := torrent.SelectedFiles.Get(fileName)
|
||||||
if !ok {
|
if !ok || file.IsDeleted {
|
||||||
log.Warnf("Cannot find file %s from path %s", fileName, req.URL.Path)
|
log.Warnf("Cannot find file %s from path %s", fileName, req.URL.Path)
|
||||||
http.Error(w, "Cannot find file", http.StatusNotFound)
|
http.Error(w, "Cannot find file", http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !strings.HasPrefix(file.Link, "http") {
|
|
||||||
// This is a dead file, serve an alternate file
|
|
||||||
log.Warnf("File %s is no longer available", fileName)
|
|
||||||
http.Error(w, "Cannot find file", http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
contentType := getContentMimeType(fileName)
|
contentType := getContentMimeType(fileName)
|
||||||
contentLength := fmt.Sprintf("%d", file.Bytes)
|
contentLength := fmt.Sprintf("%d", file.Bytes)
|
||||||
lastModified := file.Ended
|
lastModified := file.Ended
|
||||||
@@ -48,12 +42,6 @@ func CheckFile(directory, torrentName, fileName string, w http.ResponseWriter, r
|
|||||||
}
|
}
|
||||||
|
|
||||||
func CheckDownloadLink(download *realdebrid.Download, w http.ResponseWriter, req *http.Request, torMgr *torrent.TorrentManager, log *logutil.Logger) {
|
func CheckDownloadLink(download *realdebrid.Download, w http.ResponseWriter, req *http.Request, torMgr *torrent.TorrentManager, log *logutil.Logger) {
|
||||||
if !strings.HasPrefix(download.Link, "http") {
|
|
||||||
// This is a dead file, serve an alternate file
|
|
||||||
log.Warnf("File %s is no longer available", download.Filename)
|
|
||||||
http.Error(w, "Cannot find file", http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
contentType := getContentMimeType(download.Filename)
|
contentType := getContentMimeType(download.Filename)
|
||||||
contentLength := fmt.Sprintf("%d", download.Filesize)
|
contentLength := fmt.Sprintf("%d", download.Filesize)
|
||||||
lastModified := download.Generated
|
lastModified := download.Generated
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ func (dl *Downloader) DownloadFile(directory, torrentName, fileName string, resp
|
|||||||
http.Error(resp, "File not found", http.StatusNotFound)
|
http.Error(resp, "File not found", http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
torrent, ok := torrents.Get(torrentName)
|
torrent, ok := torrents.Get(torrentName)
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Warnf("Cannot find torrent %sfrom path %s", torrentName, req.URL.Path)
|
log.Warnf("Cannot find torrent %sfrom path %s", torrentName, req.URL.Path)
|
||||||
@@ -39,31 +40,28 @@ func (dl *Downloader) DownloadFile(directory, torrentName, fileName string, resp
|
|||||||
}
|
}
|
||||||
|
|
||||||
file, ok := torrent.SelectedFiles.Get(fileName)
|
file, ok := torrent.SelectedFiles.Get(fileName)
|
||||||
if !ok {
|
if !ok || file.IsDeleted {
|
||||||
log.Warnf("Cannot find file %s from path %s", fileName, req.URL.Path)
|
log.Warnf("Cannot find file %s from path %s", fileName, req.URL.Path)
|
||||||
http.Error(resp, "File not found", http.StatusNotFound)
|
http.Error(resp, "File not found", http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !strings.HasPrefix(file.Link, "http") {
|
// log.Debugf("Opening file %s from torrent %s (%s)", fileName, torMgr.GetKey(torrent), file.Link)
|
||||||
// This is a dead file, serve an alternate file
|
if file.IsBroken {
|
||||||
log.Warnf("File %s is not available", fileName)
|
http.Error(resp, "File is not available", http.StatusInternalServerError)
|
||||||
http.Error(resp, "File is not available", http.StatusNotFound)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// log.Debugf("Opening file %s from torrent %s (%s)", fileName, torMgr.GetKey(torrent), file.Link)
|
|
||||||
|
|
||||||
unrestrict := torMgr.UnrestrictUntilOk(file.Link)
|
unrestrict := torMgr.UnrestrictUntilOk(file.Link)
|
||||||
if unrestrict == nil {
|
if unrestrict == nil {
|
||||||
log.Warnf("File %s cannot be unrestricted (link=%s)", fileName, file.Link)
|
file.IsBroken = true
|
||||||
file.Link = ""
|
|
||||||
if cfg.EnableRepair() {
|
if cfg.EnableRepair() {
|
||||||
|
log.Warnf("File %s cannot be unrestricted (link=%s) (repairing...)", fileName, file.Link)
|
||||||
torMgr.TriggerRepair(torrent)
|
torMgr.TriggerRepair(torrent)
|
||||||
} else {
|
} else {
|
||||||
log.Debugf("Repair is disabled, skipping repair for unavailable file %s (link=%s)", fileName, file.Link)
|
log.Warnf("Repair is disabled, skipping repair for unavailable file %s (link=%s)", fileName, file.Link)
|
||||||
}
|
}
|
||||||
http.Error(resp, "File is not available", http.StatusNotFound)
|
http.Error(resp, "File is not available", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
if unrestrict.Filesize != file.Bytes {
|
if unrestrict.Filesize != file.Bytes {
|
||||||
@@ -81,7 +79,7 @@ func (dl *Downloader) DownloadFile(directory, torrentName, fileName string, resp
|
|||||||
if cfg.ShouldVerifyDownloadLink() {
|
if cfg.ShouldVerifyDownloadLink() {
|
||||||
if !dl.client.CanFetchFirstByte(unrestrict.Download) {
|
if !dl.client.CanFetchFirstByte(unrestrict.Download) {
|
||||||
log.Warnf("File %s is not available", fileName)
|
log.Warnf("File %s is not available", fileName)
|
||||||
http.Error(resp, "File is not available", http.StatusNotFound)
|
http.Error(resp, "File is not available", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -95,19 +93,11 @@ func (dl *Downloader) DownloadFile(directory, torrentName, fileName string, resp
|
|||||||
|
|
||||||
// DownloadLink handles a GET request for downloads
|
// DownloadLink handles a GET request for downloads
|
||||||
func (dl *Downloader) DownloadLink(fileName, link string, resp http.ResponseWriter, req *http.Request, torMgr *intTor.TorrentManager, cfg config.ConfigInterface, log *logutil.Logger) {
|
func (dl *Downloader) DownloadLink(fileName, link string, resp http.ResponseWriter, req *http.Request, torMgr *intTor.TorrentManager, cfg config.ConfigInterface, log *logutil.Logger) {
|
||||||
if !strings.HasPrefix(link, "http") {
|
|
||||||
// This is a dead file, serve an alternate file
|
|
||||||
log.Warnf("File %s is not available", fileName)
|
|
||||||
http.Error(resp, "File is not available", http.StatusNotFound)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// log.Debugf("Opening file %s (%s)", fileName, link)
|
// log.Debugf("Opening file %s (%s)", fileName, link)
|
||||||
|
|
||||||
unrestrict := torMgr.UnrestrictUntilOk(link)
|
unrestrict := torMgr.UnrestrictUntilOk(link)
|
||||||
if unrestrict == nil {
|
if unrestrict == nil {
|
||||||
log.Warnf("File %s cannot be unrestricted (link=%s)", fileName, link)
|
log.Warnf("File %s cannot be unrestricted (link=%s)", fileName, link)
|
||||||
http.Error(resp, "File is not available", http.StatusNotFound)
|
http.Error(resp, "File is not available", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
lFilename := strings.ToLower(fileName)
|
lFilename := strings.ToLower(fileName)
|
||||||
@@ -127,7 +117,7 @@ func (dl *Downloader) DownloadLink(fileName, link string, resp http.ResponseWrit
|
|||||||
if cfg.ShouldVerifyDownloadLink() {
|
if cfg.ShouldVerifyDownloadLink() {
|
||||||
if !dl.client.CanFetchFirstByte(unrestrict.Download) {
|
if !dl.client.CanFetchFirstByte(unrestrict.Download) {
|
||||||
log.Warnf("File %s is not available", fileName)
|
log.Warnf("File %s is not available", fileName)
|
||||||
http.Error(resp, "File is not available", http.StatusNotFound)
|
http.Error(resp, "File is not available", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -146,7 +136,7 @@ func (dl *Downloader) streamFileToResponse(torrent *intTor.Torrent, file *intTor
|
|||||||
if file != nil {
|
if file != nil {
|
||||||
log.Errorf("Error creating new request for file %s: %v", file.Path, err)
|
log.Errorf("Error creating new request for file %s: %v", file.Path, err)
|
||||||
}
|
}
|
||||||
http.Error(resp, "File is not available", http.StatusNotFound)
|
http.Error(resp, "File is not available", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,31 +155,35 @@ func (dl *Downloader) streamFileToResponse(torrent *intTor.Torrent, file *intTor
|
|||||||
|
|
||||||
download, err := dl.client.Do(dlReq)
|
download, err := dl.client.Do(dlReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnf("Cannot download file %s: %v", unrestrict.Download, err)
|
|
||||||
if file != nil && unrestrict.Streamable == 1 {
|
if file != nil && unrestrict.Streamable == 1 {
|
||||||
file.Link = ""
|
file.IsBroken = true
|
||||||
if cfg.EnableRepair() && torrent != nil {
|
if cfg.EnableRepair() && torrent != nil {
|
||||||
|
log.Warnf("Cannot download file %s: %v (repairing...)", unrestrict.Download, err)
|
||||||
torMgr.TriggerRepair(torrent)
|
torMgr.TriggerRepair(torrent)
|
||||||
} else {
|
} else {
|
||||||
log.Debugf("Repair is disabled, skipping repair for unavailable file %s (link=%s)", file.Path, file.Link)
|
log.Warnf("Repair is disabled, skipping repair for unavailable file %s (link=%s)", file.Path, file.Link)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
log.Warnf("Cannot download file %s: %v", unrestrict.Download, err)
|
||||||
}
|
}
|
||||||
http.Error(resp, "File is not available", http.StatusNotFound)
|
http.Error(resp, "File is not available", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer download.Body.Close()
|
defer download.Body.Close()
|
||||||
|
|
||||||
if download.StatusCode/100 != 2 {
|
if download.StatusCode/100 != 2 {
|
||||||
if file != nil && unrestrict.Streamable == 1 {
|
if file != nil && unrestrict.Streamable == 1 {
|
||||||
log.Warnf("Received a %s status code for file %s", download.Status, file.Path)
|
file.IsBroken = true
|
||||||
file.Link = ""
|
|
||||||
if cfg.EnableRepair() && torrent != nil {
|
if cfg.EnableRepair() && torrent != nil {
|
||||||
|
log.Warnf("Received a %s status code for file %s (repairing...)", download.Status, file.Path)
|
||||||
torMgr.TriggerRepair(torrent)
|
torMgr.TriggerRepair(torrent)
|
||||||
} else {
|
} else {
|
||||||
log.Debugf("Repair is disabled, skipping repair for unavailable file %s (link=%s)", file.Path, file.Link)
|
log.Warnf("Repair is disabled, skipping repair for unavailable file %s (link=%s)", file.Path, file.Link)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
log.Warnf("Received a %s status code for file %s", download.Status, unrestrict.Download)
|
||||||
}
|
}
|
||||||
http.Error(resp, "File is not available", http.StatusNotFound)
|
http.Error(resp, "File is not available", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user