Skip to content

Commit f254b28

Browse files
authored
Merge branch 'develop' into pre-commit-ci-update-config
2 parents 7ba0eae + 441659b commit f254b28

19 files changed

+222
-405
lines changed

.github/workflows/dependabot-approve-and-auto-merge.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
# will not occur.
2020
- name: Dependabot metadata
2121
id: dependabot-metadata
22-
uses: dependabot/fetch-metadata@v2.4.0
22+
uses: dependabot/fetch-metadata@v2.5.0
2323
with:
2424
github-token: "${{ secrets.GITHUB_TOKEN }}"
2525
# Here the PR gets approved.

.github/workflows/develop.yml

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@ name: Docker Develop Release
22

33
on:
44
push:
5-
branches: [ develop ]
5+
branches: [develop]
66
workflow_dispatch:
77

88
concurrency:
99
group: ${{ github.workflow }}-${{ github.ref }}
1010
cancel-in-progress: true
1111

1212
jobs:
13-
1413
build-binaries:
1514
name: Build Standalone Binaries (${{ matrix.os }})
1615
permissions:
@@ -21,14 +20,14 @@ jobs:
2120
matrix:
2221
include:
2322
- os: ubuntu-latest
24-
python-version: '3.12'
23+
python-version: "3.12"
2524
- os: windows-latest
26-
python-version: '3.12'
27-
- os: 'macos-latest' # for Arm based macs (M1 and above).
28-
python-version: '3.12'
25+
python-version: "3.12"
26+
- os: "macos-latest" # for Arm based macs (M1 and above).
27+
python-version: "3.12"
2928
arch: arm64
30-
- os: 'macos-13' # for Intel based macs.
31-
python-version: '3.12'
29+
- os: "macos-15-intel" # for Intel based macs.
30+
python-version: "3.12"
3231
arch: x86_64
3332
env:
3433
APP_NAME: qbit-manage
@@ -43,7 +42,7 @@ jobs:
4342
uses: actions/setup-python@v6
4443
with:
4544
python-version: ${{ matrix.python-version }}
46-
cache: 'pip'
45+
cache: "pip"
4746
cache-dependency-path: |
4847
pyproject.toml
4948
uv.lock
@@ -113,7 +112,6 @@ jobs:
113112
mv "dist/${APP_NAME}" "out/${APP_NAME}-linux-amd64"
114113
fi
115114
116-
117115
# Build Tauri desktop shell after binaries are ready
118116
- name: Setup Rust toolchain
119117
uses: dtolnay/rust-toolchain@stable
@@ -280,7 +278,7 @@ jobs:
280278
fi
281279
282280
- name: Upload build outputs (binary + Tauri bundles)
283-
uses: actions/upload-artifact@v5
281+
uses: actions/upload-artifact@v7
284282
with:
285283
name: build-outputs-${{ runner.os }}-${{ env.BUILD_ARCH }}
286284
path: |
@@ -298,7 +296,7 @@ jobs:
298296
contents: read
299297
steps:
300298
- name: Download and collect all build outputs
301-
uses: actions/download-artifact@v6
299+
uses: actions/download-artifact@v8
302300
with:
303301
pattern: build-outputs-*
304302
path: collected
@@ -386,7 +384,7 @@ jobs:
386384
echo "Desktop installers: $(find release-assets -name "*desktop-installer*" | wc -l)"
387385
388386
- name: Upload final release assets
389-
uses: actions/upload-artifact@v5
387+
uses: actions/upload-artifact@v7
390388
with:
391389
name: qbit-manage-release-assets
392390
path: release-assets/*
@@ -401,7 +399,7 @@ jobs:
401399
run: |
402400
echo "OWNER_LC=${OWNER,,}" >>${GITHUB_ENV}
403401
env:
404-
OWNER: '${{ github.repository_owner }}'
402+
OWNER: "${{ github.repository_owner }}"
405403

406404
- name: Check Out Repo
407405
uses: actions/checkout@v6

.github/workflows/update-supported-versions.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ jobs:
7575
- name: Create Pull Request
7676
if: ${{ steps.detect-changes.outputs.changed == 'true' }}
7777
id: create-pr
78-
uses: peter-evans/create-pull-request@v7
78+
uses: peter-evans/create-pull-request@v8
7979
with:
8080
commit-message: Update SUPPORTED_VERSIONS.json
8181
title: "Update SUPPORTED_VERSIONS.json for ${{ steps.get-develop-version.outputs.version || github.event.inputs.targetBranch || github.ref_name }}"

.github/workflows/version.yml

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ concurrency:
1010
cancel-in-progress: true
1111

1212
jobs:
13-
1413
build-binaries:
1514
name: Build Standalone Binaries (${{ matrix.os }})
1615
permissions:
@@ -21,14 +20,14 @@ jobs:
2120
matrix:
2221
include:
2322
- os: ubuntu-latest
24-
python-version: '3.12'
23+
python-version: "3.12"
2524
- os: windows-latest
26-
python-version: '3.12'
27-
- os: 'macos-latest' # for Arm based macs (M1 and above).
28-
python-version: '3.12'
25+
python-version: "3.12"
26+
- os: "macos-latest" # for Arm based macs (M1 and above).
27+
python-version: "3.12"
2928
arch: arm64
30-
- os: 'macos-13' # for Intel based macs.
31-
python-version: '3.12'
29+
- os: "macos-15-intel" # for Intel based macs.
30+
python-version: "3.12"
3231
arch: x86_64
3332
env:
3433
APP_NAME: qbit-manage
@@ -41,7 +40,7 @@ jobs:
4140
uses: actions/setup-python@v6
4241
with:
4342
python-version: ${{ matrix.python-version }}
44-
cache: 'pip'
43+
cache: "pip"
4544
cache-dependency-path: |
4645
pyproject.toml
4746
uv.lock
@@ -111,7 +110,6 @@ jobs:
111110
mv "dist/${APP_NAME}" "out/${APP_NAME}-linux-amd64"
112111
fi
113112
114-
115113
# Build Tauri desktop shell after binaries are ready
116114
- name: Setup Rust toolchain
117115
uses: dtolnay/rust-toolchain@stable
@@ -278,7 +276,7 @@ jobs:
278276
fi
279277
280278
- name: Upload build outputs (binary + Tauri bundles)
281-
uses: actions/upload-artifact@v5
279+
uses: actions/upload-artifact@v7
282280
with:
283281
name: build-outputs-${{ runner.os }}-${{ env.BUILD_ARCH }}
284282
path: |
@@ -296,7 +294,7 @@ jobs:
296294
contents: read
297295
steps:
298296
- name: Download and collect all build outputs
299-
uses: actions/download-artifact@v6
297+
uses: actions/download-artifact@v8
300298
with:
301299
pattern: build-outputs-*
302300
path: collected
@@ -384,7 +382,7 @@ jobs:
384382
echo "Desktop installers: $(find release-assets -name "*desktop-installer*" | wc -l)"
385383
386384
- name: Upload final release assets
387-
uses: actions/upload-artifact@v5
385+
uses: actions/upload-artifact@v7
388386
with:
389387
name: qbit-manage-release-assets
390388
path: release-assets/*
@@ -429,7 +427,7 @@ jobs:
429427
run: |
430428
echo "OWNER_LC=${OWNER,,}" >>${GITHUB_ENV}
431429
env:
432-
OWNER: '${{ github.repository_owner }}'
430+
OWNER: "${{ github.repository_owner }}"
433431

434432
- name: Check Out Repo
435433
uses: actions/checkout@v6
@@ -509,7 +507,7 @@ jobs:
509507
run: echo "VERSION=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_OUTPUT
510508

511509
- name: Download prepared release assets
512-
uses: actions/download-artifact@v6
510+
uses: actions/download-artifact@v8
513511
with:
514512
name: qbit-manage-release-assets
515513
path: release-assets

SUPPORTED_VERSIONS.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"master": {
3-
"qbit": "v5.1.3",
4-
"qbitapi": "2025.11.0"
3+
"qbit": "v5.1.4",
4+
"qbitapi": "2025.11.1"
55
},
66
"develop": {
77
"qbit": "v5.1.4",

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
4.6.5
1+
4.6.6-develop3

docs/Config-Setup.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,12 @@ If you're needing information regarding hardlinks here are some excellent resour
181181
This functionality will tag any torrent's whose file (or largest file if multi-file) does not have any hardlinks outside the qbm root_dir.
182182
Note that `ignore_root_dir` (Default: True) will ignore any hardlinks detected in the same root_dir.
183183

184+
> [!TIP]
185+
> Use `No Hardlinks` with [sharelimits](#sharelimits) to remove torrents whose largest file is no longer hardlinked based on seedtime and/or seed ratio.
186+
187+
> [!TIP]
188+
> For Linux/Mac users you can use [TRaSH Guide's Method 3](https://trash-guides.info/File-and-Folder-Structure/Check-if-hardlinks-are-working/#mac-or-linux-method-3-using-inode-copies) to locate the other hardlinked files.
189+
184190
| Configuration | Definition | Required |
185191
| :------------ | :-------------------------------------------------------- | :------------------ |
186192
| `key` | Category name to check for nohardlinked torrents in qbit. | <center>✅</center> |
@@ -206,8 +212,8 @@ Control how torrent share limits are set depending on the priority of your group
206212
| `exclude_all_tags` | Filter the group based on one or more tags. Multiple exclude_all_tags are checked with an **AND** condition. All tags defined here must be present in the torrent for it to be excluded in this group | None | list | <center>❌</center> |
207213
| `exclude_any_tags` | Filter the group based on one or more tags. Multiple exclude_any_tags are checked with an **OR** condition. Any tags defined here must be present in the torrent for it to be excluded in this group | None | list | <center>❌</center> |
208214
| `categories` | Filter by including one or more categories. Multiple categories are checked with an **OR** condition. Since one torrent can only be associated with a single category, multiple categories are checked with an **OR** condition | None | list | <center>❌</center> |
209-
| `min_torrent_size` | Only include torrents at least this size in the group. Accepts human‑readable sizes like `200MB`, `40GB`, `1024MiB`. Leave unset/blank to disable. | None | str | <center>❌</center> |
210-
| `max_torrent_size` | Only include torrents no larger than this size in the group. Accepts human‑readable sizes like `200MB`, `40GB`, `1024MiB`. Leave unset/blank to disable. | None | str | <center>❌</center> |
215+
| `min_torrent_size` | Only include torrents at least this size in the group. Accepts human‑readable sizes like `200MB`, `40GB`, `1024MiB`. Leave unset/blank to disable. Uses `>=` (at least this size) | None | str | <center>❌</center> |
216+
| `max_torrent_size` | Only include torrents no larger than this size in the group. Accepts human‑readable sizes like `200MB`, `40GB`, `1024MiB`. Leave unset/blank to disable. Uses `<=` (at most this size) | None | str | <center>❌</center> |
211217
| `cleanup` | **WARNING!!** Setting this as true will remove and delete contents of any torrents that satisfies the share limits **(max time OR max ratio)** It will also delete the torrent's data if and only if no other torrents are using the same folder/files. | False | bool | <center>❌</center> |
212218
| `max_ratio` | Will set the torrent Maximum share ratio until torrent is stopped from seeding/uploading and may be cleaned up / removed if the minimums have been met. (`-2` : Global Limit , `-1` : No Limit) | -1 | float | <center>❌</center> |
213219
| `max_seeding_time` | Will set the torrent Maximum seeding time until torrent is stopped from seeding/uploading and may be cleaned up / removed if the minimums have been met. (`-2` : Global Limit , `-1` : No Limit) (Max value of 1 year (525600 minutes)) See Some examples of [valid time expressions](https://github.com/onegreyonewhite/pytimeparse2?tab=readme-ov-file#pytimeparse2-time-expression-parser) 32m, 2h32m, 3d2h32m, 1w3d2h32m | -1 | str | <center>❌</center> |

modules/core/category.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import time
22

3+
from qbittorrentapi import Conflict409Error
4+
35
from modules import util
46
from modules.qbit_error_handler import handle_qbit_api_errors
57

@@ -104,9 +106,18 @@ def set_category_with_creation():
104106
and not any(tag in torrent.tags for tag in self.config.settings.get("force_auto_tmm_ignore_tags", []))
105107
):
106108
torrent.set_auto_management(True)
109+
except Conflict409Error:
110+
# Conflict409Error with "Incorrect category name" means category doesn't exist
111+
ex = logger.print_line(
112+
f'Existing category "{new_cat}" not found for save path {torrent.save_path}, category will be created.',
113+
self.config.loglevel,
114+
)
115+
self.config.notify(ex, "Update Category", False)
116+
self.client.torrent_categories.create_category(name=new_cat, save_path=torrent.save_path)
117+
torrent.set_category(category=new_cat)
107118
except Exception as e:
108-
# Check if it's a category creation issue
109-
if "not found" in str(e).lower() or "409" in str(e):
119+
# Check if it's a category creation issue (fallback for other error types)
120+
if "not found" in str(e).lower():
110121
ex = logger.print_line(
111122
f'Existing category "{new_cat}" not found for save path '
112123
f"{torrent.save_path}, category will be created.",

0 commit comments

Comments
 (0)