* 4.1.19-develop1

* [pre-commit.ci] pre-commit autoupdate (#750)

updates:
- [github.com/PyCQA/flake8: 7.1.1 → 7.1.2](https://github.com/PyCQA/flake8/compare/7.1.1...7.1.2)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* Update SUPPORTED_VERSIONS.json for master (#760)

* 4.1.18-develop1

* Bump flake8 from 7.1.1 to 7.1.2 (#748)

Bumps [flake8](https://github.com/pycqa/flake8) from 7.1.1 to 7.1.2.
- [Commits](https://github.com/pycqa/flake8/compare/7.1.1...7.1.2)

---
updated-dependencies:
- dependency-name: flake8
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump humanize from 4.11.0 to 4.12.0 (#749)

Bumps [humanize](https://github.com/python-humanize/humanize) from 4.11.0 to 4.12.0.
- [Release notes](https://github.com/python-humanize/humanize/releases)
- [Commits](https://github.com/python-humanize/humanize/compare/4.11.0...4.12.0)

---
updated-dependencies:
- dependency-name: humanize
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump humanize from 4.12.0 to 4.12.1 (#753)

Bumps [humanize](https://github.com/python-humanize/humanize) from 4.12.0 to 4.12.1.
- [Release notes](https://github.com/python-humanize/humanize/releases)
- [Commits](https://github.com/python-humanize/humanize/compare/4.12.0...4.12.1)

---
updated-dependencies:
- dependency-name: humanize
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump qbittorrent-api from 2024.12.71 to 2025.2.0 (#752)

* Update SUPPORTED_VERSIONS.json (#754)

* chore(docs): Sync wiki to docs [skip-cd]

* 4.1.18

* Update SUPPORTED_VERSIONS.json

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: bobokun <jon.cy.lee98@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Actionbot <actions@github.com>
Co-authored-by: bobokun <12660469+bobokun@users.noreply.github.com>

* Add "torrent deleted" and "torrent banned" as unregistered (#746)

* 4.1.18-develop1

* Update util.py

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: bobokun <jon.cy.lee98@gmail.com>
Co-authored-by: bobokun <12660469+bobokun@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* Adds additional comments for nexusPHP remove_registered

* Removes cross-seed deprecated function (Adds #758)

* Adds #757

* Fixes #755

* Adds #756

* Fixes #756

* chore(config): make config example more sample-like (#761)

users think the config is defaults not a sample

* show qbitorrent version info instead of debug

* 4.2.0

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Actionbot <actions@github.com>
Co-authored-by: Ninboy <ninboy@users.noreply.github.com>
Co-authored-by: bakerboy448 <55419169+bakerboy448@users.noreply.github.com>
This commit is contained in:
bobokun 2025-02-28 20:39:21 -05:00 committed by GitHub
parent 54cee3acd0
commit fc24d1d934
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 83 additions and 261 deletions

View file

@ -49,7 +49,7 @@ repos:
language_version: python3 language_version: python3
args: [--line-length, '130'] args: [--line-length, '130']
- repo: https://github.com/PyCQA/flake8 - repo: https://github.com/PyCQA/flake8
rev: 7.1.1 rev: 7.1.2
hooks: hooks:
- id: flake8 - id: flake8
args: [--config=.flake8] args: [--config=.flake8]

View file

@ -1,5 +1,9 @@
# Requirements Updated # New Updates
qbittorrent-api==2025.2.0 - Removes deprecated cross-seed command/function (#758)
humanize==4.12.1 - Adds ability to tag stalled downloads (#757)
- Adds ability to customize a list of status to ignore during rem_unregistered command (#756)
**Full Changelog**: https://github.com/StuffAnThings/qbit_manage/compare/v4.1.17...v4.1.18 # Bug Fixes
- Fixes bug in Windows during category updates (#755)
**Full Changelog**: https://github.com/StuffAnThings/qbit_manage/compare/v4.1.18...v4.2.0

View file

@ -15,7 +15,6 @@ This is a program used to manage your qBittorrent instance such as:
* Apply category based on `save_path` to uncategorized torrents in category's `save_path` * Apply category based on `save_path` to uncategorized torrents in category's `save_path`
* Change categories based on current category (`cat_change`) * Change categories based on current category (`cat_change`)
* Remove unregistered torrents (delete data & torrent if it is not being cross-seeded, otherwise it will just remove the torrent) * Remove unregistered torrents (delete data & torrent if it is not being cross-seeded, otherwise it will just remove the torrent)
* Automatically add [cross-seed](https://github.com/cross-seed/cross-seed) torrents in paused state. **\*Note: cross-seed now allows for torrent injections directly to qBit, making this feature rarely needed/used.\***
* Recheck paused torrents sorted by lowest size and resume if completed * Recheck paused torrents sorted by lowest size and resume if completed
* Remove orphaned files from your root directory that are not referenced by qBittorrent * Remove orphaned files from your root directory that are not referenced by qBittorrent
* Tag any torrents that have no hard links outside the root folder (for multi-file torrents the largest file is used) * Tag any torrents that have no hard links outside the root folder (for multi-file torrents the largest file is used)

View file

@ -1,7 +1,7 @@
{ {
"master": { "master": {
"qbit": "v5.0.3", "qbit": "v5.0.4",
"qbitapi": "2024.12.71" "qbitapi": "2025.2.0"
}, },
"develop": { "develop": {
"qbit": "v5.0.4", "qbit": "v5.0.4",

View file

@ -1 +1 @@
4.1.18 4.2.0

View file

@ -1,12 +1,12 @@
# This is an example configuration file that documents all the options. # This is an example configuration file that documents all the options.
# It will need to be modified for your specific use case. # It will need to be modified for your specific use case.
# These are not default values. You MUST review the config settings and properly configure this EXAMPLE file.
# Please refer to the link below for more details on how to set up the configuration file # Please refer to the link below for more details on how to set up the configuration file
# https://github.com/StuffAnThings/qbit_manage/wiki/Config-Setup # https://github.com/StuffAnThings/qbit_manage/wiki/Config-Setup
commands: commands:
# The commands defined below will IGNORE any commands used in command line and docker env variables. # The commands defined below will IGNORE any commands used in command line and docker env variables.
dry_run: True dry_run: True
cross_seed: False
recheck: False recheck: False
cat_update: False cat_update: False
tag_update: False tag_update: False
@ -36,16 +36,18 @@ settings:
share_limits_min_seeding_time_tag: MinSeedTimeNotReached # Tag to be added to torrents that have not yet reached the minimum seeding time share_limits_min_seeding_time_tag: MinSeedTimeNotReached # Tag to be added to torrents that have not yet reached the minimum seeding time
share_limits_min_num_seeds_tag: MinSeedsNotMet # Tag to be added to torrents that have not yet reached the minimum number of seeds share_limits_min_num_seeds_tag: MinSeedsNotMet # Tag to be added to torrents that have not yet reached the minimum number of seeds
share_limits_last_active_tag: LastActiveLimitNotReached # Tag to be added to torrents that have not yet reached the last active limit share_limits_last_active_tag: LastActiveLimitNotReached # Tag to be added to torrents that have not yet reached the last active limit
cross_seed_tag: cross-seed # Will set the tag of any torrents that are added by cross-seed command
cat_filter_completed: True # Filters for completed torrents only when running cat_update command 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 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 tag_nohardlinks_filter_completed: True # Filters for completed torrents only when running tag_nohardlinks command
cat_update_all: True # Checks and updates all torrent categories if set to True when running cat_update command, otherwise only update torrents that are uncategorized cat_update_all: True # Checks and updates all torrent categories if set to True when running cat_update command, otherwise only update torrents that are uncategorized
disable_qbt_default_share_limits: True # Allows QBM to handle share limits by disabling qBittorrents default Share limits. Only active when the share_limits command is set to True disable_qbt_default_share_limits: True # Allows QBM to handle share limits by disabling qBittorrents default Share limits. Only active when the share_limits command is set to True
tag_stalled_torrents: True # Tags any downloading torrents that are stalled with the `stalledDL` tag when running the tag_update command
rem_unregistered_ignore_list: # Ignores a list of words found in the status of the tracker when running rem_unregistered command and will not remove the torrent if matched
- example placeholder words
- ignore if found
directory: directory:
# Do not remove these # Do not remove these
# Cross-seed var: </your/path/here/> # Output directory of cross-seed
# root_dir var: </your/path/here/> # Root downloads directory used to check for orphaned files, noHL, and RecycleBin. # root_dir var: </your/path/here/> # Root downloads directory used to check for orphaned files, noHL, and RecycleBin.
# <OPTIONAL> remote_dir var: </your/path/here/> # Path of docker host mapping of root_dir. # <OPTIONAL> remote_dir var: </your/path/here/> # Path of docker host mapping of root_dir.
# remote_dir must be set if you're running qbit_manage locally and qBittorrent/cross_seed is in a docker # remote_dir must be set if you're running qbit_manage locally and qBittorrent/cross_seed is in a docker
@ -53,12 +55,11 @@ directory:
# <OPTIONAL> recycle_bin var: </your/path/here/> # Path of the RecycleBin folder. Default location is set to remote_dir/.RecycleBin # <OPTIONAL> recycle_bin var: </your/path/here/> # Path of the RecycleBin folder. Default location is set to remote_dir/.RecycleBin
# <OPTIONAL> torrents_dir var: </your/path/here/> # Path of the your qbittorrent torrents directory. Required for `save_torrents` attribute in recyclebin # <OPTIONAL> torrents_dir var: </your/path/here/> # Path of the your qbittorrent torrents directory. Required for `save_torrents` attribute in recyclebin
# <OPTIONAL> orphaned_dir var: </your/path/here/> # Path of the the Orphaned Data folder. This is similar to RecycleBin, but only for orphaned data. # <OPTIONAL> orphaned_dir var: </your/path/here/> # Path of the the Orphaned Data folder. This is similar to RecycleBin, but only for orphaned data.
cross_seed: "/your/path/here/" root_dir: "/path/to/torrents/"
root_dir: "/data/torrents/" remote_dir: "/host/path/to/torrents/ifdocker/torrents/"
remote_dir: "/mnt/user/data/torrents/" recycle_bin: "/path/to/.RecycleBin"
recycle_bin: "/mnt/user/data/torrents/.RecycleBin" torrents_dir: "/path/to/qbitAppData/BT_backup"
torrents_dir: "/qbittorrent/data/BT_backup" orphaned_dir: "/path/to/orphaned_data"
orphaned_dir: "/data/torrents/orphaned_data"
cat: cat:
# Category & Path Parameters # Category & Path Parameters
@ -66,17 +67,15 @@ cat:
# If you want to leave a save_path as uncategorized you can use the key 'Uncategorized' as the name of the category. # If you want to leave a save_path as uncategorized you can use the key 'Uncategorized' as the name of the category.
# You can use Unix filename pattern matching as well when specifying the save_path # You can use Unix filename pattern matching as well when specifying the save_path
# <Category Name> : <save_path> # Path of your save directory. # <Category Name> : <save_path> # Path of your save directory.
movies: "/data/torrents/Movies" somecategory: "/path/to/torrents/somecategory"
tv: "/data/torrents/TV" anothercategory: "/path/to/torrents/anothercategory"
cat_change: cat_change:
# This moves all the torrents from one category to another category. This executes on --cat-update # This moves all the torrents from one category to another category. This executes on --cat-update
# WARNING: if the paths are different and Default Torrent Management Mode is set to automatic the files could be moved !!! # WARNING: if the paths are different and Default Torrent Management Mode is set to automatic the files could be moved !!!
# <Old Category Name> : <New Category> # <Old Category Name> : <New Category>
Radarr-HD.cross-seed: movies-hd CatA.cross-seed: CatA
Radarr-UHD.cross-seed: movies-uhd CatB.cross-seed: CatB
movies-hd.cross-seed: movies-hd
movies-uhd.cross-seed: movies-uhd
tracker: tracker:
# Mandatory # Mandatory
@ -311,7 +310,6 @@ webhooks:
run_start: notifiarr run_start: notifiarr
run_end: apprise run_end: apprise
function: function:
cross_seed: https://mywebhookurl.com/qbt_manage
recheck: notifiarr recheck: notifiarr
cat_update: apprise cat_update: apprise
tag_update: notifiarr tag_update: notifiarr

View file

@ -7,7 +7,6 @@
| `-sd` or `--startup-delay` | QBT_STARTUP_DELAY | N/A | Set delay in seconds on the first run of a schedule (Default set to 0) | 0 | | `-sd` or `--startup-delay` | QBT_STARTUP_DELAY | N/A | Set delay in seconds on the first run of a schedule (Default set to 0) | 0 |
| `-c CONFIG` or `--config-file CONFIG` | QBT_CONFIG | N/A | This is used if you want to use a different name for your config.yml. `Example: tv.yml` | config.yml | | `-c CONFIG` or `--config-file CONFIG` | QBT_CONFIG | N/A | This is used if you want to use a different name for your config.yml. `Example: tv.yml` | config.yml |
| `-lf LOGFILE,` or `--log-file LOGFILE,` | QBT_LOGFILE | N/A | This is used if you want to use a different name for your log file. `Example: tv.log` | activity.log | | `-lf LOGFILE,` or `--log-file LOGFILE,` | QBT_LOGFILE | N/A | This is used if you want to use a different name for your log file. `Example: tv.log` | activity.log |
| `-cs` or `--cross-seed` | QBT_CROSS_SEED | cross_seed | Use this after running [cross-seed script](https://github.com/mmgoodnow/cross-seed) to add torrents from the cross-seed output folder to qBittorrent | False |
| `-re` or `--recheck` | QBT_RECHECK | recheck | Recheck paused torrents sorted by lowest size. Resume if Completed. | False | | `-re` or `--recheck` | QBT_RECHECK | recheck | Recheck paused torrents sorted by lowest size. Resume if Completed. | False |
| `-cu` or `--cat-update` | QBT_CAT_UPDATE | cat_update | Use this if you would like to update your categories or move from one category to another. | False | | `-cu` or `--cat-update` | QBT_CAT_UPDATE | cat_update | Use this if you would like to update your categories or move from one category to another. | False |
| `-tu` or `--tag-update` | QBT_TAG_UPDATE | tag_update | Use this if you would like to update your tags and/or set seed goals/limit upload speed by tag. (Only adds tags to untagged torrents) | False | | `-tu` or `--tag-update` | QBT_TAG_UPDATE | tag_update | Use this if you would like to update your tags and/or set seed goals/limit upload speed by tag. (Only adds tags to untagged torrents) | False |

View file

@ -52,12 +52,13 @@ This section defines any settings defined in the configuration.
| `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 | <center></center> | | `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 | <center></center> |
| `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 | <center></center> | | `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 | <center></center> |
| `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 | <center></center> | | `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 | <center></center> |
| `cross_seed_tag` | When running `--cross-seed` function, it will update any added cross-seed torrents with this tag. | cross-seed | <center></center> |
| `cat_filter_completed` | When running `--cat-update` function, it will filter for completed torrents only. | True | <center></center> | | `cat_filter_completed` | When running `--cat-update` function, it will filter for completed torrents only. | True | <center></center> |
| `share_limits_filter_completed` | When running `--share-limits` function, it will filter for completed torrents only. | True | <center></center> | | `share_limits_filter_completed` | When running `--share-limits` function, it will filter for completed torrents only. | True | <center></center> |
| `tag_nohardlinks_filter_completed` | When running `--tag-nohardlinks` function, , it will filter for completed torrents only. | True | <center></center> | | `tag_nohardlinks_filter_completed` | When running `--tag-nohardlinks` function, , it will filter for completed torrents only. | True | <center></center> |
| `cat_update_all` | When running `--cat-update` function, it will check and update all torrents categories, otherwise it will only update uncategorized torrents. | True | <center></center> | | `cat_update_all` | When running `--cat-update` function, it will check and update all torrents categories, otherwise it will only update uncategorized torrents. | True | <center></center> |
| `disable_qbt_default_share_limits` | When running `--share-limits` function, it allows QBM to handle share limits by disabling qBittorrents default Share limits. | True | <center></center> | | `disable_qbt_default_share_limits` | When running `--share-limits` function, it allows QBM to handle share limits by disabling qBittorrents default Share limits. | True | <center></center> |
| `tag_stalled_torrents` | Tags any downloading torrents that are stalled with the `stalledDL` tag when running the tag_update command | True | <center></center> |
| `rem_unregistered_ignore_list` | Ignores a list of words found in the status of the tracker when running rem_unregistered command and will not remove the torrent if matched | | <center></center> |
## **directory:** ## **directory:**
@ -66,7 +67,6 @@ This section defines the directories that qbit_manage will be looking into for v
| Variable | Definition | Required | | Variable | Definition | Required |
| :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------ | | :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------ |
| `cross_seed` | Output directory of cross-seed, originally the application [cross-seed](https://github.com/mmgoodnow/cross-seed) was incapable of injecting cross-seed torrent into qB, this was built to inject them for the application. This is no longer required if you're using injects with that software. However, you can find other uses for this as it is more of a watch directory now. | QBT_CROSS_SEED |
| `root_dir` | Root downloads directory used to check for orphaned files, noHL, and remove unregistered. This directory is where you place all your downloads. This will need to be how qB views the directory where it places the downloads. This is required if you're using qbit_managee and/or qBittorrent within a container. | QBT_REM_ORPHANED / QBT_TAG_NOHARDLINKS / QBT_REM_UNREGISTERED | | `root_dir` | Root downloads directory used to check for orphaned files, noHL, and remove unregistered. This directory is where you place all your downloads. This will need to be how qB views the directory where it places the downloads. This is required if you're using qbit_managee and/or qBittorrent within a container. | QBT_REM_ORPHANED / QBT_TAG_NOHARDLINKS / QBT_REM_UNREGISTERED |
| `remote_dir` | Path of docker host mapping of root_dir, this must be set if you're running qbit_manage locally (not required if running qbit_manage in a container) and qBittorrent/cross_seed is in a docker. Essentially this is where your downloads are being kept on the host. | <center></center> | | `remote_dir` | Path of docker host mapping of root_dir, this must be set if you're running qbit_manage locally (not required if running qbit_manage in a container) and qBittorrent/cross_seed is in a docker. Essentially this is where your downloads are being kept on the host. | <center></center> |
| `recycle_bin` | Path of the RecycleBin folder. Default location is set to `remote_dir/.RecycleBin`. All files in this folder will be cleaned up based on your recycle bin settings. | <center></center> | | `recycle_bin` | Path of the RecycleBin folder. Default location is set to `remote_dir/.RecycleBin`. All files in this folder will be cleaned up based on your recycle bin settings. | <center></center> |
@ -237,7 +237,6 @@ Provide webhook notifications based on event triggers
| [error](#error-notifications) | When errors occur during the run | N/A | <center></center> | | [error](#error-notifications) | When errors occur during the run | N/A | <center></center> |
| [run_start](#run-start-notifications) | At the beginning of every run | N/A | <center></center> | | [run_start](#run-start-notifications) | At the beginning of every run | N/A | <center></center> |
| [run_end](#run-end-notifications) | At the end of every run | N/A | <center></center> | | [run_end](#run-end-notifications) | At the end of every run | N/A | <center></center> |
| [cross_seed](#cross-seed-notifications) | During the cross-seed function | N/A | <center></center> |
| [recheck](#recheck-notifications) | During the recheck function | N/A | <center></center> | | [recheck](#recheck-notifications) | During the recheck function | N/A | <center></center> |
| [cat_update](#category-update-notifications) | During the category update function | N/A | <center></center> | | [cat_update](#category-update-notifications) | During the category update function | N/A | <center></center> |
| [tag_update](#tag-update-notifications) | During the tag update function | N/A | <center></center> | | [tag_update](#tag-update-notifications) | During the tag update function | N/A | <center></center> |
@ -309,36 +308,6 @@ Payload will be sent at the end of the run
} }
``` ```
### **Cross-Seed Notifications**
Payload will be sent when adding a cross-seed torrent to qBittorrent if the original torrent is complete
```yaml
{
"function": "cross_seed", // Webhook Trigger keyword
"title": str, // Title of the Payload
"body": str, // Message of the Payload
"torrents": [str], // List of Torrent Names
"torrent_category": str, // Torrent Category
"torrent_save_path": str, // Torrent Download directory
"torrent_tag": "cross-seed", // Total Torrents Added
"torrent_tracker": str // Torrent Tracker
}
```
Payload will be sent when there are existing torrents found that are missing the cross-seed tag
```yaml
{
"function": "tag_cross_seed", // Webhook Trigger keyword
"title": str, // Title of the Payload
"body": str, // Message of the Payload
"torrents": [str], // List of Torrent Names
"torrent_category": str, // Torrent Category
"torrent_tag": "cross-seed", // Tag Added
"torrent_tracker": str // Torrent Tracker
}
```
### **Recheck Notifications** ### **Recheck Notifications**

View file

@ -38,7 +38,6 @@ services:
- QBT_SCHEDULE=1440 - QBT_SCHEDULE=1440
- QBT_CONFIG=/config/config.yml - QBT_CONFIG=/config/config.yml
- QBT_LOGFILE=activity.log - QBT_LOGFILE=activity.log
- QBT_CROSS_SEED=false
- QBT_RECHECK=false - QBT_RECHECK=false
- QBT_CAT_UPDATE=false - QBT_CAT_UPDATE=false
- QBT_TAG_UPDATE=false - QBT_TAG_UPDATE=false

View file

@ -22,7 +22,6 @@ from modules.webhooks import Webhooks
logger = util.logger logger = util.logger
COMMANDS = [ COMMANDS = [
"cross_seed",
"recheck", "recheck",
"cat_update", "cat_update",
"tag_update", "tag_update",
@ -91,7 +90,6 @@ class Config:
logger.debug(f" --debug (QBT_DEBUG): {args['debug']}") logger.debug(f" --debug (QBT_DEBUG): {args['debug']}")
logger.debug(f" --trace (QBT_TRACE): {args['trace']}") logger.debug(f" --trace (QBT_TRACE): {args['trace']}")
logger.separator("CONFIG OVERRIDE RUN COMMDANDS", space=False, border=False, loglevel="DEBUG") logger.separator("CONFIG OVERRIDE RUN COMMDANDS", space=False, border=False, loglevel="DEBUG")
logger.debug(f" --cross-seed (QBT_CROSS_SEED): {self.commands['cross_seed']}")
logger.debug(f" --recheck (QBT_RECHECK): {self.commands['recheck']}") logger.debug(f" --recheck (QBT_RECHECK): {self.commands['recheck']}")
logger.debug(f" --cat-update (QBT_CAT_UPDATE): {self.commands['cat_update']}") logger.debug(f" --cat-update (QBT_CAT_UPDATE): {self.commands['cat_update']}")
logger.debug(f" --tag-update (QBT_TAG_UPDATE): {self.commands['tag_update']}") logger.debug(f" --tag-update (QBT_TAG_UPDATE): {self.commands['tag_update']}")
@ -119,7 +117,6 @@ class Config:
logger.debug(f" --debug (QBT_DEBUG): {args['debug']}") logger.debug(f" --debug (QBT_DEBUG): {args['debug']}")
logger.debug(f" --trace (QBT_TRACE): {args['trace']}") logger.debug(f" --trace (QBT_TRACE): {args['trace']}")
logger.separator("DOCKER ENV RUN COMMANDS", space=False, border=False, loglevel="DEBUG") logger.separator("DOCKER ENV RUN COMMANDS", space=False, border=False, loglevel="DEBUG")
logger.debug(f" --cross-seed (QBT_CROSS_SEED): {args['cross_seed']}")
logger.debug(f" --recheck (QBT_RECHECK): {args['recheck']}") logger.debug(f" --recheck (QBT_RECHECK): {args['recheck']}")
logger.debug(f" --cat-update (QBT_CAT_UPDATE): {args['cat_update']}") logger.debug(f" --cat-update (QBT_CAT_UPDATE): {args['cat_update']}")
logger.debug(f" --tag-update (QBT_TAG_UPDATE): {args['tag_update']}") logger.debug(f" --tag-update (QBT_TAG_UPDATE): {args['tag_update']}")
@ -175,7 +172,6 @@ class Config:
temp["function"][attr] = {} temp["function"][attr] = {}
temp["function"][attr] = None temp["function"][attr] = None
hooks("cross_seed")
hooks("recheck") hooks("recheck")
hooks("cat_update") hooks("cat_update")
hooks("tag_update") hooks("tag_update")
@ -218,7 +214,6 @@ class Config:
"share_limits_last_active_tag": self.util.check_for_attribute( "share_limits_last_active_tag": self.util.check_for_attribute(
self.data, "share_limits_last_active_tag", parent="settings", default="LastActiveLimitNotReached" self.data, "share_limits_last_active_tag", parent="settings", default="LastActiveLimitNotReached"
), ),
"cross_seed_tag": self.util.check_for_attribute(self.data, "cross_seed_tag", parent="settings", default="cross-seed"),
"cat_filter_completed": self.util.check_for_attribute( "cat_filter_completed": self.util.check_for_attribute(
self.data, "cat_filter_completed", parent="settings", var_type="bool", default=True self.data, "cat_filter_completed", parent="settings", var_type="bool", default=True
), ),
@ -237,6 +232,12 @@ class Config:
"disable_qbt_default_share_limits": self.util.check_for_attribute( "disable_qbt_default_share_limits": self.util.check_for_attribute(
self.data, "disable_qbt_default_share_limits", parent="settings", var_type="bool", default=True self.data, "disable_qbt_default_share_limits", parent="settings", var_type="bool", default=True
), ),
"tag_stalled_torrents": self.util.check_for_attribute(
self.data, "tag_stalled_torrents", parent="settings", var_type="bool", default=True
),
"rem_unregistered_ignore_list": self.util.check_for_attribute(
self.data, "rem_unregistered_ignore_list", parent="settings", var_type="upper_list", default=[]
),
} }
self.tracker_error_tag = self.settings["tracker_error_tag"] self.tracker_error_tag = self.settings["tracker_error_tag"]
@ -246,12 +247,10 @@ class Config:
self.share_limits_min_seeding_time_tag = self.settings["share_limits_min_seeding_time_tag"] self.share_limits_min_seeding_time_tag = self.settings["share_limits_min_seeding_time_tag"]
self.share_limits_min_num_seeds_tag = self.settings["share_limits_min_num_seeds_tag"] self.share_limits_min_num_seeds_tag = self.settings["share_limits_min_num_seeds_tag"]
self.share_limits_last_active_tag = self.settings["share_limits_last_active_tag"] self.share_limits_last_active_tag = self.settings["share_limits_last_active_tag"]
self.cross_seed_tag = self.settings["cross_seed_tag"]
self.default_ignore_tags = [ self.default_ignore_tags = [
self.nohardlinks_tag, self.nohardlinks_tag,
self.tracker_error_tag, self.tracker_error_tag,
self.cross_seed_tag,
self.share_limits_min_seeding_time_tag, self.share_limits_min_seeding_time_tag,
self.share_limits_min_num_seeds_tag, self.share_limits_min_num_seeds_tag,
self.share_limits_last_active_tag, self.share_limits_last_active_tag,
@ -262,7 +261,6 @@ class Config:
self.util.overwrite_attributes(self.settings, "settings") self.util.overwrite_attributes(self.settings, "settings")
default_function = { default_function = {
"cross_seed": None,
"recheck": None, "recheck": None,
"cat_update": None, "cat_update": None,
"tag_update": None, "tag_update": None,
@ -662,7 +660,7 @@ class Config:
), ),
"", "",
) )
if self.commands["cross_seed"] or self.commands["tag_nohardlinks"] or self.commands["rem_orphaned"]: if self.commands["tag_nohardlinks"] or self.commands["rem_orphaned"]:
self.remote_dir = self.util.check_for_attribute( self.remote_dir = self.util.check_for_attribute(
self.data, self.data,
"remote_dir", "remote_dir",
@ -685,12 +683,6 @@ class Config:
) )
if not self.remote_dir: if not self.remote_dir:
self.remote_dir = self.root_dir self.remote_dir = self.root_dir
if self.commands["cross_seed"]:
self.cross_seed_dir = self.util.check_for_attribute(self.data, "cross_seed", parent="directory", var_type="path")
else:
self.cross_seed_dir = self.util.check_for_attribute(
self.data, "cross_seed", parent="directory", default_is_none=True
)
if self.commands["rem_orphaned"]: if self.commands["rem_orphaned"]:
if "orphaned_dir" in self.data["directory"] and self.data["directory"]["orphaned_dir"] is not None: if "orphaned_dir" in self.data["directory"] and self.data["directory"]["orphaned_dir"] is not None:
default_orphaned = os.path.join( default_orphaned = os.path.join(

View file

@ -1,157 +0,0 @@
import os
from collections import Counter
from modules import util
from modules.torrent_hash_generator import TorrentHashGenerator
logger = util.logger
class CrossSeed:
def __init__(self, qbit_manager):
self.qbt = qbit_manager
self.config = qbit_manager.config
self.client = qbit_manager.client
self.stats_added = 0
self.stats_tagged = 0
self.cross_seed_tag = qbit_manager.config.cross_seed_tag
self.torrents_updated = [] # List of torrents added by cross-seed
self.notify_attr = [] # List of single torrent attributes to send to notifiarr
self.cross_seed()
def cross_seed(self):
"""Move torrents from cross seed directory to correct save directory."""
logger.separator("Checking for Cross-Seed Torrents", space=False, border=False)
# List of categories for all torrents moved
categories = []
# Only get torrent files
cs_files = [f for f in os.listdir(self.config.cross_seed_dir) if f.endswith("torrent")]
dir_cs = self.config.cross_seed_dir
dir_cs_out = os.path.join(dir_cs, "qbit_manage_added")
os.makedirs(dir_cs_out, exist_ok=True)
dir_cs_err = os.path.join(dir_cs, "qbit_manage_error")
os.makedirs(dir_cs_err, exist_ok=True)
for file in cs_files:
tr_name = file.split("]", 2)[2].split(".torrent")[0]
t_tracker = file.split("]", 2)[1][1:]
# Substring Key match in dictionary (used because t_name might not match exactly with self.qbt.torrentinfo key)
# Returned the dictionary of filtered item
torrentdict_file = dict(filter(lambda item: tr_name in item[0], self.qbt.torrentinfo.items()))
src = os.path.join(dir_cs, file)
file_cs_out = os.path.join(dir_cs_out, file)
file_cs_err = os.path.join(dir_cs_err, file)
if torrentdict_file:
# Get the exact torrent match name from self.qbt.torrentinfo
t_name = next(iter(torrentdict_file))
dest = os.path.join(self.qbt.torrentinfo[t_name]["save_path"], "")
category = self.qbt.torrentinfo[t_name].get("Category", self.qbt.get_category(dest)[0])
# Only add cross-seed torrent if original torrent is complete
if self.qbt.torrentinfo[t_name]["is_complete"]:
categories.append(category)
body = []
body += logger.print_line(
f"{'Not Adding' if self.config.dry_run else 'Adding'} to qBittorrent:", self.config.loglevel
)
body += logger.print_line(logger.insert_space(f"Torrent Name: {t_name}", 3), self.config.loglevel)
body += logger.print_line(logger.insert_space(f"Category: {category}", 7), self.config.loglevel)
body += logger.print_line(logger.insert_space(f"Save_Path: {dest}", 6), self.config.loglevel)
body += logger.print_line(logger.insert_space(f"Tracker: {t_tracker}", 8), self.config.loglevel)
attr = {
"function": "cross_seed",
"title": "Adding New Cross-Seed Torrent",
"body": "\n".join(body),
"torrents": [t_name],
"torrent_category": category,
"torrent_save_path": dest,
"torrent_tag": self.cross_seed_tag,
"torrent_tracker": t_tracker,
}
self.notify_attr.append(attr)
self.torrents_updated.append(t_name)
self.stats_added += 1
if not self.config.dry_run:
self.client.torrents.add(
torrent_files=src, save_path=dest, category=category, tags=self.cross_seed_tag, is_paused=True
)
try:
torrent_hash_generator = TorrentHashGenerator(src)
torrent_hash = torrent_hash_generator.generate_torrent_hash()
util.move_files(src, file_cs_out)
except Exception as e:
logger.warning(f"Unable to generate torrent hash from cross-seed {t_name}: {e}")
try:
if torrent_hash:
torrent_info = self.qbt.get_torrents({"torrent_hashes": torrent_hash})
except Exception as e:
logger.warning(f"Unable to find hash {torrent_hash} in qbt: {e}")
if torrent_info:
torrent = torrent_info[0]
self.qbt.add_torrent_files(torrent.hash, torrent.files, torrent.save_path)
self.qbt.torrentvalid.append(torrent)
self.qbt.torrentinfo[t_name]["torrents"].append(torrent)
self.qbt.torrent_list.append(torrent)
else:
logger.print_line(f"Found {t_name} in {dir_cs} but original torrent is not complete.", self.config.loglevel)
logger.print_line("Not adding to qBittorrent", self.config.loglevel)
else:
error = f"{tr_name} not found in torrents. Cross-seed Torrent not added to qBittorrent."
if self.config.dry_run:
logger.print_line(error, self.config.loglevel)
else:
logger.print_line(error, "WARNING")
util.move_files(src, file_cs_err)
self.config.notify(error, "cross-seed", False)
self.config.webhooks_factory.notify(self.torrents_updated, self.notify_attr, group_by="category")
self.torrents_updated = []
self.notify_attr = []
# Tag missing cross-seed torrents tags
for torrent in self.qbt.torrent_list:
t_name = torrent.name
t_cat = torrent.category
if (
not util.is_tag_in_torrent(self.cross_seed_tag, torrent.tags)
and self.qbt.is_cross_seed(torrent)
and torrent.downloaded == 0
and torrent.seeding_time > 0
):
tracker = self.qbt.get_tags(self.qbt.get_tracker_urls(torrent.trackers))
self.stats_tagged += 1
body = logger.print_line(
f"{'Not Adding' if self.config.dry_run else 'Adding'} '{self.cross_seed_tag}' tag to {t_name}",
self.config.loglevel,
)
attr = {
"function": "tag_cross_seed",
"title": "Tagging Cross-Seed Torrent",
"body": body,
"torrents": [t_name],
"torrent_category": t_cat,
"torrent_tag": self.cross_seed_tag,
"torrent_tracker": tracker["url"],
}
self.notify_attr.append(attr)
self.torrents_updated.append(t_name)
if not self.config.dry_run:
torrent.add_tags(tags=self.cross_seed_tag)
self.config.webhooks_factory.notify(self.torrents_updated, self.notify_attr, group_by="category")
numcategory = Counter(categories)
for cat in numcategory:
if numcategory[cat] > 0:
logger.print_line(
f"{numcategory[cat]} {cat} cross-seed .torrents {'not added' if self.config.dry_run else 'added'}.",
self.config.loglevel,
)
if self.stats_added > 0:
logger.print_line(
f"Total {self.stats_added} cross-seed .torrents {'not added' if self.config.dry_run else 'added'}.",
self.config.loglevel,
)
if self.stats_tagged > 0:
logger.print_line(
f"Total {self.stats_tagged} cross-seed .torrents {'not added' if self.config.dry_run else 'added'}.",
self.config.loglevel,
)

View file

@ -21,6 +21,7 @@ class RemoveUnregistered:
self.tag_error = self.config.tracker_error_tag self.tag_error = self.config.tracker_error_tag
self.cfg_rem_unregistered = self.config.commands["rem_unregistered"] self.cfg_rem_unregistered = self.config.commands["rem_unregistered"]
self.cfg_tag_error = self.config.commands["tag_tracker_error"] self.cfg_tag_error = self.config.commands["tag_tracker_error"]
self.rem_unregistered_ignore_list = self.config.settings["rem_unregistered_ignore_list"]
tag_error_msg = "Tagging Torrents with Tracker Errors" if self.cfg_tag_error else "" tag_error_msg = "Tagging Torrents with Tracker Errors" if self.cfg_tag_error else ""
rem_unregistered_msg = "Removing Unregistered Torrents" if self.cfg_rem_unregistered else "" rem_unregistered_msg = "Removing Unregistered Torrents" if self.cfg_rem_unregistered else ""
@ -125,7 +126,13 @@ class RemoveUnregistered:
if list_in_text(msg_up, TorrentMessages.UNREGISTERED_MSGS) and not list_in_text( if list_in_text(msg_up, TorrentMessages.UNREGISTERED_MSGS) and not list_in_text(
msg_up, TorrentMessages.IGNORE_MSGS msg_up, TorrentMessages.IGNORE_MSGS
): ):
self.del_unregistered(msg, tracker, torrent) if list_in_text(msg_up, self.rem_unregistered_ignore_list):
logger.print_line(
f"Ignoring unregistered torrent {self.t_name} due to matching phrase found in ignore list.",
self.config.loglevel,
)
else:
self.del_unregistered(msg, tracker, torrent)
else: else:
if self.check_for_unregistered_torrents_in_bhd(tracker, msg_up, torrent.hash): if self.check_for_unregistered_torrents_in_bhd(tracker, msg_up, torrent.hash):
self.del_unregistered(msg, tracker, torrent) self.del_unregistered(msg, tracker, torrent)

View file

@ -12,6 +12,7 @@ class Tags:
self.share_limits_tag = qbit_manager.config.share_limits_tag # suffix tag for share limits self.share_limits_tag = qbit_manager.config.share_limits_tag # suffix tag for share limits
self.torrents_updated = [] # List of torrents updated self.torrents_updated = [] # List of torrents updated
self.notify_attr = [] # List of single torrent attributes to send to notifiarr self.notify_attr = [] # List of single torrent attributes to send to notifiarr
self.stalled_tag = "stalledDL"
self.tags() self.tags()
self.config.webhooks_factory.notify(self.torrents_updated, self.notify_attr, group_by="tag") self.config.webhooks_factory.notify(self.torrents_updated, self.notify_attr, group_by="tag")
@ -21,8 +22,26 @@ class Tags:
logger.separator("Updating Tags", space=False, border=False) logger.separator("Updating Tags", space=False, border=False)
for torrent in self.qbt.torrent_list: for torrent in self.qbt.torrent_list:
tracker = self.qbt.get_tags(self.qbt.get_tracker_urls(torrent.trackers)) tracker = self.qbt.get_tags(self.qbt.get_tracker_urls(torrent.trackers))
if torrent.tags == "" or not util.is_tag_in_torrent(tracker["tag"], torrent.tags):
if tracker["tag"]: # Remove stalled_tag if torrent is no longer stalled
if util.is_tag_in_torrent(self.stalled_tag, torrent.tags) and torrent.state != "stalledDL":
t_name = torrent.name
body = []
body += logger.print_line(logger.insert_space(f"Torrent Name: {t_name}", 3), self.config.loglevel)
body += logger.print_line(logger.insert_space(f"Removing Tag: {self.stalled_tag}", 3), self.config.loglevel)
body += logger.print_line(logger.insert_space(f'Tracker: {tracker["url"]}', 8), self.config.loglevel)
if not self.config.dry_run:
torrent.remove_tags(self.stalled_tag)
if (
torrent.tags == ""
or not util.is_tag_in_torrent(tracker["tag"], torrent.tags)
or (torrent.state == "stalledDL" and not util.is_tag_in_torrent(self.stalled_tag, torrent.tags))
):
stalled = False
if torrent.state == "stalledDL":
stalled = True
tracker["tag"].append(self.stalled_tag)
if tracker["tag"] or stalled:
t_name = torrent.name t_name = torrent.name
self.stats += len(tracker["tag"]) self.stats += len(tracker["tag"])
body = [] body = []

View file

@ -27,7 +27,7 @@ class Qbt:
SUPPORTED_VERSION = Version.latest_supported_app_version() SUPPORTED_VERSION = Version.latest_supported_app_version()
MIN_SUPPORTED_VERSION = "v4.3.0" MIN_SUPPORTED_VERSION = "v4.3.0"
TORRENT_DICT_COMMANDS = ["recheck", "cross_seed", "rem_unregistered", "tag_tracker_error", "tag_nohardlinks", "share_limits"] TORRENT_DICT_COMMANDS = ["recheck", "rem_unregistered", "tag_tracker_error", "tag_nohardlinks", "share_limits"]
def __init__(self, config, params): def __init__(self, config, params):
self.config = config self.config = config
@ -48,9 +48,9 @@ class Qbt:
) )
self.client.auth_log_in() self.client.auth_log_in()
self.current_version = self.client.app.version self.current_version = self.client.app.version
logger.debug(f"qBittorrent: {self.current_version}") logger.info(f"qBittorrent: {self.current_version}")
logger.debug(f"qBittorrent Web API: {self.client.app.web_api_version}") logger.info(f"qBittorrent Web API: {self.client.app.web_api_version}")
logger.debug(f"qbit_manage supported versions: {self.MIN_SUPPORTED_VERSION} - {self.SUPPORTED_VERSION}") logger.info(f"qbit_manage supported versions: {self.MIN_SUPPORTED_VERSION} - {self.SUPPORTED_VERSION}")
if self.current_version < self.MIN_SUPPORTED_VERSION: if self.current_version < self.MIN_SUPPORTED_VERSION:
ex = ( ex = (
f"Qbittorrent Error: qbit_manage is only compatible with {self.MIN_SUPPORTED_VERSION} or higher. " f"Qbittorrent Error: qbit_manage is only compatible with {self.MIN_SUPPORTED_VERSION} or higher. "
@ -311,7 +311,7 @@ class Qbt:
self.config.data, "tag", parent="tracker", subparent="other", default_is_none=True, var_type="list", save=False self.config.data, "tag", parent="tracker", subparent="other", default_is_none=True, var_type="list", save=False
) )
try: try:
tracker["url"] = util.trunc_val(urls[0], os.sep) tracker["url"] = util.trunc_val(urls[0], "/")
except IndexError as e: except IndexError as e:
tracker["url"] = None tracker["url"] = None
if not urls: if not urls:
@ -331,8 +331,8 @@ class Qbt:
default_tag = tracker_other_tag default_tag = tracker_other_tag
else: else:
try: try:
tracker["url"] = util.trunc_val(url, os.sep) tracker["url"] = util.trunc_val(url, "/")
default_tag = tracker["url"].split(os.sep)[2].split(":")[0] default_tag = tracker["url"].split("/")[2].split(":")[0]
except IndexError as e: except IndexError as e:
logger.debug(f"Tracker Url:{url}") logger.debug(f"Tracker Url:{url}")
logger.debug(e) logger.debug(e)
@ -380,7 +380,7 @@ class Qbt:
if tracker_other_tag: if tracker_other_tag:
default_tag = tracker_other_tag default_tag = tracker_other_tag
else: else:
default_tag = tracker["url"].split(os.sep)[2].split(":")[0] default_tag = tracker["url"].split("/")[2].split(":")[0]
tracker["tag"] = self.config.util.check_for_attribute( tracker["tag"] = self.config.util.check_for_attribute(
self.config.data, "tag", parent="tracker", subparent=default_tag, default=default_tag, var_type="list" self.config.data, "tag", parent="tracker", subparent=default_tag, default=default_tag, var_type="list"
) )

View file

@ -17,11 +17,15 @@ from ruamel.yaml.constructor import ConstructorError
logger = logging.getLogger("qBit Manage") logger = logging.getLogger("qBit Manage")
def get_list(data, lower=False, split=True, int_list=False): def get_list(data, lower=False, split=True, int_list=False, upper=False):
"""Return a list from a string or list.""" """Return a list from a string or list."""
if data is None: if data is None:
return None return None
elif isinstance(data, list): elif isinstance(data, list):
if lower is True:
return [d.strip().lower() for d in data]
if upper is True:
return [d.strip().upper() for d in data]
return data return data
elif isinstance(data, dict): elif isinstance(data, dict):
return [data] return [data]
@ -29,6 +33,8 @@ def get_list(data, lower=False, split=True, int_list=False):
return [str(data)] return [str(data)]
elif lower is True: elif lower is True:
return [d.strip().lower() for d in str(data).split(",")] return [d.strip().lower() for d in str(data).split(",")]
elif upper is True:
return [d.strip().upper() for d in str(data).split(",")]
elif int_list is True: elif int_list is True:
try: try:
return [int(d.strip()) for d in str(data).split(",")] return [int(d.strip()) for d in str(data).split(",")]
@ -81,6 +87,8 @@ class TorrentMessages:
"TRACKER NICHT REGISTRIERT.", "TRACKER NICHT REGISTRIERT.",
"TORRENT EXISTIERT NICHT", "TORRENT EXISTIERT NICHT",
"TORRENT NICHT GEFUNDEN", "TORRENT NICHT GEFUNDEN",
"TORRENT DELETED", # NexusPHP
"TORRENT BANNED", # NexusPHP
] ]
UNREGISTERED_MSGS_BHD = [ UNREGISTERED_MSGS_BHD = [
@ -357,6 +365,8 @@ class check:
message = "No Paths exist" message = "No Paths exist"
elif var_type == "lower_list": elif var_type == "lower_list":
return get_list(data[attribute], lower=True) return get_list(data[attribute], lower=True)
elif var_type == "upper_list":
return get_list(data[attribute], upper=True)
elif test_list is None or data[attribute] in test_list: elif test_list is None or data[attribute] in test_list:
return data[attribute] return data[attribute]
else: else:

View file

@ -83,14 +83,6 @@ parser.add_argument(
type=str, type=str,
help="This is used if you want to use a different name for your log file. Example: tv.log", help="This is used if you want to use a different name for your log file. Example: tv.log",
) )
parser.add_argument(
"-cs",
"--cross-seed",
dest="cross_seed",
action="store_true",
default=False,
help="Use this after running cross-seed script to add torrents from the cross-seed output folder to qBittorrent",
)
parser.add_argument( parser.add_argument(
"-re", "-re",
"--recheck", "--recheck",
@ -271,7 +263,6 @@ sch = get_arg("QBT_SCHEDULE", args.schedule)
startupDelay = get_arg("QBT_STARTUP_DELAY", args.startupDelay) startupDelay = get_arg("QBT_STARTUP_DELAY", args.startupDelay)
config_files = get_arg("QBT_CONFIG", args.configfiles) config_files = get_arg("QBT_CONFIG", args.configfiles)
log_file = get_arg("QBT_LOGFILE", args.logfile) log_file = get_arg("QBT_LOGFILE", args.logfile)
cross_seed = get_arg("QBT_CROSS_SEED", args.cross_seed, arg_bool=True)
recheck = get_arg("QBT_RECHECK", args.recheck, arg_bool=True) recheck = get_arg("QBT_RECHECK", args.recheck, arg_bool=True)
cat_update = get_arg("QBT_CAT_UPDATE", args.cat_update, arg_bool=True) cat_update = get_arg("QBT_CAT_UPDATE", args.cat_update, arg_bool=True)
tag_update = get_arg("QBT_TAG_UPDATE", args.tag_update, arg_bool=True) tag_update = get_arg("QBT_TAG_UPDATE", args.tag_update, arg_bool=True)
@ -322,7 +313,6 @@ for v in [
"startupDelay", "startupDelay",
"config_files", "config_files",
"log_file", "log_file",
"cross_seed",
"recheck", "recheck",
"cat_update", "cat_update",
"tag_update", "tag_update",
@ -370,7 +360,6 @@ from modules import util # noqa
util.logger = logger util.logger = logger
from modules.config import Config # noqa from modules.config import Config # noqa
from modules.core.category import Category # noqa from modules.core.category import Category # noqa
from modules.core.cross_seed import CrossSeed # noqa
from modules.core.recheck import ReCheck # noqa from modules.core.recheck import ReCheck # noqa
from modules.core.remove_orphaned import RemoveOrphaned # noqa from modules.core.remove_orphaned import RemoveOrphaned # noqa
from modules.core.remove_unregistered import RemoveUnregistered # noqa from modules.core.remove_unregistered import RemoveUnregistered # noqa
@ -497,12 +486,6 @@ def start():
if cfg.commands["tag_update"]: if cfg.commands["tag_update"]:
stats["tagged"] += Tags(qbit_manager).stats stats["tagged"] += Tags(qbit_manager).stats
# Set Cross Seed
if cfg.commands["cross_seed"]:
cross_seed = CrossSeed(qbit_manager)
stats["added"] += cross_seed.stats_added
stats["tagged"] += cross_seed.stats_tagged
# Remove Unregistered Torrents and tag errors # Remove Unregistered Torrents and tag errors
if cfg.commands["rem_unregistered"] or cfg.commands["tag_tracker_error"]: if cfg.commands["rem_unregistered"] or cfg.commands["tag_tracker_error"]:
rem_unreg = RemoveUnregistered(qbit_manager) rem_unreg = RemoveUnregistered(qbit_manager)