mirror of
https://github.com/StuffAnThings/qbit_manage.git
synced 2025-12-10 13:56:13 +08:00
feat(tags): add support for tagging private torrents
Introduces a new `private_tag` setting to automatically tag torrents identified as private. Changes include: - Added `is_torrent_private` method to check torrent privacy status via attributes or tracker messages - Updated tagging logic to apply the configured private tag - Added `private_tag` to config, docs, and Web UI schema - Bumped version to 4.6.5-develop11 - Adds [FR]: Allow tagging by "Private" tracker or otherwise Fixes #883
This commit is contained in:
parent
5b9d4d806e
commit
1570c01b4c
7 changed files with 257 additions and 150 deletions
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
|||
4.6.5-develop10
|
||||
4.6.5-develop11
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ settings:
|
|||
tracker_error_tag: issue # Will set the tag of any torrents that do not have a working tracker.
|
||||
nohardlinks_tag: noHL # Will set the tag of any torrents with no hardlinks.
|
||||
stalled_tag: stalledDL # Will set the tag of any torrents stalled downloading.
|
||||
private_tag: null # Will set the tag of any torrents that are private. (Set to null to disable)
|
||||
share_limits_tag: ~share_limit # Will add this tag when applying share limits to provide an easy way to filter torrents by share limit group/priority for each torrent
|
||||
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
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ This section defines any settings defined in the configuration.
|
|||
| `force_auto_tmm_ignore_tags` | Torrents with these tags will be ignored when force_auto_tmm is enabled. | | <center>❌</center> |
|
||||
| `tracker_error_tag` | Define the tag of any torrents that do not have a working tracker. (Used in `--tag-tracker-error`) | issue | <center>❌</center> |
|
||||
| `nohardlinks_tag` | Define the tag of any torrents that don't have hardlinks (Used in `--tag-nohardlinks`) | noHL | <center>❌</center> |
|
||||
| `private_tag` | Define the tag of any torrents that are private. | None | <center>❌</center> |
|
||||
| `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 | <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> |
|
||||
|
|
@ -306,13 +307,15 @@ Provide webhook notifications based on event triggers
|
|||
Payload will be sent on any errors
|
||||
|
||||
```yaml
|
||||
{
|
||||
"function": "run_error", // Webhook Trigger keyword
|
||||
"title": str, // Title of the Payload
|
||||
"body": str, // Error Message of the Payload
|
||||
"critical": bool, // Critical Error
|
||||
"type": str // severity of error
|
||||
}
|
||||
{ "function": "run_error", ? // Webhook Trigger keyword
|
||||
"title"
|
||||
: str, ? // Title of the Payload
|
||||
"body"
|
||||
: str, ? // Error Message of the Payload
|
||||
"critical"
|
||||
: bool, ? // Critical Error
|
||||
"type"
|
||||
: str // severity of error }
|
||||
```
|
||||
|
||||
### **Run Start Notifications**
|
||||
|
|
@ -320,16 +323,21 @@ Payload will be sent on any errors
|
|||
Payload will be sent at the start of the run
|
||||
|
||||
```yaml
|
||||
{
|
||||
"function": "run_start", // Webhook Trigger keyword
|
||||
"title": str, // Title of the Payload
|
||||
"body": str, // Message of the Payload
|
||||
"start_time": str, // Time Run is started Format "YYYY-mm-dd HH:MM:SS"
|
||||
"dry_run": bool, // Dry-Run
|
||||
"web_api_used": bool, // Indicates whether the run was initiated via the Web API (true) or not (false).
|
||||
"commands": list, // List of commands that that will be ran
|
||||
"execution_options": list // List of eecution options selected
|
||||
}
|
||||
{ "function": "run_start", ? // Webhook Trigger keyword
|
||||
"title"
|
||||
: str, ? // Title of the Payload
|
||||
"body"
|
||||
: str, ? // Message of the Payload
|
||||
"start_time"
|
||||
: str, ? // Time Run is started Format "YYYY-mm-dd HH:MM:SS"
|
||||
"dry_run"
|
||||
: bool, ? // Dry-Run
|
||||
"web_api_used"
|
||||
: bool, ? // Indicates whether the run was initiated via the Web API (true) or not (false).
|
||||
"commands"
|
||||
: list, ? // List of commands that that will be ran
|
||||
"execution_options"
|
||||
: list // List of eecution options selected }
|
||||
```
|
||||
|
||||
### **Run End Notifications**
|
||||
|
|
@ -370,16 +378,21 @@ Payload will be sent at the end of the run
|
|||
Payload will be sent when rechecking/resuming a torrent that is paused
|
||||
|
||||
```yaml
|
||||
{
|
||||
"function": "recheck", // Webhook Trigger keyword
|
||||
"title": str, // Title of the Payload
|
||||
"body": str, // Message of the Payload
|
||||
"torrents": [str], // List of Torrent Names
|
||||
"torrent_tag": str, // Torrent Tags
|
||||
"torrent_category": str, // Torrent Category
|
||||
"torrent_tracker": str, // Torrent Tracker URL
|
||||
"notifiarr_indexer": str, // Notifiarr React name/id for indexer
|
||||
}
|
||||
{ "function": "recheck", ? // Webhook Trigger keyword
|
||||
"title"
|
||||
: str, ? // Title of the Payload
|
||||
"body"
|
||||
: str, ? // Message of the Payload
|
||||
"torrents"
|
||||
: [str], ? // List of Torrent Names
|
||||
"torrent_tag"
|
||||
: str, ? // Torrent Tags
|
||||
"torrent_category"
|
||||
: str, ? // Torrent Category
|
||||
"torrent_tracker"
|
||||
: str, ? // Torrent Tracker URL
|
||||
"notifiarr_indexer"
|
||||
: str, // Notifiarr React name/id for indexer }
|
||||
```
|
||||
|
||||
### **Category Update Notifications**
|
||||
|
|
@ -387,16 +400,21 @@ Payload will be sent when rechecking/resuming a torrent that is paused
|
|||
Payload will be sent when updating torrents with missing category
|
||||
|
||||
```yaml
|
||||
{
|
||||
"function": "cat_update", // Webhook Trigger keyword
|
||||
"title": str, // Title of the Payload
|
||||
"body": str, // Message of the Payload
|
||||
"torrents": [str], // List of Torrent Names
|
||||
"torrent_category": str, // New Torrent Category
|
||||
"torrent_tag": str, // Torrent Tags
|
||||
"torrent_tracker": str, // Torrent Tracker URL
|
||||
"notifiarr_indexer": str, // Notifiarr React name/id for indexer
|
||||
}
|
||||
{ "function": "cat_update", ? // Webhook Trigger keyword
|
||||
"title"
|
||||
: str, ? // Title of the Payload
|
||||
"body"
|
||||
: str, ? // Message of the Payload
|
||||
"torrents"
|
||||
: [str], ? // List of Torrent Names
|
||||
"torrent_category"
|
||||
: str, ? // New Torrent Category
|
||||
"torrent_tag"
|
||||
: str, ? // Torrent Tags
|
||||
"torrent_tracker"
|
||||
: str, ? // Torrent Tracker URL
|
||||
"notifiarr_indexer"
|
||||
: str, // Notifiarr React name/id for indexer }
|
||||
```
|
||||
|
||||
### **Tag Update Notifications**
|
||||
|
|
@ -404,16 +422,21 @@ Payload will be sent when updating torrents with missing category
|
|||
Payload will be sent when updating torrents with missing tag
|
||||
|
||||
```yaml
|
||||
{
|
||||
"function": "tag_update", // 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": str, // New Torrent Tag
|
||||
"torrent_tracker": str, // Torrent Tracker URL
|
||||
"notifiarr_indexer": str, // Notifiarr React name/id for indexer
|
||||
}
|
||||
{ "function": "tag_update", ? // 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"
|
||||
: str, ? // New Torrent Tag
|
||||
"torrent_tracker"
|
||||
: str, ? // Torrent Tracker URL
|
||||
"notifiarr_indexer"
|
||||
: str, // Notifiarr React name/id for indexer }
|
||||
```
|
||||
|
||||
### **Remove Unregistered Torrents Notifications**
|
||||
|
|
@ -421,18 +444,25 @@ Payload will be sent when updating torrents with missing tag
|
|||
Payload will be sent when Unregistered Torrents are found
|
||||
|
||||
```yaml
|
||||
{
|
||||
"function": "rem_unregistered", // 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_status": str, // Torrent Tracker Status message
|
||||
"torrent_tag": str, // Torrent Tags
|
||||
"torrent_tracker": str, // Torrent Tracker URL
|
||||
"notifiarr_indexer": str, // Notifiarr React name/id for indexer
|
||||
"torrents_deleted_and_contents": bool, // Deleted Torrents and contents or Deleted just the torrent
|
||||
}
|
||||
{ "function": "rem_unregistered", ? // 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_status"
|
||||
: str, ? // Torrent Tracker Status message
|
||||
"torrent_tag"
|
||||
: str, ? // Torrent Tags
|
||||
"torrent_tracker"
|
||||
: str, ? // Torrent Tracker URL
|
||||
"notifiarr_indexer"
|
||||
: str, ? // Notifiarr React name/id for indexer
|
||||
"torrents_deleted_and_contents"
|
||||
: bool, // Deleted Torrents and contents or Deleted just the torrent }
|
||||
```
|
||||
|
||||
### **Tag Tracker Error Notifications**
|
||||
|
|
@ -440,30 +470,41 @@ Payload will be sent when Unregistered Torrents are found
|
|||
Payload will be sent when trackers with errors are tagged/untagged
|
||||
|
||||
```yaml
|
||||
{
|
||||
"function": "tag_tracker_error", // 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": "issue", // Tag Added
|
||||
"torrent_status": str, // Torrent Tracker Status message
|
||||
"torrent_tracker": str, // Torrent Tracker URL
|
||||
"notifiarr_indexer": str, // Notifiarr React name/id for indexer
|
||||
}
|
||||
{ "function": "tag_tracker_error", ? // 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"
|
||||
: "issue", ? // Tag Added
|
||||
"torrent_status"
|
||||
: str, ? // Torrent Tracker Status message
|
||||
"torrent_tracker"
|
||||
: str, ? // Torrent Tracker URL
|
||||
"notifiarr_indexer"
|
||||
: str, // Notifiarr React name/id for indexer }
|
||||
```
|
||||
|
||||
```yaml
|
||||
{
|
||||
"function": "untag_tracker_error", // 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": str, // Tag Added
|
||||
"torrent_tracker": str, // Torrent Tracker URL
|
||||
"notifiarr_indexer": str, // Notifiarr React name/id for indexer
|
||||
}
|
||||
{ "function": "untag_tracker_error", ? // 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"
|
||||
: str, ? // Tag Added
|
||||
"torrent_tracker"
|
||||
: str, ? // Torrent Tracker URL
|
||||
"notifiarr_indexer"
|
||||
: str, // Notifiarr React name/id for indexer }
|
||||
```
|
||||
|
||||
### **Remove Orphaned Files Notifications**
|
||||
|
|
@ -471,14 +512,17 @@ Payload will be sent when trackers with errors are tagged/untagged
|
|||
Payload will be sent when Orphaned Files are found and moved into the orphaned folder
|
||||
|
||||
```yaml
|
||||
{
|
||||
"function": "rem_orphaned", // Webhook Trigger keyword
|
||||
"title": str, // Title of the Payload
|
||||
"body": str, // Message of the Payload
|
||||
"orphaned_files": list, // List of orphaned files
|
||||
"orphaned_directory": str, // Folder path where orphaned files will be moved to
|
||||
"total_orphaned_files": int, // Total number of orphaned files found
|
||||
}
|
||||
{ "function": "rem_orphaned", ? // Webhook Trigger keyword
|
||||
"title"
|
||||
: str, ? // Title of the Payload
|
||||
"body"
|
||||
: str, ? // Message of the Payload
|
||||
"orphaned_files"
|
||||
: list, ? // List of orphaned files
|
||||
"orphaned_directory"
|
||||
: str, ? // Folder path where orphaned files will be moved to
|
||||
"total_orphaned_files"
|
||||
: int, // Total number of orphaned files found }
|
||||
```
|
||||
|
||||
### **Tag No Hardlinks Notifications**
|
||||
|
|
@ -486,31 +530,41 @@ Payload will be sent when Orphaned Files are found and moved into the orphaned f
|
|||
Payload will be sent when no hard links are found for any files in a particular torrent
|
||||
|
||||
```yaml
|
||||
{
|
||||
"function": "tag_nohardlinks", // 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": 'noHL', // Add `noHL` to Torrent Tags
|
||||
"torrent_tracker": str, // Torrent Tracker URL
|
||||
"notifiarr_indexer": str, // Notifiarr React name/id for indexer
|
||||
}
|
||||
{ "function": "tag_nohardlinks", ? // 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"
|
||||
: "noHL", ? // Add `noHL` to Torrent Tags
|
||||
"torrent_tracker"
|
||||
: str, ? // Torrent Tracker URL
|
||||
"notifiarr_indexer"
|
||||
: str, // Notifiarr React name/id for indexer }
|
||||
```
|
||||
|
||||
Payload will be sent when hard links are found for any torrents that were previously tagged with `noHL`
|
||||
|
||||
```yaml
|
||||
{
|
||||
"function": "untag_nohardlinks", // 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": 'noHL', // Remove `noHL` from Torrent Tags
|
||||
"torrent_tracker": str, // Torrent Tracker URL
|
||||
"notifiarr_indexer": str, // Notifiarr React name/id for indexer
|
||||
}
|
||||
{ "function": "untag_nohardlinks", ? // 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"
|
||||
: "noHL", ? // Remove `noHL` from Torrent Tags
|
||||
"torrent_tracker"
|
||||
: str, ? // Torrent Tracker URL
|
||||
"notifiarr_indexer"
|
||||
: str, // Notifiarr React name/id for indexer }
|
||||
```
|
||||
|
||||
### **Share Limits Notifications**
|
||||
|
|
@ -518,35 +572,49 @@ Payload will be sent when hard links are found for any torrents that were previo
|
|||
Payload will be sent when Share Limits are updated for a specific group
|
||||
|
||||
```yaml
|
||||
{
|
||||
"function": "share_limits", // Webhook Trigger keyword
|
||||
"title": str, // Title of the Payload
|
||||
"body": str, // Message of the Payload
|
||||
"grouping": str, // Share Limit group name
|
||||
"torrents": [str], // List of Torrent Names
|
||||
"torrent_tag": str, // Torrent Tags
|
||||
"torrent_max_ratio": float, // Set the Max Ratio Share Limit
|
||||
"torrent_max_seeding_time": int, // Set the Max Seeding Time (minutes) Share Limit
|
||||
"torrent_min_seeding_time": int, // Set the Min Seeding Time (minutes) Share Limit
|
||||
"torrent_limit_upload_speed": int // Set the the torrent upload speed limit (kB/s)
|
||||
}
|
||||
{ "function": "share_limits", ? // Webhook Trigger keyword
|
||||
"title"
|
||||
: str, ? // Title of the Payload
|
||||
"body"
|
||||
: str, ? // Message of the Payload
|
||||
"grouping"
|
||||
: str, ? // Share Limit group name
|
||||
"torrents"
|
||||
: [str], ? // List of Torrent Names
|
||||
"torrent_tag"
|
||||
: str, ? // Torrent Tags
|
||||
"torrent_max_ratio"
|
||||
: float, ? // Set the Max Ratio Share Limit
|
||||
"torrent_max_seeding_time"
|
||||
: int, ? // Set the Max Seeding Time (minutes) Share Limit
|
||||
"torrent_min_seeding_time"
|
||||
: int, ? // Set the Min Seeding Time (minutes) Share Limit
|
||||
"torrent_limit_upload_speed"
|
||||
: int // Set the the torrent upload speed limit (kB/s) }
|
||||
```
|
||||
|
||||
Payload will be sent when `cleanup` flag is set to true and torrent meets share limit criteria.
|
||||
|
||||
```yaml
|
||||
{
|
||||
"function": "cleanup_share_limits", // Webhook Trigger keyword
|
||||
"title": str, // Title of the Payload
|
||||
"body": str, // Message of the Payload
|
||||
"grouping": str, // Share Limit group name
|
||||
"torrents": [str], // List of Torrent Names
|
||||
"torrent_category": str, // Torrent Category
|
||||
"cleanup": True, // Cleanup flag
|
||||
"torrent_tracker": str, // Torrent Tracker URL
|
||||
"notifiarr_indexer": str, // Notifiarr React name/id for indexer
|
||||
"torrents_deleted_and_contents": bool, // Deleted Torrents and contents or Deleted just the torrent
|
||||
}
|
||||
{ "function": "cleanup_share_limits", ? // Webhook Trigger keyword
|
||||
"title"
|
||||
: str, ? // Title of the Payload
|
||||
"body"
|
||||
: str, ? // Message of the Payload
|
||||
"grouping"
|
||||
: str, ? // Share Limit group name
|
||||
"torrents"
|
||||
: [str], ? // List of Torrent Names
|
||||
"torrent_category"
|
||||
: str, ? // Torrent Category
|
||||
"cleanup"
|
||||
: True, ? // Cleanup flag
|
||||
"torrent_tracker"
|
||||
: str, ? // Torrent Tracker URL
|
||||
"notifiarr_indexer"
|
||||
: str, ? // Notifiarr React name/id for indexer
|
||||
"torrents_deleted_and_contents"
|
||||
: bool, // Deleted Torrents and contents or Deleted just the torrent }
|
||||
```
|
||||
|
||||
### **Cleanup directories Notifications**
|
||||
|
|
@ -554,13 +622,17 @@ Payload will be sent when `cleanup` flag is set to true and torrent meets share
|
|||
Payload will be sent when files are deleted/cleaned up from the various folders
|
||||
|
||||
```yaml
|
||||
{
|
||||
"function": "cleanup_dirs", // Webhook Trigger keyword
|
||||
"location": str, // Location of the folder that is being cleaned
|
||||
"title": str, // Title of the Payload
|
||||
"body": str, // Message of the Payload
|
||||
"files": list, // List of files that were deleted from the location
|
||||
"empty_after_x_days": int, // Number of days that the files will be kept in the location
|
||||
"size_in_bytes": int, // Total number of bytes deleted from the location
|
||||
}
|
||||
{ "function": "cleanup_dirs", ? // Webhook Trigger keyword
|
||||
"location"
|
||||
: str, ? // Location of the folder that is being cleaned
|
||||
"title"
|
||||
: str, ? // Title of the Payload
|
||||
"body"
|
||||
: str, ? // Message of the Payload
|
||||
"files"
|
||||
: list, ? // List of files that were deleted from the location
|
||||
"empty_after_x_days"
|
||||
: int, ? // Number of days that the files will be kept in the location
|
||||
"size_in_bytes"
|
||||
: int, // Total number of bytes deleted from the location }
|
||||
```
|
||||
|
|
|
|||
|
|
@ -302,6 +302,7 @@ class Config:
|
|||
),
|
||||
"nohardlinks_tag": self.util.check_for_attribute(self.data, "nohardlinks_tag", parent="settings", default="noHL"),
|
||||
"stalled_tag": self.util.check_for_attribute(self.data, "stalled_tag", parent="settings", default="stalledDL"),
|
||||
"private_tag": self.util.check_for_attribute(self.data, "private_tag", parent="settings", default_is_none=True),
|
||||
"share_limits_tag": self.util.check_for_attribute(
|
||||
self.data, "share_limits_tag", parent="settings", default=share_limits_tag
|
||||
),
|
||||
|
|
@ -352,6 +353,7 @@ class Config:
|
|||
self.tracker_error_tag = self.settings["tracker_error_tag"]
|
||||
self.nohardlinks_tag = self.settings["nohardlinks_tag"]
|
||||
self.stalled_tag = self.settings["stalled_tag"]
|
||||
self.private_tag = self.settings["private_tag"]
|
||||
self.share_limits_tag = self.settings["share_limits_tag"]
|
||||
self.share_limits_custom_tags = []
|
||||
self.share_limits_min_seeding_time_tag = self.settings["share_limits_min_seeding_time_tag"]
|
||||
|
|
@ -365,6 +367,7 @@ class Config:
|
|||
self.share_limits_min_num_seeds_tag,
|
||||
self.share_limits_last_active_tag,
|
||||
self.share_limits_tag,
|
||||
self.private_tag,
|
||||
]
|
||||
# "Migrate settings from v4.0.0 to v4.0.1 and beyond. Convert 'share_limits_suffix_tag' to 'share_limits_tag'"
|
||||
if "share_limits_suffix_tag" in self.data["settings"]:
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ class Tags:
|
|||
self.torrents_updated = [] # List of torrents updated
|
||||
self.notify_attr = [] # List of single torrent attributes to send to notifiarr
|
||||
self.stalled_tag = qbit_manager.config.stalled_tag
|
||||
self.private_tag = qbit_manager.config.private_tag
|
||||
self.tag_stalled_torrents = self.config.settings["tag_stalled_torrents"]
|
||||
|
||||
self.tags()
|
||||
|
|
@ -53,23 +54,29 @@ class Tags:
|
|||
and torrent.state == "stalledDL"
|
||||
and not util.is_tag_in_torrent(self.stalled_tag, torrent.tags)
|
||||
)
|
||||
or (
|
||||
self.private_tag
|
||||
and not util.is_tag_in_torrent(self.private_tag, torrent.tags)
|
||||
and self.qbt.is_torrent_private(torrent)
|
||||
)
|
||||
):
|
||||
stalled = False
|
||||
tags_to_add = tracker["tag"].copy()
|
||||
if self.tag_stalled_torrents and torrent.state == "stalledDL":
|
||||
stalled = True
|
||||
tracker["tag"].append(self.stalled_tag)
|
||||
if tracker["tag"] or stalled:
|
||||
tags_to_add.append(self.stalled_tag)
|
||||
if self.private_tag and self.qbt.is_torrent_private(torrent):
|
||||
tags_to_add.append(self.private_tag)
|
||||
if tags_to_add:
|
||||
t_name = torrent.name
|
||||
self.stats += len(tracker["tag"])
|
||||
self.stats += len(tags_to_add)
|
||||
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"New Tag{'s' if len(tracker['tag']) > 1 else ''}: {', '.join(tracker['tag'])}", 8),
|
||||
logger.insert_space(f"New Tag{'s' if len(tags_to_add) > 1 else ''}: {', '.join(tags_to_add)}", 8),
|
||||
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.add_tags(tracker["tag"])
|
||||
torrent.add_tags(tags_to_add)
|
||||
category = self.qbt.get_category(torrent.save_path)[0] if torrent.category == "" else torrent.category
|
||||
attr = {
|
||||
"function": "tag_update",
|
||||
|
|
@ -77,7 +84,7 @@ class Tags:
|
|||
"body": "\n".join(body),
|
||||
"torrents": [t_name],
|
||||
"torrent_category": category,
|
||||
"torrent_tag": ", ".join(tracker["tag"]),
|
||||
"torrent_tag": ", ".join(tags_to_add),
|
||||
"torrent_tracker": tracker["url"],
|
||||
"notifiarr_indexer": tracker["notifiarr"],
|
||||
}
|
||||
|
|
|
|||
|
|
@ -299,6 +299,23 @@ class Qbt:
|
|||
"""Get tracker urls from torrent"""
|
||||
return tuple(x.url for x in trackers if x.url.startswith(("http", "udp", "ws")))
|
||||
|
||||
def is_torrent_private(self, torrent):
|
||||
"""Checks if torrent is private"""
|
||||
if hasattr(torrent, "private") and torrent.private:
|
||||
return True
|
||||
if hasattr(torrent, "private") and not torrent.private:
|
||||
return False
|
||||
|
||||
if isinstance(torrent, str):
|
||||
torrent_hash = torrent
|
||||
else:
|
||||
torrent_hash = torrent.hash
|
||||
torrent_trackers = self.client.torrents_trackers(torrent_hash)
|
||||
for tracker in torrent_trackers:
|
||||
if "private" in tracker["msg"].lower() or "private" in tracker["url"].lower():
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_tags(self, urls):
|
||||
"""Get tags from config file based on keyword"""
|
||||
urls = list(urls)
|
||||
|
|
|
|||
|
|
@ -44,6 +44,13 @@ export const settingsSchema = {
|
|||
description: 'The tag to apply to torrents that are stalled during download.',
|
||||
default: 'stalledDL'
|
||||
},
|
||||
{
|
||||
name: 'private_tag',
|
||||
type: 'text',
|
||||
label: 'Private Tag',
|
||||
description: 'The tag to apply to private torrents.',
|
||||
default: null
|
||||
},
|
||||
{
|
||||
name: 'share_limits_tag',
|
||||
type: 'text',
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue