[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-81770":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":8,"htmlUrl":8,"language":9,"languages":8,"totalLinesOfCode":8,"stars":10,"forks":11,"watchers":10,"openIssues":12,"contributorsCount":13,"subscribersCount":13,"size":13,"stars1d":13,"stars7d":13,"stars30d":13,"stars90d":13,"forks30d":13,"starsTrendScore":13,"compositeScore":14,"rankGlobal":8,"rankLanguage":8,"license":8,"archived":15,"fork":15,"defaultBranch":16,"hasWiki":17,"hasPages":15,"topics":18,"createdAt":8,"pushedAt":8,"updatedAt":19,"readmeContent":20,"aiSummary":21,"trendingCount":13,"starSnapshotCount":13,"syncStatus":22,"lastSyncTime":23,"discoverSource":24},81770,"gardener","joway\u002Fgardener","joway",null,"Go",23,3,1,0,1.81,false,"main",true,[],"2026-06-12 02:04:19","# gardener\n\nA CLI that searches BT torrent sites and ranks results by **verified** swarm health,\nnot by the seeder counts the site claims (which are usually stale or inflated).\n\n## Why\n\n`torrentz2.nz` and similar meta-search engines aggregate seeder counts that are\noften wildly out of date. A torrent listed with \"200 seeders\" may have zero\npeers actually serving pieces. `gardener` takes the top N candidates and:\n\n1. Looks up live peers in the DHT.\n2. Scrapes every tracker advertised in the magnet URI.\n3. Connects to a sample of peers, fetches metadata via BEP-9, reads each peer's\n   BITFIELD, and counts how many actually have all pieces.\n\nThe result is sorted by a weighted health score so the top entry is the one most\nlikely to actually download.\n\n## Install\n\n```sh\ngo install github.com\u002Fjoway\u002Fgardener\u002Fcmd\u002Fgardener@latest\n```\n\nOr build locally:\n\n```sh\ngo build -o gardener .\u002Fcmd\u002Fgardener\n```\n\n## Usage\n\n```sh\ngardener \"ubuntu 24.04\"\ngardener -n 30 \"...\"                # test top 30 instead of default 20\ngardener -v \"...\"                   # also show site-reported seeds\u002Fpeers\ngardener --json \"...\"               # machine-readable output with full magnets\ngardener --timeout 120s \"...\"       # extend overall budget\n```\n\n## Output\n\nDefault table columns:\n\n| column     | meaning                                                                  |\n|------------|--------------------------------------------------------------------------|\n| `#`        | rank by score (best first)                                               |\n| `name`     | torrent name                                                             |\n| `size`     | total content size                                                       |\n| `added`    | age (e.g. `3y`, `2mo`)                                                   |\n| `verified` | peers that handshook AND have every piece — this is the gold signal      |\n| `dht`      | unique peer addresses returned by DHT `get_peers`                        |\n| `trk_avg`  | average seeder count across responsive trackers                          |\n| `score`    | weighted health score (see below)                                        |\n| `magnet`   | minimal `magnet:?xt=urn:btih:\u003CHASH>` — paste into any BT client          |\n\n`--json` adds: full magnet (with `dn` + all `tr=`), per-tracker results,\nmetadata acquisition status, total piece count, partial-vs-seeder breakdown.\n\n## Scoring\n\n```\nscore = 10 * verified_seeders        # peers we actually handshook + bitfield-confirmed\n      +  2 * dht_peers                # raw DHT swarm size\n      +  1 * tracker_seeders_avg      # what trackers report\n      +  0.5 * age_factor             # 1 \u002F (1 + years), favors newer entries on ties\n```\n\n`verified_seeders` dominates by design: it is the only signal that proves a peer\nwill actually serve bytes to you right now. The other terms break ties when\nverification didn't sample enough of the swarm in time.\n\nA score of 0 with `dht > 0` means DHT still has stale announces but no peer in\nthe sample completed a handshake — usually a dying swarm.\n\n## How verification works\n\nFor each candidate torrent, in parallel:\n\n- **DHT phase** — `AnnounceTraversal` against a shared, bootstrapped DHT server\n  collects peer addresses for ~15s.\n- **Tracker phase** — UDP\u002FHTTP scrape against every tracker URL in the magnet.\n- **Handshake phase** — feeds DHT-discovered peers into a shared `torrent.Client`,\n  waits for metadata via BEP-9, then samples up to 30 peer connections. A peer is\n  counted as `verified_seeders` when its `PeerPieces()` bitmap covers all pieces.\n\nThe whole pipeline is wall-clock bounded (`--timeout`, default 90s).\n\n## Adding a search provider\n\nImplement `internal\u002Fsearch.Provider`:\n\n```go\ntype Provider interface {\n    Name() string\n    Search(ctx context.Context, query string, limit int) ([]SearchResult, error)\n}\n```\n\nWire it up in `cmd\u002Fgardener\u002Fmain.go:pickProvider`. `SearchResult.Magnet` must be\nsanitized — only `udp\u002Fhttp\u002Fhttps` trackers in the `tr=` params (anacrolix\u002Ftorrent\npanics on unknown schemes). See `parseMagnet` in `internal\u002Fsearch\u002Ftorrentz2.go`\nfor the reference implementation.\n\n## Caveats\n\n- DHT bootstrap is best-effort; if your network blocks UDP, scoring degrades to\n  trackers + handshake only.\n- Handshake sampling is capped at 30 peers per torrent. Healthy-but-slow-to-respond\n  swarms may show `verified \u003C dht`. Raise `--verify-timeout` if that hurts you.\n- torrentz2 is HTML-scraped; if the site changes its markup, the scraper breaks.\n- The verifier writes to a temp dir but never actually downloads piece data. The\n  dir is cleaned up on exit.\n","gardener 是一个命令行工具，用于搜索BT种子站点，并根据实际验证过的群健康状况对结果进行排名，而非依赖站点声称的可能已过时或夸大的做种者数量。其核心功能包括实时查询DHT中的活跃节点、遍历磁力链接中声明的所有追踪器以及与样本对等点连接以获取元数据并检查每个对等点是否拥有所有片段。该工具适用于需要确保下载资源有效性和完整性的场景，尤其是在寻找高质量种子文件时。通过计算加权健康分数，gardener 能够帮助用户识别最有可能成功下载的种子，从而提高下载效率和成功率。",2,"2026-06-11 04:06:19","CREATED_QUERY"]