diff --git a/.github/workflows/dependabot-approve-and-auto-merge.yml b/.github/workflows/dependabot-approve-and-auto-merge.yml index 8b7d597c..f989c8d0 100644 --- a/.github/workflows/dependabot-approve-and-auto-merge.yml +++ b/.github/workflows/dependabot-approve-and-auto-merge.yml @@ -32,7 +32,7 @@ jobs: # updates if all checks pass - name: Enable auto-merge for Dependabot PRs if: ${{ steps.dependabot-metadata.outputs.update-type != 'version-update:semver-major' }} - run: gh pr merge --auto --merge "$PR_URL" + run: gh pr merge --auto --squash "$PR_URL" env: PR_URL: ${{ github.event.pull_request.html_url }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/update-supported-versions.yml b/.github/workflows/update-supported-versions.yml index 25b95c9f..99318079 100644 --- a/.github/workflows/update-supported-versions.yml +++ b/.github/workflows/update-supported-versions.yml @@ -41,6 +41,7 @@ jobs: run: python scripts/update-readme-version.py ${{ github.event.inputs.targetBranch || github.ref_name }} - name: Create Pull Request + id: cpr uses: peter-evans/create-pull-request@v6 with: commit-message: Update SUPPORTED_VERSIONS.json @@ -48,3 +49,15 @@ jobs: branch: update-supported-versions-${{ github.event.inputs.targetBranch || github.ref_name }} base: develop body: "This PR updates the SUPPORTED_VERSIONS.json to reflect new versions." + + - name: Approve the Pull Request + if: ${{ steps.cpr.outputs.pull-request-number }} + run: gh pr review ${{ steps.cpr.outputs.pull-request-number }} --approve + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Merge the Pull Request + if: ${{ steps.cpr.outputs.pull-request-number }} + run: gh pr merge ${{ steps.cpr.outputs.pull-request-number }} --auto --squash + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/CHANGELOG b/CHANGELOG index 4df7fee5..cbf20739 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,15 +1,13 @@ # Requirements Updated -- requests==2.32.2 +- qbittorrent-api==2024.5.63 +- requests==2.32.3 +- schedule==1.2.2 # New Updates -- Customize tag names in share limits (Adds [#551](https://github.com/StuffAnThings/qbit_manage/issues/551)) -- Force category updates for all torrents (Adds [#483](https://github.com/StuffAnThings/qbit_manage/issues/483)) +- Add config option `cat_update_all` to categorize only uncategorized torrents (Closes [#575](https://github.com/StuffAnThings/qbit_manage/issues/575)) # Bug Fixes -- Fixes [#552](https://github.com/StuffAnThings/qbit_manage/issues/552) -- Fixes [#557](https://github.com/StuffAnThings/qbit_manage/issues/557) -- Fixes [#558](https://github.com/StuffAnThings/qbit_manage/issues/558) +- Fixes [#560](https://github.com/StuffAnThings/qbit_manage/issues/560) - -**Full Changelog**: https://github.com/StuffAnThings/qbit_manage/compare/v4.1.4...v4.1.5 +**Full Changelog**: https://github.com/StuffAnThings/qbit_manage/compare/v4.1.5...v4.1.6 diff --git a/README.md b/README.md index e958b84a..81da3f4f 100755 --- a/README.md +++ b/README.md @@ -26,6 +26,10 @@ This is a program used to manage your qBittorrent instance such as: ## Supported Qbittorrent Versions +We rely on [qbittorrent-api](https://pypi.org/project/qbittorrent-api/) to interact with Qbittorrent. + +Generally expect new releases of Qbittorrent to not immediately be supported. Support CANNOT be added until qbittorrent-api adds support gor the version. Any material changed and impact must then be assessed prior to Qbit Manage supporting it. + ### Master ![master - qBittorrent version](https://img.shields.io/badge/dynamic/json?label=master%20-%20qBittorrent&query=master.qbit&url=https%3A%2F%2Fraw.githubusercontent.com%2FStuffAnThings%2Fqbit_manage%2Fdevelop%2FSUPPORTED_VERSIONS.json&color=brightgreen) diff --git a/SUPPORTED_VERSIONS.json b/SUPPORTED_VERSIONS.json index a3648bd9..6dc59e4c 100644 --- a/SUPPORTED_VERSIONS.json +++ b/SUPPORTED_VERSIONS.json @@ -1,10 +1,10 @@ { "master": { - "qbit": "v4.6.4", - "qbitapi": "2024.3.60" + "qbit": "v4.6.5", + "qbitapi": "2024.5.63" }, "develop": { - "qbit": "v4.6.4", - "qbitapi": "2024.3.60" + "qbit": "v4.6.5", + "qbitapi": "2024.5.63" } } diff --git a/VERSION b/VERSION index b1cbc1fc..561ad334 100755 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.1.5 +4.1.6 diff --git a/config/config.yml.sample b/config/config.yml.sample index 3250dcfb..e99eeabb 100755 --- a/config/config.yml.sample +++ b/config/config.yml.sample @@ -36,6 +36,8 @@ settings: cat_filter_completed: True # Filters for completed torrents only when running cat_update command share_limits_filter_completed: True # Filters for completed torrents only when running share_limits command tag_nohardlinks_filter_completed: True # Filters for completed torrents only when running tag_nohardlinks command + cat_update_all: True # Checks and udpates all torrent categories if set to True when running cat_update command, otherwise only update torrents that are uncategorized + directory: # Do not remove these # Cross-seed var: # Output directory of cross-seed diff --git a/docs/Config-Setup.md b/docs/Config-Setup.md index 829689f9..8ee0c087 100644 --- a/docs/Config-Setup.md +++ b/docs/Config-Setup.md @@ -43,19 +43,20 @@ This section defines your qBittorrent instance. --- This section defines any settings defined in the configuration. -| Variable | Definition | Required | -| :-------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------- | -| `force_auto_tmm` | Will force qBittorrent to enable Automatic Torrent Management for each torrent. |
| -| `tracker_error_tag` | Define the tag of any torrents that do not have a working tracker. (Used in `--rem-unregistered` and `--tag-tracker-error`) |
| -| `nohardlinks_tag` | Define the tag of any torrents that don't have hardlinks (Used in `--tag-nohardlinks`) |
| -| `share_limits_tag` | Will add this tag when applying share limits to provide an easy way to filter torrents by share limit group/priority for each torrent. For example, if you have a share-limit group `cross-seed` with a priority of 2 and the default share_limits_tag `~share_limits` would add the tag `~share_limit_2.cross-seed` (Used in `--share-limits`) |
| -| `share_limits_min_seeding_time_tag` | Will add this tag when applying share limits to torrents that have not yet reached the minimum seeding time (Used in `--share-limits`) |
| -| `share_limits_min_num_seeds_tag` | Will add this tag when applying share limits to torrents that have not yet reached the minimum number of seeds (Used in `--share-limits`) |
| -| `share_limits_last_active_tag` | Will add this tag when applying share limits to torrents that have not yet reached the last active limit (Used in `--share-limits`) |
| -| `cross_seed_tag` | When running `--cross-seed` function, it will update any added cross-seed torrents with this tag. |
| -| `cat_filter_completed` | When running `--cat-update` function, it will filter for completed torrents only. |
| -| `share_limits_filter_completed` | When running `--share-limits` function, it will filter for completed torrents only. |
| -| `tag_nohardlinks_filter_completed` | When running `--tag-nohardlinks` function, , it will filter for completed torrents only. |
| +| Variable | Definition | Default Values | Required | +| :-------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------| :----------------- | :----------------- | +| `force_auto_tmm` | Will force qBittorrent to enable Automatic Torrent Management for each torrent. | False |
| +| `tracker_error_tag` | Define the tag of any torrents that do not have a working tracker. (Used in `--rem-unregistered` and `--tag-tracker-error`) | issue |
| +| `nohardlinks_tag` | Define the tag of any torrents that don't have hardlinks (Used in `--tag-nohardlinks`) | noHL |
| +| `share_limits_tag` | Will add this tag when applying share limits to provide an easy way to filter torrents by share limit group/priority for each torrent. For example, if you have a share-limit group `cross-seed` with a priority of 2 and the default share_limits_tag `~share_limits` would add the tag `~share_limit_2.cross-seed` (Used in `--share-limits`) | ~share_limit |
| +| `share_limits_min_seeding_time_tag` | Will add this tag when applying share limits to torrents that have not yet reached the minimum seeding time (Used in `--share-limits`) | MinSeedTimeNotReached |
| +| `share_limits_min_num_seeds_tag` | Will add this tag when applying share limits to torrents that have not yet reached the minimum number of seeds (Used in `--share-limits`) | MinSeedsNotMet |
| +| `share_limits_last_active_tag` | Will add this tag when applying share limits to torrents that have not yet reached the last active limit (Used in `--share-limits`) | LastActiveLimitNotReached |
| +| `cross_seed_tag` | When running `--cross-seed` function, it will update any added cross-seed torrents with this tag. | cross-seed |
| +| `cat_filter_completed` | When running `--cat-update` function, it will filter for completed torrents only. | True |
| +| `share_limits_filter_completed` | When running `--share-limits` function, it will filter for completed torrents only. | True |
| +| `tag_nohardlinks_filter_completed` | When running `--tag-nohardlinks` function, , it will filter for completed torrents only. | True |
| +| `cat_update_all` | When running `--cat-update` function, it will check and update all torrents categories, otherwise it will only update uncategorized torrents. | True |
| ## **directory:** --- @@ -74,7 +75,7 @@ This section defines the directories that qbit_manage will be looking into for v --- This section defines the categories that you are currently using and the path's that are associated with them.
-> **NOTE** ALL categories must be defined, if it is in your qBit, then it **MUST** be defined here, if not the script will throw errors. +> **NOTE** ALL categories must be defined, if it is in your qBit, then it **MUST** be defined here, if not the script will throw errors. If you want to leave a save_path as uncategorized you can use the key 'Uncategorized' as the name of the category. | Configuration | Definition | Required | | :------------ | :------------------------ | :----------------- | @@ -169,6 +170,7 @@ Control how torrent share limits are set depending on the priority of your group | `resume_torrent_after_change` | Will resume your torrent after changing share limits. | True | bool |
| | `add_group_to_tag` | This adds your grouping as a tag with a prefix defined in settings (share_limits_tag). Example: A grouping named noHL with a priority of 1 will have a tag set to `~share_limit_1.noHL` (if using the default prefix). | True | bool |
| | `min_num_seeds` | Will prevent torrent deletion by cleanup variable if the number of seeds is less than the value set here (depending on the tracker, you may or may not be included). If the torrent has less number of seeds than the min_num_seeds, the share limits will be changed back to no limits and resume the torrent to continue seeding. | 0 | int |
| +| `custom_tag` | Apply a custom tag name for this particular group. **WARNING (This tag MUST be unique as it will be used to determine share limits. Please ensure it does not overlap with any other tags in qBittorrent)** | None | str |
| ## **recyclebin:** --- diff --git a/modules/config.py b/modules/config.py index 1192b9a7..ad85a969 100755 --- a/modules/config.py +++ b/modules/config.py @@ -187,6 +187,9 @@ def hooks(attr): "tag_nohardlinks_filter_completed": self.util.check_for_attribute( self.data, "tag_nohardlinks_filter_completed", parent="settings", var_type="bool", default=True ), + "cat_update_all": self.util.check_for_attribute( + self.data, "cat_update_all", parent="settings", var_type="bool", default=True + ), } self.tracker_error_tag = self.settings["tracker_error_tag"] diff --git a/modules/core/category.py b/modules/core/category.py index b00e7acc..b3367849 100644 --- a/modules/core/category.py +++ b/modules/core/category.py @@ -15,20 +15,30 @@ def __init__(self, qbit_manager): self.notify_attr = [] # List of single torrent attributes to send to notifiarr self.uncategorized_mapping = "Uncategorized" self.status_filter = "completed" if self.config.settings["cat_filter_completed"] else "all" - + self.cat_update_all = self.config.settings["cat_update_all"] self.category() self.config.webhooks_factory.notify(self.torrents_updated, self.notify_attr, group_by="category") def category(self): """Update category for torrents that don't have any category defined and returns total number categories updated""" logger.separator("Updating Categories", space=False, border=False) - torrent_list = self.qbt.get_torrents({"status_filter": self.status_filter}) + torrent_list_filter = {"status_filter": self.status_filter} + if not self.cat_update_all: + torrent_list_filter["category"] = "" + torrent_list = self.qbt.get_torrents(torrent_list_filter) for torrent in torrent_list: torrent_category = torrent.category new_cat = [] new_cat.extend(self.get_tracker_cat(torrent) or self.qbt.get_category(torrent.save_path)) + if not torrent.auto_tmm and torrent_category: + logger.print_line( + f"{torrent.name} has Automatic Torrent Management disabled and already has a category" + f"{torrent_category}. Skipping..", + "DEBUG", + ) + continue if new_cat[0] == self.uncategorized_mapping: - logger.print_line(f"{torrent.name} remains uncategorized.", self.config.loglevel) + logger.print_line(f"{torrent.name} remains uncategorized.", "DEBUG") continue if torrent_category not in new_cat: self.update_cat(torrent, new_cat[0], False) @@ -46,7 +56,7 @@ def category(self): def get_tracker_cat(self, torrent): tracker = self.qbt.get_tags(self.qbt.get_tracker_urls(torrent.trackers)) - return tracker["cat"] + return [tracker["cat"]] if tracker["cat"] else None def update_cat(self, torrent, new_cat, cat_change): """Update category based on the torrent information""" diff --git a/requirements.txt b/requirements.txt index 5ca8890a..6ada11a8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ GitPython==3.1.43 humanize==4.9.0 pytimeparse2==1.7.1 qbittorrent-api==2024.5.63 -requests==2.32.2 +requests==2.32.3 retrying==1.3.4 ruamel.yaml==0.18.6 -schedule==1.2.1 +schedule==1.2.2