Reimplement deletes and marking files as broken
This commit is contained in:
@@ -3,20 +3,20 @@ package torrent
|
||||
import cmap "github.com/orcaman/concurrent-map/v2"
|
||||
|
||||
func (t *TorrentManager) CheckDeletedStatus(torrent *Torrent) bool {
|
||||
var unselectedIDs []int
|
||||
var deletedIDs []int
|
||||
torrent.SelectedFiles.IterCb(func(_ string, file *File) {
|
||||
if file.Link == "unselect" {
|
||||
unselectedIDs = append(unselectedIDs, file.ID)
|
||||
if file.IsDeleted {
|
||||
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
|
||||
} else if len(unselectedIDs) > 0 {
|
||||
} else if len(deletedIDs) > 0 {
|
||||
t.saveTorrentChangesToDisk(torrent, func(info *Torrent) {
|
||||
info.SelectedFiles.IterCb(func(_ string, file *File) {
|
||||
for _, unselectedID := range unselectedIDs {
|
||||
if file.ID == unselectedID {
|
||||
file.Link = "unselect"
|
||||
for _, deletedID := range deletedIDs {
|
||||
if file.ID == deletedID {
|
||||
file.IsDeleted = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ type TorrentManager struct {
|
||||
DownloadCache cmap.ConcurrentMap[string, *realdebrid.Download]
|
||||
DownloadMap cmap.ConcurrentMap[string, *realdebrid.Download]
|
||||
fixers cmap.ConcurrentMap[string, *Torrent]
|
||||
deleteOnceDone mapset.Set[string]
|
||||
allAccessKeys mapset.Set[string]
|
||||
latestState *LibraryState
|
||||
requiredVersion string
|
||||
@@ -56,7 +55,6 @@ func NewTorrentManager(cfg config.ConfigInterface, api *realdebrid.RealDebrid, w
|
||||
RefreshKillSwitch: make(chan struct{}, 1),
|
||||
RepairKillSwitch: make(chan struct{}, 1),
|
||||
fixers: cmap.New[*Torrent](),
|
||||
deleteOnceDone: mapset.NewSet[string](),
|
||||
allAccessKeys: mapset.NewSet[string](),
|
||||
latestState: &LibraryState{},
|
||||
requiredVersion: "0.9.3-hotfix.3",
|
||||
@@ -78,6 +76,7 @@ func NewTorrentManager(cfg config.ConfigInterface, api *realdebrid.RealDebrid, w
|
||||
|
||||
// proxy
|
||||
func (t *TorrentManager) UnrestrictUntilOk(link string) *realdebrid.Download {
|
||||
// check if it's a valid link
|
||||
if !strings.HasPrefix(link, "http") {
|
||||
return nil
|
||||
}
|
||||
@@ -114,6 +113,9 @@ func (t *TorrentManager) GetKey(torrent *Torrent) string {
|
||||
}
|
||||
|
||||
func (t *TorrentManager) GetPath(file *File) string {
|
||||
if !t.Config.ShouldIgnoreRenames() && file.Rename != "" {
|
||||
return file.Rename
|
||||
}
|
||||
if t.Config.ShouldExposeFullPath() {
|
||||
filename := strings.TrimPrefix(file.Path, "/")
|
||||
filename = strings.ReplaceAll(filename, "/", " - ")
|
||||
|
||||
@@ -24,10 +24,8 @@ func (t *TorrentManager) refreshTorrents() []string {
|
||||
var wg sync.WaitGroup
|
||||
|
||||
allTorrents, _ := t.DirectoryMap.Get(INT_ALL)
|
||||
doesNotExist := t.deleteOnceDone.Clone()
|
||||
for i := range instances {
|
||||
idx := i
|
||||
doesNotExist.Remove(instances[idx].ID) // remove if existing
|
||||
wg.Add(1)
|
||||
_ = t.workerPool.Submit(func() {
|
||||
defer wg.Done()
|
||||
@@ -48,30 +46,6 @@ func (t *TorrentManager) refreshTorrents() []string {
|
||||
close(infoChan)
|
||||
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]()
|
||||
noInfoCount := 0
|
||||
for info := range infoChan {
|
||||
@@ -169,7 +143,7 @@ func (t *TorrentManager) getMoreInfo(rdTorrent realdebrid.Torrent) *Torrent {
|
||||
|
||||
hasBrokenFiles := false
|
||||
torrentFromFile.SelectedFiles.IterCb(func(filepath string, file *File) {
|
||||
if !strings.HasPrefix(file.Link, "http") && file.Link != "unselect" {
|
||||
if file.IsBroken && !file.IsDeleted {
|
||||
hasBrokenFiles = true
|
||||
}
|
||||
})
|
||||
@@ -307,7 +281,6 @@ func (t *TorrentManager) mergeToMain(existing, toMerge *Torrent) Torrent {
|
||||
|
||||
// the link can have the following values
|
||||
// 1. https://*** - the file is available
|
||||
// 2. unselect - the file is deleted
|
||||
// 3. empty - the file is not available
|
||||
mainTorrent.SelectedFiles.IterCb(func(key string, file *File) {
|
||||
if file.Link == "" {
|
||||
@@ -320,7 +293,7 @@ func (t *TorrentManager) mergeToMain(existing, toMerge *Torrent) Torrent {
|
||||
older.SelectedFiles.IterCb(func(key string, file *File) {
|
||||
if !mainTorrent.SelectedFiles.Has(key) {
|
||||
mainTorrent.SelectedFiles.Set(key, file)
|
||||
} else if file.Link == "unselect" {
|
||||
} else if file.IsDeleted {
|
||||
mainTorrent.SelectedFiles.Set(key, file)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -101,7 +101,7 @@ func (t *TorrentManager) repairAll(torrent *Torrent) {
|
||||
// check 1: for broken files
|
||||
brokenFileIDs := mapset.NewSet[int]()
|
||||
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)
|
||||
}
|
||||
})
|
||||
@@ -337,7 +337,6 @@ func (t *TorrentManager) redownloadTorrent(torrent *Torrent, selection string) (
|
||||
err = t.Api.SelectTorrentFiles(newTorrentID, selection)
|
||||
if err != nil {
|
||||
t.Api.DeleteTorrent(newTorrentID)
|
||||
t.deleteOnceDone.Add(newTorrentID)
|
||||
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)
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -364,7 +362,6 @@ func (t *TorrentManager) redownloadTorrent(torrent *Torrent, selection string) (
|
||||
}
|
||||
if !isOkStatus {
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -372,7 +369,6 @@ func (t *TorrentManager) redownloadTorrent(torrent *Torrent, selection string) (
|
||||
selectionCount := len(strings.Split(selection, ","))
|
||||
if info.Progress == 100 && len(info.Links) != selectionCount {
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -384,13 +380,11 @@ func (t *TorrentManager) redownloadTorrent(torrent *Torrent, selection string) (
|
||||
for _, id := range oldTorrentIDs {
|
||||
torrent.DownloadedIDs.Remove(id)
|
||||
t.Api.DeleteTorrent(id)
|
||||
t.deleteOnceDone.Add(id)
|
||||
infoCache.Remove(id)
|
||||
}
|
||||
} else {
|
||||
// it's a fixer
|
||||
t.fixers.Set(newTorrentID, torrent)
|
||||
t.deleteOnceDone.Add(newTorrentID)
|
||||
}
|
||||
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 {
|
||||
var brokenFiles []*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)
|
||||
}
|
||||
})
|
||||
@@ -515,7 +509,6 @@ func (t *TorrentManager) handleFixers(fixer realdebrid.Torrent) *Torrent {
|
||||
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.Api.DeleteTorrent(fixer.ID)
|
||||
t.deleteOnceDone.Add(fixer.ID)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -542,7 +535,6 @@ func (t *TorrentManager) handleFixers(fixer realdebrid.Torrent) *Torrent {
|
||||
} 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.Api.DeleteTorrent(info.ID)
|
||||
t.deleteOnceDone.Add(fixer.ID)
|
||||
return t.getMoreInfo(fixer)
|
||||
}
|
||||
} else {
|
||||
@@ -550,7 +542,6 @@ func (t *TorrentManager) handleFixers(fixer realdebrid.Torrent) *Torrent {
|
||||
}
|
||||
|
||||
t.Api.DeleteTorrent(fixer.ID) // delete the fixer
|
||||
t.deleteOnceDone.Add(fixer.ID)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -152,6 +152,9 @@ func (t *Torrent) OlderThanDuration(duration time.Duration) bool {
|
||||
|
||||
type File struct {
|
||||
realdebrid.File
|
||||
Ended string `json:"Ended"`
|
||||
Link string `json:"Link"`
|
||||
Ended string `json:"Ended"`
|
||||
Link string `json:"Link"`
|
||||
IsBroken bool `json:"IsBroken"`
|
||||
IsDeleted bool `json:"IsDeleted"`
|
||||
Rename string `json:"Rename"`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user