Repository: Jackett/Jackett
Pull request #15892: feat(hdbao): Add new HDBao Chinese private tracker
Author: login: rpatterson
Created: 2025-03-06T07:12:45Z | Merged: 2025-03-08T17:38:10Z

This is my second new indexer definition. Thanks to the maintainers'
gracious response to my previous request for education about what to
test, I know much more what I don't know. So this time I had more
questions while writing the definition before submitting a PR and I
captured them in `# TODO: ` comments. Please reply to each of the
questions in each of those comments in your review. As I ingest review
feedback I'll cleanup those comments and force push without them.

For this new definition, I performed all the testing I originally did
for my previour PR plus all the additional testing I learned from the
maintainers on my previous PR. I'll do the same as I incorporate
feedback for this new definition.

This PR includes this commit and the previous which just copies the
example definition I started from. Its valuable for VCS history to
show which definition a new definition is based on, but it's an even
more valuable reference about the differences between indexers for VCS
history to show the *changes* made to the example definition to create
the new one. Subsequent changes from review feedback should be
squashed into this commit, but not into the previous commit so the
changes from the example definition are preserved in VCS history.



Diff:
diff --git a/README.md b/README.md
index e34c356eeb45b..690133528c57d 100644
--- a/README.md
+++ b/README.md
@@ -383,6 +383,7 @@ Prior versions of Jackett are no longer supported.
  * HD-UNiT3D
  * HDArea (HDA)
  * HDAtmos
+ * HDBao
  * HDBits [![(invite needed)][inviteneeded]](#)
  * HDCiTY (HDC) [![(invite needed)][inviteneeded]](#)
  * HDClone
diff --git a/src/Jackett.Common/Definitions/hdbao.yml b/src/Jackett.Common/Definitions/hdbao.yml
new file mode 100644
index 0000000000000..046e34738cd1a
--- /dev/null
+++ b/src/Jackett.Common/Definitions/hdbao.yml
@@ -0,0 +1,185 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  categorymappings:
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio/Video, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+
+  modes:
+    search: [q]
+    tv-search: [q, season, ep]
+    movie-search: [q]
+    music-search: [q]
+    book-search: [q]
+
+settings:
+  - name: username
+    type: text
+    label: Username
+  - name: password
+    type: password
+    label: Password
+  - name: 2facode
+    type: text
+    label: 2FA code
+  - name: info_2fa
+    type: info
+    label: "About 2FA code"
+    default: "Only fill in the <b>2FA code</b> box if you have enabled <b>2FA</b> on the HDBao Web Site. Otherwise just leave it empty."
+  - name: freeleech
+    type: checkbox
+    label: Search freeleech only
+    default: false
+  - name: sort
+    type: select
+    label: Sort requested from site
+    default: 4
+    options:
+      4: created
+      7: seeders
+      5: size
+      1: title
+  - name: type
+    type: select
+    label: Order requested from site
+    default: desc
+    options:
+      desc: desc
+      asc: asc
+  - name: info_tpp
+    type: info
+    label: Results Per Page
+    default: For best results, change the <b>Torrents per page:</b> setting to <b>100</b> on your account profile.
+  - name: info_activity
+    type: info
+    label: Account Inactivity
+    default: "Cherish your user account. Inactive accounts would be deleted based on the following rules:<ol><li>Veteran User or above would never be deleted.</li><li>Elite User or above would never be deleted if parked (at User CP).</li><li>Parked accounts would be deleted if users have not logged in for more than 400 days in a row.</li><li>Unparked accounts would be deleted if users have not logged in for more than 150 days in a row.</li><li>Accounts with both uploaded and downloaded amount being 0 would be deleted if users have not logged in for more than 100 days in a row.</li></ol>"
+
+login:
+  path: login.php
+  method: form
+  form: form[action="takelogin.php"]
+  inputs:
+    secret: ""
+    username: "{{ .Config.username }}"
+    password: "{{ .Config.password }}"
+    two_step_code: "{{ .Config.2facode }}"
+    logout: ""
+    securelogin: ""
+    ssl: yes
+    trackerssl: yes
+  error:
+    - selector: td.embedded:contains("登录失败！")
+  test:
+    path: index.php
+    selector: a[href="logout.php"]
+
+search:
+  paths:
+    - path: torrents.php
+  inputs:
+    $raw: "{{ range .Categories }}cat{{.}}=1&{{end}}"
+    search: "{{ .Keywords }}"
+    # 0: include dead, 1: alive, 2: dead
+    incldead: 0
+    spstate: "{{ if .Config.freeleech }}2{{ else }}0{{ end }}"
+    # 0: title, 1: description, 3: uploader, 4: imdburl (4 does not appear to work)
+    search_area: "0"
+    # 0: AND, 2: exact
+    search_mode: 0
+    sort: "{{ .Config.sort }}"
+    type: "{{ .Config.type }}"
+    # Support in NexusPHP so bots don't pollute trending searches:
+    notnewword: 1
+
+  rows:
+    selector: table.torrents > tbody > tr:has(a[href^="download.php?id="])
+
+  fields:
+    category:
+      selector: a[href^="?cat="]
+      attribute: href
+      filters:
+        - name: querystring
+          args: cat
+    title_default:
+      selector: a[href^="details.php?id="]
+    title:
+      selector: a[title][href^="details.php?id="]
+      attribute: title
+      optional: true
+      default: "{{ .Result.title_default }}"
+    details:
+      selector: a[href^="details.php?id="]
+      attribute: href
+    download:
+      selector: a[href^="download.php?id="]
+      attribute: href
+    poster:
+      selector: img[data-src]
+      attribute: data-src
+    # Users can change the "Time display type" in their tracker preferences:
+    date_elapsed:
+      # time type: time elapsed (default)
+      selector: td:nth-child(4) > span[title]
+      attribute: title
+      optional: true
+      filters:
+        - name: append
+          args: " +08:00" # CST
+        - name: dateparse
+          args: "yyyy-MM-dd HH:mm:ss zzz"
+    date_added:
+      # time added
+      selector: td:nth-child(4):not(:has(span))
+      optional: true
+      filters:
+        - name: append
+          args: " +08:00" # CST
+        - name: dateparse
+          args: "yyyy-MM-ddHH:mm:ss zzz"
+    date:
+      text: "{{ if or .Result.date_elapsed .Result.date_added }}{{ or .Result.date_elapsed .Result.date_added }}{{ else }}now{{ end }}"
+    size:
+      selector: td:nth-child(5)
+    seeders:
+      selector: td:nth-child(6)
+    leechers:
+      selector: td:nth-child(7)
+    grabs:
+      selector: td:nth-child(8)
+    downloadvolumefactor:
+      case:
+        img.pro_free: 0
+        img.pro_free2up: 0
+        img.pro_50pctdown: 0.5
+        img.pro_50pctdown2up: 0.5
+        img.pro_30pctdown: 0.3
+        "*": 1
+    uploadvolumefactor:
+      case:
+        img.pro_50pctdown2up: 2
+        img.pro_free2up: 2
+        img.pro_2up: 2
+        "*": 1
+    description:
+      selector: td:nth-child(2)
+      remove: a, b, font, img, span
+# NexusPHP v1.9.0 2025-02-06


Reviews:
user: login: ilike2burnthing
body: Will test later.
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-07T07:14:08Z
user: login: mynameisbogdan
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-07T07:51:19Z
user: login: rpatterson
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-07T16:02:32Z
user: login: rpatterson
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-07T16:08:35Z
user: login: rpatterson
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-07T16:14:44Z
user: login: rpatterson
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-07T16:19:43Z
user: login: rpatterson
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-07T16:47:30Z
user: login: rpatterson
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-07T16:57:14Z
user: login: rpatterson
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-07T17:03:30Z
user: login: rpatterson
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-07T17:13:07Z
user: login: rpatterson
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-07T17:15:22Z
user: login: rpatterson
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-07T17:19:56Z
user: login: rpatterson
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-07T18:04:19Z
user: login: ilike2burnthing
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-08T00:42:09Z
user: login: ilike2burnthing
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-08T01:01:51Z
user: login: ilike2burnthing
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-08T02:03:57Z
user: login: ilike2burnthing
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-08T02:05:05Z
user: login: rpatterson
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-08T16:47:33Z
user: login: rpatterson
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-08T16:51:36Z
user: login: garfield69
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-08T17:36:57Z
user: login: ilike2burnthing
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-09T03:27:52Z
user: login: rpatterson
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-09T20:55:10Z

Review comments:
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: ilike2burnthing
body: ```suggestion
  categorymappings:
```

If the tracker had a second search page (typically this is for XXX or VIP content), then we would need to perform a second request to get these results. The `default` flag determines if that category is used when no categories are set, and so we generally set all categories on the primary page to `true`, and all those on the secondary page to `false`, so that we minimise the number of requests made for the majority of searches. We also add a `requestDelay` of 2 in these cases, or more if it's specified as a rate limit for a tracker's site or API.
created_at: 2025-03-07T05:52:54Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: ilike2burnthing
body: ```suggestion
```

Other than keywords, these are the only other searches we make:
https://github.com/Jackett/Jackett/blob/55ab37470ef8f25b805d3adbc3952f286a91acdd/src/Jackett.Common/Models/TorznabQuery.cs#L86-L103

In practice IMDB, Douban, season, episode, and genre are the only ones used with any regularity.
created_at: 2025-03-07T06:08:00Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: ilike2burnthing
body: ```suggestion
```

Sometimes Chinese (particularly NexusPHP) sites will say IMDB but actually use Douban. In this case it appears to be neither, so we can just ignore it. Sometimes this can also be achieved by searching the description instead, but that doesn't seem to be the case here either.
created_at: 2025-03-07T06:13:13Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
+    # TODO: Searching for `S01` and `S01E01` for an example, that
+    # yields other results when searched without, yields no difference
+    # in results. Am I missing something?
+    #
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: ilike2burnthing
body: ```suggestion
```

So long as `matching mode` is set to `And`, instead of `Exact`, season/season and episode searching seems to be working fine - see `Severance`, `Severance S02`, `Severance S02E01`.
created_at: 2025-03-07T06:19:03Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
+    # TODO: Searching for `S01` and `S01E01` for an example, that
+    # yields other results when searched without, yields no difference
+    # in results. Am I missing something?
+    #
+    # TODO: The example I copied, `./freefarm.yml`, includes support
+    # for `DoubanID` but I don't find any evidence of that support in
+    # *that* example's web UI. For *this* indexer I tested the
+    # `DoubanID` like I tested an IMDB ID above. Is the example
+    # definiton wrong or out of date? If not, where can you see the
+    # support for `DoubanID` in *that* example and does this indexer
+    # also support it?
+    tv-search: [q]
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: ilike2burnthing
body: ```suggestion
    tv-search: [q, season, ep]
```
created_at: 2025-03-07T06:19:28Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
+    # TODO: Searching for `S01` and `S01E01` for an example, that
+    # yields other results when searched without, yields no difference
+    # in results. Am I missing something?
+    #
+    # TODO: The example I copied, `./freefarm.yml`, includes support
+    # for `DoubanID` but I don't find any evidence of that support in
+    # *that* example's web UI. For *this* indexer I tested the
+    # `DoubanID` like I tested an IMDB ID above. Is the example
+    # definiton wrong or out of date? If not, where can you see the
+    # support for `DoubanID` in *that* example and does this indexer
+    # also support it?
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: ilike2burnthing
body: ```suggestion
```

Douban ID is searched for in the description:
https://github.com/Jackett/Jackett/blob/e72a81b1a4188b9a248ca84bf34e0682d25cf7ba/src/Jackett.Common/Definitions/freefarm.yml#L133
created_at: 2025-03-07T06:24:14Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
+    # TODO: Searching for `S01` and `S01E01` for an example, that
+    # yields other results when searched without, yields no difference
+    # in results. Am I missing something?
+    #
+    # TODO: The example I copied, `./freefarm.yml`, includes support
+    # for `DoubanID` but I don't find any evidence of that support in
+    # *that* example's web UI. For *this* indexer I tested the
+    # `DoubanID` like I tested an IMDB ID above. Is the example
+    # definiton wrong or out of date? If not, where can you see the
+    # support for `DoubanID` in *that* example and does this indexer
+    # also support it?
+    tv-search: [q]
+    movie-search: [q]
+    music-search: [q]
+    book-search: [q]
+
+settings:
+  - name: username
+    type: text
+    label: Username
+  - name: password
+    type: password
+    label: Password
+  - name: 2facode
+    type: text
+    label: 2FA code
+  - name: info_2fa
+    type: info
+    label: "About 2FA code"
+    default: "Only fill in the <b>2FA code</b> box if you have enabled <b>2FA</b> on the HDBao Web Site. Otherwise just leave it empty."
+  # TODO: While testing this field, I noticed the results only includ
+  # *just* "Free" items and *not* "2X Free" items. This is also the
+  # case for the example I copied. I understand its better for
+  # Jackett/Prowlarr to use the filtering supported server-side. Does
+  # NexusPHP support multiple `spstate` values? If no, is there a good
+  # place for feature requests?
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: ilike2burnthing
body: ```suggestion
```

It does not.

https://github.com/xiaomlove/nexusphp

I did a quick check in English for existing requests, couldn't see any. You may want to look further.
created_at: 2025-03-07T06:29:29Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: ilike2burnthing
body: ```suggestion
    - {id: 403, cat: TV, desc: "TV Shows/综艺"}
```

They're both just TV, no need to distinguish between them.
created_at: 2025-03-07T06:31:13Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: ilike2burnthing
body: ```suggestion
    - {id: 409, cat: Other, desc: "Misc/音乐"}
```

I'd go by the title rather than the single result.
created_at: 2025-03-07T06:32:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: ilike2burnthing
body: ```suggestion
    - {id: 408, cat: Audio/Video, desc: "Concert/演唱会"}
```
created_at: 2025-03-07T06:34:26Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
+    # TODO: Searching for `S01` and `S01E01` for an example, that
+    # yields other results when searched without, yields no difference
+    # in results. Am I missing something?
+    #
+    # TODO: The example I copied, `./freefarm.yml`, includes support
+    # for `DoubanID` but I don't find any evidence of that support in
+    # *that* example's web UI. For *this* indexer I tested the
+    # `DoubanID` like I tested an IMDB ID above. Is the example
+    # definiton wrong or out of date? If not, where can you see the
+    # support for `DoubanID` in *that* example and does this indexer
+    # also support it?
+    tv-search: [q]
+    movie-search: [q]
+    music-search: [q]
+    book-search: [q]
+
+settings:
+  - name: username
+    type: text
+    label: Username
+  - name: password
+    type: password
+    label: Password
+  - name: 2facode
+    type: text
+    label: 2FA code
+  - name: info_2fa
+    type: info
+    label: "About 2FA code"
+    default: "Only fill in the <b>2FA code</b> box if you have enabled <b>2FA</b> on the HDBao Web Site. Otherwise just leave it empty."
+  # TODO: While testing this field, I noticed the results only includ
+  # *just* "Free" items and *not* "2X Free" items. This is also the
+  # case for the example I copied. I understand its better for
+  # Jackett/Prowlarr to use the filtering supported server-side. Does
+  # NexusPHP support multiple `spstate` values? If no, is there a good
+  # place for feature requests?
+  - name: freeleech
+    type: checkbox
+    label: Search freeleech only
+    default: false
+  - name: sort
+    type: select
+    label: Sort requested from site
+    default: 4
+    options:
+      4: created
+      7: seeders
+      5: size
+      1: title
+  - name: type
+    type: select
+    label: Order requested from site
+    default: desc
+    options:
+      desc: desc
+      asc: asc
+  # TODO: I didn't get any FS challenges for this indexer that I can
+  # recall, and definitely not while developing this definition. I
+  # confirmed FS usage by looking at the response headers and
+  # cookie. Is that a sufficient way to identify FS usage?
+  - name: info_flaresolverr
+    type: info_flaresolverr
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: ilike2burnthing
body: ```suggestion
```

The only place I can find it triggered is on the Attendance page, which we don't interact with. Unless it's on the login or search pages (or I suppose download, but I've never seen that), no need to mention it.
created_at: 2025-03-07T06:37:55Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
+    # TODO: Searching for `S01` and `S01E01` for an example, that
+    # yields other results when searched without, yields no difference
+    # in results. Am I missing something?
+    #
+    # TODO: The example I copied, `./freefarm.yml`, includes support
+    # for `DoubanID` but I don't find any evidence of that support in
+    # *that* example's web UI. For *this* indexer I tested the
+    # `DoubanID` like I tested an IMDB ID above. Is the example
+    # definiton wrong or out of date? If not, where can you see the
+    # support for `DoubanID` in *that* example and does this indexer
+    # also support it?
+    tv-search: [q]
+    movie-search: [q]
+    music-search: [q]
+    book-search: [q]
+
+settings:
+  - name: username
+    type: text
+    label: Username
+  - name: password
+    type: password
+    label: Password
+  - name: 2facode
+    type: text
+    label: 2FA code
+  - name: info_2fa
+    type: info
+    label: "About 2FA code"
+    default: "Only fill in the <b>2FA code</b> box if you have enabled <b>2FA</b> on the HDBao Web Site. Otherwise just leave it empty."
+  # TODO: While testing this field, I noticed the results only includ
+  # *just* "Free" items and *not* "2X Free" items. This is also the
+  # case for the example I copied. I understand its better for
+  # Jackett/Prowlarr to use the filtering supported server-side. Does
+  # NexusPHP support multiple `spstate` values? If no, is there a good
+  # place for feature requests?
+  - name: freeleech
+    type: checkbox
+    label: Search freeleech only
+    default: false
+  - name: sort
+    type: select
+    label: Sort requested from site
+    default: 4
+    options:
+      4: created
+      7: seeders
+      5: size
+      1: title
+  - name: type
+    type: select
+    label: Order requested from site
+    default: desc
+    options:
+      desc: desc
+      asc: asc
+  # TODO: I didn't get any FS challenges for this indexer that I can
+  # recall, and definitely not while developing this definition. I
+  # confirmed FS usage by looking at the response headers and
+  # cookie. Is that a sufficient way to identify FS usage?
+  - name: info_flaresolverr
+    type: info_flaresolverr
+  - name: info_tpp
+    type: info
+    label: Results Per Page
+    default: For best results, change the <b>Torrents per page:</b> setting to <b>100</b> on your account profile.
+  - name: info_activity
+    type: info
+    label: Account Inactivity
+    default: "Cherish your user account. Inactive accounts would be deleted based on the following rules:<ol><li>Veteran User or above would never be deleted.</li><li>Elite User or above would never be deleted if parked (at User CP).</li><li>Parked accounts would be deleted if users have not logged in for more than 400 days in a row.</li><li>Unparked accounts would be deleted if users have not logged in for more than 150 days in a row.</li><li>Accounts with both uploaded and downloaded amount being 0 would be deleted if users have not logged in for more than 100 days in a row.</li></ol>"
+
+login:
+  path: login.php
+  method: form
+  form: form[action="takelogin.php"]
+  inputs:
+    secret: ""
+    username: "{{ .Config.username }}"
+    password: "{{ .Config.password }}"
+    two_step_code: "{{ .Config.2facode }}"
+    logout: ""
+    securelogin: ""
+    ssl: yes
+    trackerssl: yes
+  error:
+    - selector: td.embedded:contains("登录失败！")
+  test:
+    path: index.php
+    selector: a[href="logout.php"]
+
+search:
+  paths:
+    - path: torrents.php
+  inputs:
+    $raw: "{{ range .Categories }}cat{{.}}=1&{{end}}"
+    search: "{{ if .Query.IMDBID }}{{ .Query.IMDBID }}{{ else }}{{ .Keywords }}{{ end }}"
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: ilike2burnthing
body: ```suggestion
    search: "{{ .Keywords }}"
```

Not supported.
created_at: 2025-03-07T06:40:23Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
+    # TODO: Searching for `S01` and `S01E01` for an example, that
+    # yields other results when searched without, yields no difference
+    # in results. Am I missing something?
+    #
+    # TODO: The example I copied, `./freefarm.yml`, includes support
+    # for `DoubanID` but I don't find any evidence of that support in
+    # *that* example's web UI. For *this* indexer I tested the
+    # `DoubanID` like I tested an IMDB ID above. Is the example
+    # definiton wrong or out of date? If not, where can you see the
+    # support for `DoubanID` in *that* example and does this indexer
+    # also support it?
+    tv-search: [q]
+    movie-search: [q]
+    music-search: [q]
+    book-search: [q]
+
+settings:
+  - name: username
+    type: text
+    label: Username
+  - name: password
+    type: password
+    label: Password
+  - name: 2facode
+    type: text
+    label: 2FA code
+  - name: info_2fa
+    type: info
+    label: "About 2FA code"
+    default: "Only fill in the <b>2FA code</b> box if you have enabled <b>2FA</b> on the HDBao Web Site. Otherwise just leave it empty."
+  # TODO: While testing this field, I noticed the results only includ
+  # *just* "Free" items and *not* "2X Free" items. This is also the
+  # case for the example I copied. I understand its better for
+  # Jackett/Prowlarr to use the filtering supported server-side. Does
+  # NexusPHP support multiple `spstate` values? If no, is there a good
+  # place for feature requests?
+  - name: freeleech
+    type: checkbox
+    label: Search freeleech only
+    default: false
+  - name: sort
+    type: select
+    label: Sort requested from site
+    default: 4
+    options:
+      4: created
+      7: seeders
+      5: size
+      1: title
+  - name: type
+    type: select
+    label: Order requested from site
+    default: desc
+    options:
+      desc: desc
+      asc: asc
+  # TODO: I didn't get any FS challenges for this indexer that I can
+  # recall, and definitely not while developing this definition. I
+  # confirmed FS usage by looking at the response headers and
+  # cookie. Is that a sufficient way to identify FS usage?
+  - name: info_flaresolverr
+    type: info_flaresolverr
+  - name: info_tpp
+    type: info
+    label: Results Per Page
+    default: For best results, change the <b>Torrents per page:</b> setting to <b>100</b> on your account profile.
+  - name: info_activity
+    type: info
+    label: Account Inactivity
+    default: "Cherish your user account. Inactive accounts would be deleted based on the following rules:<ol><li>Veteran User or above would never be deleted.</li><li>Elite User or above would never be deleted if parked (at User CP).</li><li>Parked accounts would be deleted if users have not logged in for more than 400 days in a row.</li><li>Unparked accounts would be deleted if users have not logged in for more than 150 days in a row.</li><li>Accounts with both uploaded and downloaded amount being 0 would be deleted if users have not logged in for more than 100 days in a row.</li></ol>"
+
+login:
+  path: login.php
+  method: form
+  form: form[action="takelogin.php"]
+  inputs:
+    secret: ""
+    username: "{{ .Config.username }}"
+    password: "{{ .Config.password }}"
+    two_step_code: "{{ .Config.2facode }}"
+    logout: ""
+    securelogin: ""
+    ssl: yes
+    trackerssl: yes
+  error:
+    - selector: td.embedded:contains("登录失败！")
+  test:
+    path: index.php
+    selector: a[href="logout.php"]
+
+search:
+  paths:
+    - path: torrents.php
+  inputs:
+    $raw: "{{ range .Categories }}cat{{.}}=1&{{end}}"
+    search: "{{ if .Query.IMDBID }}{{ .Query.IMDBID }}{{ else }}{{ .Keywords }}{{ end }}"
+    # 0: include dead, 1: alive, 2: dead
+    incldead: 0
+    spstate: "{{ if .Config.freeleech }}2{{ else }}0{{ end }}"
+    # 0: title, 1: description, 3: uploader, 4: IMDB URL
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: ilike2burnthing
body: ```suggestion
    # 0: title, 1: description, 3: uploader, 4: imdburl (4 does not appear to work)
```
created_at: 2025-03-07T06:42:39Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
+    # TODO: Searching for `S01` and `S01E01` for an example, that
+    # yields other results when searched without, yields no difference
+    # in results. Am I missing something?
+    #
+    # TODO: The example I copied, `./freefarm.yml`, includes support
+    # for `DoubanID` but I don't find any evidence of that support in
+    # *that* example's web UI. For *this* indexer I tested the
+    # `DoubanID` like I tested an IMDB ID above. Is the example
+    # definiton wrong or out of date? If not, where can you see the
+    # support for `DoubanID` in *that* example and does this indexer
+    # also support it?
+    tv-search: [q]
+    movie-search: [q]
+    music-search: [q]
+    book-search: [q]
+
+settings:
+  - name: username
+    type: text
+    label: Username
+  - name: password
+    type: password
+    label: Password
+  - name: 2facode
+    type: text
+    label: 2FA code
+  - name: info_2fa
+    type: info
+    label: "About 2FA code"
+    default: "Only fill in the <b>2FA code</b> box if you have enabled <b>2FA</b> on the HDBao Web Site. Otherwise just leave it empty."
+  # TODO: While testing this field, I noticed the results only includ
+  # *just* "Free" items and *not* "2X Free" items. This is also the
+  # case for the example I copied. I understand its better for
+  # Jackett/Prowlarr to use the filtering supported server-side. Does
+  # NexusPHP support multiple `spstate` values? If no, is there a good
+  # place for feature requests?
+  - name: freeleech
+    type: checkbox
+    label: Search freeleech only
+    default: false
+  - name: sort
+    type: select
+    label: Sort requested from site
+    default: 4
+    options:
+      4: created
+      7: seeders
+      5: size
+      1: title
+  - name: type
+    type: select
+    label: Order requested from site
+    default: desc
+    options:
+      desc: desc
+      asc: asc
+  # TODO: I didn't get any FS challenges for this indexer that I can
+  # recall, and definitely not while developing this definition. I
+  # confirmed FS usage by looking at the response headers and
+  # cookie. Is that a sufficient way to identify FS usage?
+  - name: info_flaresolverr
+    type: info_flaresolverr
+  - name: info_tpp
+    type: info
+    label: Results Per Page
+    default: For best results, change the <b>Torrents per page:</b> setting to <b>100</b> on your account profile.
+  - name: info_activity
+    type: info
+    label: Account Inactivity
+    default: "Cherish your user account. Inactive accounts would be deleted based on the following rules:<ol><li>Veteran User or above would never be deleted.</li><li>Elite User or above would never be deleted if parked (at User CP).</li><li>Parked accounts would be deleted if users have not logged in for more than 400 days in a row.</li><li>Unparked accounts would be deleted if users have not logged in for more than 150 days in a row.</li><li>Accounts with both uploaded and downloaded amount being 0 would be deleted if users have not logged in for more than 100 days in a row.</li></ol>"
+
+login:
+  path: login.php
+  method: form
+  form: form[action="takelogin.php"]
+  inputs:
+    secret: ""
+    username: "{{ .Config.username }}"
+    password: "{{ .Config.password }}"
+    two_step_code: "{{ .Config.2facode }}"
+    logout: ""
+    securelogin: ""
+    ssl: yes
+    trackerssl: yes
+  error:
+    - selector: td.embedded:contains("登录失败！")
+  test:
+    path: index.php
+    selector: a[href="logout.php"]
+
+search:
+  paths:
+    - path: torrents.php
+  inputs:
+    $raw: "{{ range .Categories }}cat{{.}}=1&{{end}}"
+    search: "{{ if .Query.IMDBID }}{{ .Query.IMDBID }}{{ else }}{{ .Keywords }}{{ end }}"
+    # 0: include dead, 1: alive, 2: dead
+    incldead: 0
+    spstate: "{{ if .Config.freeleech }}2{{ else }}0{{ end }}"
+    # 0: title, 1: description, 3: uploader, 4: IMDB URL
+    search_area: "0"
+    # 0: AND, 2: exact
+    search_mode: 0
+    sort: "{{ .Config.sort }}"
+    type: "{{ .Config.type }}"
+    # TODO: The example I copied, `./freefarm.yml`, includes a
+    # `notnewword` key but I don't see that key from submitting the
+    # search form in the web UI of either that example or this
+    # indexer. What am I missing?
+    #
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: ilike2burnthing
body: ```suggestion
    notnewword: 1
```

https://github.com/Jackett/Jackett/pull/14137
created_at: 2025-03-07T06:46:33Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
+    # TODO: Searching for `S01` and `S01E01` for an example, that
+    # yields other results when searched without, yields no difference
+    # in results. Am I missing something?
+    #
+    # TODO: The example I copied, `./freefarm.yml`, includes support
+    # for `DoubanID` but I don't find any evidence of that support in
+    # *that* example's web UI. For *this* indexer I tested the
+    # `DoubanID` like I tested an IMDB ID above. Is the example
+    # definiton wrong or out of date? If not, where can you see the
+    # support for `DoubanID` in *that* example and does this indexer
+    # also support it?
+    tv-search: [q]
+    movie-search: [q]
+    music-search: [q]
+    book-search: [q]
+
+settings:
+  - name: username
+    type: text
+    label: Username
+  - name: password
+    type: password
+    label: Password
+  - name: 2facode
+    type: text
+    label: 2FA code
+  - name: info_2fa
+    type: info
+    label: "About 2FA code"
+    default: "Only fill in the <b>2FA code</b> box if you have enabled <b>2FA</b> on the HDBao Web Site. Otherwise just leave it empty."
+  # TODO: While testing this field, I noticed the results only includ
+  # *just* "Free" items and *not* "2X Free" items. This is also the
+  # case for the example I copied. I understand its better for
+  # Jackett/Prowlarr to use the filtering supported server-side. Does
+  # NexusPHP support multiple `spstate` values? If no, is there a good
+  # place for feature requests?
+  - name: freeleech
+    type: checkbox
+    label: Search freeleech only
+    default: false
+  - name: sort
+    type: select
+    label: Sort requested from site
+    default: 4
+    options:
+      4: created
+      7: seeders
+      5: size
+      1: title
+  - name: type
+    type: select
+    label: Order requested from site
+    default: desc
+    options:
+      desc: desc
+      asc: asc
+  # TODO: I didn't get any FS challenges for this indexer that I can
+  # recall, and definitely not while developing this definition. I
+  # confirmed FS usage by looking at the response headers and
+  # cookie. Is that a sufficient way to identify FS usage?
+  - name: info_flaresolverr
+    type: info_flaresolverr
+  - name: info_tpp
+    type: info
+    label: Results Per Page
+    default: For best results, change the <b>Torrents per page:</b> setting to <b>100</b> on your account profile.
+  - name: info_activity
+    type: info
+    label: Account Inactivity
+    default: "Cherish your user account. Inactive accounts would be deleted based on the following rules:<ol><li>Veteran User or above would never be deleted.</li><li>Elite User or above would never be deleted if parked (at User CP).</li><li>Parked accounts would be deleted if users have not logged in for more than 400 days in a row.</li><li>Unparked accounts would be deleted if users have not logged in for more than 150 days in a row.</li><li>Accounts with both uploaded and downloaded amount being 0 would be deleted if users have not logged in for more than 100 days in a row.</li></ol>"
+
+login:
+  path: login.php
+  method: form
+  form: form[action="takelogin.php"]
+  inputs:
+    secret: ""
+    username: "{{ .Config.username }}"
+    password: "{{ .Config.password }}"
+    two_step_code: "{{ .Config.2facode }}"
+    logout: ""
+    securelogin: ""
+    ssl: yes
+    trackerssl: yes
+  error:
+    - selector: td.embedded:contains("登录失败！")
+  test:
+    path: index.php
+    selector: a[href="logout.php"]
+
+search:
+  paths:
+    - path: torrents.php
+  inputs:
+    $raw: "{{ range .Categories }}cat{{.}}=1&{{end}}"
+    search: "{{ if .Query.IMDBID }}{{ .Query.IMDBID }}{{ else }}{{ .Keywords }}{{ end }}"
+    # 0: include dead, 1: alive, 2: dead
+    incldead: 0
+    spstate: "{{ if .Config.freeleech }}2{{ else }}0{{ end }}"
+    # 0: title, 1: description, 3: uploader, 4: IMDB URL
+    search_area: "0"
+    # 0: AND, 2: exact
+    search_mode: 0
+    sort: "{{ .Config.sort }}"
+    type: "{{ .Config.type }}"
+    # TODO: The example I copied, `./freefarm.yml`, includes a
+    # `notnewword` key but I don't see that key from submitting the
+    # search form in the web UI of either that example or this
+    # indexer. What am I missing?
+    #
+    # TODO: On that note, while inspecting the payloads of both search
+    # forms I noted a bunch of parameters that the web UI sends that
+    # aren't included in that example. How does that reconcile with
+    # "we don't want an obvious 'Jackett footprint'" from my last PR
+    # feedback especially given how much of Jackett/Prowlarr's traffic
+    # is submissions of this form?
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: ilike2burnthing
body: ```suggestion
```

We did use to have every single search input for many/most(?) indexers, but some had a ridiculous number that were just null or 0, and we now default to stripping empty inputs (although this can be overridden with `allowEmptyInputs`). So we now tend to keep it to what is necessary, as makes maintaining indexers much easier, and there's less to break one if a site makes a change.
created_at: 2025-03-07T06:56:19Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
+    # TODO: Searching for `S01` and `S01E01` for an example, that
+    # yields other results when searched without, yields no difference
+    # in results. Am I missing something?
+    #
+    # TODO: The example I copied, `./freefarm.yml`, includes support
+    # for `DoubanID` but I don't find any evidence of that support in
+    # *that* example's web UI. For *this* indexer I tested the
+    # `DoubanID` like I tested an IMDB ID above. Is the example
+    # definiton wrong or out of date? If not, where can you see the
+    # support for `DoubanID` in *that* example and does this indexer
+    # also support it?
+    tv-search: [q]
+    movie-search: [q]
+    music-search: [q]
+    book-search: [q]
+
+settings:
+  - name: username
+    type: text
+    label: Username
+  - name: password
+    type: password
+    label: Password
+  - name: 2facode
+    type: text
+    label: 2FA code
+  - name: info_2fa
+    type: info
+    label: "About 2FA code"
+    default: "Only fill in the <b>2FA code</b> box if you have enabled <b>2FA</b> on the HDBao Web Site. Otherwise just leave it empty."
+  # TODO: While testing this field, I noticed the results only includ
+  # *just* "Free" items and *not* "2X Free" items. This is also the
+  # case for the example I copied. I understand its better for
+  # Jackett/Prowlarr to use the filtering supported server-side. Does
+  # NexusPHP support multiple `spstate` values? If no, is there a good
+  # place for feature requests?
+  - name: freeleech
+    type: checkbox
+    label: Search freeleech only
+    default: false
+  - name: sort
+    type: select
+    label: Sort requested from site
+    default: 4
+    options:
+      4: created
+      7: seeders
+      5: size
+      1: title
+  - name: type
+    type: select
+    label: Order requested from site
+    default: desc
+    options:
+      desc: desc
+      asc: asc
+  # TODO: I didn't get any FS challenges for this indexer that I can
+  # recall, and definitely not while developing this definition. I
+  # confirmed FS usage by looking at the response headers and
+  # cookie. Is that a sufficient way to identify FS usage?
+  - name: info_flaresolverr
+    type: info_flaresolverr
+  - name: info_tpp
+    type: info
+    label: Results Per Page
+    default: For best results, change the <b>Torrents per page:</b> setting to <b>100</b> on your account profile.
+  - name: info_activity
+    type: info
+    label: Account Inactivity
+    default: "Cherish your user account. Inactive accounts would be deleted based on the following rules:<ol><li>Veteran User or above would never be deleted.</li><li>Elite User or above would never be deleted if parked (at User CP).</li><li>Parked accounts would be deleted if users have not logged in for more than 400 days in a row.</li><li>Unparked accounts would be deleted if users have not logged in for more than 150 days in a row.</li><li>Accounts with both uploaded and downloaded amount being 0 would be deleted if users have not logged in for more than 100 days in a row.</li></ol>"
+
+login:
+  path: login.php
+  method: form
+  form: form[action="takelogin.php"]
+  inputs:
+    secret: ""
+    username: "{{ .Config.username }}"
+    password: "{{ .Config.password }}"
+    two_step_code: "{{ .Config.2facode }}"
+    logout: ""
+    securelogin: ""
+    ssl: yes
+    trackerssl: yes
+  error:
+    - selector: td.embedded:contains("登录失败！")
+  test:
+    path: index.php
+    selector: a[href="logout.php"]
+
+search:
+  paths:
+    - path: torrents.php
+  inputs:
+    $raw: "{{ range .Categories }}cat{{.}}=1&{{end}}"
+    search: "{{ if .Query.IMDBID }}{{ .Query.IMDBID }}{{ else }}{{ .Keywords }}{{ end }}"
+    # 0: include dead, 1: alive, 2: dead
+    incldead: 0
+    spstate: "{{ if .Config.freeleech }}2{{ else }}0{{ end }}"
+    # 0: title, 1: description, 3: uploader, 4: IMDB URL
+    search_area: "0"
+    # 0: AND, 2: exact
+    search_mode: 0
+    sort: "{{ .Config.sort }}"
+    type: "{{ .Config.type }}"
+    # TODO: The example I copied, `./freefarm.yml`, includes a
+    # `notnewword` key but I don't see that key from submitting the
+    # search form in the web UI of either that example or this
+    # indexer. What am I missing?
+    #
+    # TODO: On that note, while inspecting the payloads of both search
+    # forms I noted a bunch of parameters that the web UI sends that
+    # aren't included in that example. How does that reconcile with
+    # "we don't want an obvious 'Jackett footprint'" from my last PR
+    # feedback especially given how much of Jackett/Prowlarr's traffic
+    # is submissions of this form?
+
+  rows:
+    selector: table.torrents > tbody > tr:has(a[href^="download.php?id="])
+
+  fields:
+    category:
+      selector: a[href^="?cat="]
+      attribute: href
+      filters:
+        - name: querystring
+          args: cat
+    title_default:
+      selector: a[href^="details.php?id="]
+    title:
+      selector: a[title][href^="details.php?id="]
+      attribute: title
+      optional: true
+      default: "{{ .Result.title_default }}"
+    details:
+      selector: a[href^="details.php?id="]
+      attribute: href
+    download:
+      selector: a[href^="download.php?id="]
+      attribute: href
+    poster:
+      selector: img[data-src]
+      attribute: data-src
+    imdbid:
+      # site currently only has a badge and rating, the id is not present. just in case a future update.
+      selector: a[href*="imdb.com/title/tt"]
+      attribute: href
+    doubanid:
+      # site currently only has a badge and rating, the id is not present. just in case a future update.
+      selector: a[href*="movie.douban.com/subject/"]
+      attribute: href
+    date_elapsed:
+      # TODO: The selector from the example I copied includes
+      # `.rowfollow` which is a class for most of the column cells and
+      # AFAICT is only for presentation. As such I think it makes the
+      # selector more fragile and I've removed it from this
+      # definition. Should it be cleaned up in other definitions?
+      #
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: ilike2burnthing
body: ```suggestion
```

I think this might have been necessary at some point, as there were other `td`s, and then it has just persisted in the template. If it's working for this indexer, fine, but no the others don't need updated.
created_at: 2025-03-07T06:59:33Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
+    # TODO: Searching for `S01` and `S01E01` for an example, that
+    # yields other results when searched without, yields no difference
+    # in results. Am I missing something?
+    #
+    # TODO: The example I copied, `./freefarm.yml`, includes support
+    # for `DoubanID` but I don't find any evidence of that support in
+    # *that* example's web UI. For *this* indexer I tested the
+    # `DoubanID` like I tested an IMDB ID above. Is the example
+    # definiton wrong or out of date? If not, where can you see the
+    # support for `DoubanID` in *that* example and does this indexer
+    # also support it?
+    tv-search: [q]
+    movie-search: [q]
+    music-search: [q]
+    book-search: [q]
+
+settings:
+  - name: username
+    type: text
+    label: Username
+  - name: password
+    type: password
+    label: Password
+  - name: 2facode
+    type: text
+    label: 2FA code
+  - name: info_2fa
+    type: info
+    label: "About 2FA code"
+    default: "Only fill in the <b>2FA code</b> box if you have enabled <b>2FA</b> on the HDBao Web Site. Otherwise just leave it empty."
+  # TODO: While testing this field, I noticed the results only includ
+  # *just* "Free" items and *not* "2X Free" items. This is also the
+  # case for the example I copied. I understand its better for
+  # Jackett/Prowlarr to use the filtering supported server-side. Does
+  # NexusPHP support multiple `spstate` values? If no, is there a good
+  # place for feature requests?
+  - name: freeleech
+    type: checkbox
+    label: Search freeleech only
+    default: false
+  - name: sort
+    type: select
+    label: Sort requested from site
+    default: 4
+    options:
+      4: created
+      7: seeders
+      5: size
+      1: title
+  - name: type
+    type: select
+    label: Order requested from site
+    default: desc
+    options:
+      desc: desc
+      asc: asc
+  # TODO: I didn't get any FS challenges for this indexer that I can
+  # recall, and definitely not while developing this definition. I
+  # confirmed FS usage by looking at the response headers and
+  # cookie. Is that a sufficient way to identify FS usage?
+  - name: info_flaresolverr
+    type: info_flaresolverr
+  - name: info_tpp
+    type: info
+    label: Results Per Page
+    default: For best results, change the <b>Torrents per page:</b> setting to <b>100</b> on your account profile.
+  - name: info_activity
+    type: info
+    label: Account Inactivity
+    default: "Cherish your user account. Inactive accounts would be deleted based on the following rules:<ol><li>Veteran User or above would never be deleted.</li><li>Elite User or above would never be deleted if parked (at User CP).</li><li>Parked accounts would be deleted if users have not logged in for more than 400 days in a row.</li><li>Unparked accounts would be deleted if users have not logged in for more than 150 days in a row.</li><li>Accounts with both uploaded and downloaded amount being 0 would be deleted if users have not logged in for more than 100 days in a row.</li></ol>"
+
+login:
+  path: login.php
+  method: form
+  form: form[action="takelogin.php"]
+  inputs:
+    secret: ""
+    username: "{{ .Config.username }}"
+    password: "{{ .Config.password }}"
+    two_step_code: "{{ .Config.2facode }}"
+    logout: ""
+    securelogin: ""
+    ssl: yes
+    trackerssl: yes
+  error:
+    - selector: td.embedded:contains("登录失败！")
+  test:
+    path: index.php
+    selector: a[href="logout.php"]
+
+search:
+  paths:
+    - path: torrents.php
+  inputs:
+    $raw: "{{ range .Categories }}cat{{.}}=1&{{end}}"
+    search: "{{ if .Query.IMDBID }}{{ .Query.IMDBID }}{{ else }}{{ .Keywords }}{{ end }}"
+    # 0: include dead, 1: alive, 2: dead
+    incldead: 0
+    spstate: "{{ if .Config.freeleech }}2{{ else }}0{{ end }}"
+    # 0: title, 1: description, 3: uploader, 4: IMDB URL
+    search_area: "0"
+    # 0: AND, 2: exact
+    search_mode: 0
+    sort: "{{ .Config.sort }}"
+    type: "{{ .Config.type }}"
+    # TODO: The example I copied, `./freefarm.yml`, includes a
+    # `notnewword` key but I don't see that key from submitting the
+    # search form in the web UI of either that example or this
+    # indexer. What am I missing?
+    #
+    # TODO: On that note, while inspecting the payloads of both search
+    # forms I noted a bunch of parameters that the web UI sends that
+    # aren't included in that example. How does that reconcile with
+    # "we don't want an obvious 'Jackett footprint'" from my last PR
+    # feedback especially given how much of Jackett/Prowlarr's traffic
+    # is submissions of this form?
+
+  rows:
+    selector: table.torrents > tbody > tr:has(a[href^="download.php?id="])
+
+  fields:
+    category:
+      selector: a[href^="?cat="]
+      attribute: href
+      filters:
+        - name: querystring
+          args: cat
+    title_default:
+      selector: a[href^="details.php?id="]
+    title:
+      selector: a[title][href^="details.php?id="]
+      attribute: title
+      optional: true
+      default: "{{ .Result.title_default }}"
+    details:
+      selector: a[href^="details.php?id="]
+      attribute: href
+    download:
+      selector: a[href^="download.php?id="]
+      attribute: href
+    poster:
+      selector: img[data-src]
+      attribute: data-src
+    imdbid:
+      # site currently only has a badge and rating, the id is not present. just in case a future update.
+      selector: a[href*="imdb.com/title/tt"]
+      attribute: href
+    doubanid:
+      # site currently only has a badge and rating, the id is not present. just in case a future update.
+      selector: a[href*="movie.douban.com/subject/"]
+      attribute: href
+    date_elapsed:
+      # TODO: The selector from the example I copied includes
+      # `.rowfollow` which is a class for most of the column cells and
+      # AFAICT is only for presentation. As such I think it makes the
+      # selector more fragile and I've removed it from this
+      # definition. Should it be cleaned up in other definitions?
+      #
+      # time type: time elapsed (default)
+      selector: td:nth-child(4) > span[title]
+      attribute: title
+      optional: true
+      filters:
+        - name: append
+          # TODO: This is another demonstration of why a more verbose comment is
+          # valuable here. The `CST` abbreviation is used for both `-04:00` through
+          # `-06:00` in the Americas *and* `+08:00` in Asia. The more verbose comment
+          # removes ambiguity and saves contributor time.
+          args: " +08:00" # Asia/Taipei, CST
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: ilike2burnthing
body: ```suggestion
          args: " +08:00" # CST
```

The combination of the time difference and the time zone abbreviation is enough to make that distinction. This conversation has been had, thanks.
created_at: 2025-03-07T07:01:06Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
+    # TODO: Searching for `S01` and `S01E01` for an example, that
+    # yields other results when searched without, yields no difference
+    # in results. Am I missing something?
+    #
+    # TODO: The example I copied, `./freefarm.yml`, includes support
+    # for `DoubanID` but I don't find any evidence of that support in
+    # *that* example's web UI. For *this* indexer I tested the
+    # `DoubanID` like I tested an IMDB ID above. Is the example
+    # definiton wrong or out of date? If not, where can you see the
+    # support for `DoubanID` in *that* example and does this indexer
+    # also support it?
+    tv-search: [q]
+    movie-search: [q]
+    music-search: [q]
+    book-search: [q]
+
+settings:
+  - name: username
+    type: text
+    label: Username
+  - name: password
+    type: password
+    label: Password
+  - name: 2facode
+    type: text
+    label: 2FA code
+  - name: info_2fa
+    type: info
+    label: "About 2FA code"
+    default: "Only fill in the <b>2FA code</b> box if you have enabled <b>2FA</b> on the HDBao Web Site. Otherwise just leave it empty."
+  # TODO: While testing this field, I noticed the results only includ
+  # *just* "Free" items and *not* "2X Free" items. This is also the
+  # case for the example I copied. I understand its better for
+  # Jackett/Prowlarr to use the filtering supported server-side. Does
+  # NexusPHP support multiple `spstate` values? If no, is there a good
+  # place for feature requests?
+  - name: freeleech
+    type: checkbox
+    label: Search freeleech only
+    default: false
+  - name: sort
+    type: select
+    label: Sort requested from site
+    default: 4
+    options:
+      4: created
+      7: seeders
+      5: size
+      1: title
+  - name: type
+    type: select
+    label: Order requested from site
+    default: desc
+    options:
+      desc: desc
+      asc: asc
+  # TODO: I didn't get any FS challenges for this indexer that I can
+  # recall, and definitely not while developing this definition. I
+  # confirmed FS usage by looking at the response headers and
+  # cookie. Is that a sufficient way to identify FS usage?
+  - name: info_flaresolverr
+    type: info_flaresolverr
+  - name: info_tpp
+    type: info
+    label: Results Per Page
+    default: For best results, change the <b>Torrents per page:</b> setting to <b>100</b> on your account profile.
+  - name: info_activity
+    type: info
+    label: Account Inactivity
+    default: "Cherish your user account. Inactive accounts would be deleted based on the following rules:<ol><li>Veteran User or above would never be deleted.</li><li>Elite User or above would never be deleted if parked (at User CP).</li><li>Parked accounts would be deleted if users have not logged in for more than 400 days in a row.</li><li>Unparked accounts would be deleted if users have not logged in for more than 150 days in a row.</li><li>Accounts with both uploaded and downloaded amount being 0 would be deleted if users have not logged in for more than 100 days in a row.</li></ol>"
+
+login:
+  path: login.php
+  method: form
+  form: form[action="takelogin.php"]
+  inputs:
+    secret: ""
+    username: "{{ .Config.username }}"
+    password: "{{ .Config.password }}"
+    two_step_code: "{{ .Config.2facode }}"
+    logout: ""
+    securelogin: ""
+    ssl: yes
+    trackerssl: yes
+  error:
+    - selector: td.embedded:contains("登录失败！")
+  test:
+    path: index.php
+    selector: a[href="logout.php"]
+
+search:
+  paths:
+    - path: torrents.php
+  inputs:
+    $raw: "{{ range .Categories }}cat{{.}}=1&{{end}}"
+    search: "{{ if .Query.IMDBID }}{{ .Query.IMDBID }}{{ else }}{{ .Keywords }}{{ end }}"
+    # 0: include dead, 1: alive, 2: dead
+    incldead: 0
+    spstate: "{{ if .Config.freeleech }}2{{ else }}0{{ end }}"
+    # 0: title, 1: description, 3: uploader, 4: IMDB URL
+    search_area: "0"
+    # 0: AND, 2: exact
+    search_mode: 0
+    sort: "{{ .Config.sort }}"
+    type: "{{ .Config.type }}"
+    # TODO: The example I copied, `./freefarm.yml`, includes a
+    # `notnewword` key but I don't see that key from submitting the
+    # search form in the web UI of either that example or this
+    # indexer. What am I missing?
+    #
+    # TODO: On that note, while inspecting the payloads of both search
+    # forms I noted a bunch of parameters that the web UI sends that
+    # aren't included in that example. How does that reconcile with
+    # "we don't want an obvious 'Jackett footprint'" from my last PR
+    # feedback especially given how much of Jackett/Prowlarr's traffic
+    # is submissions of this form?
+
+  rows:
+    selector: table.torrents > tbody > tr:has(a[href^="download.php?id="])
+
+  fields:
+    category:
+      selector: a[href^="?cat="]
+      attribute: href
+      filters:
+        - name: querystring
+          args: cat
+    title_default:
+      selector: a[href^="details.php?id="]
+    title:
+      selector: a[title][href^="details.php?id="]
+      attribute: title
+      optional: true
+      default: "{{ .Result.title_default }}"
+    details:
+      selector: a[href^="details.php?id="]
+      attribute: href
+    download:
+      selector: a[href^="download.php?id="]
+      attribute: href
+    poster:
+      selector: img[data-src]
+      attribute: data-src
+    imdbid:
+      # site currently only has a badge and rating, the id is not present. just in case a future update.
+      selector: a[href*="imdb.com/title/tt"]
+      attribute: href
+    doubanid:
+      # site currently only has a badge and rating, the id is not present. just in case a future update.
+      selector: a[href*="movie.douban.com/subject/"]
+      attribute: href
+    date_elapsed:
+      # TODO: The selector from the example I copied includes
+      # `.rowfollow` which is a class for most of the column cells and
+      # AFAICT is only for presentation. As such I think it makes the
+      # selector more fragile and I've removed it from this
+      # definition. Should it be cleaned up in other definitions?
+      #
+      # time type: time elapsed (default)
+      selector: td:nth-child(4) > span[title]
+      attribute: title
+      optional: true
+      filters:
+        - name: append
+          # TODO: This is another demonstration of why a more verbose comment is
+          # valuable here. The `CST` abbreviation is used for both `-04:00` through
+          # `-06:00` in the Americas *and* `+08:00` in Asia. The more verbose comment
+          # removes ambiguity and saves contributor time.
+          args: " +08:00" # Asia/Taipei, CST
+        - name: dateparse
+          args: "yyyy-MM-dd HH:mm:ss zzz"
+    # TODO: I couldn't find an example of this when I sorted the full
+    # listing by date in both directions in the web UI of the exampale
+    # I copied. Where can I see the need for this in the example I
+    # copied so I can identify when it's needed for future
+    # definitions? Is it necessary for this definition?
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: ilike2burnthing
body: ```suggestion
```

https://hdbao.cc/usercp.php?action=tracker > `Time Type`
created_at: 2025-03-07T07:03:14Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
+    # TODO: Searching for `S01` and `S01E01` for an example, that
+    # yields other results when searched without, yields no difference
+    # in results. Am I missing something?
+    #
+    # TODO: The example I copied, `./freefarm.yml`, includes support
+    # for `DoubanID` but I don't find any evidence of that support in
+    # *that* example's web UI. For *this* indexer I tested the
+    # `DoubanID` like I tested an IMDB ID above. Is the example
+    # definiton wrong or out of date? If not, where can you see the
+    # support for `DoubanID` in *that* example and does this indexer
+    # also support it?
+    tv-search: [q]
+    movie-search: [q]
+    music-search: [q]
+    book-search: [q]
+
+settings:
+  - name: username
+    type: text
+    label: Username
+  - name: password
+    type: password
+    label: Password
+  - name: 2facode
+    type: text
+    label: 2FA code
+  - name: info_2fa
+    type: info
+    label: "About 2FA code"
+    default: "Only fill in the <b>2FA code</b> box if you have enabled <b>2FA</b> on the HDBao Web Site. Otherwise just leave it empty."
+  # TODO: While testing this field, I noticed the results only includ
+  # *just* "Free" items and *not* "2X Free" items. This is also the
+  # case for the example I copied. I understand its better for
+  # Jackett/Prowlarr to use the filtering supported server-side. Does
+  # NexusPHP support multiple `spstate` values? If no, is there a good
+  # place for feature requests?
+  - name: freeleech
+    type: checkbox
+    label: Search freeleech only
+    default: false
+  - name: sort
+    type: select
+    label: Sort requested from site
+    default: 4
+    options:
+      4: created
+      7: seeders
+      5: size
+      1: title
+  - name: type
+    type: select
+    label: Order requested from site
+    default: desc
+    options:
+      desc: desc
+      asc: asc
+  # TODO: I didn't get any FS challenges for this indexer that I can
+  # recall, and definitely not while developing this definition. I
+  # confirmed FS usage by looking at the response headers and
+  # cookie. Is that a sufficient way to identify FS usage?
+  - name: info_flaresolverr
+    type: info_flaresolverr
+  - name: info_tpp
+    type: info
+    label: Results Per Page
+    default: For best results, change the <b>Torrents per page:</b> setting to <b>100</b> on your account profile.
+  - name: info_activity
+    type: info
+    label: Account Inactivity
+    default: "Cherish your user account. Inactive accounts would be deleted based on the following rules:<ol><li>Veteran User or above would never be deleted.</li><li>Elite User or above would never be deleted if parked (at User CP).</li><li>Parked accounts would be deleted if users have not logged in for more than 400 days in a row.</li><li>Unparked accounts would be deleted if users have not logged in for more than 150 days in a row.</li><li>Accounts with both uploaded and downloaded amount being 0 would be deleted if users have not logged in for more than 100 days in a row.</li></ol>"
+
+login:
+  path: login.php
+  method: form
+  form: form[action="takelogin.php"]
+  inputs:
+    secret: ""
+    username: "{{ .Config.username }}"
+    password: "{{ .Config.password }}"
+    two_step_code: "{{ .Config.2facode }}"
+    logout: ""
+    securelogin: ""
+    ssl: yes
+    trackerssl: yes
+  error:
+    - selector: td.embedded:contains("登录失败！")
+  test:
+    path: index.php
+    selector: a[href="logout.php"]
+
+search:
+  paths:
+    - path: torrents.php
+  inputs:
+    $raw: "{{ range .Categories }}cat{{.}}=1&{{end}}"
+    search: "{{ if .Query.IMDBID }}{{ .Query.IMDBID }}{{ else }}{{ .Keywords }}{{ end }}"
+    # 0: include dead, 1: alive, 2: dead
+    incldead: 0
+    spstate: "{{ if .Config.freeleech }}2{{ else }}0{{ end }}"
+    # 0: title, 1: description, 3: uploader, 4: IMDB URL
+    search_area: "0"
+    # 0: AND, 2: exact
+    search_mode: 0
+    sort: "{{ .Config.sort }}"
+    type: "{{ .Config.type }}"
+    # TODO: The example I copied, `./freefarm.yml`, includes a
+    # `notnewword` key but I don't see that key from submitting the
+    # search form in the web UI of either that example or this
+    # indexer. What am I missing?
+    #
+    # TODO: On that note, while inspecting the payloads of both search
+    # forms I noted a bunch of parameters that the web UI sends that
+    # aren't included in that example. How does that reconcile with
+    # "we don't want an obvious 'Jackett footprint'" from my last PR
+    # feedback especially given how much of Jackett/Prowlarr's traffic
+    # is submissions of this form?
+
+  rows:
+    selector: table.torrents > tbody > tr:has(a[href^="download.php?id="])
+
+  fields:
+    category:
+      selector: a[href^="?cat="]
+      attribute: href
+      filters:
+        - name: querystring
+          args: cat
+    title_default:
+      selector: a[href^="details.php?id="]
+    title:
+      selector: a[title][href^="details.php?id="]
+      attribute: title
+      optional: true
+      default: "{{ .Result.title_default }}"
+    details:
+      selector: a[href^="details.php?id="]
+      attribute: href
+    download:
+      selector: a[href^="download.php?id="]
+      attribute: href
+    poster:
+      selector: img[data-src]
+      attribute: data-src
+    imdbid:
+      # site currently only has a badge and rating, the id is not present. just in case a future update.
+      selector: a[href*="imdb.com/title/tt"]
+      attribute: href
+    doubanid:
+      # site currently only has a badge and rating, the id is not present. just in case a future update.
+      selector: a[href*="movie.douban.com/subject/"]
+      attribute: href
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: ilike2burnthing
body: ```suggestion
```

They don't seem to be using these at all.
created_at: 2025-03-07T07:06:46Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
+    # TODO: Searching for `S01` and `S01E01` for an example, that
+    # yields other results when searched without, yields no difference
+    # in results. Am I missing something?
+    #
+    # TODO: The example I copied, `./freefarm.yml`, includes support
+    # for `DoubanID` but I don't find any evidence of that support in
+    # *that* example's web UI. For *this* indexer I tested the
+    # `DoubanID` like I tested an IMDB ID above. Is the example
+    # definiton wrong or out of date? If not, where can you see the
+    # support for `DoubanID` in *that* example and does this indexer
+    # also support it?
+    tv-search: [q]
+    movie-search: [q]
+    music-search: [q]
+    book-search: [q]
+
+settings:
+  - name: username
+    type: text
+    label: Username
+  - name: password
+    type: password
+    label: Password
+  - name: 2facode
+    type: text
+    label: 2FA code
+  - name: info_2fa
+    type: info
+    label: "About 2FA code"
+    default: "Only fill in the <b>2FA code</b> box if you have enabled <b>2FA</b> on the HDBao Web Site. Otherwise just leave it empty."
+  # TODO: While testing this field, I noticed the results only includ
+  # *just* "Free" items and *not* "2X Free" items. This is also the
+  # case for the example I copied. I understand its better for
+  # Jackett/Prowlarr to use the filtering supported server-side. Does
+  # NexusPHP support multiple `spstate` values? If no, is there a good
+  # place for feature requests?
+  - name: freeleech
+    type: checkbox
+    label: Search freeleech only
+    default: false
+  - name: sort
+    type: select
+    label: Sort requested from site
+    default: 4
+    options:
+      4: created
+      7: seeders
+      5: size
+      1: title
+  - name: type
+    type: select
+    label: Order requested from site
+    default: desc
+    options:
+      desc: desc
+      asc: asc
+  # TODO: I didn't get any FS challenges for this indexer that I can
+  # recall, and definitely not while developing this definition. I
+  # confirmed FS usage by looking at the response headers and
+  # cookie. Is that a sufficient way to identify FS usage?
+  - name: info_flaresolverr
+    type: info_flaresolverr
+  - name: info_tpp
+    type: info
+    label: Results Per Page
+    default: For best results, change the <b>Torrents per page:</b> setting to <b>100</b> on your account profile.
+  - name: info_activity
+    type: info
+    label: Account Inactivity
+    default: "Cherish your user account. Inactive accounts would be deleted based on the following rules:<ol><li>Veteran User or above would never be deleted.</li><li>Elite User or above would never be deleted if parked (at User CP).</li><li>Parked accounts would be deleted if users have not logged in for more than 400 days in a row.</li><li>Unparked accounts would be deleted if users have not logged in for more than 150 days in a row.</li><li>Accounts with both uploaded and downloaded amount being 0 would be deleted if users have not logged in for more than 100 days in a row.</li></ol>"
+
+login:
+  path: login.php
+  method: form
+  form: form[action="takelogin.php"]
+  inputs:
+    secret: ""
+    username: "{{ .Config.username }}"
+    password: "{{ .Config.password }}"
+    two_step_code: "{{ .Config.2facode }}"
+    logout: ""
+    securelogin: ""
+    ssl: yes
+    trackerssl: yes
+  error:
+    - selector: td.embedded:contains("登录失败！")
+  test:
+    path: index.php
+    selector: a[href="logout.php"]
+
+search:
+  paths:
+    - path: torrents.php
+  inputs:
+    $raw: "{{ range .Categories }}cat{{.}}=1&{{end}}"
+    search: "{{ if .Query.IMDBID }}{{ .Query.IMDBID }}{{ else }}{{ .Keywords }}{{ end }}"
+    # 0: include dead, 1: alive, 2: dead
+    incldead: 0
+    spstate: "{{ if .Config.freeleech }}2{{ else }}0{{ end }}"
+    # 0: title, 1: description, 3: uploader, 4: IMDB URL
+    search_area: "0"
+    # 0: AND, 2: exact
+    search_mode: 0
+    sort: "{{ .Config.sort }}"
+    type: "{{ .Config.type }}"
+    # TODO: The example I copied, `./freefarm.yml`, includes a
+    # `notnewword` key but I don't see that key from submitting the
+    # search form in the web UI of either that example or this
+    # indexer. What am I missing?
+    #
+    # TODO: On that note, while inspecting the payloads of both search
+    # forms I noted a bunch of parameters that the web UI sends that
+    # aren't included in that example. How does that reconcile with
+    # "we don't want an obvious 'Jackett footprint'" from my last PR
+    # feedback especially given how much of Jackett/Prowlarr's traffic
+    # is submissions of this form?
+
+  rows:
+    selector: table.torrents > tbody > tr:has(a[href^="download.php?id="])
+
+  fields:
+    category:
+      selector: a[href^="?cat="]
+      attribute: href
+      filters:
+        - name: querystring
+          args: cat
+    title_default:
+      selector: a[href^="details.php?id="]
+    title:
+      selector: a[title][href^="details.php?id="]
+      attribute: title
+      optional: true
+      default: "{{ .Result.title_default }}"
+    details:
+      selector: a[href^="details.php?id="]
+      attribute: href
+    download:
+      selector: a[href^="download.php?id="]
+      attribute: href
+    poster:
+      selector: img[data-src]
+      attribute: data-src
+    imdbid:
+      # site currently only has a badge and rating, the id is not present. just in case a future update.
+      selector: a[href*="imdb.com/title/tt"]
+      attribute: href
+    doubanid:
+      # site currently only has a badge and rating, the id is not present. just in case a future update.
+      selector: a[href*="movie.douban.com/subject/"]
+      attribute: href
+    date_elapsed:
+      # TODO: The selector from the example I copied includes
+      # `.rowfollow` which is a class for most of the column cells and
+      # AFAICT is only for presentation. As such I think it makes the
+      # selector more fragile and I've removed it from this
+      # definition. Should it be cleaned up in other definitions?
+      #
+      # time type: time elapsed (default)
+      selector: td:nth-child(4) > span[title]
+      attribute: title
+      optional: true
+      filters:
+        - name: append
+          # TODO: This is another demonstration of why a more verbose comment is
+          # valuable here. The `CST` abbreviation is used for both `-04:00` through
+          # `-06:00` in the Americas *and* `+08:00` in Asia. The more verbose comment
+          # removes ambiguity and saves contributor time.
+          args: " +08:00" # Asia/Taipei, CST
+        - name: dateparse
+          args: "yyyy-MM-dd HH:mm:ss zzz"
+    # TODO: I couldn't find an example of this when I sorted the full
+    # listing by date in both directions in the web UI of the exampale
+    # I copied. Where can I see the need for this in the example I
+    # copied so I can identify when it's needed for future
+    # definitions? Is it necessary for this definition?
+    date_added:
+      # time added
+      selector: td:nth-child(4):not(:has(span))
+      optional: true
+      filters:
+        - name: append
+          args: " +08:00" # CST
+        - name: dateparse
+          args: "yyyy-MM-ddHH:mm:ss zzz"
+    date:
+      text: "{{ if or .Result.date_elapsed .Result.date_added }}{{ or .Result.date_elapsed .Result.date_added }}{{ else }}now{{ end }}"
+    size:
+      selector: td:nth-child(5)
+    seeders:
+      selector: td:nth-child(6)
+    leechers:
+      selector: td:nth-child(7)
+    grabs:
+      selector: td:nth-child(8)
+    # TODO: There are no results for "2X", "2X 50%", and "30%" so I
+    # can't confirm their selectors but there are other examples in
+    # the example I copied of adding presumprive support for `imdbid`
+    # and `doubanid`, so I included them here.
+    #
+    # TODO: While testing, I could only find instances of "2X Free"
+    # and "ordinary" when I clicked through each of the top-level
+    # categories above, so those two are the only I could confirm by
+    # testing in the Prowlarr search UI. Is there a way I could have
+    # confirmed the rest?
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: ilike2burnthing
body: ```suggestion
```

The template seems to be fairly consistent, so if you can see a couple being the same, it's safe enough to assume the rest will be too.
created_at: 2025-03-07T07:09:18Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
+    # TODO: Searching for `S01` and `S01E01` for an example, that
+    # yields other results when searched without, yields no difference
+    # in results. Am I missing something?
+    #
+    # TODO: The example I copied, `./freefarm.yml`, includes support
+    # for `DoubanID` but I don't find any evidence of that support in
+    # *that* example's web UI. For *this* indexer I tested the
+    # `DoubanID` like I tested an IMDB ID above. Is the example
+    # definiton wrong or out of date? If not, where can you see the
+    # support for `DoubanID` in *that* example and does this indexer
+    # also support it?
+    tv-search: [q]
+    movie-search: [q]
+    music-search: [q]
+    book-search: [q]
+
+settings:
+  - name: username
+    type: text
+    label: Username
+  - name: password
+    type: password
+    label: Password
+  - name: 2facode
+    type: text
+    label: 2FA code
+  - name: info_2fa
+    type: info
+    label: "About 2FA code"
+    default: "Only fill in the <b>2FA code</b> box if you have enabled <b>2FA</b> on the HDBao Web Site. Otherwise just leave it empty."
+  # TODO: While testing this field, I noticed the results only includ
+  # *just* "Free" items and *not* "2X Free" items. This is also the
+  # case for the example I copied. I understand its better for
+  # Jackett/Prowlarr to use the filtering supported server-side. Does
+  # NexusPHP support multiple `spstate` values? If no, is there a good
+  # place for feature requests?
+  - name: freeleech
+    type: checkbox
+    label: Search freeleech only
+    default: false
+  - name: sort
+    type: select
+    label: Sort requested from site
+    default: 4
+    options:
+      4: created
+      7: seeders
+      5: size
+      1: title
+  - name: type
+    type: select
+    label: Order requested from site
+    default: desc
+    options:
+      desc: desc
+      asc: asc
+  # TODO: I didn't get any FS challenges for this indexer that I can
+  # recall, and definitely not while developing this definition. I
+  # confirmed FS usage by looking at the response headers and
+  # cookie. Is that a sufficient way to identify FS usage?
+  - name: info_flaresolverr
+    type: info_flaresolverr
+  - name: info_tpp
+    type: info
+    label: Results Per Page
+    default: For best results, change the <b>Torrents per page:</b> setting to <b>100</b> on your account profile.
+  - name: info_activity
+    type: info
+    label: Account Inactivity
+    default: "Cherish your user account. Inactive accounts would be deleted based on the following rules:<ol><li>Veteran User or above would never be deleted.</li><li>Elite User or above would never be deleted if parked (at User CP).</li><li>Parked accounts would be deleted if users have not logged in for more than 400 days in a row.</li><li>Unparked accounts would be deleted if users have not logged in for more than 150 days in a row.</li><li>Accounts with both uploaded and downloaded amount being 0 would be deleted if users have not logged in for more than 100 days in a row.</li></ol>"
+
+login:
+  path: login.php
+  method: form
+  form: form[action="takelogin.php"]
+  inputs:
+    secret: ""
+    username: "{{ .Config.username }}"
+    password: "{{ .Config.password }}"
+    two_step_code: "{{ .Config.2facode }}"
+    logout: ""
+    securelogin: ""
+    ssl: yes
+    trackerssl: yes
+  error:
+    - selector: td.embedded:contains("登录失败！")
+  test:
+    path: index.php
+    selector: a[href="logout.php"]
+
+search:
+  paths:
+    - path: torrents.php
+  inputs:
+    $raw: "{{ range .Categories }}cat{{.}}=1&{{end}}"
+    search: "{{ if .Query.IMDBID }}{{ .Query.IMDBID }}{{ else }}{{ .Keywords }}{{ end }}"
+    # 0: include dead, 1: alive, 2: dead
+    incldead: 0
+    spstate: "{{ if .Config.freeleech }}2{{ else }}0{{ end }}"
+    # 0: title, 1: description, 3: uploader, 4: IMDB URL
+    search_area: "0"
+    # 0: AND, 2: exact
+    search_mode: 0
+    sort: "{{ .Config.sort }}"
+    type: "{{ .Config.type }}"
+    # TODO: The example I copied, `./freefarm.yml`, includes a
+    # `notnewword` key but I don't see that key from submitting the
+    # search form in the web UI of either that example or this
+    # indexer. What am I missing?
+    #
+    # TODO: On that note, while inspecting the payloads of both search
+    # forms I noted a bunch of parameters that the web UI sends that
+    # aren't included in that example. How does that reconcile with
+    # "we don't want an obvious 'Jackett footprint'" from my last PR
+    # feedback especially given how much of Jackett/Prowlarr's traffic
+    # is submissions of this form?
+
+  rows:
+    selector: table.torrents > tbody > tr:has(a[href^="download.php?id="])
+
+  fields:
+    category:
+      selector: a[href^="?cat="]
+      attribute: href
+      filters:
+        - name: querystring
+          args: cat
+    title_default:
+      selector: a[href^="details.php?id="]
+    title:
+      selector: a[title][href^="details.php?id="]
+      attribute: title
+      optional: true
+      default: "{{ .Result.title_default }}"
+    details:
+      selector: a[href^="details.php?id="]
+      attribute: href
+    download:
+      selector: a[href^="download.php?id="]
+      attribute: href
+    poster:
+      selector: img[data-src]
+      attribute: data-src
+    imdbid:
+      # site currently only has a badge and rating, the id is not present. just in case a future update.
+      selector: a[href*="imdb.com/title/tt"]
+      attribute: href
+    doubanid:
+      # site currently only has a badge and rating, the id is not present. just in case a future update.
+      selector: a[href*="movie.douban.com/subject/"]
+      attribute: href
+    date_elapsed:
+      # TODO: The selector from the example I copied includes
+      # `.rowfollow` which is a class for most of the column cells and
+      # AFAICT is only for presentation. As such I think it makes the
+      # selector more fragile and I've removed it from this
+      # definition. Should it be cleaned up in other definitions?
+      #
+      # time type: time elapsed (default)
+      selector: td:nth-child(4) > span[title]
+      attribute: title
+      optional: true
+      filters:
+        - name: append
+          # TODO: This is another demonstration of why a more verbose comment is
+          # valuable here. The `CST` abbreviation is used for both `-04:00` through
+          # `-06:00` in the Americas *and* `+08:00` in Asia. The more verbose comment
+          # removes ambiguity and saves contributor time.
+          args: " +08:00" # Asia/Taipei, CST
+        - name: dateparse
+          args: "yyyy-MM-dd HH:mm:ss zzz"
+    # TODO: I couldn't find an example of this when I sorted the full
+    # listing by date in both directions in the web UI of the exampale
+    # I copied. Where can I see the need for this in the example I
+    # copied so I can identify when it's needed for future
+    # definitions? Is it necessary for this definition?
+    date_added:
+      # time added
+      selector: td:nth-child(4):not(:has(span))
+      optional: true
+      filters:
+        - name: append
+          args: " +08:00" # CST
+        - name: dateparse
+          args: "yyyy-MM-ddHH:mm:ss zzz"
+    date:
+      text: "{{ if or .Result.date_elapsed .Result.date_added }}{{ or .Result.date_elapsed .Result.date_added }}{{ else }}now{{ end }}"
+    size:
+      selector: td:nth-child(5)
+    seeders:
+      selector: td:nth-child(6)
+    leechers:
+      selector: td:nth-child(7)
+    grabs:
+      selector: td:nth-child(8)
+    # TODO: There are no results for "2X", "2X 50%", and "30%" so I
+    # can't confirm their selectors but there are other examples in
+    # the example I copied of adding presumprive support for `imdbid`
+    # and `doubanid`, so I included them here.
+    #
+    # TODO: While testing, I could only find instances of "2X Free"
+    # and "ordinary" when I clicked through each of the top-level
+    # categories above, so those two are the only I could confirm by
+    # testing in the Prowlarr search UI. Is there a way I could have
+    # confirmed the rest?
+    downloadvolumefactor:
+      case:
+        img.pro_free: 0
+        img.pro_free2up: 0
+        img.pro_50pctdown: 0.5
+        img.pro_50pctdown2up: 0.5
+        img.pro_30pctdown: 0.3
+        "*": 1
+    uploadvolumefactor:
+      case:
+        img.pro_50pctdown2up: 2
+        img.pro_free2up: 2
+        img.pro_2up: 2
+        "*": 1
+    minimumseedtime:
+      # special 7 days (as seconds = 7 x 24 x 60 x 60)
+      # normal 3 days (as seconds = 3 x 24 x 60 x 60)
+      case:
+        # TODO: I found an instance of this in the example I copied by
+        # sorting by reverse date but that didn't yield an example for
+        # this indexer. See above regarding presumptive support. Am I
+        # correct to leave this in?
+        img[title="H&R"]: 604800
+        "*": 259200
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: ilike2burnthing
body: ```suggestion
```

Nothing in the rules about H&R, and no torrents marked as it.
created_at: 2025-03-07T07:11:18Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
+    # TODO: Searching for `S01` and `S01E01` for an example, that
+    # yields other results when searched without, yields no difference
+    # in results. Am I missing something?
+    #
+    # TODO: The example I copied, `./freefarm.yml`, includes support
+    # for `DoubanID` but I don't find any evidence of that support in
+    # *that* example's web UI. For *this* indexer I tested the
+    # `DoubanID` like I tested an IMDB ID above. Is the example
+    # definiton wrong or out of date? If not, where can you see the
+    # support for `DoubanID` in *that* example and does this indexer
+    # also support it?
+    tv-search: [q]
+    movie-search: [q]
+    music-search: [q]
+    book-search: [q]
+
+settings:
+  - name: username
+    type: text
+    label: Username
+  - name: password
+    type: password
+    label: Password
+  - name: 2facode
+    type: text
+    label: 2FA code
+  - name: info_2fa
+    type: info
+    label: "About 2FA code"
+    default: "Only fill in the <b>2FA code</b> box if you have enabled <b>2FA</b> on the HDBao Web Site. Otherwise just leave it empty."
+  # TODO: While testing this field, I noticed the results only includ
+  # *just* "Free" items and *not* "2X Free" items. This is also the
+  # case for the example I copied. I understand its better for
+  # Jackett/Prowlarr to use the filtering supported server-side. Does
+  # NexusPHP support multiple `spstate` values? If no, is there a good
+  # place for feature requests?
+  - name: freeleech
+    type: checkbox
+    label: Search freeleech only
+    default: false
+  - name: sort
+    type: select
+    label: Sort requested from site
+    default: 4
+    options:
+      4: created
+      7: seeders
+      5: size
+      1: title
+  - name: type
+    type: select
+    label: Order requested from site
+    default: desc
+    options:
+      desc: desc
+      asc: asc
+  # TODO: I didn't get any FS challenges for this indexer that I can
+  # recall, and definitely not while developing this definition. I
+  # confirmed FS usage by looking at the response headers and
+  # cookie. Is that a sufficient way to identify FS usage?
+  - name: info_flaresolverr
+    type: info_flaresolverr
+  - name: info_tpp
+    type: info
+    label: Results Per Page
+    default: For best results, change the <b>Torrents per page:</b> setting to <b>100</b> on your account profile.
+  - name: info_activity
+    type: info
+    label: Account Inactivity
+    default: "Cherish your user account. Inactive accounts would be deleted based on the following rules:<ol><li>Veteran User or above would never be deleted.</li><li>Elite User or above would never be deleted if parked (at User CP).</li><li>Parked accounts would be deleted if users have not logged in for more than 400 days in a row.</li><li>Unparked accounts would be deleted if users have not logged in for more than 150 days in a row.</li><li>Accounts with both uploaded and downloaded amount being 0 would be deleted if users have not logged in for more than 100 days in a row.</li></ol>"
+
+login:
+  path: login.php
+  method: form
+  form: form[action="takelogin.php"]
+  inputs:
+    secret: ""
+    username: "{{ .Config.username }}"
+    password: "{{ .Config.password }}"
+    two_step_code: "{{ .Config.2facode }}"
+    logout: ""
+    securelogin: ""
+    ssl: yes
+    trackerssl: yes
+  error:
+    - selector: td.embedded:contains("登录失败！")
+  test:
+    path: index.php
+    selector: a[href="logout.php"]
+
+search:
+  paths:
+    - path: torrents.php
+  inputs:
+    $raw: "{{ range .Categories }}cat{{.}}=1&{{end}}"
+    search: "{{ if .Query.IMDBID }}{{ .Query.IMDBID }}{{ else }}{{ .Keywords }}{{ end }}"
+    # 0: include dead, 1: alive, 2: dead
+    incldead: 0
+    spstate: "{{ if .Config.freeleech }}2{{ else }}0{{ end }}"
+    # 0: title, 1: description, 3: uploader, 4: IMDB URL
+    search_area: "0"
+    # 0: AND, 2: exact
+    search_mode: 0
+    sort: "{{ .Config.sort }}"
+    type: "{{ .Config.type }}"
+    # TODO: The example I copied, `./freefarm.yml`, includes a
+    # `notnewword` key but I don't see that key from submitting the
+    # search form in the web UI of either that example or this
+    # indexer. What am I missing?
+    #
+    # TODO: On that note, while inspecting the payloads of both search
+    # forms I noted a bunch of parameters that the web UI sends that
+    # aren't included in that example. How does that reconcile with
+    # "we don't want an obvious 'Jackett footprint'" from my last PR
+    # feedback especially given how much of Jackett/Prowlarr's traffic
+    # is submissions of this form?
+
+  rows:
+    selector: table.torrents > tbody > tr:has(a[href^="download.php?id="])
+
+  fields:
+    category:
+      selector: a[href^="?cat="]
+      attribute: href
+      filters:
+        - name: querystring
+          args: cat
+    title_default:
+      selector: a[href^="details.php?id="]
+    title:
+      selector: a[title][href^="details.php?id="]
+      attribute: title
+      optional: true
+      default: "{{ .Result.title_default }}"
+    details:
+      selector: a[href^="details.php?id="]
+      attribute: href
+    download:
+      selector: a[href^="download.php?id="]
+      attribute: href
+    poster:
+      selector: img[data-src]
+      attribute: data-src
+    imdbid:
+      # site currently only has a badge and rating, the id is not present. just in case a future update.
+      selector: a[href*="imdb.com/title/tt"]
+      attribute: href
+    doubanid:
+      # site currently only has a badge and rating, the id is not present. just in case a future update.
+      selector: a[href*="movie.douban.com/subject/"]
+      attribute: href
+    date_elapsed:
+      # TODO: The selector from the example I copied includes
+      # `.rowfollow` which is a class for most of the column cells and
+      # AFAICT is only for presentation. As such I think it makes the
+      # selector more fragile and I've removed it from this
+      # definition. Should it be cleaned up in other definitions?
+      #
+      # time type: time elapsed (default)
+      selector: td:nth-child(4) > span[title]
+      attribute: title
+      optional: true
+      filters:
+        - name: append
+          # TODO: This is another demonstration of why a more verbose comment is
+          # valuable here. The `CST` abbreviation is used for both `-04:00` through
+          # `-06:00` in the Americas *and* `+08:00` in Asia. The more verbose comment
+          # removes ambiguity and saves contributor time.
+          args: " +08:00" # Asia/Taipei, CST
+        - name: dateparse
+          args: "yyyy-MM-dd HH:mm:ss zzz"
+    # TODO: I couldn't find an example of this when I sorted the full
+    # listing by date in both directions in the web UI of the exampale
+    # I copied. Where can I see the need for this in the example I
+    # copied so I can identify when it's needed for future
+    # definitions? Is it necessary for this definition?
+    date_added:
+      # time added
+      selector: td:nth-child(4):not(:has(span))
+      optional: true
+      filters:
+        - name: append
+          args: " +08:00" # CST
+        - name: dateparse
+          args: "yyyy-MM-ddHH:mm:ss zzz"
+    date:
+      text: "{{ if or .Result.date_elapsed .Result.date_added }}{{ or .Result.date_elapsed .Result.date_added }}{{ else }}now{{ end }}"
+    size:
+      selector: td:nth-child(5)
+    seeders:
+      selector: td:nth-child(6)
+    leechers:
+      selector: td:nth-child(7)
+    grabs:
+      selector: td:nth-child(8)
+    # TODO: There are no results for "2X", "2X 50%", and "30%" so I
+    # can't confirm their selectors but there are other examples in
+    # the example I copied of adding presumprive support for `imdbid`
+    # and `doubanid`, so I included them here.
+    #
+    # TODO: While testing, I could only find instances of "2X Free"
+    # and "ordinary" when I clicked through each of the top-level
+    # categories above, so those two are the only I could confirm by
+    # testing in the Prowlarr search UI. Is there a way I could have
+    # confirmed the rest?
+    downloadvolumefactor:
+      case:
+        img.pro_free: 0
+        img.pro_free2up: 0
+        img.pro_50pctdown: 0.5
+        img.pro_50pctdown2up: 0.5
+        img.pro_30pctdown: 0.3
+        "*": 1
+    uploadvolumefactor:
+      case:
+        img.pro_50pctdown2up: 2
+        img.pro_free2up: 2
+        img.pro_2up: 2
+        "*": 1
+    minimumseedtime:
+      # special 7 days (as seconds = 7 x 24 x 60 x 60)
+      # normal 3 days (as seconds = 3 x 24 x 60 x 60)
+      case:
+        # TODO: I found an instance of this in the example I copied by
+        # sorting by reverse date but that didn't yield an example for
+        # this indexer. See above regarding presumptive support. Am I
+        # correct to leave this in?
+        img[title="H&R"]: 604800
+        "*": 259200
+    description_verified:
+      case:
+        # TODO: I don't see these icons in this indexer's web UI but I
+        # do in the example I copied. Another case of presumptive
+        # support, correct?
+        span[title="通过"], span[title="通過"], span[title="Allowed"]: "Verified:"
+        span[title="未审"], span[title="未審"], span[title="Not reviewed"]: "Unverified:"
+        # TODO: Another case I can't find an instance of in the example I copide. How do I find an insance?
+        span[title="拒绝"], span[title="拒絕"], span[title="Denied"]: "Banned:"
+    description:
+      selector: td:nth-child(2)
+      remove: a, b, font, img, span
+      filters:
+        - name: prepend
+          args: "{{ .Result.description_verified }} "
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: ilike2burnthing
body: ```suggestion
    description:
      selector: td:nth-child(2)
      remove: a, b, font, img, span
```

It's the ticks/crosses/warning/question mark at the end of the titles (on some trackers it's at the start or has its own column). They don't exist here.
created_at: 2025-03-07T07:13:47Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
+    # TODO: Searching for `S01` and `S01E01` for an example, that
+    # yields other results when searched without, yields no difference
+    # in results. Am I missing something?
+    #
+    # TODO: The example I copied, `./freefarm.yml`, includes support
+    # for `DoubanID` but I don't find any evidence of that support in
+    # *that* example's web UI. For *this* indexer I tested the
+    # `DoubanID` like I tested an IMDB ID above. Is the example
+    # definiton wrong or out of date? If not, where can you see the
+    # support for `DoubanID` in *that* example and does this indexer
+    # also support it?
+    tv-search: [q]
+    movie-search: [q]
+    music-search: [q]
+    book-search: [q]
+
+settings:
+  - name: username
+    type: text
+    label: Username
+  - name: password
+    type: password
+    label: Password
+  - name: 2facode
+    type: text
+    label: 2FA code
+  - name: info_2fa
+    type: info
+    label: "About 2FA code"
+    default: "Only fill in the <b>2FA code</b> box if you have enabled <b>2FA</b> on the HDBao Web Site. Otherwise just leave it empty."
+  # TODO: While testing this field, I noticed the results only includ
+  # *just* "Free" items and *not* "2X Free" items. This is also the
+  # case for the example I copied. I understand its better for
+  # Jackett/Prowlarr to use the filtering supported server-side. Does
+  # NexusPHP support multiple `spstate` values? If no, is there a good
+  # place for feature requests?
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: mynameisbogdan
body: Last time I checked, spstate doesn't support multiple values. 
created_at: 2025-03-07T07:51:19Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
+    # TODO: Searching for `S01` and `S01E01` for an example, that
+    # yields other results when searched without, yields no difference
+    # in results. Am I missing something?
+    #
+    # TODO: The example I copied, `./freefarm.yml`, includes support
+    # for `DoubanID` but I don't find any evidence of that support in
+    # *that* example's web UI. For *this* indexer I tested the
+    # `DoubanID` like I tested an IMDB ID above. Is the example
+    # definiton wrong or out of date? If not, where can you see the
+    # support for `DoubanID` in *that* example and does this indexer
+    # also support it?
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: rpatterson
body: Thanks for example in the definition. I was unclear, I meant where in the example's *web UI* can I find support for DoubanID and how would I know to use the description? IOW, if I were writing that definition from scratch, how would I know to do that?
created_at: 2025-03-07T16:02:32Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: rpatterson
body: Thanks. I'm still unclear on when to use the `*/Other` categories. For another tracker, because the categories have a 2-level hierarchy in the web UI,  guessed I should use a sub-category for all the items at that 2nd level. I also guessed that because there's already a "TV" category with no qualifiers in the web UI, that all web UI categories with qualifiers should have sub-categories. In both cases I guessed I should use `*/Other` when the qualifier didn't cleanly match another Cardigann sub-category.

When *is* it appropriate to use the `*/Other` sub-categories?
created_at: 2025-03-07T16:08:34Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: rpatterson
body: I guessed "Audio" because Google translated the part after the slash as `Misc/Music`, not because of the results. LKM if you still want me to make this change.
created_at: 2025-03-07T16:14:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
+    # TODO: Searching for `S01` and `S01E01` for an example, that
+    # yields other results when searched without, yields no difference
+    # in results. Am I missing something?
+    #
+    # TODO: The example I copied, `./freefarm.yml`, includes support
+    # for `DoubanID` but I don't find any evidence of that support in
+    # *that* example's web UI. For *this* indexer I tested the
+    # `DoubanID` like I tested an IMDB ID above. Is the example
+    # definiton wrong or out of date? If not, where can you see the
+    # support for `DoubanID` in *that* example and does this indexer
+    # also support it?
+    tv-search: [q]
+    movie-search: [q]
+    music-search: [q]
+    book-search: [q]
+
+settings:
+  - name: username
+    type: text
+    label: Username
+  - name: password
+    type: password
+    label: Password
+  - name: 2facode
+    type: text
+    label: 2FA code
+  - name: info_2fa
+    type: info
+    label: "About 2FA code"
+    default: "Only fill in the <b>2FA code</b> box if you have enabled <b>2FA</b> on the HDBao Web Site. Otherwise just leave it empty."
+  # TODO: While testing this field, I noticed the results only includ
+  # *just* "Free" items and *not* "2X Free" items. This is also the
+  # case for the example I copied. I understand its better for
+  # Jackett/Prowlarr to use the filtering supported server-side. Does
+  # NexusPHP support multiple `spstate` values? If no, is there a good
+  # place for feature requests?
+  - name: freeleech
+    type: checkbox
+    label: Search freeleech only
+    default: false
+  - name: sort
+    type: select
+    label: Sort requested from site
+    default: 4
+    options:
+      4: created
+      7: seeders
+      5: size
+      1: title
+  - name: type
+    type: select
+    label: Order requested from site
+    default: desc
+    options:
+      desc: desc
+      asc: asc
+  # TODO: I didn't get any FS challenges for this indexer that I can
+  # recall, and definitely not while developing this definition. I
+  # confirmed FS usage by looking at the response headers and
+  # cookie. Is that a sufficient way to identify FS usage?
+  - name: info_flaresolverr
+    type: info_flaresolverr
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: rpatterson
body: How did you confirm it was only triggered there? IOW, is there some way other than checking the response headers and the cookie to explicitly confirm what is protected by CF? Especially from URL path to path? Or is it all just happening to get a challenge while using the web UI?
created_at: 2025-03-07T16:19:43Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
+    # TODO: Searching for `S01` and `S01E01` for an example, that
+    # yields other results when searched without, yields no difference
+    # in results. Am I missing something?
+    #
+    # TODO: The example I copied, `./freefarm.yml`, includes support
+    # for `DoubanID` but I don't find any evidence of that support in
+    # *that* example's web UI. For *this* indexer I tested the
+    # `DoubanID` like I tested an IMDB ID above. Is the example
+    # definiton wrong or out of date? If not, where can you see the
+    # support for `DoubanID` in *that* example and does this indexer
+    # also support it?
+    tv-search: [q]
+    movie-search: [q]
+    music-search: [q]
+    book-search: [q]
+
+settings:
+  - name: username
+    type: text
+    label: Username
+  - name: password
+    type: password
+    label: Password
+  - name: 2facode
+    type: text
+    label: 2FA code
+  - name: info_2fa
+    type: info
+    label: "About 2FA code"
+    default: "Only fill in the <b>2FA code</b> box if you have enabled <b>2FA</b> on the HDBao Web Site. Otherwise just leave it empty."
+  # TODO: While testing this field, I noticed the results only includ
+  # *just* "Free" items and *not* "2X Free" items. This is also the
+  # case for the example I copied. I understand its better for
+  # Jackett/Prowlarr to use the filtering supported server-side. Does
+  # NexusPHP support multiple `spstate` values? If no, is there a good
+  # place for feature requests?
+  - name: freeleech
+    type: checkbox
+    label: Search freeleech only
+    default: false
+  - name: sort
+    type: select
+    label: Sort requested from site
+    default: 4
+    options:
+      4: created
+      7: seeders
+      5: size
+      1: title
+  - name: type
+    type: select
+    label: Order requested from site
+    default: desc
+    options:
+      desc: desc
+      asc: asc
+  # TODO: I didn't get any FS challenges for this indexer that I can
+  # recall, and definitely not while developing this definition. I
+  # confirmed FS usage by looking at the response headers and
+  # cookie. Is that a sufficient way to identify FS usage?
+  - name: info_flaresolverr
+    type: info_flaresolverr
+  - name: info_tpp
+    type: info
+    label: Results Per Page
+    default: For best results, change the <b>Torrents per page:</b> setting to <b>100</b> on your account profile.
+  - name: info_activity
+    type: info
+    label: Account Inactivity
+    default: "Cherish your user account. Inactive accounts would be deleted based on the following rules:<ol><li>Veteran User or above would never be deleted.</li><li>Elite User or above would never be deleted if parked (at User CP).</li><li>Parked accounts would be deleted if users have not logged in for more than 400 days in a row.</li><li>Unparked accounts would be deleted if users have not logged in for more than 150 days in a row.</li><li>Accounts with both uploaded and downloaded amount being 0 would be deleted if users have not logged in for more than 100 days in a row.</li></ol>"
+
+login:
+  path: login.php
+  method: form
+  form: form[action="takelogin.php"]
+  inputs:
+    secret: ""
+    username: "{{ .Config.username }}"
+    password: "{{ .Config.password }}"
+    two_step_code: "{{ .Config.2facode }}"
+    logout: ""
+    securelogin: ""
+    ssl: yes
+    trackerssl: yes
+  error:
+    - selector: td.embedded:contains("登录失败！")
+  test:
+    path: index.php
+    selector: a[href="logout.php"]
+
+search:
+  paths:
+    - path: torrents.php
+  inputs:
+    $raw: "{{ range .Categories }}cat{{.}}=1&{{end}}"
+    search: "{{ if .Query.IMDBID }}{{ .Query.IMDBID }}{{ else }}{{ .Keywords }}{{ end }}"
+    # 0: include dead, 1: alive, 2: dead
+    incldead: 0
+    spstate: "{{ if .Config.freeleech }}2{{ else }}0{{ end }}"
+    # 0: title, 1: description, 3: uploader, 4: IMDB URL
+    search_area: "0"
+    # 0: AND, 2: exact
+    search_mode: 0
+    sort: "{{ .Config.sort }}"
+    type: "{{ .Config.type }}"
+    # TODO: The example I copied, `./freefarm.yml`, includes a
+    # `notnewword` key but I don't see that key from submitting the
+    # search form in the web UI of either that example or this
+    # indexer. What am I missing?
+    #
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: rpatterson
body: Thanks for the context!
created_at: 2025-03-07T16:47:30Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
+    # TODO: Searching for `S01` and `S01E01` for an example, that
+    # yields other results when searched without, yields no difference
+    # in results. Am I missing something?
+    #
+    # TODO: The example I copied, `./freefarm.yml`, includes support
+    # for `DoubanID` but I don't find any evidence of that support in
+    # *that* example's web UI. For *this* indexer I tested the
+    # `DoubanID` like I tested an IMDB ID above. Is the example
+    # definiton wrong or out of date? If not, where can you see the
+    # support for `DoubanID` in *that* example and does this indexer
+    # also support it?
+    tv-search: [q]
+    movie-search: [q]
+    music-search: [q]
+    book-search: [q]
+
+settings:
+  - name: username
+    type: text
+    label: Username
+  - name: password
+    type: password
+    label: Password
+  - name: 2facode
+    type: text
+    label: 2FA code
+  - name: info_2fa
+    type: info
+    label: "About 2FA code"
+    default: "Only fill in the <b>2FA code</b> box if you have enabled <b>2FA</b> on the HDBao Web Site. Otherwise just leave it empty."
+  # TODO: While testing this field, I noticed the results only includ
+  # *just* "Free" items and *not* "2X Free" items. This is also the
+  # case for the example I copied. I understand its better for
+  # Jackett/Prowlarr to use the filtering supported server-side. Does
+  # NexusPHP support multiple `spstate` values? If no, is there a good
+  # place for feature requests?
+  - name: freeleech
+    type: checkbox
+    label: Search freeleech only
+    default: false
+  - name: sort
+    type: select
+    label: Sort requested from site
+    default: 4
+    options:
+      4: created
+      7: seeders
+      5: size
+      1: title
+  - name: type
+    type: select
+    label: Order requested from site
+    default: desc
+    options:
+      desc: desc
+      asc: asc
+  # TODO: I didn't get any FS challenges for this indexer that I can
+  # recall, and definitely not while developing this definition. I
+  # confirmed FS usage by looking at the response headers and
+  # cookie. Is that a sufficient way to identify FS usage?
+  - name: info_flaresolverr
+    type: info_flaresolverr
+  - name: info_tpp
+    type: info
+    label: Results Per Page
+    default: For best results, change the <b>Torrents per page:</b> setting to <b>100</b> on your account profile.
+  - name: info_activity
+    type: info
+    label: Account Inactivity
+    default: "Cherish your user account. Inactive accounts would be deleted based on the following rules:<ol><li>Veteran User or above would never be deleted.</li><li>Elite User or above would never be deleted if parked (at User CP).</li><li>Parked accounts would be deleted if users have not logged in for more than 400 days in a row.</li><li>Unparked accounts would be deleted if users have not logged in for more than 150 days in a row.</li><li>Accounts with both uploaded and downloaded amount being 0 would be deleted if users have not logged in for more than 100 days in a row.</li></ol>"
+
+login:
+  path: login.php
+  method: form
+  form: form[action="takelogin.php"]
+  inputs:
+    secret: ""
+    username: "{{ .Config.username }}"
+    password: "{{ .Config.password }}"
+    two_step_code: "{{ .Config.2facode }}"
+    logout: ""
+    securelogin: ""
+    ssl: yes
+    trackerssl: yes
+  error:
+    - selector: td.embedded:contains("登录失败！")
+  test:
+    path: index.php
+    selector: a[href="logout.php"]
+
+search:
+  paths:
+    - path: torrents.php
+  inputs:
+    $raw: "{{ range .Categories }}cat{{.}}=1&{{end}}"
+    search: "{{ if .Query.IMDBID }}{{ .Query.IMDBID }}{{ else }}{{ .Keywords }}{{ end }}"
+    # 0: include dead, 1: alive, 2: dead
+    incldead: 0
+    spstate: "{{ if .Config.freeleech }}2{{ else }}0{{ end }}"
+    # 0: title, 1: description, 3: uploader, 4: IMDB URL
+    search_area: "0"
+    # 0: AND, 2: exact
+    search_mode: 0
+    sort: "{{ .Config.sort }}"
+    type: "{{ .Config.type }}"
+    # TODO: The example I copied, `./freefarm.yml`, includes a
+    # `notnewword` key but I don't see that key from submitting the
+    # search form in the web UI of either that example or this
+    # indexer. What am I missing?
+    #
+    # TODO: On that note, while inspecting the payloads of both search
+    # forms I noted a bunch of parameters that the web UI sends that
+    # aren't included in that example. How does that reconcile with
+    # "we don't want an obvious 'Jackett footprint'" from my last PR
+    # feedback especially given how much of Jackett/Prowlarr's traffic
+    # is submissions of this form?
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: rpatterson
body: Totally makes sense, but given that search requests are the bulk of Jackett/Prowlarr/etc. traffid, this makes [the "Jackett footprint" argument](https://github.com/Jackett/Jackett/pull/15887#discussion_r1980591339) moot.
created_at: 2025-03-07T16:57:14Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
+    # TODO: Searching for `S01` and `S01E01` for an example, that
+    # yields other results when searched without, yields no difference
+    # in results. Am I missing something?
+    #
+    # TODO: The example I copied, `./freefarm.yml`, includes support
+    # for `DoubanID` but I don't find any evidence of that support in
+    # *that* example's web UI. For *this* indexer I tested the
+    # `DoubanID` like I tested an IMDB ID above. Is the example
+    # definiton wrong or out of date? If not, where can you see the
+    # support for `DoubanID` in *that* example and does this indexer
+    # also support it?
+    tv-search: [q]
+    movie-search: [q]
+    music-search: [q]
+    book-search: [q]
+
+settings:
+  - name: username
+    type: text
+    label: Username
+  - name: password
+    type: password
+    label: Password
+  - name: 2facode
+    type: text
+    label: 2FA code
+  - name: info_2fa
+    type: info
+    label: "About 2FA code"
+    default: "Only fill in the <b>2FA code</b> box if you have enabled <b>2FA</b> on the HDBao Web Site. Otherwise just leave it empty."
+  # TODO: While testing this field, I noticed the results only includ
+  # *just* "Free" items and *not* "2X Free" items. This is also the
+  # case for the example I copied. I understand its better for
+  # Jackett/Prowlarr to use the filtering supported server-side. Does
+  # NexusPHP support multiple `spstate` values? If no, is there a good
+  # place for feature requests?
+  - name: freeleech
+    type: checkbox
+    label: Search freeleech only
+    default: false
+  - name: sort
+    type: select
+    label: Sort requested from site
+    default: 4
+    options:
+      4: created
+      7: seeders
+      5: size
+      1: title
+  - name: type
+    type: select
+    label: Order requested from site
+    default: desc
+    options:
+      desc: desc
+      asc: asc
+  # TODO: I didn't get any FS challenges for this indexer that I can
+  # recall, and definitely not while developing this definition. I
+  # confirmed FS usage by looking at the response headers and
+  # cookie. Is that a sufficient way to identify FS usage?
+  - name: info_flaresolverr
+    type: info_flaresolverr
+  - name: info_tpp
+    type: info
+    label: Results Per Page
+    default: For best results, change the <b>Torrents per page:</b> setting to <b>100</b> on your account profile.
+  - name: info_activity
+    type: info
+    label: Account Inactivity
+    default: "Cherish your user account. Inactive accounts would be deleted based on the following rules:<ol><li>Veteran User or above would never be deleted.</li><li>Elite User or above would never be deleted if parked (at User CP).</li><li>Parked accounts would be deleted if users have not logged in for more than 400 days in a row.</li><li>Unparked accounts would be deleted if users have not logged in for more than 150 days in a row.</li><li>Accounts with both uploaded and downloaded amount being 0 would be deleted if users have not logged in for more than 100 days in a row.</li></ol>"
+
+login:
+  path: login.php
+  method: form
+  form: form[action="takelogin.php"]
+  inputs:
+    secret: ""
+    username: "{{ .Config.username }}"
+    password: "{{ .Config.password }}"
+    two_step_code: "{{ .Config.2facode }}"
+    logout: ""
+    securelogin: ""
+    ssl: yes
+    trackerssl: yes
+  error:
+    - selector: td.embedded:contains("登录失败！")
+  test:
+    path: index.php
+    selector: a[href="logout.php"]
+
+search:
+  paths:
+    - path: torrents.php
+  inputs:
+    $raw: "{{ range .Categories }}cat{{.}}=1&{{end}}"
+    search: "{{ if .Query.IMDBID }}{{ .Query.IMDBID }}{{ else }}{{ .Keywords }}{{ end }}"
+    # 0: include dead, 1: alive, 2: dead
+    incldead: 0
+    spstate: "{{ if .Config.freeleech }}2{{ else }}0{{ end }}"
+    # 0: title, 1: description, 3: uploader, 4: IMDB URL
+    search_area: "0"
+    # 0: AND, 2: exact
+    search_mode: 0
+    sort: "{{ .Config.sort }}"
+    type: "{{ .Config.type }}"
+    # TODO: The example I copied, `./freefarm.yml`, includes a
+    # `notnewword` key but I don't see that key from submitting the
+    # search form in the web UI of either that example or this
+    # indexer. What am I missing?
+    #
+    # TODO: On that note, while inspecting the payloads of both search
+    # forms I noted a bunch of parameters that the web UI sends that
+    # aren't included in that example. How does that reconcile with
+    # "we don't want an obvious 'Jackett footprint'" from my last PR
+    # feedback especially given how much of Jackett/Prowlarr's traffic
+    # is submissions of this form?
+
+  rows:
+    selector: table.torrents > tbody > tr:has(a[href^="download.php?id="])
+
+  fields:
+    category:
+      selector: a[href^="?cat="]
+      attribute: href
+      filters:
+        - name: querystring
+          args: cat
+    title_default:
+      selector: a[href^="details.php?id="]
+    title:
+      selector: a[title][href^="details.php?id="]
+      attribute: title
+      optional: true
+      default: "{{ .Result.title_default }}"
+    details:
+      selector: a[href^="details.php?id="]
+      attribute: href
+    download:
+      selector: a[href^="download.php?id="]
+      attribute: href
+    poster:
+      selector: img[data-src]
+      attribute: data-src
+    imdbid:
+      # site currently only has a badge and rating, the id is not present. just in case a future update.
+      selector: a[href*="imdb.com/title/tt"]
+      attribute: href
+    doubanid:
+      # site currently only has a badge and rating, the id is not present. just in case a future update.
+      selector: a[href*="movie.douban.com/subject/"]
+      attribute: href
+    date_elapsed:
+      # TODO: The selector from the example I copied includes
+      # `.rowfollow` which is a class for most of the column cells and
+      # AFAICT is only for presentation. As such I think it makes the
+      # selector more fragile and I've removed it from this
+      # definition. Should it be cleaned up in other definitions?
+      #
+      # time type: time elapsed (default)
+      selector: td:nth-child(4) > span[title]
+      attribute: title
+      optional: true
+      filters:
+        - name: append
+          # TODO: This is another demonstration of why a more verbose comment is
+          # valuable here. The `CST` abbreviation is used for both `-04:00` through
+          # `-06:00` in the Americas *and* `+08:00` in Asia. The more verbose comment
+          # removes ambiguity and saves contributor time.
+          args: " +08:00" # Asia/Taipei, CST
+        - name: dateparse
+          args: "yyyy-MM-dd HH:mm:ss zzz"
+    # TODO: I couldn't find an example of this when I sorted the full
+    # listing by date in both directions in the web UI of the exampale
+    # I copied. Where can I see the need for this in the example I
+    # copied so I can identify when it's needed for future
+    # definitions? Is it necessary for this definition?
+    date_added:
+      # time added
+      selector: td:nth-child(4):not(:has(span))
+      optional: true
+      filters:
+        - name: append
+          args: " +08:00" # CST
+        - name: dateparse
+          args: "yyyy-MM-ddHH:mm:ss zzz"
+    date:
+      text: "{{ if or .Result.date_elapsed .Result.date_added }}{{ or .Result.date_elapsed .Result.date_added }}{{ else }}now{{ end }}"
+    size:
+      selector: td:nth-child(5)
+    seeders:
+      selector: td:nth-child(6)
+    leechers:
+      selector: td:nth-child(7)
+    grabs:
+      selector: td:nth-child(8)
+    # TODO: There are no results for "2X", "2X 50%", and "30%" so I
+    # can't confirm their selectors but there are other examples in
+    # the example I copied of adding presumprive support for `imdbid`
+    # and `doubanid`, so I included them here.
+    #
+    # TODO: While testing, I could only find instances of "2X Free"
+    # and "ordinary" when I clicked through each of the top-level
+    # categories above, so those two are the only I could confirm by
+    # testing in the Prowlarr search UI. Is there a way I could have
+    # confirmed the rest?
+    downloadvolumefactor:
+      case:
+        img.pro_free: 0
+        img.pro_free2up: 0
+        img.pro_50pctdown: 0.5
+        img.pro_50pctdown2up: 0.5
+        img.pro_30pctdown: 0.3
+        "*": 1
+    uploadvolumefactor:
+      case:
+        img.pro_50pctdown2up: 2
+        img.pro_free2up: 2
+        img.pro_2up: 2
+        "*": 1
+    minimumseedtime:
+      # special 7 days (as seconds = 7 x 24 x 60 x 60)
+      # normal 3 days (as seconds = 3 x 24 x 60 x 60)
+      case:
+        # TODO: I found an instance of this in the example I copied by
+        # sorting by reverse date but that didn't yield an example for
+        # this indexer. See above regarding presumptive support. Am I
+        # correct to leave this in?
+        img[title="H&R"]: 604800
+        "*": 259200
+    description_verified:
+      case:
+        # TODO: I don't see these icons in this indexer's web UI but I
+        # do in the example I copied. Another case of presumptive
+        # support, correct?
+        span[title="通过"], span[title="通過"], span[title="Allowed"]: "Verified:"
+        span[title="未审"], span[title="未審"], span[title="Not reviewed"]: "Unverified:"
+        # TODO: Another case I can't find an instance of in the example I copide. How do I find an insance?
+        span[title="拒绝"], span[title="拒絕"], span[title="Denied"]: "Banned:"
+    description:
+      selector: td:nth-child(2)
+      remove: a, b, font, img, span
+      filters:
+        - name: prepend
+          args: "{{ .Result.description_verified }} "
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: rpatterson
body: But from what I've observed, this is a NexusPHP feature, no? If yes, then this tracker may use it at some point and it doesn't seem very fragile to keep this support in. Why do some things get presumptive support and others not?
created_at: 2025-03-07T17:03:30Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
+    # TODO: Searching for `S01` and `S01E01` for an example, that
+    # yields other results when searched without, yields no difference
+    # in results. Am I missing something?
+    #
+    # TODO: The example I copied, `./freefarm.yml`, includes support
+    # for `DoubanID` but I don't find any evidence of that support in
+    # *that* example's web UI. For *this* indexer I tested the
+    # `DoubanID` like I tested an IMDB ID above. Is the example
+    # definiton wrong or out of date? If not, where can you see the
+    # support for `DoubanID` in *that* example and does this indexer
+    # also support it?
+    tv-search: [q]
+    movie-search: [q]
+    music-search: [q]
+    book-search: [q]
+
+settings:
+  - name: username
+    type: text
+    label: Username
+  - name: password
+    type: password
+    label: Password
+  - name: 2facode
+    type: text
+    label: 2FA code
+  - name: info_2fa
+    type: info
+    label: "About 2FA code"
+    default: "Only fill in the <b>2FA code</b> box if you have enabled <b>2FA</b> on the HDBao Web Site. Otherwise just leave it empty."
+  # TODO: While testing this field, I noticed the results only includ
+  # *just* "Free" items and *not* "2X Free" items. This is also the
+  # case for the example I copied. I understand its better for
+  # Jackett/Prowlarr to use the filtering supported server-side. Does
+  # NexusPHP support multiple `spstate` values? If no, is there a good
+  # place for feature requests?
+  - name: freeleech
+    type: checkbox
+    label: Search freeleech only
+    default: false
+  - name: sort
+    type: select
+    label: Sort requested from site
+    default: 4
+    options:
+      4: created
+      7: seeders
+      5: size
+      1: title
+  - name: type
+    type: select
+    label: Order requested from site
+    default: desc
+    options:
+      desc: desc
+      asc: asc
+  # TODO: I didn't get any FS challenges for this indexer that I can
+  # recall, and definitely not while developing this definition. I
+  # confirmed FS usage by looking at the response headers and
+  # cookie. Is that a sufficient way to identify FS usage?
+  - name: info_flaresolverr
+    type: info_flaresolverr
+  - name: info_tpp
+    type: info
+    label: Results Per Page
+    default: For best results, change the <b>Torrents per page:</b> setting to <b>100</b> on your account profile.
+  - name: info_activity
+    type: info
+    label: Account Inactivity
+    default: "Cherish your user account. Inactive accounts would be deleted based on the following rules:<ol><li>Veteran User or above would never be deleted.</li><li>Elite User or above would never be deleted if parked (at User CP).</li><li>Parked accounts would be deleted if users have not logged in for more than 400 days in a row.</li><li>Unparked accounts would be deleted if users have not logged in for more than 150 days in a row.</li><li>Accounts with both uploaded and downloaded amount being 0 would be deleted if users have not logged in for more than 100 days in a row.</li></ol>"
+
+login:
+  path: login.php
+  method: form
+  form: form[action="takelogin.php"]
+  inputs:
+    secret: ""
+    username: "{{ .Config.username }}"
+    password: "{{ .Config.password }}"
+    two_step_code: "{{ .Config.2facode }}"
+    logout: ""
+    securelogin: ""
+    ssl: yes
+    trackerssl: yes
+  error:
+    - selector: td.embedded:contains("登录失败！")
+  test:
+    path: index.php
+    selector: a[href="logout.php"]
+
+search:
+  paths:
+    - path: torrents.php
+  inputs:
+    $raw: "{{ range .Categories }}cat{{.}}=1&{{end}}"
+    search: "{{ if .Query.IMDBID }}{{ .Query.IMDBID }}{{ else }}{{ .Keywords }}{{ end }}"
+    # 0: include dead, 1: alive, 2: dead
+    incldead: 0
+    spstate: "{{ if .Config.freeleech }}2{{ else }}0{{ end }}"
+    # 0: title, 1: description, 3: uploader, 4: IMDB URL
+    search_area: "0"
+    # 0: AND, 2: exact
+    search_mode: 0
+    sort: "{{ .Config.sort }}"
+    type: "{{ .Config.type }}"
+    # TODO: The example I copied, `./freefarm.yml`, includes a
+    # `notnewword` key but I don't see that key from submitting the
+    # search form in the web UI of either that example or this
+    # indexer. What am I missing?
+    #
+    # TODO: On that note, while inspecting the payloads of both search
+    # forms I noted a bunch of parameters that the web UI sends that
+    # aren't included in that example. How does that reconcile with
+    # "we don't want an obvious 'Jackett footprint'" from my last PR
+    # feedback especially given how much of Jackett/Prowlarr's traffic
+    # is submissions of this form?
+
+  rows:
+    selector: table.torrents > tbody > tr:has(a[href^="download.php?id="])
+
+  fields:
+    category:
+      selector: a[href^="?cat="]
+      attribute: href
+      filters:
+        - name: querystring
+          args: cat
+    title_default:
+      selector: a[href^="details.php?id="]
+    title:
+      selector: a[title][href^="details.php?id="]
+      attribute: title
+      optional: true
+      default: "{{ .Result.title_default }}"
+    details:
+      selector: a[href^="details.php?id="]
+      attribute: href
+    download:
+      selector: a[href^="download.php?id="]
+      attribute: href
+    poster:
+      selector: img[data-src]
+      attribute: data-src
+    imdbid:
+      # site currently only has a badge and rating, the id is not present. just in case a future update.
+      selector: a[href*="imdb.com/title/tt"]
+      attribute: href
+    doubanid:
+      # site currently only has a badge and rating, the id is not present. just in case a future update.
+      selector: a[href*="movie.douban.com/subject/"]
+      attribute: href
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: rpatterson
body: I assume you also meant to remove the `imdbid:` line above, too. That's what I've committed, so LMK if I should keep it and why if so.
created_at: 2025-03-07T17:13:07Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
+    # TODO: Searching for `S01` and `S01E01` for an example, that
+    # yields other results when searched without, yields no difference
+    # in results. Am I missing something?
+    #
+    # TODO: The example I copied, `./freefarm.yml`, includes support
+    # for `DoubanID` but I don't find any evidence of that support in
+    # *that* example's web UI. For *this* indexer I tested the
+    # `DoubanID` like I tested an IMDB ID above. Is the example
+    # definiton wrong or out of date? If not, where can you see the
+    # support for `DoubanID` in *that* example and does this indexer
+    # also support it?
+    tv-search: [q]
+    movie-search: [q]
+    music-search: [q]
+    book-search: [q]
+
+settings:
+  - name: username
+    type: text
+    label: Username
+  - name: password
+    type: password
+    label: Password
+  - name: 2facode
+    type: text
+    label: 2FA code
+  - name: info_2fa
+    type: info
+    label: "About 2FA code"
+    default: "Only fill in the <b>2FA code</b> box if you have enabled <b>2FA</b> on the HDBao Web Site. Otherwise just leave it empty."
+  # TODO: While testing this field, I noticed the results only includ
+  # *just* "Free" items and *not* "2X Free" items. This is also the
+  # case for the example I copied. I understand its better for
+  # Jackett/Prowlarr to use the filtering supported server-side. Does
+  # NexusPHP support multiple `spstate` values? If no, is there a good
+  # place for feature requests?
+  - name: freeleech
+    type: checkbox
+    label: Search freeleech only
+    default: false
+  - name: sort
+    type: select
+    label: Sort requested from site
+    default: 4
+    options:
+      4: created
+      7: seeders
+      5: size
+      1: title
+  - name: type
+    type: select
+    label: Order requested from site
+    default: desc
+    options:
+      desc: desc
+      asc: asc
+  # TODO: I didn't get any FS challenges for this indexer that I can
+  # recall, and definitely not while developing this definition. I
+  # confirmed FS usage by looking at the response headers and
+  # cookie. Is that a sufficient way to identify FS usage?
+  - name: info_flaresolverr
+    type: info_flaresolverr
+  - name: info_tpp
+    type: info
+    label: Results Per Page
+    default: For best results, change the <b>Torrents per page:</b> setting to <b>100</b> on your account profile.
+  - name: info_activity
+    type: info
+    label: Account Inactivity
+    default: "Cherish your user account. Inactive accounts would be deleted based on the following rules:<ol><li>Veteran User or above would never be deleted.</li><li>Elite User or above would never be deleted if parked (at User CP).</li><li>Parked accounts would be deleted if users have not logged in for more than 400 days in a row.</li><li>Unparked accounts would be deleted if users have not logged in for more than 150 days in a row.</li><li>Accounts with both uploaded and downloaded amount being 0 would be deleted if users have not logged in for more than 100 days in a row.</li></ol>"
+
+login:
+  path: login.php
+  method: form
+  form: form[action="takelogin.php"]
+  inputs:
+    secret: ""
+    username: "{{ .Config.username }}"
+    password: "{{ .Config.password }}"
+    two_step_code: "{{ .Config.2facode }}"
+    logout: ""
+    securelogin: ""
+    ssl: yes
+    trackerssl: yes
+  error:
+    - selector: td.embedded:contains("登录失败！")
+  test:
+    path: index.php
+    selector: a[href="logout.php"]
+
+search:
+  paths:
+    - path: torrents.php
+  inputs:
+    $raw: "{{ range .Categories }}cat{{.}}=1&{{end}}"
+    search: "{{ if .Query.IMDBID }}{{ .Query.IMDBID }}{{ else }}{{ .Keywords }}{{ end }}"
+    # 0: include dead, 1: alive, 2: dead
+    incldead: 0
+    spstate: "{{ if .Config.freeleech }}2{{ else }}0{{ end }}"
+    # 0: title, 1: description, 3: uploader, 4: IMDB URL
+    search_area: "0"
+    # 0: AND, 2: exact
+    search_mode: 0
+    sort: "{{ .Config.sort }}"
+    type: "{{ .Config.type }}"
+    # TODO: The example I copied, `./freefarm.yml`, includes a
+    # `notnewword` key but I don't see that key from submitting the
+    # search form in the web UI of either that example or this
+    # indexer. What am I missing?
+    #
+    # TODO: On that note, while inspecting the payloads of both search
+    # forms I noted a bunch of parameters that the web UI sends that
+    # aren't included in that example. How does that reconcile with
+    # "we don't want an obvious 'Jackett footprint'" from my last PR
+    # feedback especially given how much of Jackett/Prowlarr's traffic
+    # is submissions of this form?
+
+  rows:
+    selector: table.torrents > tbody > tr:has(a[href^="download.php?id="])
+
+  fields:
+    category:
+      selector: a[href^="?cat="]
+      attribute: href
+      filters:
+        - name: querystring
+          args: cat
+    title_default:
+      selector: a[href^="details.php?id="]
+    title:
+      selector: a[title][href^="details.php?id="]
+      attribute: title
+      optional: true
+      default: "{{ .Result.title_default }}"
+    details:
+      selector: a[href^="details.php?id="]
+      attribute: href
+    download:
+      selector: a[href^="download.php?id="]
+      attribute: href
+    poster:
+      selector: img[data-src]
+      attribute: data-src
+    imdbid:
+      # site currently only has a badge and rating, the id is not present. just in case a future update.
+      selector: a[href*="imdb.com/title/tt"]
+      attribute: href
+    doubanid:
+      # site currently only has a badge and rating, the id is not present. just in case a future update.
+      selector: a[href*="movie.douban.com/subject/"]
+      attribute: href
+    date_elapsed:
+      # TODO: The selector from the example I copied includes
+      # `.rowfollow` which is a class for most of the column cells and
+      # AFAICT is only for presentation. As such I think it makes the
+      # selector more fragile and I've removed it from this
+      # definition. Should it be cleaned up in other definitions?
+      #
+      # time type: time elapsed (default)
+      selector: td:nth-child(4) > span[title]
+      attribute: title
+      optional: true
+      filters:
+        - name: append
+          # TODO: This is another demonstration of why a more verbose comment is
+          # valuable here. The `CST` abbreviation is used for both `-04:00` through
+          # `-06:00` in the Americas *and* `+08:00` in Asia. The more verbose comment
+          # removes ambiguity and saves contributor time.
+          args: " +08:00" # Asia/Taipei, CST
+        - name: dateparse
+          args: "yyyy-MM-dd HH:mm:ss zzz"
+    # TODO: I couldn't find an example of this when I sorted the full
+    # listing by date in both directions in the web UI of the exampale
+    # I copied. Where can I see the need for this in the example I
+    # copied so I can identify when it's needed for future
+    # definitions? Is it necessary for this definition?
+    date_added:
+      # time added
+      selector: td:nth-child(4):not(:has(span))
+      optional: true
+      filters:
+        - name: append
+          args: " +08:00" # CST
+        - name: dateparse
+          args: "yyyy-MM-ddHH:mm:ss zzz"
+    date:
+      text: "{{ if or .Result.date_elapsed .Result.date_added }}{{ or .Result.date_elapsed .Result.date_added }}{{ else }}now{{ end }}"
+    size:
+      selector: td:nth-child(5)
+    seeders:
+      selector: td:nth-child(6)
+    leechers:
+      selector: td:nth-child(7)
+    grabs:
+      selector: td:nth-child(8)
+    # TODO: There are no results for "2X", "2X 50%", and "30%" so I
+    # can't confirm their selectors but there are other examples in
+    # the example I copied of adding presumprive support for `imdbid`
+    # and `doubanid`, so I included them here.
+    #
+    # TODO: While testing, I could only find instances of "2X Free"
+    # and "ordinary" when I clicked through each of the top-level
+    # categories above, so those two are the only I could confirm by
+    # testing in the Prowlarr search UI. Is there a way I could have
+    # confirmed the rest?
+    downloadvolumefactor:
+      case:
+        img.pro_free: 0
+        img.pro_free2up: 0
+        img.pro_50pctdown: 0.5
+        img.pro_50pctdown2up: 0.5
+        img.pro_30pctdown: 0.3
+        "*": 1
+    uploadvolumefactor:
+      case:
+        img.pro_50pctdown2up: 2
+        img.pro_free2up: 2
+        img.pro_2up: 2
+        "*": 1
+    minimumseedtime:
+      # special 7 days (as seconds = 7 x 24 x 60 x 60)
+      # normal 3 days (as seconds = 3 x 24 x 60 x 60)
+      case:
+        # TODO: I found an instance of this in the example I copied by
+        # sorting by reverse date but that didn't yield an example for
+        # this indexer. See above regarding presumptive support. Am I
+        # correct to leave this in?
+        img[title="H&R"]: 604800
+        "*": 259200
+    description_verified:
+      case:
+        # TODO: I don't see these icons in this indexer's web UI but I
+        # do in the example I copied. Another case of presumptive
+        # support, correct?
+        span[title="通过"], span[title="通過"], span[title="Allowed"]: "Verified:"
+        span[title="未审"], span[title="未審"], span[title="Not reviewed"]: "Unverified:"
+        # TODO: Another case I can't find an instance of in the example I copide. How do I find an insance?
+        span[title="拒绝"], span[title="拒絕"], span[title="Denied"]: "Banned:"
+    description:
+      selector: td:nth-child(2)
+      remove: a, b, font, img, span
+      filters:
+        - name: prepend
+          args: "{{ .Result.description_verified }} "
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: rpatterson
body: Oh, NM. It has to be removed from the definition when not in use so as not to pollute the row results. Sorry.
created_at: 2025-03-07T17:15:22Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
+    # TODO: Searching for `S01` and `S01E01` for an example, that
+    # yields other results when searched without, yields no difference
+    # in results. Am I missing something?
+    #
+    # TODO: The example I copied, `./freefarm.yml`, includes support
+    # for `DoubanID` but I don't find any evidence of that support in
+    # *that* example's web UI. For *this* indexer I tested the
+    # `DoubanID` like I tested an IMDB ID above. Is the example
+    # definiton wrong or out of date? If not, where can you see the
+    # support for `DoubanID` in *that* example and does this indexer
+    # also support it?
+    tv-search: [q]
+    movie-search: [q]
+    music-search: [q]
+    book-search: [q]
+
+settings:
+  - name: username
+    type: text
+    label: Username
+  - name: password
+    type: password
+    label: Password
+  - name: 2facode
+    type: text
+    label: 2FA code
+  - name: info_2fa
+    type: info
+    label: "About 2FA code"
+    default: "Only fill in the <b>2FA code</b> box if you have enabled <b>2FA</b> on the HDBao Web Site. Otherwise just leave it empty."
+  # TODO: While testing this field, I noticed the results only includ
+  # *just* "Free" items and *not* "2X Free" items. This is also the
+  # case for the example I copied. I understand its better for
+  # Jackett/Prowlarr to use the filtering supported server-side. Does
+  # NexusPHP support multiple `spstate` values? If no, is there a good
+  # place for feature requests?
+  - name: freeleech
+    type: checkbox
+    label: Search freeleech only
+    default: false
+  - name: sort
+    type: select
+    label: Sort requested from site
+    default: 4
+    options:
+      4: created
+      7: seeders
+      5: size
+      1: title
+  - name: type
+    type: select
+    label: Order requested from site
+    default: desc
+    options:
+      desc: desc
+      asc: asc
+  # TODO: I didn't get any FS challenges for this indexer that I can
+  # recall, and definitely not while developing this definition. I
+  # confirmed FS usage by looking at the response headers and
+  # cookie. Is that a sufficient way to identify FS usage?
+  - name: info_flaresolverr
+    type: info_flaresolverr
+  - name: info_tpp
+    type: info
+    label: Results Per Page
+    default: For best results, change the <b>Torrents per page:</b> setting to <b>100</b> on your account profile.
+  - name: info_activity
+    type: info
+    label: Account Inactivity
+    default: "Cherish your user account. Inactive accounts would be deleted based on the following rules:<ol><li>Veteran User or above would never be deleted.</li><li>Elite User or above would never be deleted if parked (at User CP).</li><li>Parked accounts would be deleted if users have not logged in for more than 400 days in a row.</li><li>Unparked accounts would be deleted if users have not logged in for more than 150 days in a row.</li><li>Accounts with both uploaded and downloaded amount being 0 would be deleted if users have not logged in for more than 100 days in a row.</li></ol>"
+
+login:
+  path: login.php
+  method: form
+  form: form[action="takelogin.php"]
+  inputs:
+    secret: ""
+    username: "{{ .Config.username }}"
+    password: "{{ .Config.password }}"
+    two_step_code: "{{ .Config.2facode }}"
+    logout: ""
+    securelogin: ""
+    ssl: yes
+    trackerssl: yes
+  error:
+    - selector: td.embedded:contains("登录失败！")
+  test:
+    path: index.php
+    selector: a[href="logout.php"]
+
+search:
+  paths:
+    - path: torrents.php
+  inputs:
+    $raw: "{{ range .Categories }}cat{{.}}=1&{{end}}"
+    search: "{{ if .Query.IMDBID }}{{ .Query.IMDBID }}{{ else }}{{ .Keywords }}{{ end }}"
+    # 0: include dead, 1: alive, 2: dead
+    incldead: 0
+    spstate: "{{ if .Config.freeleech }}2{{ else }}0{{ end }}"
+    # 0: title, 1: description, 3: uploader, 4: IMDB URL
+    search_area: "0"
+    # 0: AND, 2: exact
+    search_mode: 0
+    sort: "{{ .Config.sort }}"
+    type: "{{ .Config.type }}"
+    # TODO: The example I copied, `./freefarm.yml`, includes a
+    # `notnewword` key but I don't see that key from submitting the
+    # search form in the web UI of either that example or this
+    # indexer. What am I missing?
+    #
+    # TODO: On that note, while inspecting the payloads of both search
+    # forms I noted a bunch of parameters that the web UI sends that
+    # aren't included in that example. How does that reconcile with
+    # "we don't want an obvious 'Jackett footprint'" from my last PR
+    # feedback especially given how much of Jackett/Prowlarr's traffic
+    # is submissions of this form?
+
+  rows:
+    selector: table.torrents > tbody > tr:has(a[href^="download.php?id="])
+
+  fields:
+    category:
+      selector: a[href^="?cat="]
+      attribute: href
+      filters:
+        - name: querystring
+          args: cat
+    title_default:
+      selector: a[href^="details.php?id="]
+    title:
+      selector: a[title][href^="details.php?id="]
+      attribute: title
+      optional: true
+      default: "{{ .Result.title_default }}"
+    details:
+      selector: a[href^="details.php?id="]
+      attribute: href
+    download:
+      selector: a[href^="download.php?id="]
+      attribute: href
+    poster:
+      selector: img[data-src]
+      attribute: data-src
+    imdbid:
+      # site currently only has a badge and rating, the id is not present. just in case a future update.
+      selector: a[href*="imdb.com/title/tt"]
+      attribute: href
+    doubanid:
+      # site currently only has a badge and rating, the id is not present. just in case a future update.
+      selector: a[href*="movie.douban.com/subject/"]
+      attribute: href
+    date_elapsed:
+      # TODO: The selector from the example I copied includes
+      # `.rowfollow` which is a class for most of the column cells and
+      # AFAICT is only for presentation. As such I think it makes the
+      # selector more fragile and I've removed it from this
+      # definition. Should it be cleaned up in other definitions?
+      #
+      # time type: time elapsed (default)
+      selector: td:nth-child(4) > span[title]
+      attribute: title
+      optional: true
+      filters:
+        - name: append
+          # TODO: This is another demonstration of why a more verbose comment is
+          # valuable here. The `CST` abbreviation is used for both `-04:00` through
+          # `-06:00` in the Americas *and* `+08:00` in Asia. The more verbose comment
+          # removes ambiguity and saves contributor time.
+          args: " +08:00" # Asia/Taipei, CST
+        - name: dateparse
+          args: "yyyy-MM-dd HH:mm:ss zzz"
+    # TODO: I couldn't find an example of this when I sorted the full
+    # listing by date in both directions in the web UI of the exampale
+    # I copied. Where can I see the need for this in the example I
+    # copied so I can identify when it's needed for future
+    # definitions? Is it necessary for this definition?
+    date_added:
+      # time added
+      selector: td:nth-child(4):not(:has(span))
+      optional: true
+      filters:
+        - name: append
+          args: " +08:00" # CST
+        - name: dateparse
+          args: "yyyy-MM-ddHH:mm:ss zzz"
+    date:
+      text: "{{ if or .Result.date_elapsed .Result.date_added }}{{ or .Result.date_elapsed .Result.date_added }}{{ else }}now{{ end }}"
+    size:
+      selector: td:nth-child(5)
+    seeders:
+      selector: td:nth-child(6)
+    leechers:
+      selector: td:nth-child(7)
+    grabs:
+      selector: td:nth-child(8)
+    # TODO: There are no results for "2X", "2X 50%", and "30%" so I
+    # can't confirm their selectors but there are other examples in
+    # the example I copied of adding presumprive support for `imdbid`
+    # and `doubanid`, so I included them here.
+    #
+    # TODO: While testing, I could only find instances of "2X Free"
+    # and "ordinary" when I clicked through each of the top-level
+    # categories above, so those two are the only I could confirm by
+    # testing in the Prowlarr search UI. Is there a way I could have
+    # confirmed the rest?
+    downloadvolumefactor:
+      case:
+        img.pro_free: 0
+        img.pro_free2up: 0
+        img.pro_50pctdown: 0.5
+        img.pro_50pctdown2up: 0.5
+        img.pro_30pctdown: 0.3
+        "*": 1
+    uploadvolumefactor:
+      case:
+        img.pro_50pctdown2up: 2
+        img.pro_free2up: 2
+        img.pro_2up: 2
+        "*": 1
+    minimumseedtime:
+      # special 7 days (as seconds = 7 x 24 x 60 x 60)
+      # normal 3 days (as seconds = 3 x 24 x 60 x 60)
+      case:
+        # TODO: I found an instance of this in the example I copied by
+        # sorting by reverse date but that didn't yield an example for
+        # this indexer. See above regarding presumptive support. Am I
+        # correct to leave this in?
+        img[title="H&R"]: 604800
+        "*": 259200
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: rpatterson
body: Sorry I missed this. I remember reviewing the rules and forums looking for anything about H&R, I'm not sure what I did with those findings if I left this in. :-/
created_at: 2025-03-07T17:19:56Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
+    # TODO: Searching for `S01` and `S01E01` for an example, that
+    # yields other results when searched without, yields no difference
+    # in results. Am I missing something?
+    #
+    # TODO: The example I copied, `./freefarm.yml`, includes support
+    # for `DoubanID` but I don't find any evidence of that support in
+    # *that* example's web UI. For *this* indexer I tested the
+    # `DoubanID` like I tested an IMDB ID above. Is the example
+    # definiton wrong or out of date? If not, where can you see the
+    # support for `DoubanID` in *that* example and does this indexer
+    # also support it?
+    tv-search: [q]
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: rpatterson
body: I wasn't able to confirm this in the Prowlarr search UI, I'm guessing because it handles episode terms as just other keywords.
created_at: 2025-03-07T18:04:19Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
+    # TODO: Searching for `S01` and `S01E01` for an example, that
+    # yields other results when searched without, yields no difference
+    # in results. Am I missing something?
+    #
+    # TODO: The example I copied, `./freefarm.yml`, includes support
+    # for `DoubanID` but I don't find any evidence of that support in
+    # *that* example's web UI. For *this* indexer I tested the
+    # `DoubanID` like I tested an IMDB ID above. Is the example
+    # definiton wrong or out of date? If not, where can you see the
+    # support for `DoubanID` in *that* example and does this indexer
+    # also support it?
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: ilike2burnthing
body: You just test a few IMDB and Douban IDs for torrents which exist on site. Most NexusPHP sites I've seen will have these in the descriptions on the details pages, so you don't have to go searching, but if not then just google them.
created_at: 2025-03-08T00:42:09Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: ilike2burnthing
body: It's usually for something distinct enough from others in that category and not covered by the other sub-categories, like kids cartoons (that aren't anime), anime films, comedy specials, or audio lectures; or when the site itself classes it as 'other' or 'misc', either of a particular category or the tracker only caters to a particular category.
created_at: 2025-03-08T01:01:50Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: ilike2burnthing
body: Ah kk. Seems that it's a mix of `Audio` and `Audio/Video` in other indexers, with the only exception being OshenPT - https://github.com/search?q=repo%3AJackett%2FJackett+%22%E9%9F%B3%E4%B9%90%22+language%3AYAML&type=code

OshenPT uses the same `Misc/音乐` cat label, and the misc/other category icon for NexusPHP trackers (and its results are a mess of everything, though mostly software). As the only result for HDBao is a video of a concert, I'll leave it up to you to choose between `Other` and `Audio/Video`.
created_at: 2025-03-08T02:03:57Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
+    # TODO: Searching for `S01` and `S01E01` for an example, that
+    # yields other results when searched without, yields no difference
+    # in results. Am I missing something?
+    #
+    # TODO: The example I copied, `./freefarm.yml`, includes support
+    # for `DoubanID` but I don't find any evidence of that support in
+    # *that* example's web UI. For *this* indexer I tested the
+    # `DoubanID` like I tested an IMDB ID above. Is the example
+    # definiton wrong or out of date? If not, where can you see the
+    # support for `DoubanID` in *that* example and does this indexer
+    # also support it?
+    tv-search: [q]
+    movie-search: [q]
+    music-search: [q]
+    book-search: [q]
+
+settings:
+  - name: username
+    type: text
+    label: Username
+  - name: password
+    type: password
+    label: Password
+  - name: 2facode
+    type: text
+    label: 2FA code
+  - name: info_2fa
+    type: info
+    label: "About 2FA code"
+    default: "Only fill in the <b>2FA code</b> box if you have enabled <b>2FA</b> on the HDBao Web Site. Otherwise just leave it empty."
+  # TODO: While testing this field, I noticed the results only includ
+  # *just* "Free" items and *not* "2X Free" items. This is also the
+  # case for the example I copied. I understand its better for
+  # Jackett/Prowlarr to use the filtering supported server-side. Does
+  # NexusPHP support multiple `spstate` values? If no, is there a good
+  # place for feature requests?
+  - name: freeleech
+    type: checkbox
+    label: Search freeleech only
+    default: false
+  - name: sort
+    type: select
+    label: Sort requested from site
+    default: 4
+    options:
+      4: created
+      7: seeders
+      5: size
+      1: title
+  - name: type
+    type: select
+    label: Order requested from site
+    default: desc
+    options:
+      desc: desc
+      asc: asc
+  # TODO: I didn't get any FS challenges for this indexer that I can
+  # recall, and definitely not while developing this definition. I
+  # confirmed FS usage by looking at the response headers and
+  # cookie. Is that a sufficient way to identify FS usage?
+  - name: info_flaresolverr
+    type: info_flaresolverr
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: ilike2burnthing
body: Just traverse the site in browser.
created_at: 2025-03-08T02:05:05Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
+    # TODO: Searching for `S01` and `S01E01` for an example, that
+    # yields other results when searched without, yields no difference
+    # in results. Am I missing something?
+    #
+    # TODO: The example I copied, `./freefarm.yml`, includes support
+    # for `DoubanID` but I don't find any evidence of that support in
+    # *that* example's web UI. For *this* indexer I tested the
+    # `DoubanID` like I tested an IMDB ID above. Is the example
+    # definiton wrong or out of date? If not, where can you see the
+    # support for `DoubanID` in *that* example and does this indexer
+    # also support it?
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: rpatterson
body: Yeah, I didn't have a problem finding example IDs in the indexer's web UI, that's not what I was asking:

> if I were writing that definition from scratch, how would I know to do that

IOW, if a contributor is writing a new indexer definition, how do they know from that indexer's web UI that they should add IMDB and/or Douban ID support to the definition? Are you saying that they know whether to add that support by:
1. looking for example IMDB/Douban IDs in some details pages
2. if found, then try those IDs blindly in various ways on search forms?
created_at: 2025-03-08T16:47:33Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: rpatterson
body: Ah, I'd say precedent is better than going by *either* unclear results or the google translation. In this case it seems precedent agrees with the translation.
created_at: 2025-03-08T16:51:36Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
+    # TODO: Searching for `S01` and `S01E01` for an example, that
+    # yields other results when searched without, yields no difference
+    # in results. Am I missing something?
+    #
+    # TODO: The example I copied, `./freefarm.yml`, includes support
+    # for `DoubanID` but I don't find any evidence of that support in
+    # *that* example's web UI. For *this* indexer I tested the
+    # `DoubanID` like I tested an IMDB ID above. Is the example
+    # definiton wrong or out of date? If not, where can you see the
+    # support for `DoubanID` in *that* example and does this indexer
+    # also support it?
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: ilike2burnthing
body: If there's no relevant search input for these on the tracker's site, they don't appear in the description on the details page (or there's no way to search the description), and other indexers based on the same engine don't use these searches, then don't waste your time.
created_at: 2025-03-09T03:27:51Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,297 @@
+---
+id: hdbao
+name: HDBao
+description: "HDBao is a CHINESE Private Torrent Tracker for MOVIES / TV / GENERAL"
+language: zh-CN
+type: private
+encoding: UTF-8
+links:
+  - https://hdbao.cc/
+
+caps:
+  # dont forget to update the path categories in the search block
+  categorymappings:
+    # TODO: The example I copied, `./freefarm.yml`, has a `default`
+    # key in each item below while the example I copied for my last PR
+    # does not. Reading through the docs, I think this is about
+    # `search/paths/*/path/categories`, correct? I don't see a
+    # separate search form for a subset of categories for this
+    # indexer, but when I submit the separate search form from the
+    # example I copied, I don't see how to identify the specific
+    # subset of categories each form uses. Maybe not relevant for this
+    # indexer, but how would I determine those sets of categories in
+    # the example I copied?
+    - {id: 407, cat: TV/Sport, desc: "Sports/赛事"}
+    - {id: 401, cat: Movies, desc: "Movies/电影"}
+    - {id: 402, cat: TV, desc: "TV Series/电视剧"}
+    - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+    - {id: 403, cat: TV/Other, desc: "TV Shows/综艺"}
+    - {id: 409, cat: Audio, desc: "Misc/音乐"}
+    - {id: 408, cat: Audio, desc: "Concert/演唱会"}
+    - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+    - {id: 405, cat: TV/Other, desc: "Animations/动漫&动画"}
+    - {id: 410, cat: Books/Technical, desc: "Tutorial/教程"}
+    - {id: 411, cat: Other, desc: "Others/其他"}
+    # TODO: There are also checkboxes under the above categories for
+    # "medium", "Resolution", "coding", "Audio Coding", and
+    # "Production Team". The example I copied has similar but
+    # different sets of checkboxes and the `categorymappings` for that
+    # definition don't seem to clearly correspond clearly to any of
+    # those sets. I could see trying to massage the sets of checkboxes
+    # from this indexer or the example into various Torznab categories
+    # but it's ambiguous and I'm not entirely clear how to do
+    # that. They also use different `<input...` names which I'm also
+    # not sure how to do. How should a contibutor approach such
+    # indexers?
+
+  modes:
+    search: [q]
+    # TODO: The "scope" dropdown claims to support "IMDb Link" but
+    # searching for either the IMDB ID or URL of an example found in
+    # the web UI yeilds no result. Am I missing something?
+    #
+    # TODO: Searching for `S01` and `S01E01` for an example, that
+    # yields other results when searched without, yields no difference
+    # in results. Am I missing something?
+    #
+    # TODO: The example I copied, `./freefarm.yml`, includes support
+    # for `DoubanID` but I don't find any evidence of that support in
+    # *that* example's web UI. For *this* indexer I tested the
+    # `DoubanID` like I tested an IMDB ID above. Is the example
+    # definiton wrong or out of date? If not, where can you see the
+    # support for `DoubanID` in *that* example and does this indexer
+    # also support it?
path: src/Jackett.Common/Definitions/hdbao.yml
user: login: rpatterson
body: Awesomely exhaustive, thanks!
created_at: 2025-03-09T20:55:10Z
author_association: CONTRIBUTOR

PR comments:
user: login: jackettbot[bot]
created_at: 2025-03-06T07:13:07Z
body: Hi @rpatterson,

Thanks for your contribution to Jackett!

If you are adding a new indexer, please ensure that you've added it to the readme as well

A human will be along soon to review

author_association: CONTRIBUTOR
user: login: mynameisbogdan
created_at: 2025-03-06T12:12:10Z
body: You should revert any freefarm changes not related to this PR, correct? Looks like they switched filenames. 
author_association: CONTRIBUTOR
user: login: rpatterson
created_at: 2025-03-06T18:41:28Z
body: > You should revert any freefarm changes not related to this PR, correct? Looks like they switched filenames.

Sorry. I rebased my commits from the machine where I tested them to my laptop with my signing key and such and the rebase applied the changes to the wrong file and I missed it. I just fixed and force pushed. The only changes are to `./src/Jackett.Common/Definitions/hdbao.yml`. Some of my `# TODO: ` comments are *about* `./src/Jackett.Common/Definitions/freefarm.yml` but no changes to it are in this PR. Sorry again and thanks for the catch.
author_association: CONTRIBUTOR
user: login: rpatterson
created_at: 2025-03-07T16:23:55Z
body: I'm still working through the feedback, so don't bother testing yet. I have some followup questions in the unresolved comments above.
author_association: CONTRIBUTOR
user: login: rpatterson
created_at: 2025-03-07T17:21:57Z
body: K, I finished working through the feedback and I'm testing the resolved changes now. I still need some followup on the unresolved comments above.
author_association: CONTRIBUTOR
user: login: rpatterson
created_at: 2025-03-07T18:14:44Z
body: Ok, I've finished testing the changes. Most of it is removing comments and the rest I can't test in Prowlarr and wasn't among the testing for my previous PR, including that requested in the feedback. Pretty much just confirming the category changes, and the `notnewword: 1` query parameter.

I'm standing by for unresolved followup.
author_association: CONTRIBUTOR
user: login: rpatterson
created_at: 2025-03-08T17:07:06Z
body: Ok, there's one unresolved comment left, but that's just discussion. All the changes have been made, squashed and force-pushed so I think it's ready for y'all to start testing.
author_association: CONTRIBUTOR
user: login: garfield69
created_at: 2025-03-09T05:57:10Z
body: v0.22.1564
author_association: CONTRIBUTOR
user: login: rpatterson
created_at: 2025-03-09T21:56:36Z
body: Just to confirm, I removed my custom definition, restarted, and the merged definition from the updated image seems to be working.
author_association: CONTRIBUTOR