Add media info filters

This commit is contained in:
Ben Adrian Sarmiento
2024-06-05 19:19:03 +02:00
parent fa26553933
commit c63ce8da0a
7 changed files with 265 additions and 58 deletions

View File

@@ -136,22 +136,23 @@ func (t *TorrentManager) binOnceDoneErrorCheck(torrentId, status string) bool {
// binOnceDone checks if the torrent is in the OnceDoneBin and deletes it if it is.
// returns true if the torrent was in the bin and was deleted, false otherwise
func (t *TorrentManager) binOnceDone(torrentId string) bool {
if t.OnceDoneBin.Contains(torrentId) {
if err := t.api.DeleteTorrent(torrentId); err != nil {
t.repairLog.Warnf("Failed to delete torrent %s: %v", torrentId, err)
func (t *TorrentManager) binOnceDone(completedTorrentId string) bool {
if t.OnceDoneBin.Contains(completedTorrentId) {
if err := t.api.DeleteTorrent(completedTorrentId); err != nil {
t.repairLog.Warnf("Failed to delete torrent %s: %v", completedTorrentId, err)
}
t.deleteInfoFile(torrentId)
t.OnceDoneBin.Remove(torrentId)
t.deleteInfoFile(completedTorrentId)
t.OnceDoneBin.Remove(completedTorrentId)
t.persistBins()
return true
}
// special case: yyy-xxx means if yyy is done, delete xxx
specialCase := fmt.Sprintf("%s-", torrentId)
specialCase := fmt.Sprintf("%s-", completedTorrentId)
if !t.OnceDoneBin.Contains(specialCase) {
return false
}
t.OnceDoneBin.Remove(specialCase)
t.OnceDoneBin.Clone().Each(func(entry string) bool {
if strings.Contains(entry, specialCase) {
idToDelete := strings.Split(entry, "-")[1]
@@ -162,7 +163,7 @@ func (t *TorrentManager) binOnceDone(torrentId string) bool {
}
return false
})
t.deleteInfoFile(torrentId)
t.deleteInfoFile(completedTorrentId)
t.OnceDoneBin.Remove(specialCase)
t.persistBins()
return true

View File

@@ -14,6 +14,7 @@ import (
"github.com/debridmediamanager/zurg/internal/rar"
"github.com/debridmediamanager/zurg/pkg/logutil"
"github.com/debridmediamanager/zurg/pkg/realdebrid"
"github.com/debridmediamanager/zurg/pkg/utils"
mapset "github.com/deckarep/golang-set/v2"
cmap "github.com/orcaman/concurrent-map/v2"
"github.com/panjf2000/ants/v2"
@@ -107,10 +108,7 @@ func NewTorrentManager(cfg config.ConfigInterface, api *realdebrid.RealDebrid, r
if torrent != nil {
accessKey := t.GetKey(torrent)
allTorrents.Set(accessKey, torrent)
t.assignDirectory(torrent, func(directory string) {
listing, _ := t.DirectoryMap.Get(directory)
listing.Set(accessKey, torrent)
})
t.assignDirectory(torrent, false)
}
return false
})
@@ -230,13 +228,16 @@ func (t *TorrentManager) writeTorrentToFile(torrent *Torrent) {
}
func (t *TorrentManager) applyMediaInfoDetails(torrent *Torrent) {
changesApplied := false
torrent.SelectedFiles.IterCb(func(_ string, file *File) {
if file.MediaInfo != nil || file.State.Is("broken_file") {
isPlayable := utils.IsPlayable(file.Path) || t.IsPlayable(file.Path)
if file.MediaInfo != nil || file.State.Is("broken_file") || !isPlayable {
return
}
unrestrict := t.UnrestrictFileUntilOk(file, false)
unrestrict := t.UnrestrictFileUntilOk(file, true)
if unrestrict == nil {
file.State.Event(context.Background(), "break_file")
changesApplied = true
return
}
ctx, cancelFn := context.WithTimeout(context.Background(), 5*time.Second)
@@ -244,11 +245,15 @@ func (t *TorrentManager) applyMediaInfoDetails(torrent *Torrent) {
data, err := ffprobe.ProbeURL(ctx, unrestrict.Download)
if err != nil {
t.log.Warnf("Cannot probe file %s: %v", file.Path, err)
file.State.Event(context.Background(), "break_file")
return
}
file.MediaInfo = data
changesApplied = true
})
if changesApplied {
t.assignDirectory(torrent, true)
t.writeTorrentToFile(torrent)
}
}
func (t *TorrentManager) readTorrentFromFile(filePath string) *Torrent {
@@ -436,7 +441,6 @@ func (t *TorrentManager) analyzeAllTorrents() {
idx := 0
allTorrents.IterCb(func(_ string, torrent *Torrent) {
t.applyMediaInfoDetails(torrent)
t.writeTorrentToFile(torrent)
idx++
t.log.Debugf("Applied media info details to torrent %s (%d/%d)", t.GetKey(torrent), idx, totalCount)
})

View File

@@ -13,25 +13,24 @@ import (
"github.com/debridmediamanager/zurg/pkg/utils"
mapset "github.com/deckarep/golang-set/v2"
cmap "github.com/orcaman/concurrent-map/v2"
"gopkg.in/vansante/go-ffprobe.v2"
)
func inProgressStatus(status string) bool {
return status == "downloading" || status == "uploading" || status == "queued" || status == "compressing"
}
func (t *TorrentManager) refreshTorrents() []string {
func (t *TorrentManager) refreshTorrents() {
t.inProgressHashes = mapset.NewSet[string]()
instances, _, err := t.api.GetTorrents(false)
if err != nil {
t.log.Warnf("Cannot get torrents: %v", err)
return nil
return
}
var wg sync.WaitGroup
var mergeChan = make(chan *Torrent, len(instances))
updatedPaths := mapset.NewSet[string]()
allTorrents, _ := t.DirectoryMap.Get(INT_ALL)
freshIDs := mapset.NewSet[string]()
@@ -62,15 +61,8 @@ func (t *TorrentManager) refreshTorrents() []string {
mainTorrent, exists := allTorrents.Get(accessKey)
if !exists {
allTorrents.Set(accessKey, torrent)
t.assignDirectory(torrent, func(directory string) {
listing, _ := t.DirectoryMap.Get(directory)
listing.Set(accessKey, torrent)
updatedPaths.Add(fmt.Sprintf("%s/%s", directory, accessKey))
})
t.writeTorrentToFile(torrent)
t.assignDirectory(torrent, true)
} else if !mainTorrent.DownloadedIDs.Contains(tInfo.ID) {
forMerging = torrent
}
@@ -102,20 +94,7 @@ func (t *TorrentManager) refreshTorrents() []string {
mainTorrent := t.mergeTorrents(existing, torrent)
allTorrents.Set(accessKey, mainTorrent)
t.writeTorrentToFile(mainTorrent)
t.DirectoryMap.IterCb(func(directory string, torrents cmap.ConcurrentMap[string, *Torrent]) {
if strings.HasPrefix(directory, "int__") {
return
}
torrents.Remove(accessKey)
})
t.assignDirectory(mainTorrent, func(directory string) {
listing, _ := t.DirectoryMap.Get(directory)
listing.Set(accessKey, mainTorrent)
updatedPaths.Add(fmt.Sprintf("%s/%s", directory, accessKey))
})
t.assignDirectory(mainTorrent, true)
}
// removed torrents
@@ -163,8 +142,6 @@ func (t *TorrentManager) refreshTorrents() []string {
}
})
})
return updatedPaths.ToSlice()
}
// StartRefreshJob periodically refreshes the torrents
@@ -183,10 +160,8 @@ func (t *TorrentManager) StartRefreshJob() {
}
t.setNewLatestState(checksum)
updatedPaths := t.refreshTorrents()
t.refreshTorrents()
t.log.Info("Finished refreshing torrents")
t.TriggerHookOnLibraryUpdate(updatedPaths)
case <-t.RefreshKillSwitch:
t.log.Info("Stopping periodic refresh job")
return
@@ -364,15 +339,28 @@ func (t *TorrentManager) mergeTorrents(existing, toMerge *Torrent) *Torrent {
return mergedTorrent
}
func (t *TorrentManager) assignDirectory(tor *Torrent, cb func(string)) {
func (t *TorrentManager) assignDirectory(tor *Torrent, triggerHook bool) {
accessKey := t.GetKey(tor)
t.DirectoryMap.IterCb(func(directory string, torrents cmap.ConcurrentMap[string, *Torrent]) {
if strings.HasPrefix(directory, "int__") {
return
}
torrents.Remove(accessKey)
})
torrentIDs := tor.DownloadedIDs.ToSlice()
// get filenames needed for directory conditions
var filenames []string
var fileSizes []int64
var mediaInfos []*ffprobe.ProbeData
unplayable := true
tor.SelectedFiles.IterCb(func(key string, file *File) {
filenames = append(filenames, filepath.Base(file.Path))
fileSizes = append(fileSizes, file.Bytes)
if file.MediaInfo != nil {
mediaInfos = append(mediaInfos, file.MediaInfo)
}
if utils.IsPlayable(file.Path) || t.IsPlayable(file.Path) {
unplayable = false
}
@@ -389,8 +377,13 @@ func (t *TorrentManager) assignDirectory(tor *Torrent, cb func(string)) {
configV1 := t.Config.(*config.ZurgConfigV1)
for _, directories := range configV1.GetGroupMap() {
for _, directory := range directories {
if t.Config.MeetsConditions(directory, t.GetKey(tor), tor.ComputeTotalSize(), torrentIDs, filenames, fileSizes) {
cb(directory)
if t.Config.MeetsConditions(directory, t.GetKey(tor), tor.ComputeTotalSize(), torrentIDs, filenames, fileSizes, mediaInfos) {
listing, _ := t.DirectoryMap.Get(directory)
listing.Set(accessKey, tor)
if triggerHook {
t.TriggerHookOnLibraryUpdate([]string{fmt.Sprintf("%s/%s", directory, accessKey)})
}
break
}
}

View File

@@ -119,6 +119,7 @@ func (t *TorrentManager) repairAll(torrent *Torrent) {
}
})
if brokenFileCount > 0 {
t.repairLog.Debugf("Torrent %s has %d broken file(s), adding to repair list", t.GetKey(torrent), brokenFileCount)
toRepair.Add(torrent)
return
}
@@ -184,7 +185,7 @@ func (t *TorrentManager) repair(torrent *Torrent) {
}
allPlayable = false
if t.Config.GetRarAction() == "extract" {
if t.Config.GetRarAction() == "extract" && file.ID != 0 {
info, _ := t.redownloadTorrent(torrent, []string{fmt.Sprintf("%d", file.ID)})
if info != nil {
t.setToBinOnceDone(info.ID)