Fix repairs

This commit is contained in:
Ben Sarmiento
2023-12-02 02:05:35 +01:00
parent 2f7e3b0ca9
commit b5a923fd17

View File

@@ -238,21 +238,13 @@ func (t *TorrentManager) startRefreshJob() {
} }
func (t *TorrentManager) RefreshTorrents() { func (t *TorrentManager) RefreshTorrents() {
// get all torrent info
instances, _, err := t.Api.GetTorrents(0) instances, _, err := t.Api.GetTorrents(0)
if err != nil { if err != nil {
t.log.Warnf("Cannot get torrents: %v\n", err) t.log.Warnf("Cannot get torrents: %v\n", err)
return return
} }
instanceCount := len(instances) instanceCount := len(instances)
// todo: inefficient
// handle deleted torrents in info cache
// but only do it if there is an info cache filled
infoCache, _ := t.DirectoryMap.Get(INT_INFO_CACHE)
if infoCache.Count() > 0 {
t.cleanInfoCache(instances)
}
infoChan := make(chan *Torrent, instanceCount) infoChan := make(chan *Torrent, instanceCount)
var wg sync.WaitGroup var wg sync.WaitGroup
for i := range instances { for i := range instances {
@@ -267,6 +259,14 @@ func (t *TorrentManager) RefreshTorrents() {
close(infoChan) close(infoChan)
t.log.Infof("Fetched info for %d torrents", instanceCount) t.log.Infof("Fetched info for %d torrents", instanceCount)
// todo: inefficient
// handle deleted torrents in info cache
// but only do it if there is an info cache filled
infoCache, _ := t.DirectoryMap.Get(INT_INFO_CACHE)
if infoCache.Count() > 0 {
t.cleanInfoCache(instances)
}
freshKeys := set.NewStringSet() freshKeys := set.NewStringSet()
oldTorrents, _ := t.DirectoryMap.Get(INT_ALL) oldTorrents, _ := t.DirectoryMap.Get(INT_ALL)
noInfoCount := 0 noInfoCount := 0
@@ -298,8 +298,8 @@ func (t *TorrentManager) RefreshTorrents() {
t.accessKeySet.Add(accessKey) t.accessKeySet.Add(accessKey)
return true return true
}) })
// now we can build the directory responses
t.checkForOtherDeletedTorrents() t.checkForOtherDeletedTorrents()
// now we can build the directory responses
t.UpdateDirectoryResponsesCache() t.UpdateDirectoryResponsesCache()
t.log.Infof("Compiled into %d torrents, %d were missing info", oldTorrents.Count(), noInfoCount) t.log.Infof("Compiled into %d torrents, %d were missing info", oldTorrents.Count(), noInfoCount)
@@ -340,15 +340,15 @@ func (t *TorrentManager) cleanInfoCache(torrents []realdebrid.Torrent) {
// getMoreInfo gets original name, size and files for a torrent // getMoreInfo gets original name, size and files for a torrent
func (t *TorrentManager) getMoreInfo(rdTorrent realdebrid.Torrent) *Torrent { func (t *TorrentManager) getMoreInfo(rdTorrent realdebrid.Torrent) *Torrent {
infoCache, _ := t.DirectoryMap.Get(INT_INFO_CACHE) infoCache, _ := t.DirectoryMap.Get(INT_INFO_CACHE)
if infoCache.Has(rdTorrent.ID) { if tor, exists := infoCache.Get(rdTorrent.ID); exists {
tor, _ := infoCache.Get(rdTorrent.ID) // in memory cache is always fresh
return tor return tor
} }
var info *realdebrid.TorrentInfo var info *realdebrid.TorrentInfo
var err error var err error
// file cache
torrentFromFile := t.readTorrentFromFile(rdTorrent.ID) torrentFromFile := t.readTorrentFromFile(rdTorrent.ID)
// check staleness of file cache
if torrentFromFile != nil && len(torrentFromFile.ID) > 0 && len(torrentFromFile.Links) > 0 && len(torrentFromFile.Links) == len(rdTorrent.Links) && torrentFromFile.Links[0] == rdTorrent.Links[0] { if torrentFromFile != nil && len(torrentFromFile.ID) > 0 && len(torrentFromFile.Links) > 0 && len(torrentFromFile.Links) == len(rdTorrent.Links) && torrentFromFile.Links[0] == rdTorrent.Links[0] {
info = torrentFromFile info = torrentFromFile
info.Progress = rdTorrent.Progress info.Progress = rdTorrent.Progress
@@ -381,6 +381,10 @@ func (t *TorrentManager) getMoreInfo(rdTorrent realdebrid.Torrent) *Torrent {
} }
if len(selectedFiles) > len(info.Links) && info.Progress == 100 { if len(selectedFiles) > len(info.Links) && info.Progress == 100 {
t.log.Warnf("Torrent id=%s is partly expired, it has %d selected files but only %d links", info.ID, len(selectedFiles), len(info.Links)) t.log.Warnf("Torrent id=%s is partly expired, it has %d selected files but only %d links", info.ID, len(selectedFiles), len(info.Links))
for i, file := range selectedFiles {
file.Link = "repair"
i++
}
} else if len(selectedFiles) == len(info.Links) { } else if len(selectedFiles) == len(info.Links) {
// all links are still intact! good! // all links are still intact! good!
for i, file := range selectedFiles { for i, file := range selectedFiles {
@@ -447,8 +451,10 @@ func (t *TorrentManager) readTorrentFromFile(torrentID string) *realdebrid.Torre
file, err := os.Open(filePath) file, err := os.Open(filePath)
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
t.log.Debug("[file] file does not exist")
return nil return nil
} }
t.log.Debugf("[file] error opening file: %v", err)
return nil return nil
} }
defer file.Close() defer file.Close()
@@ -457,9 +463,11 @@ func (t *TorrentManager) readTorrentFromFile(torrentID string) *realdebrid.Torre
var torrent realdebrid.TorrentInfo var torrent realdebrid.TorrentInfo
dataDecoder := gob.NewDecoder(r) dataDecoder := gob.NewDecoder(r)
if err := dataDecoder.Decode(&torrent); err != nil { if err := dataDecoder.Decode(&torrent); err != nil {
t.log.Debugf("[file] error decoding torrent: %v", err)
return nil return nil
} }
if torrent.Version != t.requiredVersion { if torrent.Version != t.requiredVersion {
t.log.Debugf("[file] not the right version: %s", torrent.Version)
return nil return nil
} }
return &torrent return &torrent
@@ -492,7 +500,7 @@ func (t *TorrentManager) organizeChaos(links []string, selectedFiles []*File) ([
resultsChan <- Result{Response: download} resultsChan <- Result{Response: download}
return return
} }
resp := t.Api.UnrestrictUntilOk(link, t.Config.ShouldServeFromRclone()) resp := t.UnrestrictUntilOk(link)
resultsChan <- Result{Response: resp} resultsChan <- Result{Response: resp}
}) })
} }
@@ -544,6 +552,7 @@ func (t *TorrentManager) repairAll() {
} }
allTorrents, _ := t.DirectoryMap.Get(INT_ALL) allTorrents, _ := t.DirectoryMap.Get(INT_ALL)
var toRepair []string
allTorrents.IterCb(func(_ string, torrent *Torrent) { allTorrents.IterCb(func(_ string, torrent *Torrent) {
if torrent.AnyInProgress() { if torrent.AnyInProgress() {
t.log.Debugf("Skipping %s for repairs because it is in progress", torrent.AccessKey) t.log.Debugf("Skipping %s for repairs because it is in progress", torrent.AccessKey)
@@ -553,15 +562,18 @@ func (t *TorrentManager) repairAll() {
torrent.SelectedFiles.IterCb(func(_ string, file *File) { torrent.SelectedFiles.IterCb(func(_ string, file *File) {
if file.Link == "repair" && !forRepair { if file.Link == "repair" && !forRepair {
file.Link = "repairing" file.Link = "repairing"
t.log.Debugf("Found a file to repair for torrent %s", torrent.AccessKey)
forRepair = true forRepair = true
} }
}) })
if forRepair { if forRepair {
t.log.Infof("Repairing %s", torrent.AccessKey) toRepair = append(toRepair, torrent.AccessKey)
t.Repair(torrent.AccessKey)
} }
}) })
t.log.Debugf("Found %d torrents to repair", len(toRepair))
for _, accessKey := range toRepair {
t.log.Infof("Repairing %s", accessKey)
t.Repair(accessKey)
}
} }
func (t *TorrentManager) checkForOtherDeletedTorrents() { func (t *TorrentManager) checkForOtherDeletedTorrents() {
@@ -577,7 +589,7 @@ func (t *TorrentManager) checkForOtherDeletedTorrents() {
if unselected == torrent.SelectedFiles.Count() && unselected > 0 { if unselected == torrent.SelectedFiles.Count() && unselected > 0 {
t.log.Infof("Deleting %s", torrent.AccessKey) t.log.Infof("Deleting %s", torrent.AccessKey)
toDelete = append(toDelete, torrent.AccessKey) toDelete = append(toDelete, torrent.AccessKey)
} else { } else if unselected > 0 {
// save to file // save to file
for i := range torrent.Instances { for i := range torrent.Instances {
t.writeTorrentToFile(&torrent.Instances[i]) t.writeTorrentToFile(&torrent.Instances[i])
@@ -590,8 +602,8 @@ func (t *TorrentManager) checkForOtherDeletedTorrents() {
} }
func (t *TorrentManager) Delete(accessKey string, deleteInRD bool, updateDirectoryResponses bool) { func (t *TorrentManager) Delete(accessKey string, deleteInRD bool, updateDirectoryResponses bool) {
t.log.Infof("Deleting torrent %s", accessKey)
if deleteInRD { if deleteInRD {
t.log.Infof("Deleting torrent %s in RD", accessKey)
allTorrents, _ := t.DirectoryMap.Get(INT_ALL) allTorrents, _ := t.DirectoryMap.Get(INT_ALL)
if torrent, ok := allTorrents.Get(accessKey); ok { if torrent, ok := allTorrents.Get(accessKey); ok {
for _, instance := range torrent.Instances { for _, instance := range torrent.Instances {
@@ -612,11 +624,6 @@ func (t *TorrentManager) Delete(accessKey string, deleteInRD bool, updateDirecto
} }
func (t *TorrentManager) Repair(accessKey string) { func (t *TorrentManager) Repair(accessKey string) {
if !t.Config.EnableRepair() {
t.log.Warn("Repair is disabled; if you do not have other zurg instances running, you should enable repair")
return
}
allTorrents, _ := t.DirectoryMap.Get(INT_ALL) allTorrents, _ := t.DirectoryMap.Get(INT_ALL)
torrent, _ := allTorrents.Get(accessKey) torrent, _ := allTorrents.Get(accessKey)
if torrent == nil { if torrent == nil {