This commit is contained in:
jblu 2022-07-29 16:02:19 -05:00
parent 26ac36a164
commit fca54f8952
6 changed files with 328 additions and 328 deletions

152
README.md
View File

@ -1,77 +1,77 @@
# qbit-maid
Warning: This application removes torrents that aren't downloading and that aren't from iptorrents. Age in the config.json only controls the age for torrents from iptorrents.
The objective is to remove torrents based on the following criteria:
- tracker domain name
- age
- ratio
- state
```mermaid
graph TD;
qbit-maid.py-->qlogging.py;
qbit-maid.py-->qlist.py;
qbit-maid.py-->qprocess.py;
qlogging.py-->qbit-maid.py;
qlist.py-->qbit-maid.py;
qprocess.py-->qbit-maid.py;
```
| File | Purpose |
| --- | --- |
| qbit-maid.py | Client to the qbit api and calls functions from the other files |
| qlist.py | Builds out torrent lists |
| qlogging.py | Logging and push notification communication |
| qprocess.py | Submits qualifying torrents for deletion |
You will need a config.json in the root directory.
It should look something like this:
Config.json
```
{
"host": "192.168.1.1",
"port": 8080,
"username": "admin",
"password": "admin",
"loglevel": "INFO",
"logpath": "./qc.log",
"protected_tag": "ipt",
"non_protected_tag": "public",
"age": 2419200,
"minimum_age": 432000,
"use_pushover": false,
"use_log": true,
"po_key": "",
"po_token": "",
"delete_torrents": false
}
```
You will need a category-whitelist.json in the root directory. This will ignore any of the categories found in the values of the entries.
```
{
"example": "general",
"example2": "sonarr"
}
```
| Key | Value |
| --- | --- |
| host | string, ip or hostname of qbittorrent server |
| port | number, port of admin gui(used for api aswell) |
| username | admin account for qbittorrent |
| password | password for admin account |
| loglevel | is what log messages are written to the log file. INFO or DEBUG are valid entries(case sensitive) |
| protected_tag | used to mark torrents to handle with care |
| non_protected_tag | we don't care about these torrents |
| logpath | will write a log in root directory if left as is other wise specify other path using forward slashes |
| age | number, seconds for how long we keep torrents from IPTORRENTS |
| minimum_age | age in seconds torrents should reached before they are removed |
| use_pushover | true or false to enable or disable pushover notification summary |
| use_log | true or false to enable or disable writing to alog file |
| po_key | pushover key |
| po_token | pushover api token |
# qbit-maid
Warning: This application removes torrents that aren't downloading and that aren't from iptorrents. Age in the config.json only controls the age for torrents from iptorrents.
The objective is to remove torrents based on the following criteria:
- tracker domain name
- age
- ratio
- state
```mermaid
graph TD;
qbit-maid.py-->qlogging.py;
qbit-maid.py-->qlist.py;
qbit-maid.py-->qprocess.py;
qlogging.py-->qbit-maid.py;
qlist.py-->qbit-maid.py;
qprocess.py-->qbit-maid.py;
```
| File | Purpose |
| --- | --- |
| qbit-maid.py | Client to the qbit api and calls functions from the other files |
| qlist.py | Builds out torrent lists |
| qlogging.py | Logging and push notification communication |
| qprocess.py | Submits qualifying torrents for deletion |
You will need a config.json in the root directory.
It should look something like this:
Config.json
```
{
"host": "192.168.1.1",
"port": 8080,
"username": "admin",
"password": "admin",
"loglevel": "INFO",
"logpath": "./qc.log",
"protected_tag": "ipt",
"non_protected_tag": "public",
"age": 2419200,
"minimum_age": 432000,
"use_pushover": false,
"use_log": true,
"po_key": "",
"po_token": "",
"delete_torrents": false
}
```
You will need a category-whitelist.json in the root directory. This will ignore any of the categories found in the values of the entries.
```
{
"example": "general",
"example2": "sonarr"
}
```
| Key | Value |
| --- | --- |
| host | string, ip or hostname of qbittorrent server |
| port | number, port of admin gui(used for api aswell) |
| username | admin account for qbittorrent |
| password | password for admin account |
| loglevel | is what log messages are written to the log file. INFO or DEBUG are valid entries(case sensitive) |
| protected_tag | used to mark torrents to handle with care |
| non_protected_tag | we don't care about these torrents |
| logpath | will write a log in root directory if left as is other wise specify other path using forward slashes |
| age | number, seconds for how long we keep torrents from IPTORRENTS |
| minimum_age | age in seconds torrents should reached before they are removed |
| use_pushover | true or false to enable or disable pushover notification summary |
| use_log | true or false to enable or disable writing to alog file |
| po_key | pushover key |
| po_token | pushover api token |
| delete_torrents | true or false to enable or disable deletion. Useful for dry-runs |

View File

@ -1,17 +1,17 @@
{
"host": "192.168.1.1",
"port": 8080,
"username": "admin",
"password": "admin",
"loglevel": "INFO",
"logpath": "./qc.log",
"protected_tag": "ipt",
"non_protected_tag": "public",
"age": 2419200,
"minimum_age": 432000,
"use_pushover": true,
"use_log": true,
"po_key": "",
"po_token": "",
"delete_torrents": false
{
"host": "192.168.1.1",
"port": 8080,
"username": "admin",
"password": "admin",
"loglevel": "INFO",
"logpath": "./qc.log",
"protected_tag": "ipt",
"non_protected_tag": "public",
"age": 2419200,
"minimum_age": 432000,
"use_pushover": true,
"use_log": true,
"po_key": "",
"po_token": "",
"delete_torrents": false
}

170
qbit-maid.py Normal file → Executable file
View File

@ -1,86 +1,86 @@
#The first file shall contain an client to the qbit api and the processing of the torrents.
import qbittorrentapi
import pushover
from json import load
from qlist import *
from qlogging import *
from qprocess import *
import time
import logging
from collections import Counter
class Qbt:
def __init__(self):
"""Main object, should be calling functions from qlist.py, qlogging.py and qprocess.py"""
# Open the config. Needs a json file with the data in config.json.example
c = open('./config.json')
self.config = load(c)
w = open('./category-whitelist.json')
self.cat_whitelist = load(w)
# Create the api object
self.qbt_client = qbittorrentapi.Client(
host=self.config["host"],
port=self.config["port"],
username=self.config["username"],
password=self.config["password"],
)
# Create the logging and pushover objects
self.tl = logging
self.po = pushover
self.ct = Counter
# Variables torlog uses from config.json
self.use_pushover = self.config["use_pushover"]
self.use_log = self.config["use_log"]
self.po_key = self.config["po_key"]
self.po_token = self.config["po_token"]
self.logpath = self.config["logpath"]
self.loglevel = self.config["loglevel"]
self.tracker_protected_tag = self.config["protected_tag"]
self.tracker_non_protected_tag = self.config["non_protected_tag"]
self.minimum_age = self.config["minimum_age"]
self.age = self.config["age"]
# Calling log and notify functions
torlog(self)
tornotify(self)
self.t = time
# Pulling domain names to treat carefully
f = open('./tracker-whitelist.json')
self.tracker_whitelist = load(f)
self.tracker_list = []
self.up_tor_counter = 0
self.preme_tor_counter = 0
self.ignored_counter = 0
self.torrent_hash_delete_list = []
if self.use_log:
self.tl.debug(self.tracker_whitelist)
#logging in
try:
self.tl.info('Connecting to host.')
self.qbt_client.auth_log_in()
self.tl.info('Connected.')
except qbittorrentapi.APIError as e:
self.tl.exception(e)
self.poc.send_message(e, title="qbit-maid API ERROR")
self.torrentlist = {}
# Pulling all torrent data
self.torrentlist = self.qbt_client.torrents_info()
#Main process block
if self.use_log:
listqbitapiinfo(self)
listfirsttor(self)
buildtorlist(self)
processcounts(self)
#tordeletetags(self)
if self.use_log:
torrentcount(self)
torprocessor(self)
if self.use_log:
printprocessor(self)
if self.use_pushover:
tornotifysummary(self)
if self.config["delete_torrents"]:
tordelete(self)
# Run
if __name__== "__main__":
#The first file shall contain an client to the qbit api and the processing of the torrents.
import qbittorrentapi
import pushover
from json import load
from qlist import *
from qlogging import *
from qprocess import *
import time
import logging
from collections import Counter
class Qbt:
def __init__(self):
"""Main object, should be calling functions from qlist.py, qlogging.py and qprocess.py"""
# Open the config. Needs a json file with the data in config.json.example
c = open('./config.json')
self.config = load(c)
w = open('./category-whitelist.json')
self.cat_whitelist = load(w)
# Create the api object
self.qbt_client = qbittorrentapi.Client(
host=self.config["host"],
port=self.config["port"],
username=self.config["username"],
password=self.config["password"],
)
# Create the logging and pushover objects
self.tl = logging
self.po = pushover
self.ct = Counter
# Variables torlog uses from config.json
self.use_pushover = self.config["use_pushover"]
self.use_log = self.config["use_log"]
self.po_key = self.config["po_key"]
self.po_token = self.config["po_token"]
self.logpath = self.config["logpath"]
self.loglevel = self.config["loglevel"]
self.tracker_protected_tag = self.config["protected_tag"]
self.tracker_non_protected_tag = self.config["non_protected_tag"]
self.minimum_age = self.config["minimum_age"]
self.age = self.config["age"]
# Calling log and notify functions
torlog(self)
tornotify(self)
self.t = time
# Pulling domain names to treat carefully
f = open('./tracker-whitelist.json')
self.tracker_whitelist = load(f)
self.tracker_list = []
self.up_tor_counter = 0
self.preme_tor_counter = 0
self.ignored_counter = 0
self.torrent_hash_delete_list = []
if self.use_log:
self.tl.debug(self.tracker_whitelist)
#logging in
try:
self.tl.info('Connecting to host.')
self.qbt_client.auth_log_in()
self.tl.info('Connected.')
except qbittorrentapi.APIError as e:
self.tl.exception(e)
self.poc.send_message(e, title="qbit-maid API ERROR")
self.torrentlist = {}
# Pulling all torrent data
self.torrentlist = self.qbt_client.torrents_info()
#Main process block
if self.use_log:
listqbitapiinfo(self)
listfirsttor(self)
buildtorlist(self)
processcounts(self)
#tordeletetags(self)
if self.use_log:
torrentcount(self)
torprocessor(self)
if self.use_log:
printprocessor(self)
if self.use_pushover:
tornotifysummary(self)
if self.config["delete_torrents"]:
tordelete(self)
# Run
if __name__== "__main__":
Qbt()

View File

@ -1,35 +1,35 @@
def buildtorlist(self):
"""Builds multiple lists of torrents to be sorted. Also adds tags to the torents.
There are more effecient ways of doing things but I did this rather quickly.
V2 will certainly be more performant. The reason two lists were used was so that torrents
that are in public trackers woudln't be around as long as torrents from a private tracker.
"""
self.total_torrents = len(self.torrentlist)
while self.torrentlist:
torrent = self.torrentlist.pop()
if self.use_log:
self.tl.debug(f'["{torrent["name"][0:20]}..."] {torrent["infohash_v1"]}')
if torrent['added_on'] + self.minimum_age <= self.t.time():
self.preme_tor_counter += 1
continue
if torrent['category'] in self.cat_whitelist.values():
self.tl.info(f'Ignored torrent:["{torrent["name"][0:20]}..."]')
self.ignored_counter += 1
continue
if torrent['tracker'] == '':
if self.use_log:
self.tl.warning(f'Torrent doesn\'t have a tracker ["{torrent["name"][0:20]}..."] [{torrent["tracker"]}]hash: {torrent["hash"]}')
self.ignored_counter += 1
continue
if torrent['tracker'].split('/')[2] in self.tracker_whitelist.values():
if self.use_log:
self.tl.debug(f'Protected torrent: {torrent["tracker"]}hash: {torrent["hash"]}')
if torrent['tags'] == '':
self.qbt_client.torrents_add_tags(self.tracker_protected_tag,torrent['hash'])
self.tracker_list.append(torrent)
if torrent['tracker'].split('/')[2] not in self.tracker_whitelist.values():
if self.use_log:
self.tl.debug(f'Non-protected torrent: {torrent["tracker"]}hash: {torrent["hash"]}')
if torrent['tags'] == '':
self.qbt_client.torrents_add_tags(self.tracker_non_protected_tag,torrent['hash'])
def buildtorlist(self):
"""Builds multiple lists of torrents to be sorted. Also adds tags to the torents.
There are more effecient ways of doing things but I did this rather quickly.
V2 will certainly be more performant. The reason two lists were used was so that torrents
that are in public trackers woudln't be around as long as torrents from a private tracker.
"""
self.total_torrents = len(self.torrentlist)
while self.torrentlist:
torrent = self.torrentlist.pop()
if self.use_log:
self.tl.debug(f'["{torrent["name"][0:20]}..."] {torrent["infohash_v1"]}')
if torrent['added_on'] + self.minimum_age <= self.t.time():
self.preme_tor_counter += 1
continue
if torrent['category'] in self.cat_whitelist.values():
self.tl.info(f'Ignored torrent:["{torrent["name"][0:20]}..."]')
self.ignored_counter += 1
continue
if torrent['tracker'] == '':
if self.use_log:
self.tl.warning(f'Torrent doesn\'t have a tracker ["{torrent["name"][0:20]}..."] [{torrent["tracker"]}]hash: {torrent["hash"]}')
self.ignored_counter += 1
continue
if torrent['tracker'].split('/')[2] in self.tracker_whitelist.values():
if self.use_log:
self.tl.debug(f'Protected torrent: {torrent["tracker"]}hash: {torrent["hash"]}')
if torrent['tags'] == '':
self.qbt_client.torrents_add_tags(self.tracker_protected_tag,torrent['hash'])
self.tracker_list.append(torrent)
if torrent['tracker'].split('/')[2] not in self.tracker_whitelist.values():
if self.use_log:
self.tl.debug(f'Non-protected torrent: {torrent["tracker"]}hash: {torrent["hash"]}')
if torrent['tags'] == '':
self.qbt_client.torrents_add_tags(self.tracker_non_protected_tag,torrent['hash'])
self.tracker_list.append(torrent)

View File

@ -1,75 +1,75 @@
def torlog(self):
"""Setting up the log file, if self.use_log is set to true and self.loglevel is DEBUG OR INFO"""
if self.use_log:
if self.loglevel == 'DEBUG':
self.tl.basicConfig(filename=self.logpath, format='%(asctime)s:%(levelname)s:%(message)s', encoding='utf-8', datefmt='%m/%d/%Y %I:%M:%S %p',level=self.tl.DEBUG)
elif self.loglevel == 'INFO':
self.tl.basicConfig(filename=self.logpath, format='%(asctime)s:%(levelname)s:%(message)s', encoding='utf-8', datefmt='%m/%d/%Y %I:%M:%S %p',level=self.tl.INFO)
def tornotify(self):
"""Seting up to use pushover, if self.use_pushover is set to true and
if valid self.po_key and self.po_token is provided in the config file"""
if self.use_pushover:
self.poc = self.po.Client(self.po_key, api_token=self.po_token)
def tornotifytest(self):
"""Used to make sure tornotify is working and messages are getting to the client"""
self.poc.send_message("Test Message", title="qbit-maid")
def processcounts(self):
self.c = self.ct()
for item in self.tracker_list:
self.c[item["tags"]] += 1
def printprocessor(self):
"""Print summary of torrents"""
self.tl.info(f'Total: {self.total_torrents}')
self.tl.info(f'Premature: {self.preme_tor_counter}')
self.tl.info(f'Ignored: {self.ignored_counter}')
self.tl.info(f'Protected: {self.c[self.tracker_protected_tag]}')
self.tl.info(f'Non-protected: {self.c[self.tracker_non_protected_tag]}')
self.tl.info(f'Orphaned: {self.up_tor_counter}')
self.tl.info(f'Marked for deletion: {len(self.torrent_hash_delete_list)}')
def tornotifysummary(self):
"""Main notification method when the app is used in an automated fashion"""
self.poc.send_message(f" Total: {self.total_torrents}\n\
Premature: {self.preme_tor_counter}\n\
Ignored: {self.ignored_counter}\n\
Protected: {self.c[self.tracker_protected_tag]}\n\
Non-protected: {self.c[self.tracker_non_protected_tag]}\n\
Orphaned: {self.up_tor_counter}\n\
Marked for deletion: {len(self.torrent_hash_delete_list)}", title="--- qbit-maid summary ---")
def getunixtimestamp(self):
"""Used for debuging and development related to unixtimestamps, not used in main script but useful"""
self.uts = self.t.time()
self.tl.info(self.uts)
def writetor(self, filepath='./torrentinfo.txt'):
"""Write all torrent data to a file.
Useful for development of new features.
"""
with open(filepath, 'w') as fp:
fp.write(str(self.torrentlist))
def listfirsttor(self, index=0):
"""Only lists the first torrent"""
self.tl.debug('First torrent in the list:')
torrent = self.torrentlist[index]
for k,v in torrent.items():
self.tl.debug(f'{k}: {v}')
self.tl.debug('\n')
def listqbitapiinfo(self):
"""Writes torrent info to log file"""
self.tl.debug(f'qBittorrent: {self.qbt_client.app.version}')
self.tl.debug(f'qBittorrent Web API: {self.qbt_client.app.web_api_version}')
def torrentcount(self):
"""write torrent counts to log file"""
self.tl.debug(f'torrents that are protected {self.tracker_list.count("ipt")}')
self.tl.debug(f'torrents that aren\'t protected {self.tracker_list.count("public")}')
def torlisttags(self):
def torlog(self):
"""Setting up the log file, if self.use_log is set to true and self.loglevel is DEBUG OR INFO"""
if self.use_log:
if self.loglevel == 'DEBUG':
self.tl.basicConfig(filename=self.logpath, format='%(asctime)s:%(levelname)s:%(message)s', encoding='utf-8', datefmt='%m/%d/%Y %I:%M:%S %p',level=self.tl.DEBUG)
elif self.loglevel == 'INFO':
self.tl.basicConfig(filename=self.logpath, format='%(asctime)s:%(levelname)s:%(message)s', encoding='utf-8', datefmt='%m/%d/%Y %I:%M:%S %p',level=self.tl.INFO)
def tornotify(self):
"""Seting up to use pushover, if self.use_pushover is set to true and
if valid self.po_key and self.po_token is provided in the config file"""
if self.use_pushover:
self.poc = self.po.Client(self.po_key, api_token=self.po_token)
def tornotifytest(self):
"""Used to make sure tornotify is working and messages are getting to the client"""
self.poc.send_message("Test Message", title="qbit-maid")
def processcounts(self):
self.c = self.ct()
for item in self.tracker_list:
self.c[item["tags"]] += 1
def printprocessor(self):
"""Print summary of torrents"""
self.tl.info(f'Total: {self.total_torrents}')
self.tl.info(f'Premature: {self.preme_tor_counter}')
self.tl.info(f'Ignored: {self.ignored_counter}')
self.tl.info(f'Protected: {self.c[self.tracker_protected_tag]}')
self.tl.info(f'Non-protected: {self.c[self.tracker_non_protected_tag]}')
self.tl.info(f'Orphaned: {self.up_tor_counter}')
self.tl.info(f'Marked for deletion: {len(self.torrent_hash_delete_list)}')
def tornotifysummary(self):
"""Main notification method when the app is used in an automated fashion"""
self.poc.send_message(f" Total: {self.total_torrents}\n\
Premature: {self.preme_tor_counter}\n\
Ignored: {self.ignored_counter}\n\
Protected: {self.c[self.tracker_protected_tag]}\n\
Non-protected: {self.c[self.tracker_non_protected_tag]}\n\
Orphaned: {self.up_tor_counter}\n\
Marked for deletion: {len(self.torrent_hash_delete_list)}", title="--- qbit-maid summary ---")
def getunixtimestamp(self):
"""Used for debuging and development related to unixtimestamps, not used in main script but useful"""
self.uts = self.t.time()
self.tl.info(self.uts)
def writetor(self, filepath='./torrentinfo.txt'):
"""Write all torrent data to a file.
Useful for development of new features.
"""
with open(filepath, 'w') as fp:
fp.write(str(self.torrentlist))
def listfirsttor(self, index=0):
"""Only lists the first torrent"""
self.tl.debug('First torrent in the list:')
torrent = self.torrentlist[index]
for k,v in torrent.items():
self.tl.debug(f'{k}: {v}')
self.tl.debug('\n')
def listqbitapiinfo(self):
"""Writes torrent info to log file"""
self.tl.debug(f'qBittorrent: {self.qbt_client.app.version}')
self.tl.debug(f'qBittorrent Web API: {self.qbt_client.app.web_api_version}')
def torrentcount(self):
"""write torrent counts to log file"""
self.tl.debug(f'torrents that are protected {self.tracker_list.count("ipt")}')
self.tl.debug(f'torrents that aren\'t protected {self.tracker_list.count("public")}')
def torlisttags(self):
pass

View File

@ -1,44 +1,44 @@
def torprocessor(self):
"""Main logic to sort through both self.tracker_nonprotected_list and self.tracker_protected_list
If torrent meets criteria for deletion, its infohash_v1 will be appended to self.torrent_hash_delete_list
"""
for canidate in self.tracker_list:
if canidate['state'] == 'downloading':
if self.use_log:
self.tl.info(f'["{canidate["name"][0:20]}..."] is still downloading and will be skipped.')
continue
elif canidate['ratio'] < float(1.05) and self.tracker_protected_tag in canidate["tags"]:
if self.use_log:
self.tl.debug(f'["{canidate["name"][0:20]}..."] is below a 1.05 ratio({canidate["ratio"]})')
if canidate['added_on'] + self.age <= self.t.time():
if self.use_log:
self.tl.debug(f'["{canidate["name"][0:20]}..."] Seconds old: {self.t.time() - self.age - canidate["added_on"]}')
self.torrent_hash_delete_list.append(canidate['infohash_v1'])
if self.use_log:
self.tl.info(f'Submitted ["{canidate["name"][0:20]}..."] for deletion from the protected list.')
elif canidate['ratio'] >= float(1.05) and self.tracker_protected_tag in canidate["tags"]:
if self.use_log:
self.tl.debug(f'["{canidate["name"][0:20]}..."] is above a 1.05 ratio({canidate["ratio"]}).')
self.torrent_hash_delete_list.append(canidate['infohash_v1'])
if self.use_log:
self.tl.info(f'Submitted ["{canidate["name"][0:20]}..."] for deletion from the protected list.')
elif self.tracker_non_protected_tag in canidate["tags"]:
self.torrent_hash_delete_list.append(canidate['infohash_v1'])
if self.use_log:
self.tl.info(f'Submitted ["{canidate["name"][0:20]}..."] for deletion.')
else:
self.tl.info(f'["{canidate["name"][0:20]}..."] is orphaned.')
self.up_tor_counter += 1
continue
def tordeletetags(self):
tag_list = [self.tracker_protected_tag, self.tracker_non_protected_tag]
self.qbt_client.torrents_delete_tags(tag_list)
def tordelete(self):
"""Remove torrents, will also delete files, this keeps the filesystem clean.
Only pass self.torrent_hash_delete_list if you would like to keep the files."""
if self.use_log:
self.tl.debug('Hash list submitted for deletion:')
self.tl.debug(self.torrent_hash_delete_list)
def torprocessor(self):
"""Main logic to sort through both self.tracker_nonprotected_list and self.tracker_protected_list
If torrent meets criteria for deletion, its infohash_v1 will be appended to self.torrent_hash_delete_list
"""
for canidate in self.tracker_list:
if canidate['state'] == 'downloading':
if self.use_log:
self.tl.info(f'["{canidate["name"][0:20]}..."] is still downloading and will be skipped.')
continue
elif canidate['ratio'] < float(1.05) and self.tracker_protected_tag in canidate["tags"]:
if self.use_log:
self.tl.debug(f'["{canidate["name"][0:20]}..."] is below a 1.05 ratio({canidate["ratio"]})')
if canidate['added_on'] + self.age <= self.t.time():
if self.use_log:
self.tl.debug(f'["{canidate["name"][0:20]}..."] Seconds old: {self.t.time() - self.age - canidate["added_on"]}')
self.torrent_hash_delete_list.append(canidate['infohash_v1'])
if self.use_log:
self.tl.info(f'Submitted ["{canidate["name"][0:20]}..."] for deletion from the protected list.')
elif canidate['ratio'] >= float(1.05) and self.tracker_protected_tag in canidate["tags"]:
if self.use_log:
self.tl.debug(f'["{canidate["name"][0:20]}..."] is above a 1.05 ratio({canidate["ratio"]}).')
self.torrent_hash_delete_list.append(canidate['infohash_v1'])
if self.use_log:
self.tl.info(f'Submitted ["{canidate["name"][0:20]}..."] for deletion from the protected list.')
elif self.tracker_non_protected_tag in canidate["tags"]:
self.torrent_hash_delete_list.append(canidate['infohash_v1'])
if self.use_log:
self.tl.info(f'Submitted ["{canidate["name"][0:20]}..."] for deletion.')
else:
self.tl.info(f'["{canidate["name"][0:20]}..."] is orphaned.')
self.up_tor_counter += 1
continue
def tordeletetags(self):
tag_list = [self.tracker_protected_tag, self.tracker_non_protected_tag]
self.qbt_client.torrents_delete_tags(tag_list)
def tordelete(self):
"""Remove torrents, will also delete files, this keeps the filesystem clean.
Only pass self.torrent_hash_delete_list if you would like to keep the files."""
if self.use_log:
self.tl.debug('Hash list submitted for deletion:')
self.tl.debug(self.torrent_hash_delete_list)
self.qbt_client.torrents_delete(True, self.torrent_hash_delete_list)