empty
This commit is contained in:
parent
26ac36a164
commit
fca54f8952
152
README.md
152
README.md
@ -1,77 +1,77 @@
|
|||||||
# qbit-maid
|
# 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.
|
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:
|
The objective is to remove torrents based on the following criteria:
|
||||||
- tracker domain name
|
- tracker domain name
|
||||||
- age
|
- age
|
||||||
- ratio
|
- ratio
|
||||||
- state
|
- state
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
graph TD;
|
graph TD;
|
||||||
qbit-maid.py-->qlogging.py;
|
qbit-maid.py-->qlogging.py;
|
||||||
qbit-maid.py-->qlist.py;
|
qbit-maid.py-->qlist.py;
|
||||||
qbit-maid.py-->qprocess.py;
|
qbit-maid.py-->qprocess.py;
|
||||||
qlogging.py-->qbit-maid.py;
|
qlogging.py-->qbit-maid.py;
|
||||||
qlist.py-->qbit-maid.py;
|
qlist.py-->qbit-maid.py;
|
||||||
qprocess.py-->qbit-maid.py;
|
qprocess.py-->qbit-maid.py;
|
||||||
```
|
```
|
||||||
|
|
||||||
| File | Purpose |
|
| File | Purpose |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| qbit-maid.py | Client to the qbit api and calls functions from the other files |
|
| qbit-maid.py | Client to the qbit api and calls functions from the other files |
|
||||||
| qlist.py | Builds out torrent lists |
|
| qlist.py | Builds out torrent lists |
|
||||||
| qlogging.py | Logging and push notification communication |
|
| qlogging.py | Logging and push notification communication |
|
||||||
| qprocess.py | Submits qualifying torrents for deletion |
|
| qprocess.py | Submits qualifying torrents for deletion |
|
||||||
|
|
||||||
You will need a config.json in the root directory.
|
You will need a config.json in the root directory.
|
||||||
|
|
||||||
It should look something like this:
|
It should look something like this:
|
||||||
Config.json
|
Config.json
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"host": "192.168.1.1",
|
"host": "192.168.1.1",
|
||||||
"port": 8080,
|
"port": 8080,
|
||||||
"username": "admin",
|
"username": "admin",
|
||||||
"password": "admin",
|
"password": "admin",
|
||||||
"loglevel": "INFO",
|
"loglevel": "INFO",
|
||||||
"logpath": "./qc.log",
|
"logpath": "./qc.log",
|
||||||
"protected_tag": "ipt",
|
"protected_tag": "ipt",
|
||||||
"non_protected_tag": "public",
|
"non_protected_tag": "public",
|
||||||
"age": 2419200,
|
"age": 2419200,
|
||||||
"minimum_age": 432000,
|
"minimum_age": 432000,
|
||||||
"use_pushover": false,
|
"use_pushover": false,
|
||||||
"use_log": true,
|
"use_log": true,
|
||||||
"po_key": "",
|
"po_key": "",
|
||||||
"po_token": "",
|
"po_token": "",
|
||||||
"delete_torrents": false
|
"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.
|
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",
|
"example": "general",
|
||||||
"example2": "sonarr"
|
"example2": "sonarr"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
| Key | Value |
|
| Key | Value |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| host | string, ip or hostname of qbittorrent server |
|
| host | string, ip or hostname of qbittorrent server |
|
||||||
| port | number, port of admin gui(used for api aswell) |
|
| port | number, port of admin gui(used for api aswell) |
|
||||||
| username | admin account for qbittorrent |
|
| username | admin account for qbittorrent |
|
||||||
| password | password for admin account |
|
| password | password for admin account |
|
||||||
| loglevel | is what log messages are written to the log file. INFO or DEBUG are valid entries(case sensitive) |
|
| 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 |
|
| protected_tag | used to mark torrents to handle with care |
|
||||||
| non_protected_tag | we don't care about these torrents |
|
| 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 |
|
| 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 |
|
| age | number, seconds for how long we keep torrents from IPTORRENTS |
|
||||||
| minimum_age | age in seconds torrents should reached before they are removed |
|
| 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_pushover | true or false to enable or disable pushover notification summary |
|
||||||
| use_log | true or false to enable or disable writing to alog file |
|
| use_log | true or false to enable or disable writing to alog file |
|
||||||
| po_key | pushover key |
|
| po_key | pushover key |
|
||||||
| po_token | pushover api token |
|
| po_token | pushover api token |
|
||||||
| delete_torrents | true or false to enable or disable deletion. Useful for dry-runs |
|
| delete_torrents | true or false to enable or disable deletion. Useful for dry-runs |
|
@ -1,17 +1,17 @@
|
|||||||
{
|
{
|
||||||
"host": "192.168.1.1",
|
"host": "192.168.1.1",
|
||||||
"port": 8080,
|
"port": 8080,
|
||||||
"username": "admin",
|
"username": "admin",
|
||||||
"password": "admin",
|
"password": "admin",
|
||||||
"loglevel": "INFO",
|
"loglevel": "INFO",
|
||||||
"logpath": "./qc.log",
|
"logpath": "./qc.log",
|
||||||
"protected_tag": "ipt",
|
"protected_tag": "ipt",
|
||||||
"non_protected_tag": "public",
|
"non_protected_tag": "public",
|
||||||
"age": 2419200,
|
"age": 2419200,
|
||||||
"minimum_age": 432000,
|
"minimum_age": 432000,
|
||||||
"use_pushover": true,
|
"use_pushover": true,
|
||||||
"use_log": true,
|
"use_log": true,
|
||||||
"po_key": "",
|
"po_key": "",
|
||||||
"po_token": "",
|
"po_token": "",
|
||||||
"delete_torrents": false
|
"delete_torrents": false
|
||||||
}
|
}
|
170
qbit-maid.py
Normal file → Executable file
170
qbit-maid.py
Normal file → Executable file
@ -1,86 +1,86 @@
|
|||||||
#The first file shall contain an client to the qbit api and the processing of the torrents.
|
#The first file shall contain an client to the qbit api and the processing of the torrents.
|
||||||
import qbittorrentapi
|
import qbittorrentapi
|
||||||
import pushover
|
import pushover
|
||||||
from json import load
|
from json import load
|
||||||
from qlist import *
|
from qlist import *
|
||||||
from qlogging import *
|
from qlogging import *
|
||||||
from qprocess import *
|
from qprocess import *
|
||||||
import time
|
import time
|
||||||
import logging
|
import logging
|
||||||
from collections import Counter
|
from collections import Counter
|
||||||
|
|
||||||
class Qbt:
|
class Qbt:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
"""Main object, should be calling functions from qlist.py, qlogging.py and qprocess.py"""
|
"""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
|
# Open the config. Needs a json file with the data in config.json.example
|
||||||
c = open('./config.json')
|
c = open('./config.json')
|
||||||
self.config = load(c)
|
self.config = load(c)
|
||||||
w = open('./category-whitelist.json')
|
w = open('./category-whitelist.json')
|
||||||
self.cat_whitelist = load(w)
|
self.cat_whitelist = load(w)
|
||||||
# Create the api object
|
# Create the api object
|
||||||
self.qbt_client = qbittorrentapi.Client(
|
self.qbt_client = qbittorrentapi.Client(
|
||||||
host=self.config["host"],
|
host=self.config["host"],
|
||||||
port=self.config["port"],
|
port=self.config["port"],
|
||||||
username=self.config["username"],
|
username=self.config["username"],
|
||||||
password=self.config["password"],
|
password=self.config["password"],
|
||||||
)
|
)
|
||||||
# Create the logging and pushover objects
|
# Create the logging and pushover objects
|
||||||
self.tl = logging
|
self.tl = logging
|
||||||
self.po = pushover
|
self.po = pushover
|
||||||
self.ct = Counter
|
self.ct = Counter
|
||||||
# Variables torlog uses from config.json
|
# Variables torlog uses from config.json
|
||||||
self.use_pushover = self.config["use_pushover"]
|
self.use_pushover = self.config["use_pushover"]
|
||||||
self.use_log = self.config["use_log"]
|
self.use_log = self.config["use_log"]
|
||||||
self.po_key = self.config["po_key"]
|
self.po_key = self.config["po_key"]
|
||||||
self.po_token = self.config["po_token"]
|
self.po_token = self.config["po_token"]
|
||||||
self.logpath = self.config["logpath"]
|
self.logpath = self.config["logpath"]
|
||||||
self.loglevel = self.config["loglevel"]
|
self.loglevel = self.config["loglevel"]
|
||||||
self.tracker_protected_tag = self.config["protected_tag"]
|
self.tracker_protected_tag = self.config["protected_tag"]
|
||||||
self.tracker_non_protected_tag = self.config["non_protected_tag"]
|
self.tracker_non_protected_tag = self.config["non_protected_tag"]
|
||||||
self.minimum_age = self.config["minimum_age"]
|
self.minimum_age = self.config["minimum_age"]
|
||||||
self.age = self.config["age"]
|
self.age = self.config["age"]
|
||||||
# Calling log and notify functions
|
# Calling log and notify functions
|
||||||
torlog(self)
|
torlog(self)
|
||||||
tornotify(self)
|
tornotify(self)
|
||||||
self.t = time
|
self.t = time
|
||||||
# Pulling domain names to treat carefully
|
# Pulling domain names to treat carefully
|
||||||
f = open('./tracker-whitelist.json')
|
f = open('./tracker-whitelist.json')
|
||||||
self.tracker_whitelist = load(f)
|
self.tracker_whitelist = load(f)
|
||||||
self.tracker_list = []
|
self.tracker_list = []
|
||||||
self.up_tor_counter = 0
|
self.up_tor_counter = 0
|
||||||
self.preme_tor_counter = 0
|
self.preme_tor_counter = 0
|
||||||
self.ignored_counter = 0
|
self.ignored_counter = 0
|
||||||
self.torrent_hash_delete_list = []
|
self.torrent_hash_delete_list = []
|
||||||
if self.use_log:
|
if self.use_log:
|
||||||
self.tl.debug(self.tracker_whitelist)
|
self.tl.debug(self.tracker_whitelist)
|
||||||
#logging in
|
#logging in
|
||||||
try:
|
try:
|
||||||
self.tl.info('Connecting to host.')
|
self.tl.info('Connecting to host.')
|
||||||
self.qbt_client.auth_log_in()
|
self.qbt_client.auth_log_in()
|
||||||
self.tl.info('Connected.')
|
self.tl.info('Connected.')
|
||||||
except qbittorrentapi.APIError as e:
|
except qbittorrentapi.APIError as e:
|
||||||
self.tl.exception(e)
|
self.tl.exception(e)
|
||||||
self.poc.send_message(e, title="qbit-maid API ERROR")
|
self.poc.send_message(e, title="qbit-maid API ERROR")
|
||||||
self.torrentlist = {}
|
self.torrentlist = {}
|
||||||
# Pulling all torrent data
|
# Pulling all torrent data
|
||||||
self.torrentlist = self.qbt_client.torrents_info()
|
self.torrentlist = self.qbt_client.torrents_info()
|
||||||
#Main process block
|
#Main process block
|
||||||
if self.use_log:
|
if self.use_log:
|
||||||
listqbitapiinfo(self)
|
listqbitapiinfo(self)
|
||||||
listfirsttor(self)
|
listfirsttor(self)
|
||||||
buildtorlist(self)
|
buildtorlist(self)
|
||||||
processcounts(self)
|
processcounts(self)
|
||||||
#tordeletetags(self)
|
#tordeletetags(self)
|
||||||
if self.use_log:
|
if self.use_log:
|
||||||
torrentcount(self)
|
torrentcount(self)
|
||||||
torprocessor(self)
|
torprocessor(self)
|
||||||
if self.use_log:
|
if self.use_log:
|
||||||
printprocessor(self)
|
printprocessor(self)
|
||||||
if self.use_pushover:
|
if self.use_pushover:
|
||||||
tornotifysummary(self)
|
tornotifysummary(self)
|
||||||
if self.config["delete_torrents"]:
|
if self.config["delete_torrents"]:
|
||||||
tordelete(self)
|
tordelete(self)
|
||||||
|
|
||||||
# Run
|
# Run
|
||||||
if __name__== "__main__":
|
if __name__== "__main__":
|
||||||
Qbt()
|
Qbt()
|
68
qlist.py
68
qlist.py
@ -1,35 +1,35 @@
|
|||||||
def buildtorlist(self):
|
def buildtorlist(self):
|
||||||
"""Builds multiple lists of torrents to be sorted. Also adds tags to the torents.
|
"""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.
|
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
|
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.
|
that are in public trackers woudln't be around as long as torrents from a private tracker.
|
||||||
"""
|
"""
|
||||||
self.total_torrents = len(self.torrentlist)
|
self.total_torrents = len(self.torrentlist)
|
||||||
while self.torrentlist:
|
while self.torrentlist:
|
||||||
torrent = self.torrentlist.pop()
|
torrent = self.torrentlist.pop()
|
||||||
if self.use_log:
|
if self.use_log:
|
||||||
self.tl.debug(f'["{torrent["name"][0:20]}..."] {torrent["infohash_v1"]}')
|
self.tl.debug(f'["{torrent["name"][0:20]}..."] {torrent["infohash_v1"]}')
|
||||||
if torrent['added_on'] + self.minimum_age <= self.t.time():
|
if torrent['added_on'] + self.minimum_age <= self.t.time():
|
||||||
self.preme_tor_counter += 1
|
self.preme_tor_counter += 1
|
||||||
continue
|
continue
|
||||||
if torrent['category'] in self.cat_whitelist.values():
|
if torrent['category'] in self.cat_whitelist.values():
|
||||||
self.tl.info(f'Ignored torrent:["{torrent["name"][0:20]}..."]')
|
self.tl.info(f'Ignored torrent:["{torrent["name"][0:20]}..."]')
|
||||||
self.ignored_counter += 1
|
self.ignored_counter += 1
|
||||||
continue
|
continue
|
||||||
if torrent['tracker'] == '':
|
if torrent['tracker'] == '':
|
||||||
if self.use_log:
|
if self.use_log:
|
||||||
self.tl.warning(f'Torrent doesn\'t have a tracker ["{torrent["name"][0:20]}..."] [{torrent["tracker"]}]hash: {torrent["hash"]}')
|
self.tl.warning(f'Torrent doesn\'t have a tracker ["{torrent["name"][0:20]}..."] [{torrent["tracker"]}]hash: {torrent["hash"]}')
|
||||||
self.ignored_counter += 1
|
self.ignored_counter += 1
|
||||||
continue
|
continue
|
||||||
if torrent['tracker'].split('/')[2] in self.tracker_whitelist.values():
|
if torrent['tracker'].split('/')[2] in self.tracker_whitelist.values():
|
||||||
if self.use_log:
|
if self.use_log:
|
||||||
self.tl.debug(f'Protected torrent: {torrent["tracker"]}hash: {torrent["hash"]}')
|
self.tl.debug(f'Protected torrent: {torrent["tracker"]}hash: {torrent["hash"]}')
|
||||||
if torrent['tags'] == '':
|
if torrent['tags'] == '':
|
||||||
self.qbt_client.torrents_add_tags(self.tracker_protected_tag,torrent['hash'])
|
self.qbt_client.torrents_add_tags(self.tracker_protected_tag,torrent['hash'])
|
||||||
self.tracker_list.append(torrent)
|
self.tracker_list.append(torrent)
|
||||||
if torrent['tracker'].split('/')[2] not in self.tracker_whitelist.values():
|
if torrent['tracker'].split('/')[2] not in self.tracker_whitelist.values():
|
||||||
if self.use_log:
|
if self.use_log:
|
||||||
self.tl.debug(f'Non-protected torrent: {torrent["tracker"]}hash: {torrent["hash"]}')
|
self.tl.debug(f'Non-protected torrent: {torrent["tracker"]}hash: {torrent["hash"]}')
|
||||||
if torrent['tags'] == '':
|
if torrent['tags'] == '':
|
||||||
self.qbt_client.torrents_add_tags(self.tracker_non_protected_tag,torrent['hash'])
|
self.qbt_client.torrents_add_tags(self.tracker_non_protected_tag,torrent['hash'])
|
||||||
self.tracker_list.append(torrent)
|
self.tracker_list.append(torrent)
|
148
qlogging.py
148
qlogging.py
@ -1,75 +1,75 @@
|
|||||||
def torlog(self):
|
def torlog(self):
|
||||||
"""Setting up the log file, if self.use_log is set to true and self.loglevel is DEBUG OR INFO"""
|
"""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.use_log:
|
||||||
if self.loglevel == 'DEBUG':
|
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)
|
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':
|
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)
|
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):
|
def tornotify(self):
|
||||||
"""Seting up to use pushover, if self.use_pushover is set to true and
|
"""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 valid self.po_key and self.po_token is provided in the config file"""
|
||||||
if self.use_pushover:
|
if self.use_pushover:
|
||||||
self.poc = self.po.Client(self.po_key, api_token=self.po_token)
|
self.poc = self.po.Client(self.po_key, api_token=self.po_token)
|
||||||
|
|
||||||
def tornotifytest(self):
|
def tornotifytest(self):
|
||||||
"""Used to make sure tornotify is working and messages are getting to the client"""
|
"""Used to make sure tornotify is working and messages are getting to the client"""
|
||||||
self.poc.send_message("Test Message", title="qbit-maid")
|
self.poc.send_message("Test Message", title="qbit-maid")
|
||||||
|
|
||||||
def processcounts(self):
|
def processcounts(self):
|
||||||
self.c = self.ct()
|
self.c = self.ct()
|
||||||
for item in self.tracker_list:
|
for item in self.tracker_list:
|
||||||
self.c[item["tags"]] += 1
|
self.c[item["tags"]] += 1
|
||||||
|
|
||||||
def printprocessor(self):
|
def printprocessor(self):
|
||||||
"""Print summary of torrents"""
|
"""Print summary of torrents"""
|
||||||
self.tl.info(f'Total: {self.total_torrents}')
|
self.tl.info(f'Total: {self.total_torrents}')
|
||||||
self.tl.info(f'Premature: {self.preme_tor_counter}')
|
self.tl.info(f'Premature: {self.preme_tor_counter}')
|
||||||
self.tl.info(f'Ignored: {self.ignored_counter}')
|
self.tl.info(f'Ignored: {self.ignored_counter}')
|
||||||
self.tl.info(f'Protected: {self.c[self.tracker_protected_tag]}')
|
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'Non-protected: {self.c[self.tracker_non_protected_tag]}')
|
||||||
self.tl.info(f'Orphaned: {self.up_tor_counter}')
|
self.tl.info(f'Orphaned: {self.up_tor_counter}')
|
||||||
self.tl.info(f'Marked for deletion: {len(self.torrent_hash_delete_list)}')
|
self.tl.info(f'Marked for deletion: {len(self.torrent_hash_delete_list)}')
|
||||||
|
|
||||||
def tornotifysummary(self):
|
def tornotifysummary(self):
|
||||||
"""Main notification method when the app is used in an automated fashion"""
|
"""Main notification method when the app is used in an automated fashion"""
|
||||||
self.poc.send_message(f" Total: {self.total_torrents}\n\
|
self.poc.send_message(f" Total: {self.total_torrents}\n\
|
||||||
Premature: {self.preme_tor_counter}\n\
|
Premature: {self.preme_tor_counter}\n\
|
||||||
Ignored: {self.ignored_counter}\n\
|
Ignored: {self.ignored_counter}\n\
|
||||||
Protected: {self.c[self.tracker_protected_tag]}\n\
|
Protected: {self.c[self.tracker_protected_tag]}\n\
|
||||||
Non-protected: {self.c[self.tracker_non_protected_tag]}\n\
|
Non-protected: {self.c[self.tracker_non_protected_tag]}\n\
|
||||||
Orphaned: {self.up_tor_counter}\n\
|
Orphaned: {self.up_tor_counter}\n\
|
||||||
Marked for deletion: {len(self.torrent_hash_delete_list)}", title="--- qbit-maid summary ---")
|
Marked for deletion: {len(self.torrent_hash_delete_list)}", title="--- qbit-maid summary ---")
|
||||||
|
|
||||||
def getunixtimestamp(self):
|
def getunixtimestamp(self):
|
||||||
"""Used for debuging and development related to unixtimestamps, not used in main script but useful"""
|
"""Used for debuging and development related to unixtimestamps, not used in main script but useful"""
|
||||||
self.uts = self.t.time()
|
self.uts = self.t.time()
|
||||||
self.tl.info(self.uts)
|
self.tl.info(self.uts)
|
||||||
|
|
||||||
def writetor(self, filepath='./torrentinfo.txt'):
|
def writetor(self, filepath='./torrentinfo.txt'):
|
||||||
"""Write all torrent data to a file.
|
"""Write all torrent data to a file.
|
||||||
Useful for development of new features.
|
Useful for development of new features.
|
||||||
"""
|
"""
|
||||||
with open(filepath, 'w') as fp:
|
with open(filepath, 'w') as fp:
|
||||||
fp.write(str(self.torrentlist))
|
fp.write(str(self.torrentlist))
|
||||||
|
|
||||||
def listfirsttor(self, index=0):
|
def listfirsttor(self, index=0):
|
||||||
"""Only lists the first torrent"""
|
"""Only lists the first torrent"""
|
||||||
self.tl.debug('First torrent in the list:')
|
self.tl.debug('First torrent in the list:')
|
||||||
torrent = self.torrentlist[index]
|
torrent = self.torrentlist[index]
|
||||||
for k,v in torrent.items():
|
for k,v in torrent.items():
|
||||||
self.tl.debug(f'{k}: {v}')
|
self.tl.debug(f'{k}: {v}')
|
||||||
self.tl.debug('\n')
|
self.tl.debug('\n')
|
||||||
|
|
||||||
def listqbitapiinfo(self):
|
def listqbitapiinfo(self):
|
||||||
"""Writes torrent info to log file"""
|
"""Writes torrent info to log file"""
|
||||||
self.tl.debug(f'qBittorrent: {self.qbt_client.app.version}')
|
self.tl.debug(f'qBittorrent: {self.qbt_client.app.version}')
|
||||||
self.tl.debug(f'qBittorrent Web API: {self.qbt_client.app.web_api_version}')
|
self.tl.debug(f'qBittorrent Web API: {self.qbt_client.app.web_api_version}')
|
||||||
|
|
||||||
def torrentcount(self):
|
def torrentcount(self):
|
||||||
"""write torrent counts to log file"""
|
"""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 are protected {self.tracker_list.count("ipt")}')
|
||||||
self.tl.debug(f'torrents that aren\'t protected {self.tracker_list.count("public")}')
|
self.tl.debug(f'torrents that aren\'t protected {self.tracker_list.count("public")}')
|
||||||
|
|
||||||
def torlisttags(self):
|
def torlisttags(self):
|
||||||
pass
|
pass
|
86
qprocess.py
86
qprocess.py
@ -1,44 +1,44 @@
|
|||||||
def torprocessor(self):
|
def torprocessor(self):
|
||||||
"""Main logic to sort through both self.tracker_nonprotected_list and self.tracker_protected_list
|
"""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
|
If torrent meets criteria for deletion, its infohash_v1 will be appended to self.torrent_hash_delete_list
|
||||||
"""
|
"""
|
||||||
for canidate in self.tracker_list:
|
for canidate in self.tracker_list:
|
||||||
if canidate['state'] == 'downloading':
|
if canidate['state'] == 'downloading':
|
||||||
if self.use_log:
|
if self.use_log:
|
||||||
self.tl.info(f'["{canidate["name"][0:20]}..."] is still downloading and will be skipped.')
|
self.tl.info(f'["{canidate["name"][0:20]}..."] is still downloading and will be skipped.')
|
||||||
continue
|
continue
|
||||||
elif canidate['ratio'] < float(1.05) and self.tracker_protected_tag in canidate["tags"]:
|
elif canidate['ratio'] < float(1.05) and self.tracker_protected_tag in canidate["tags"]:
|
||||||
if self.use_log:
|
if self.use_log:
|
||||||
self.tl.debug(f'["{canidate["name"][0:20]}..."] is below a 1.05 ratio({canidate["ratio"]})')
|
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 canidate['added_on'] + self.age <= self.t.time():
|
||||||
if self.use_log:
|
if self.use_log:
|
||||||
self.tl.debug(f'["{canidate["name"][0:20]}..."] Seconds old: {self.t.time() - self.age - canidate["added_on"]}')
|
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'])
|
self.torrent_hash_delete_list.append(canidate['infohash_v1'])
|
||||||
if self.use_log:
|
if self.use_log:
|
||||||
self.tl.info(f'Submitted ["{canidate["name"][0:20]}..."] for deletion from the protected list.')
|
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"]:
|
elif canidate['ratio'] >= float(1.05) and self.tracker_protected_tag in canidate["tags"]:
|
||||||
if self.use_log:
|
if self.use_log:
|
||||||
self.tl.debug(f'["{canidate["name"][0:20]}..."] is above a 1.05 ratio({canidate["ratio"]}).')
|
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'])
|
self.torrent_hash_delete_list.append(canidate['infohash_v1'])
|
||||||
if self.use_log:
|
if self.use_log:
|
||||||
self.tl.info(f'Submitted ["{canidate["name"][0:20]}..."] for deletion from the protected list.')
|
self.tl.info(f'Submitted ["{canidate["name"][0:20]}..."] for deletion from the protected list.')
|
||||||
elif self.tracker_non_protected_tag in canidate["tags"]:
|
elif self.tracker_non_protected_tag in canidate["tags"]:
|
||||||
self.torrent_hash_delete_list.append(canidate['infohash_v1'])
|
self.torrent_hash_delete_list.append(canidate['infohash_v1'])
|
||||||
if self.use_log:
|
if self.use_log:
|
||||||
self.tl.info(f'Submitted ["{canidate["name"][0:20]}..."] for deletion.')
|
self.tl.info(f'Submitted ["{canidate["name"][0:20]}..."] for deletion.')
|
||||||
else:
|
else:
|
||||||
self.tl.info(f'["{canidate["name"][0:20]}..."] is orphaned.')
|
self.tl.info(f'["{canidate["name"][0:20]}..."] is orphaned.')
|
||||||
self.up_tor_counter += 1
|
self.up_tor_counter += 1
|
||||||
continue
|
continue
|
||||||
|
|
||||||
def tordeletetags(self):
|
def tordeletetags(self):
|
||||||
tag_list = [self.tracker_protected_tag, self.tracker_non_protected_tag]
|
tag_list = [self.tracker_protected_tag, self.tracker_non_protected_tag]
|
||||||
self.qbt_client.torrents_delete_tags(tag_list)
|
self.qbt_client.torrents_delete_tags(tag_list)
|
||||||
|
|
||||||
def tordelete(self):
|
def tordelete(self):
|
||||||
"""Remove torrents, will also delete files, this keeps the filesystem clean.
|
"""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."""
|
Only pass self.torrent_hash_delete_list if you would like to keep the files."""
|
||||||
if self.use_log:
|
if self.use_log:
|
||||||
self.tl.debug('Hash list submitted for deletion:')
|
self.tl.debug('Hash list submitted for deletion:')
|
||||||
self.tl.debug(self.torrent_hash_delete_list)
|
self.tl.debug(self.torrent_hash_delete_list)
|
||||||
self.qbt_client.torrents_delete(True, self.torrent_hash_delete_list)
|
self.qbt_client.torrents_delete(True, self.torrent_hash_delete_list)
|
Loading…
x
Reference in New Issue
Block a user