Skip to content

Commit

Permalink
Changelog 0.2.5
Browse files Browse the repository at this point in the history
  • Loading branch information
sirrobot01 committed Oct 1, 2024
1 parent f6c6144 commit f118c5b
Show file tree
Hide file tree
Showing 10 changed files with 121 additions and 66 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,9 @@
- Add file download support(Sequential Download)
- Fix http handler error
- Fix *arrs map failing concurrently
- Fix cache not being updated
- Fix cache not being updated

#### 0.2.5
- Fix ContentPath not being set prior
- Rewrote Readme
- Cleaned up the code
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,19 @@ Download the binary from the releases page and run it with the config file.
"max_cache_size": 1000,
"qbittorrent": {
"port": "8282",
"username": "admin", // deprecated
"password": "admin", // deprecated
"download_folder": "/media/symlinks/",
"categories": ["sonarr", "radarr"],
"refresh_interval": 5 // in seconds
"refresh_interval": 5
}
}
```

#### Config Notes
##### Max Cache Size
- The `max_cache_size` key is used to set the maximum number of infohashes that can be stored in the availability cache. This is used to prevent round trip to the debrid provider when using the proxy/Qbittorrent
- The default value is `1000`
- The cache is stored in memory and is not persisted on restart

##### Debrid Config
- This config key is important as it's used for both Blackhole and Proxy

Expand All @@ -93,6 +96,7 @@ Download the binary from the releases page and run it with the config file.
- The `port` key is the port the qBittorrent will listen on
- The `download_folder` is the folder where the torrents will be downloaded. e.g `/media/symlinks/`
- The `categories` key is used to filter out torrents based on the category. e.g `sonarr`, `radarr`
- The `refresh_interval` key is used to set the interval in minutes to refresh the Arrs Monitored Downloads(it's in seconds). The default value is `5` seconds

### Proxy

Expand Down
1 change: 1 addition & 0 deletions pkg/debrid/torrent.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type Torrent struct {
Magnet *common.Magnet `json:"magnet"`
Files []TorrentFile `json:"files"`
Status string `json:"status"`
Added string `json:"added"`
Progress float64 `json:"progress"`
Speed int64 `json:"speed"`
Seeders int `json:"seeders"`
Expand Down
2 changes: 1 addition & 1 deletion pkg/qbit/downloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ func (q *QBit) createSymLink(path string, torrentMountPath string, file debrid.T
torrentFilePath := filepath.Join(torrentMountPath, file.Name) // debridFolder/MyTVShow/MyTVShow.S01E01.720p.mkv
err := os.Symlink(torrentFilePath, fullPath)
if err != nil {
q.logger.Printf("Failed to create symlink: %s\n", fullPath)
q.logger.Printf("Failed to create symlink: %s: %v\n", fullPath, err)
}
// Check if the file exists
if !common.FileReady(fullPath) {
Expand Down
1 change: 1 addition & 0 deletions pkg/qbit/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ func (q *QBit) AddRoutes(r chi.Router) http.Handler {
r.Get("/resume", q.handleTorrentsResume)
r.Get("/recheck", q.handleTorrentRecheck)
r.Get("/properties", q.handleTorrentProperties)
r.Get("/files", q.handleTorrentFiles)
})

r.Route("/app", func(r chi.Router) {
Expand Down
3 changes: 1 addition & 2 deletions pkg/qbit/handlers_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,5 @@ import (
)

func (q *QBit) handleLogin(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("Ok."))
_, _ = w.Write([]byte("Ok."))
}
10 changes: 10 additions & 0 deletions pkg/qbit/handlers_torrent.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,13 @@ func (q *QBit) handleTorrentProperties(w http.ResponseWriter, r *http.Request) {
properties := q.GetTorrentProperties(torrent)
JSONResponse(w, properties, http.StatusOK)
}

func (q *QBit) handleTorrentFiles(w http.ResponseWriter, r *http.Request) {
hash := r.URL.Query().Get("hash")
torrent := q.storage.Get(hash)
if torrent == nil {
return
}
files := q.GetTorrentFiles(torrent)
JSONResponse(w, files, http.StatusOK)
}
29 changes: 10 additions & 19 deletions pkg/qbit/qbit.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,7 @@ func (q *QBit) Process(ctx context.Context, magnet *common.Magnet, category stri
}
return err
}
torrent.ID = debridTorrent.Id
torrent.DebridTorrent = debridTorrent
torrent.Name = debridTorrent.Name
torrent = q.UpdateTorrentMin(torrent, debridTorrent)
q.storage.AddOrUpdate(torrent)
go q.processFiles(torrent, debridTorrent, arr, isSymlink) // We can send async for file processing not to delay the response
return nil
Expand All @@ -74,39 +72,32 @@ func (q *QBit) CreateTorrentFromMagnet(magnet *common.Magnet, category string) *
Size: magnet.Size,
Category: category,
State: "downloading",
AddedOn: time.Now().Unix(),
MagnetUri: magnet.Link,

Tracker: "udp://tracker.opentrackr.org:1337",
UpLimit: -1,
DlLimit: -1,
FlPiecePrio: false,
ForceStart: false,
AutoTmm: false,
Availability: 2,
MaxRatio: -1,
MaxSeedingTime: -1,
NumComplete: 10,
NumIncomplete: 0,
NumLeechs: 1,
Ratio: 1,
RatioLimit: 1,
Tracker: "udp://tracker.opentrackr.org:1337",
UpLimit: -1,
DlLimit: -1,
AutoTmm: false,
Ratio: 1,
RatioLimit: 1,
}
return torrent
}

func (q *QBit) processFiles(torrent *Torrent, debridTorrent *debrid.Torrent, arr *debrid.Arr, isSymlink bool) {
for debridTorrent.Status != "downloaded" {
progress := debridTorrent.Progress
q.logger.Printf("Progress: %.2f%%", progress)
q.logger.Printf("RD Download Progress: %.2f%%", progress)
time.Sleep(5 * time.Second)
dbT, err := q.debrid.CheckStatus(debridTorrent, isSymlink)
if err != nil {
q.logger.Printf("Error checking status: %v", err)
q.MarkAsFailed(torrent)
q.RefreshArr(arr)
return
}
debridTorrent = dbT
torrent = q.UpdateTorrentMin(torrent, debridTorrent)
}
if isSymlink {
q.processSymlink(torrent, debridTorrent, arr)
Expand Down
35 changes: 23 additions & 12 deletions pkg/qbit/structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,20 +174,20 @@ type Torrent struct {
TorrentPath string `json:"-"`

AddedOn int64 `json:"added_on,omitempty"`
AmountLeft int64 `json:"amount_left,omitempty"`
AmountLeft int64 `json:"amount_left"`
AutoTmm bool `json:"auto_tmm"`
Availability float64 `json:"availability"`
Availability float64 `json:"availability,omitempty"`
Category string `json:"category,omitempty"`
Completed int64 `json:"completed,omitempty"`
Completed int64 `json:"completed"`
CompletionOn int64 `json:"completion_on,omitempty"`
ContentPath string `json:"content_path,omitempty"`
DlLimit int64 `json:"dl_limit,omitempty"`
Dlspeed int64 `json:"dlspeed,omitempty"`
Downloaded int64 `json:"downloaded,omitempty"`
DownloadedSession int64 `json:"downloaded_session,omitempty"`
Eta int64 `json:"eta,omitempty"`
FlPiecePrio bool `json:"f_l_piece_prio"`
ForceStart bool `json:"force_start"`
ContentPath string `json:"content_path"`
DlLimit int64 `json:"dl_limit"`
Dlspeed int64 `json:"dlspeed"`
Downloaded int64 `json:"downloaded"`
DownloadedSession int64 `json:"downloaded_session"`
Eta int64 `json:"eta"`
FlPiecePrio bool `json:"f_l_piece_prio,omitempty"`
ForceStart bool `json:"force_start,omitempty"`
Hash string `json:"hash"`
LastActivity int64 `json:"last_activity,omitempty"`
MagnetUri string `json:"magnet_uri,omitempty"`
Expand All @@ -202,7 +202,7 @@ type Torrent struct {
Progress float32 `json:"progress"`
Ratio int64 `json:"ratio,omitempty"`
RatioLimit int64 `json:"ratio_limit,omitempty"`
SavePath string `json:"save_path,omitempty"`
SavePath string `json:"save_path"`
SeedingTimeLimit int64 `json:"seeding_time_limit,omitempty"`
SeenComplete int64 `json:"seen_complete,omitempty"`
SeqDl bool `json:"seq_dl"`
Expand Down Expand Up @@ -259,6 +259,17 @@ type TorrentProperties struct {
UpSpeedAvg int64 `json:"up_speed_avg,omitempty"`
}

type TorrentFile struct {
Index int `json:"index,omitempty"`
Name string `json:"name,omitempty"`
Size int64 `json:"size,omitempty"`
Progress int64 `json:"progress,omitempty"`
Priority int64 `json:"priority,omitempty"`
IsSeed bool `json:"is_seed,omitempty"`
PieceRange []int64 `json:"piece_range,omitempty"`
Availability float64 `json:"availability,omitempty"`
}

func NewAppPreferences() *AppPreferences {
preferences := &AppPreferences{
AddTrackers: "",
Expand Down
89 changes: 61 additions & 28 deletions pkg/qbit/torrent.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,19 @@ func (q *QBit) MarkAsFailed(t *Torrent) *Torrent {
return t
}

func (q *QBit) UpdateTorrent(t *Torrent, debridTorrent *debrid.Torrent) *Torrent {
rcLoneMount := q.debrid.GetMountPath()
if debridTorrent == nil && t.ID != "" {
debridTorrent, _ = q.debrid.GetTorrent(t.ID)
}
func (q *QBit) UpdateTorrentMin(t *Torrent, debridTorrent *debrid.Torrent) *Torrent {
if debridTorrent == nil {
q.logger.Printf("Torrent with ID %s not found in %s", t.ID, q.debrid.GetName())
return t
}
if debridTorrent.Status != "downloaded" {
debridTorrent, _ = q.debrid.GetTorrent(t.ID)
}

if t.TorrentPath == "" {
t.TorrentPath = filepath.Base(debridTorrent.GetMountFolder(rcLoneMount))
addedOn, err := time.Parse(time.RFC3339, debridTorrent.Added)
if err != nil {
addedOn = time.Now()
}

totalSize := float64(cmp.Or(debridTorrent.Bytes, 1.0))
totalSize := float64(debridTorrent.Bytes)
progress := cmp.Or(debridTorrent.Progress, 100.0)
progress = progress / 100.0
var sizeCompleted int64

sizeCompleted = int64(totalSize * progress)
savePath := filepath.Join(q.DownloadFolder, t.Category) + string(os.PathSeparator)
torrentPath := filepath.Join(savePath, t.TorrentPath) + string(os.PathSeparator)
sizeCompleted := int64(totalSize * progress)

var speed int64
if debridTorrent.Speed != 0 {
Expand All @@ -50,39 +38,69 @@ func (q *QBit) UpdateTorrent(t *Torrent, debridTorrent *debrid.Torrent) *Torrent
if speed != 0 {
eta = int64((totalSize - float64(sizeCompleted)) / float64(speed))
}

t.Size = debridTorrent.Bytes
t.ID = debridTorrent.Id
t.Name = debridTorrent.Name
t.AddedOn = addedOn.Unix()
t.DebridTorrent = debridTorrent
t.Size = int64(totalSize)
t.Completed = sizeCompleted
t.Downloaded = sizeCompleted
t.DownloadedSession = sizeCompleted
t.Uploaded = sizeCompleted
t.UploadedSession = sizeCompleted
t.AmountLeft = int64(totalSize) - sizeCompleted
t.Progress = float32(progress)
t.SavePath = savePath
t.ContentPath = torrentPath
t.Eta = eta
t.Dlspeed = speed
t.Upspeed = speed
t.SavePath = filepath.Join(q.DownloadFolder, t.Category) + string(os.PathSeparator)
t.ContentPath = filepath.Join(t.SavePath, t.Name) + string(os.PathSeparator)
return t
}

func (q *QBit) UpdateTorrent(t *Torrent, debridTorrent *debrid.Torrent) *Torrent {
rcLoneMount := q.debrid.GetMountPath()
if debridTorrent == nil && t.ID != "" {
debridTorrent, _ = q.debrid.GetTorrent(t.ID)
}
if debridTorrent == nil {
q.logger.Printf("Torrent with ID %s not found in %s", t.ID, q.debrid.GetName())
return t
}
if debridTorrent.Status != "downloaded" {
debridTorrent, _ = q.debrid.GetTorrent(t.ID)
}

if t.TorrentPath == "" {
t.TorrentPath = filepath.Base(debridTorrent.GetMountFolder(rcLoneMount))
}
savePath := filepath.Join(q.DownloadFolder, t.Category) + string(os.PathSeparator)
torrentPath := filepath.Join(savePath, t.TorrentPath) + string(os.PathSeparator)
t = q.UpdateTorrentMin(t, debridTorrent)
t.ContentPath = torrentPath

if t.IsReady() {
t.State = "pausedUP"
q.storage.AddOrUpdate(t)
q.storage.Update(t)
return t
}
ticker := time.NewTicker(3 * time.Second)

ticker := time.NewTicker(2 * time.Second)
defer ticker.Stop()

for {
select {
case <-ticker.C:
if t.IsReady() {
t.State = "pausedUP"
q.storage.AddOrUpdate(t)
ticker.Stop()
q.storage.Update(t)
return t
} else {
return q.UpdateTorrent(t, debridTorrent)
}
updatedT := q.UpdateTorrent(t, debridTorrent)
t = updatedT

case <-time.After(10 * time.Minute): // Add a timeout
return t
}
}
}
Expand Down Expand Up @@ -123,3 +141,18 @@ func (q *QBit) GetTorrentProperties(t *Torrent) *TorrentProperties {
ShareRatio: 100,
}
}

func (q *QBit) GetTorrentFiles(t *Torrent) []*TorrentFile {
files := make([]*TorrentFile, 0)
if t.DebridTorrent == nil {
return files
}
for index, file := range t.DebridTorrent.Files {
files = append(files, &TorrentFile{
Index: index,
Name: file.Path,
Size: file.Size,
})
}
return files
}

0 comments on commit f118c5b

Please sign in to comment.