Use json instead

This commit is contained in:
Ben Sarmiento
2023-12-02 05:00:37 +01:00
parent a8e8bab853
commit b140dfd4d0
3 changed files with 124 additions and 69 deletions

View File

@@ -1,9 +1,9 @@
package torrent
import (
"bufio"
"encoding/gob"
"encoding/json"
"fmt"
"io"
"math"
"net/url"
"os"
@@ -56,7 +56,7 @@ func NewTorrentManager(cfg config.ConfigInterface, api *realdebrid.RealDebrid, p
ResponseCache: cache,
accessKeySet: set.NewStringSet(),
latestState: &initialSate,
requiredVersion: "18.11.2023",
requiredVersion: "02.12.2023",
workerPool: p,
log: log,
}
@@ -317,27 +317,18 @@ func (t *TorrentManager) startRefreshJob() {
// getMoreInfo gets original name, size and files for a torrent
func (t *TorrentManager) getMoreInfo(rdTorrent realdebrid.Torrent) *Torrent {
infoCache, _ := t.DirectoryMap.Get(INT_INFO_CACHE)
if tor, exists := infoCache.Get(rdTorrent.ID); exists {
// in memory cache is always fresh
if tor, exists := infoCache.Get(rdTorrent.ID); exists && tor.SelectedFiles.Count() == len(rdTorrent.Links) {
return tor
}
var info *realdebrid.TorrentInfo
var err error
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] {
info = torrentFromFile
info.Progress = rdTorrent.Progress
} else {
torrentFromFile = nil
if torrentFromFile != nil && torrentFromFile.SelectedFiles.Count() == len(rdTorrent.Links) {
return torrentFromFile
}
if info == nil {
info, err = t.Api.GetTorrentInfo(rdTorrent.ID)
if err != nil {
t.log.Warnf("Cannot get info for id=%s: %v\n", rdTorrent.ID, err)
return nil
}
info, err := t.Api.GetTorrentInfo(rdTorrent.ID)
if err != nil {
t.log.Warnf("Cannot get info for id=%s: %v\n", rdTorrent.ID, err)
return nil
}
// SelectedFiles is a subset of Files with only the selected ones
// it also has a Link field, which can be empty
@@ -373,18 +364,18 @@ func (t *TorrentManager) getMoreInfo(rdTorrent realdebrid.Torrent) *Torrent {
torrent := Torrent{
AccessKey: t.computeAccessKey(info.Name, info.OriginalName),
LatestAdded: info.Added,
Instances: []realdebrid.TorrentInfo{*info},
Instances: []*realdebrid.TorrentInfo{info},
}
torrent.SelectedFiles = cmap.New[*File]()
for _, file := range selectedFiles {
torrent.SelectedFiles.Set(filepath.Base(file.Path), file)
}
if len(selectedFiles) > 0 && torrentFromFile == nil {
t.writeTorrentToFile(info) // only when there are selected files, else it's useless
}
infoCache.Set(rdTorrent.ID, &torrent)
err = t.writeTorrentToFile(rdTorrent.ID, &torrent)
if err != nil {
t.log.Warnf("Cannot write torrent to file: %v", err)
}
return &torrent
}
@@ -403,28 +394,31 @@ func (t *TorrentManager) computeAccessKey(name, originalName string) string {
}
}
func (t *TorrentManager) writeTorrentToFile(torrent *realdebrid.TorrentInfo) error {
filePath := "data/" + torrent.ID + ".bin"
func (t *TorrentManager) writeTorrentToFile(instanceID string, torrent *Torrent) error {
filePath := "data/" + instanceID + ".json"
file, err := os.Create(filePath)
if err != nil {
return fmt.Errorf("failed creating file: %w", err)
}
defer file.Close()
w := bufio.NewWriter(file)
defer w.Flush()
torrent.Version = t.requiredVersion
dataEncoder := gob.NewEncoder(w)
if err := dataEncoder.Encode(torrent); err != nil {
return fmt.Errorf("failed encoding torrent: %w", err)
jsonData, err := json.Marshal(torrent)
if err != nil {
return fmt.Errorf("failed marshaling torrent: %w", err)
}
t.log.Debugf("Saved torrent %s to file", torrent.ID)
if _, err := file.Write(jsonData); err != nil {
return fmt.Errorf("failed writing to file: %w", err)
}
t.log.Debugf("Saved torrent %s to file", instanceID)
return nil
}
func (t *TorrentManager) readTorrentFromFile(torrentID string) *realdebrid.TorrentInfo {
filePath := "data/" + torrentID + ".bin"
func (t *TorrentManager) readTorrentFromFile(torrentID string) *Torrent {
filePath := "data/" + torrentID + ".json"
file, err := os.Open(filePath)
if err != nil {
if os.IsNotExist(err) {
@@ -435,23 +429,25 @@ func (t *TorrentManager) readTorrentFromFile(torrentID string) *realdebrid.Torre
return nil
}
defer file.Close()
r := bufio.NewReader(file)
var torrent realdebrid.TorrentInfo
dataDecoder := gob.NewDecoder(r)
if err := dataDecoder.Decode(&torrent); err != nil {
t.log.Debugf("[file] error decoding torrent: %v", err)
jsonData, err := io.ReadAll(file)
if err != nil {
t.log.Debugf("[file] error reading file: %v", err)
return nil
}
var torrent *Torrent
if err := json.Unmarshal(jsonData, &torrent); err != nil {
t.log.Debugf("[file] error unmarshaling torrent: %v", err)
return nil
}
if torrent.Version != t.requiredVersion {
t.log.Debugf("[file] not the right version: %s", torrent.Version)
return nil
}
return &torrent
return torrent
}
func (t *TorrentManager) deleteTorrentFile(torrentID string) {
filePath := "data/" + torrentID + ".bin"
filePath := "data/" + torrentID + ".json"
err := os.Remove(filePath)
if err != nil {
t.log.Warnf("Cannot delete file %s: %v", filePath, err)
@@ -567,18 +563,17 @@ func (t *TorrentManager) checkForOtherDeletedTorrents() {
}
func (t *TorrentManager) CheckDeletedState(torrent *Torrent) bool {
unselected := 0
var unselectedIDs []int
torrent.SelectedFiles.IterCb(func(_ string, file *File) {
if file.Link == "unselect" {
unselected++
unselectedIDs = append(unselectedIDs, file.ID)
}
})
if unselected == torrent.SelectedFiles.Count() && unselected > 0 {
if len(unselectedIDs) == torrent.SelectedFiles.Count() && len(unselectedIDs) > 0 {
return true
} else if unselected > 0 {
// save to file
} else if len(unselectedIDs) > 0 {
for i := range torrent.Instances {
t.writeTorrentToFile(&torrent.Instances[i])
t.writeTorrentToFile(torrent.Instances[i].ID, torrent)
}
}
return false