-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature] Add option to set 'obsolete'-tag to private torrents that are not needed but kept anyway. #194
base: dev
Are you sure you want to change the base?
[Feature] Add option to set 'obsolete'-tag to private torrents that are not needed but kept anyway. #194
Changes from all commits
bdc7e7e
8081742
1cb773f
6c49fd8
f4e936e
2222592
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,6 +35,7 @@ You can find a sample docker-compose.yml [here](#method-1-docker). | |
- When detecting slow downloads, the speeds provided by the \*arr apps will be used, which is less accurate than what qBittorrent returns when queried directly | ||
- The feature that allows to protect downloads from removal (NO_STALLED_REMOVAL_QBIT_TAG) does not work | ||
- The feature that ignores private trackers does not work | ||
- The "obsolete" feature that tags private torrents due for removal rather than removing them does not work | ||
- If you see strange errors such as "found 10 / 3 times", consider turning on the setting "Reject Blocklisted Torrent Hashes While Grabbing". On nightly Radarr/Sonarr/Readarr/Lidarr/Whisparr, the option is located under settings/indexers in the advanced options of each indexer, on Prowlarr it is under settings/apps and then the advanced settings of the respective app | ||
- When broken torrents are removed the files belonging to them are deleted | ||
- Across all removal types: A new download from another source is automatically added by radarr/sonarr/lidarr/readarr/whisparr (if available) | ||
|
@@ -74,7 +75,7 @@ services: | |
# SSL_VERIFICATION: False | ||
LOG_LEVEL: INFO | ||
|
||
## Features | ||
## Features | ||
REMOVE_TIMER: 10 | ||
REMOVE_FAILED: True | ||
REMOVE_FAILED_IMPORTS: True | ||
|
@@ -84,6 +85,7 @@ services: | |
REMOVE_SLOW: True | ||
REMOVE_STALLED: True | ||
REMOVE_UNMONITORED: True | ||
SET_OBSOLETE_QBIT_TAG: True | ||
RUN_PERIODIC_RESCANS: ' | ||
{ | ||
"SONARR": {"MISSING": true, "CUTOFF_UNMET": true, "MAX_CONCURRENT_SCANS": 3, "MIN_DAYS_BEFORE_RESCAN": 7}, | ||
|
@@ -93,7 +95,8 @@ services: | |
# Feature Settings | ||
PERMITTED_ATTEMPTS: 3 | ||
NO_STALLED_REMOVAL_QBIT_TAG: Don't Kill | ||
MIN_DOWNLOAD_SPEED: 100 | ||
OBSOLETE_QBIT_TAG: Obsolete | ||
MIN_DOWNLOAD_SPEED: 100 | ||
FAILED_IMPORT_MESSAGE_PATTERNS: ' | ||
[ | ||
"Not a Custom Format upgrade for existing", | ||
|
@@ -259,6 +262,15 @@ Steers which type of cleaning is applied to the downloads queue | |
- Permissible Values: True, False | ||
- Is Mandatory: No (Defaults to False) | ||
|
||
**SET_OBSOLETE_QBIT_TAG** | ||
- Set a tag on torrents in qBittorrent that can be removed, but are kept because they are private torrents. | ||
- Note: Has no effect when `IGNORE_PRIVATE_TRACKERS==False`. | ||
- The tag can be used by third-party tools to remove these torrents after required seeding time has passed. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The tag can be used by third-party tools (such as qbit_manage) to remove these torrents after required seeding time has passed. would it make sense to add qbit_manage as example? |
||
- Tag is automatically created in qBittorrent (required qBittorrent is reachable on `QBITTORRENT_URL`) | ||
- Type: Boolean | ||
- Permissible Values: True, False | ||
- Is Mandatory: No (Defaults to False) | ||
|
||
**RUN_PERIODIC_RESCANS** | ||
|
||
- Steers whether searches are automatically triggered for items that are missing or have not yet met the cutoff | ||
|
@@ -317,6 +329,13 @@ If it you face issues, please first check the closed issues before opening a new | |
- Type: String | ||
- Is Mandatory: No (Defaults to `Don't Kill`) | ||
|
||
**OBSOLETE_QBIT_TAG** | ||
- Downloads in qBittorrent will receive this tag when: (1) `SET_OBSOLETE_QBIT_TAG==True`, (2) `IGNORE_PRIVATE_TRACKERS==True`, (3) torrent is private, (4) torrent is due for removal. | ||
- Note: the tag can be used by third-party tools to remove these torrents after required seeding time has passed. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note: the tag can be used by third-party tools (such as qbit_manage)to remove these torrents after required seeding time has passed. would it make sense to add qbit_manage as example? |
||
- Tag is automatically created in qBittorrent (required qBittorrent is reachable on `QBITTORRENT_URL`) | ||
- Type: String | ||
- Is Mandatory: No (Defaults to `Obsolete`) | ||
|
||
**IGNORE_PRIVATE_TRACKERS** | ||
|
||
- Private torrents in qBittorrent will not be removed from the queue if this is set to true | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -56,6 +56,9 @@ async def main(settingsDict): | |
# Create qBit protection tag if not existing | ||
await createQbitProtectionTag(settingsDict) | ||
|
||
# Create qBit obsolete tag if not existing | ||
await createQbitObsoleteTag(settingsDict) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 3. The tag should only be created if the feature is being used in qbit My point was referring to this line. In my mind you should only create a obsolete tag in qbit if this feature is even used.
|
||
|
||
# Show Logger Level | ||
showLoggerLevel(settingsDict) | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -92,6 +92,7 @@ def showSettings(settingsDict): | |
logger.info('%s | Removing slow downloads (%s)', str(settingsDict['REMOVE_SLOW']), 'REMOVE_SLOW') | ||
logger.info('%s | Removing stalled downloads (%s)', str(settingsDict['REMOVE_STALLED']), 'REMOVE_STALLED') | ||
logger.info('%s | Removing downloads belonging to unmonitored items (%s)', str(settingsDict['REMOVE_UNMONITORED']), 'REMOVE_UNMONITORED') | ||
logger.info('%s | Setting obsolete tag on private torrents that are due for removal (%s)', str(settingsDict['SET_OBSOLETE_QBIT_TAG']), 'SET_OBSOLETE_QBIT_TAG') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. logger.info("%s | Keeping private torrents in qBit due for removal and tagging instead (tag: '%s')", str(settingsDict['SET_OBSOLETE_QBIT_TAG']), 'SET_OBSOLETE_QBIT_TAG') Proposal above. |
||
for arr_type, RESCAN_SETTINGS in settingsDict['RUN_PERIODIC_RESCANS'].items(): | ||
logger.info('%s/%s (%s) | Search missing/cutoff-unmet items. Max queries/list: %s. Min. days to re-search: %s (%s)', RESCAN_SETTINGS['MISSING'], RESCAN_SETTINGS['CUTOFF_UNMET'], arr_type, RESCAN_SETTINGS['MAX_CONCURRENT_SCANS'], RESCAN_SETTINGS['MIN_DAYS_BEFORE_RESCAN'], 'RUN_PERIODIC_RESCANS') | ||
logger.info('') | ||
|
@@ -101,8 +102,10 @@ def showSettings(settingsDict): | |
logger.info('Minimum speed enforced: %s KB/s', str(settingsDict['MIN_DOWNLOAD_SPEED'])) | ||
logger.info('Permitted number of times before stalled/missing metadata/slow downloads are removed: %s', str(settingsDict['PERMITTED_ATTEMPTS'])) | ||
if settingsDict['QBITTORRENT_URL']: | ||
logger.info('Downloads with this tag will be skipped: \"%s\"', settingsDict['NO_STALLED_REMOVAL_QBIT_TAG']) | ||
logger.info('Private Trackers will be skipped: %s', settingsDict['IGNORE_PRIVATE_TRACKERS']) | ||
logger.info('Downloads with this tag will be skipped: \"%s\"', settingsDict['NO_STALLED_REMOVAL_QBIT_TAG']) | ||
if settingsDict['SET_OBSOLETE_QBIT_TAG'] and settingsDict['OBSOLETE_QBIT_TAG']: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
isn't that check redundant? this value will always be true, since you are setting a default in the definitions.py? |
||
logger.info('Obsolete private torrents will be given this tag: \"%s\"', settingsDict['OBSOLETE_QBIT_TAG']) | ||
logger.info('Private Trackers will be skipped: %s', settingsDict['IGNORE_PRIVATE_TRACKERS']) | ||
if settingsDict['IGNORED_DOWNLOAD_CLIENTS']: | ||
logger.info('Download clients skipped: %s',", ".join(settingsDict['IGNORED_DOWNLOAD_CLIENTS'])) | ||
logger.info('') | ||
|
@@ -225,6 +228,16 @@ async def createQbitProtectionTag(settingsDict): | |
if not settingsDict['TEST_RUN']: | ||
await rest_post(url=settingsDict['QBITTORRENT_URL']+'/torrents/createTags', data={'tags': settingsDict['NO_STALLED_REMOVAL_QBIT_TAG']}, headers={'content-type': 'application/x-www-form-urlencoded'}, cookies=settingsDict['QBIT_COOKIE']) | ||
|
||
async def createQbitObsoleteTag(settingsDict): | ||
# Creates the qBit Obsolete tag if not already present, feature is enabled, and tag is not an empty string | ||
if settingsDict['QBITTORRENT_URL'] and settingsDict['SET_OBSOLETE_QBIT_TAG'] and settingsDict['OBSOLETE_QBIT_TAG']: | ||
current_tags = await rest_get(settingsDict['QBITTORRENT_URL']+'/torrents/tags',cookies=settingsDict['QBIT_COOKIE']) | ||
if not settingsDict['OBSOLETE_QBIT_TAG'] in current_tags: | ||
if settingsDict['QBITTORRENT_URL']: | ||
logger.info('Creating tag in qBittorrent: %s', settingsDict['OBSOLETE_QBIT_TAG']) | ||
if not settingsDict['TEST_RUN']: | ||
await rest_post(url=settingsDict['QBITTORRENT_URL']+'/torrents/createTags', data={'tags': settingsDict['OBSOLETE_QBIT_TAG']}, headers={'content-type': 'application/x-www-form-urlencoded'}, cookies=settingsDict['QBIT_COOKIE']) | ||
|
||
def showLoggerLevel(settingsDict): | ||
logger.info('#' * 50) | ||
if settingsDict['LOG_LEVEL'] == 'INFO': | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -309,11 +309,18 @@ async def remove_download( | |
if removeFromClient: | ||
logger.info(">>> Removing %s download: %s", failType, affectedItem["title"]) | ||
else: | ||
logger.info( | ||
">>> Removing %s download (without removing from torrent client): %s", | ||
failType, | ||
affectedItem["title"], | ||
) | ||
if settingsDict['SET_OBSOLETE_QBIT_TAG'] and settingsDict['OBSOLETE_QBIT_TAG']: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. settingsDict['OBSOLETE_QBIT_TAG'] - same as above. isnt this obsolete due to default value? |
||
logger.info( | ||
">>> Removing %s download (without removing from torrent client but with setting obsolete tag): %s", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ">>> Removing %s download (keeping it in torrent client and adding tag '%s' where %s is settingsDict['OBSOLETE_QBIT_TAG'] proposal above. |
||
failType, | ||
affectedItem["title"], | ||
) | ||
else: | ||
logger.info( | ||
">>> Removing %s download (without removing from torrent client): %s", | ||
failType, | ||
affectedItem["title"], | ||
) | ||
|
||
# Print out detailed removal messages (if any were added in the jobs) | ||
if "removal_messages" in affectedItem: | ||
|
@@ -326,6 +333,9 @@ async def remove_download( | |
API_KEY, | ||
{"removeFromClient": removeFromClient, "blocklist": addToBlocklist}, | ||
) | ||
if not removeFromClient and settingsDict['QBITTORRENT_URL'] and settingsDict['SET_OBSOLETE_QBIT_TAG'] and settingsDict['OBSOLETE_QBIT_TAG'] and affectedItem["downloadId"]: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. settingsDict['OBSOLETE_QBIT_TAG'] -> redundant? |
||
await rest_post(url=settingsDict['QBITTORRENT_URL']+'/torrents/createTags', data={'hashes': affectedItem["downloadId"], 'tags': settingsDict['OBSOLETE_QBIT_TAG']}, headers={'content-type': 'application/x-www-form-urlencoded'}, cookies=settingsDict['QBIT_COOKIE']) | ||
|
||
deleted_downloads.dict.append(affectedItem["downloadId"]) | ||
|
||
logger.debug( | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would formulate it like this - if you are OK