Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(tracker): add isTrackerDown helper #14

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 31 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ filters:
default:
ignore:
# general
- TrackerStatus contains "Tracker is down"
- IsTrackerDown()
- Downloaded == false && !IsUnregistered()
- SeedingHours < 26 && !IsUnregistered()
# permaseed / un-sorted (unless torrent has been deleted)
Expand Down Expand Up @@ -194,10 +194,35 @@ All of this and more can be noted in the [language definition](https://github.co
The following helper functions are available for usage while filtering, usage examples are available in the example config above.

```go
IsUnregistered() bool // Evaluates to true if torrent is unregistered in the tracker
IsUnregistered() bool // Evaluates to true if torrent is unregistered in the tracker
IsTrackerDown() bool // Evaluates to true if the tracker appears to be down/unreachable
HasAllTags(tags ...string) bool // True if torrent has ALL tags specified
HasAnyTag(tags ...string) bool // True if torrent has at least one tag specified
Log(n float64) float64 // The natural logarithm function
HasAnyTag(tags ...string) bool // True if torrent has at least one tag specified
Log(n float64) float64 // The natural logarithm function
```

### IsUnregistered and IsTrackerDown

When using both `IsUnregistered()` and `IsTrackerDown()` in filters:

- `IsUnregistered()` has built-in protection against tracker down states - it will return `false` if the tracker is down
- `IsTrackerDown()` checks if the tracker status indicates the tracker is unreachable/down
- The functions are independent but related - a torrent can be:
- Unregistered with tracker up (IsUnregistered: true, IsTrackerDown: false)
- Status unknown with tracker down (IsUnregistered: false, IsTrackerDown: true)
- Registered with tracker up (IsUnregistered: false, IsTrackerDown: false)

Note: While `IsUnregistered()` automatically handles tracker down states, you may still want to explicitly check for `IsTrackerDown()` in your ignore filters to prevent any actions when tracker status is uncertain.

Example:

```yaml
filters:
default:
ignore:
- IsTrackerDown() # Skip any actions when tracker is down
remove:
- IsUnregistered() # Safe to use alone due to built-in protection
```

## BypassIgnoreIfUnregistered
Expand All @@ -210,7 +235,7 @@ filters:
default:
ignore:
# general
- TrackerStatus contains "Tracker is down"
- IsTrackerDown()
- Downloaded == false && !IsUnregistered()
- SeedingHours < 26 && !IsUnregistered()
# permaseed / un-sorted (unless torrent has been deleted)
Expand All @@ -228,7 +253,7 @@ filters:
default:
ignore:
# general
- TrackerStatus contains "Tracker is down"
- IsTrackerDown()
- Downloaded == false
- SeedingHours < 26
# permaseed / un-sorted (unless torrent has been deleted)
Expand All @@ -237,8 +262,6 @@ filters:
- '"permaseed" in Tags
```

**Note:** If `TrackerStatus contains "Tracker is down"` then a torrent will not be considered unregistered anyways and will be ignored when tracker is down assuming the above filters.

## Supported Clients

- Deluge
Expand Down
63 changes: 61 additions & 2 deletions config/torrent.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,52 @@ var (
"tracker nicht registriert",
"torrent not found",
"trump",
//"truncated", // Tracker is down
"unknown",
"unregistered",
"upgraded",
"uploaded",
}

trackerDownStatuses = []string{
// libtorrent HTTP status messages
// https://github.com/arvidn/libtorrent/blob/RC_2_0/src/error_code.cpp#L320-L339
// https://github.com/arvidn/libtorrent/blob/RC_1_2/src/error_code.cpp#L298-L317
"continue", // 100 - server still processing
"multiple choices", // 300 - could indicate load balancer issues
"not modified", // 304 - could be caching issues
"bad request", // 400
"unauthorized", // 401
"forbidden", // 403
"internal server error", // 500
"not implemented", // 501
"bad gateway", // 502
"service unavailable", // 503
"moved permanently", // 301
"moved temporarily", // 302
"(unknown http error)",

// tracker/network errors
"down",
"maintenance",
"tracker is down",
"tracker unavailable",
"truncated",
"unreachable",
"not working",
"not responding",
"timeout",
"refused",
"no connection",
"cannot connect",
"connection failed",
"ssl error",
"no data",
"timed out",
"temporarily disabled",
"unresolvable",
"host not found",
"offline",
}
)

type Torrent struct {
Expand Down Expand Up @@ -85,8 +125,27 @@ type Torrent struct {
regexPattern *regex.Pattern
}

func (t *Torrent) IsTrackerDown() bool {
if t.TrackerStatus == "" {
return false
}

status := strings.ToLower(t.TrackerStatus)
for _, v := range trackerDownStatuses {
if strings.Contains(status, v) {
return true
}
}

return false
}

func (t *Torrent) IsUnregistered() bool {
if t.TrackerStatus == "" || strings.Contains(t.TrackerStatus, "Tracker is down") {
if t.IsTrackerDown() {
return false
}

if t.TrackerStatus == "" {
return false
}

Expand Down
4 changes: 4 additions & 0 deletions tracker/bhd.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,7 @@ func (c *BHD) IsUnregistered(torrent *Torrent) (error, bool) {

return nil, b.TotalResults < 1
}

func (c *BHD) IsTrackerDown(torrent *Torrent) (error, bool) {
return nil, false
}
4 changes: 4 additions & 0 deletions tracker/hdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,7 @@ func (c *HDB) IsUnregistered(torrent *Torrent) (error, bool) {
// if we get no results for a valid hash, the torrent is unregistered
return nil, b.Status == 0 && len(b.Data) == 0
}

func (c *HDB) IsTrackerDown(torrent *Torrent) (error, bool) {
return nil, false
}
1 change: 1 addition & 0 deletions tracker/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ type Interface interface {
Name() string
Check(string) bool
IsUnregistered(torrent *Torrent) (error, bool)
IsTrackerDown(torrent *Torrent) (error, bool)
}
4 changes: 4 additions & 0 deletions tracker/ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,7 @@ func (c *OPS) IsUnregistered(torrent *Torrent) (error, bool) {

return nil, b.Status == "failure" && b.Error == "bad parameters"
}

func (c *OPS) IsTrackerDown(torrent *Torrent) (error, bool) {
return nil, false
}
4 changes: 4 additions & 0 deletions tracker/ptp.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,7 @@ func (c *PTP) IsUnregistered(torrent *Torrent) (error, bool) {

return nil, b.Result == "ERROR" && b.ResultDetails == "Unregistered Torrent"
}

func (c *PTP) IsTrackerDown(torrent *Torrent) (error, bool) {
return nil, false
}
4 changes: 4 additions & 0 deletions tracker/red.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,7 @@ func (c *RED) IsUnregistered(torrent *Torrent) (error, bool) {

return nil, b.Status == "failure" && b.Error == "bad hash parameter"
}

func (c *RED) IsTrackerDown(torrent *Torrent) (error, bool) {
return nil, false
}
4 changes: 4 additions & 0 deletions tracker/unit3d.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,7 @@ func (c *UNIT3D) IsUnregistered(torrent *Torrent) (error, bool) {
torrent.Hash, b.Data.Attributes.InfoHash)
return nil, true
}

func (c *UNIT3D) IsTrackerDown(torrent *Torrent) (error, bool) {
return nil, false
}
Loading