Skip to content

feat(impl): add FLD support#251

Open
wasserrutschentester wants to merge 1 commit into
autobrr:mainfrom
wasserrutschentester:feat/add-fld
Open

feat(impl): add FLD support#251
wasserrutschentester wants to merge 1 commit into
autobrr:mainfrom
wasserrutschentester:feat/add-fld

Conversation

@wasserrutschentester

@wasserrutschentester wasserrutschentester commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

FLD is a relatively new tracker with a custom source (mizo)
i've used the existing python implementation and the go one for bhd as a referenece

Summary by CodeRabbit

  • New Features
    • Added support for the FLD tracker, including configuration and tracker registration.
    • Added FLD torrent uploads with validation, metadata, descriptions, dry-run previews, and personalized torrent files.
    • Added duplicate checking for FLD movie and TV content.
    • Added FLD-specific description formatting and banned release-group handling.
  • Bug Fixes
    • Improved FLD descriptions by removing user tags and standardizing image sizing.

@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds Flood (FLD) tracker support for uploads, dry runs, duplicate checking, configuration, registry discovery, banned groups, UI fields, and tracker-specific description formatting.

Changes

Flood tracker support

Layer / File(s) Summary
FLD upload implementation
internal/trackers/impl/fld/...
Implements FLD metadata preparation, validation, descriptions, multipart uploads, dry runs, response handling, and upload tests.
FLD duplicate checking
internal/dupechecking/fld.go, internal/dupechecking/factory.go, internal/dupechecking/fld_test.go
Adds authenticated movie and TV searches against Flood’s torrent API and converts responses into duplicate entries.
Registration and configuration
internal/trackers/impl/registry.go, internal/trackers/catalog.go, internal/trackers/upload_artifact.go, internal/config/defaults/example.yaml, gui/frontend/src/hooks/useSettingsState.tsx, internal/trackers/banned.go
Registers FLD, exposes its tracker kind and upload source, and adds default configuration, UI fields, and banned groups.
Description formatting
internal/services/bbcode/tracker_profiles.go, internal/services/bbcode/tracker_profiles_test.go
Adds FLD formatting that removes user tags and gives plain images a width of 300.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant TrackerDefinition
  participant UploadPreparation
  participant FloodAPI
  TrackerDefinition->>UploadPreparation: Build FLD upload request
  UploadPreparation->>FloodAPI: POST multipart torrent upload
  FloodAPI-->>UploadPreparation: Return upload result
  UploadPreparation-->>TrackerDefinition: Return UploadSummary
Loading

Possibly related PRs

  • autobrr/upbrr#228: Updates banned-group handling that consumes the FLD banned-group entry.

Suggested reviewers: audionut

Poem

I’m a rabbit with torrents tucked tight,
FLD now hops through the upload night.
Fields bloom, duplicates flee,
BBCode images fit neatly.
Carrots celebrate the registry’s new light!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately summarizes the main change: adding FLD support.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
internal/dupechecking/fld_test.go (2)

195-206: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Prefer strings.Contains from the standard library over custom helpers.

stringsContains and stringsContainsSimple reimplement strings.Contains. Import the strings package and replace these helpers to reduce maintenance burden and improve clarity.

♻️ Proposed refactor
 import (
 	"context"
 	"io"
 	"net/http"
 	"net/http/httptest"
+	"strings"
 	"testing"
 
 	"github.com/autobrr/upbrr/internal/config"
 	"github.com/autobrr/upbrr/pkg/api"
 )

Then replace the usage at line 65:

-		if len(notes) != 1 || !stringsContains(notes[0], tc.expectedSkip) {
+		if len(notes) != 1 || !strings.Contains(notes[0], tc.expectedSkip) {

And remove lines 195-206:

-func stringsContains(s, sub string) bool {
-	return len(s) >= len(sub) && (s == sub || stringsContainsSimple(s, sub))
-}
-
-func stringsContainsSimple(s, sub string) bool {
-	for i := 0; i <= len(s)-len(sub); i++ {
-		if s[i:i+len(sub)] == sub {
-			return true
-		}
-	}
-	return false
-}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/dupechecking/fld_test.go` around lines 195 - 206, Replace usages of
the custom stringsContains helper with the standard-library strings.Contains,
adding the strings import as needed. Remove both stringsContains and
stringsContainsSimple from the test file while preserving the existing
containment behavior.

14-193: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add tests for FLD response failures
Cover the missing branches in Search: non-2xx responses, non-object JSON payloads, and items values that aren’t slices. That would lock down the defensive handling around these cases.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/dupechecking/fld_test.go` around lines 14 - 193, Extend the FLD
Search tests around TestFLDHandlerSearchMovie and TestFLDHandlerSearchTV to
cover non-2xx HTTP responses, valid JSON payloads that are not objects, and
object payloads whose items field is not a slice. Assert each case preserves the
defensive Search behavior by returning no entries and the expected error or
handling result.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/trackers/impl/fld/definition_test.go`:
- Around line 26-28: Update both torrent fixtures used by
ResolveUploadTorrentPath to contain valid bencode: correct the announce string
length prefix from 31 to the actual 25-byte URL in each os.WriteFile payload.
Keep the fixture contents and test intent otherwise unchanged so the normal
cleaned-torrent handling path is exercised.

In `@internal/trackers/impl/fld/upload.go`:
- Around line 341-346: Update resolveTMDbID to return an empty string
immediately when meta.ExternalIDs.TMDBID is less than or equal to zero;
otherwise preserve the existing TV/movie prefix formatting. Add tests covering
missing or non-positive TMDb IDs and confirming valid IDs still resolve
correctly.

---

Nitpick comments:
In `@internal/dupechecking/fld_test.go`:
- Around line 195-206: Replace usages of the custom stringsContains helper with
the standard-library strings.Contains, adding the strings import as needed.
Remove both stringsContains and stringsContainsSimple from the test file while
preserving the existing containment behavior.
- Around line 14-193: Extend the FLD Search tests around
TestFLDHandlerSearchMovie and TestFLDHandlerSearchTV to cover non-2xx HTTP
responses, valid JSON payloads that are not objects, and object payloads whose
items field is not a slice. Assert each case preserves the defensive Search
behavior by returning no entries and the expected error or handling result.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3a1dd195-5ee3-4d78-88d2-90f5160ffd36

📥 Commits

Reviewing files that changed from the base of the PR and between fb1701b and e6d13b1.

📒 Files selected for processing (15)
  • gui/frontend/src/hooks/useSettingsState.tsx
  • internal/config/defaults/example.yaml
  • internal/dupechecking/factory.go
  • internal/dupechecking/fld.go
  • internal/dupechecking/fld_test.go
  • internal/services/bbcode/tracker_profiles.go
  • internal/services/bbcode/tracker_profiles_test.go
  • internal/trackers/banned.go
  • internal/trackers/catalog.go
  • internal/trackers/impl/fld/definition.go
  • internal/trackers/impl/fld/definition_test.go
  • internal/trackers/impl/fld/upload.go
  • internal/trackers/impl/registry.go
  • internal/trackers/impl/registry_test.go
  • internal/trackers/upload_artifact.go

Comment on lines +26 to +28
if err := os.WriteFile(torrentPath, []byte("d8:announce31:http://localhost/announcee"), 0o600); err != nil {
t.Fatalf("write torrent: %v", err)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Use valid bencode torrent fixtures.

The announce URL is 25 bytes, not 31. These malformed torrents make ResolveUploadTorrentPath take its load-error fallback instead of exercising normal cleaned-torrent handling.

Proposed fix
-		[]byte("d8:announce31:http://localhost/announcee"),
+		[]byte("d8:announce25:http://localhost/announcee"),

Apply this to both fixtures.

Also applies to: 97-100

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/trackers/impl/fld/definition_test.go` around lines 26 - 28, Update
both torrent fixtures used by ResolveUploadTorrentPath to contain valid bencode:
correct the announce string length prefix from 31 to the actual 25-byte URL in
each os.WriteFile payload. Keep the fixture contents and test intent otherwise
unchanged so the normal cleaned-torrent handling path is exercised.

Comment on lines +341 to +346
func resolveTMDbID(meta api.PreparedMetadata) string {
if resolveCategory(meta) == "TV" {
return fmt.Sprintf("tv/%d", meta.ExternalIDs.TMDBID)
}
return fmt.Sprintf("movie/%d", meta.ExternalIDs.TMDBID)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Return no TMDb field when the ID is absent.

A zero ID becomes movie/0 or tv/0, so the missing-ID gate at Line 204 never blocks and uploads with a valid IMDb ID can still submit an invalid TMDb ID. Return "" when TMDBID <= 0, and cover the no-TMDb case.

Proposed fix
 func resolveTMDbID(meta api.PreparedMetadata) string {
+	if meta.ExternalIDs.TMDBID <= 0 {
+		return ""
+	}
 	if resolveCategory(meta) == "TV" {
 		return fmt.Sprintf("tv/%d", meta.ExternalIDs.TMDBID)
 	}

As per coding guidelines, “add tests for changed behavior.”

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func resolveTMDbID(meta api.PreparedMetadata) string {
if resolveCategory(meta) == "TV" {
return fmt.Sprintf("tv/%d", meta.ExternalIDs.TMDBID)
}
return fmt.Sprintf("movie/%d", meta.ExternalIDs.TMDBID)
}
func resolveTMDbID(meta api.PreparedMetadata) string {
if meta.ExternalIDs.TMDBID <= 0 {
return ""
}
if resolveCategory(meta) == "TV" {
return fmt.Sprintf("tv/%d", meta.ExternalIDs.TMDBID)
}
return fmt.Sprintf("movie/%d", meta.ExternalIDs.TMDBID)
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/trackers/impl/fld/upload.go` around lines 341 - 346, Update
resolveTMDbID to return an empty string immediately when meta.ExternalIDs.TMDBID
is less than or equal to zero; otherwise preserve the existing TV/movie prefix
formatting. Add tests covering missing or non-positive TMDb IDs and confirming
valid IDs still resolve correctly.

Source: Coding guidelines

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant