mirror of
https://github.com/StuffAnThings/qbit_manage.git
synced 2025-11-10 00:10:46 +08:00
BHD Integration for unregistered torrents #70
This commit is contained in:
parent
b42ef3328c
commit
2d0b7b675b
4 changed files with 102 additions and 44 deletions
|
|
@ -8,7 +8,7 @@ qbt:
|
||||||
pass: "password"
|
pass: "password"
|
||||||
|
|
||||||
settings:
|
settings:
|
||||||
force_auto_tmm: False #Will force qBittorrent to enable Automatic Torrent Managment for each torrent.
|
force_auto_tmm: False # Will force qBittorrent to enable Automatic Torrent Management for each torrent.
|
||||||
|
|
||||||
directory:
|
directory:
|
||||||
# Do not remove these
|
# Do not remove these
|
||||||
|
|
@ -173,3 +173,7 @@ webhooks:
|
||||||
rem_orphaned: notifiarr
|
rem_orphaned: notifiarr
|
||||||
tag_nohardlinks: notifiarr
|
tag_nohardlinks: notifiarr
|
||||||
empty_recyclebin: notifiarr
|
empty_recyclebin: notifiarr
|
||||||
|
|
||||||
|
#BHD Integration used for checking unregistered torrents
|
||||||
|
bhd:
|
||||||
|
apikey:
|
||||||
34
modules/bhd.py
Normal file
34
modules/bhd.py
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from modules.util import Failed
|
||||||
|
from json import JSONDecodeError
|
||||||
|
|
||||||
|
logger = logging.getLogger("qBit Manage")
|
||||||
|
|
||||||
|
base_url = "https://beyond-hd.me/api/"
|
||||||
|
|
||||||
|
class BeyondHD:
|
||||||
|
def __init__(self, config, params):
|
||||||
|
self.config = config
|
||||||
|
self.apikey = params["apikey"]
|
||||||
|
json = {"search":"test"}
|
||||||
|
results = self.search(json)
|
||||||
|
|
||||||
|
def search(self, json, path="torrents/"):
|
||||||
|
url = f"{base_url}{path}{self.apikey}"
|
||||||
|
json["action"] = "search"
|
||||||
|
if self.config.trace_mode:
|
||||||
|
logger.debug(url.replace(self.apikey, "APIKEY"))
|
||||||
|
logger.debug(f"JSON: {json}")
|
||||||
|
try:
|
||||||
|
response = self.config.post(url, json=json)
|
||||||
|
response_json = response.json()
|
||||||
|
except JSONDecodeError as e:
|
||||||
|
if response.status_code >= 400:
|
||||||
|
raise Failed(e)
|
||||||
|
if response.status_code >= 400:
|
||||||
|
logger.debug(f"Response: {response_json}")
|
||||||
|
raise Failed(f"({response.status_code} [{response.reason}]) {response_json}")
|
||||||
|
if not response_json["success"]:
|
||||||
|
raise Failed(f"BHD Error: {response_json['status_message']}")
|
||||||
|
return response.json()
|
||||||
|
|
@ -4,6 +4,7 @@ from modules.util import Failed, check
|
||||||
from modules.qbittorrent import Qbt
|
from modules.qbittorrent import Qbt
|
||||||
from modules.webhooks import Webhooks
|
from modules.webhooks import Webhooks
|
||||||
from modules.notifiarr import Notifiarr
|
from modules.notifiarr import Notifiarr
|
||||||
|
from modules.bhd import BeyondHD
|
||||||
from modules.apprise import Apprise
|
from modules.apprise import Apprise
|
||||||
from ruamel import yaml
|
from ruamel import yaml
|
||||||
from retrying import retry
|
from retrying import retry
|
||||||
|
|
@ -67,6 +68,7 @@ class Config:
|
||||||
hooks("tag_nohardlinks")
|
hooks("tag_nohardlinks")
|
||||||
hooks("empty_recyclebin")
|
hooks("empty_recyclebin")
|
||||||
new_config["webhooks"] = temp
|
new_config["webhooks"] = temp
|
||||||
|
if "bhd" in new_config: new_config["bhd"] = new_config.pop("bhd")
|
||||||
yaml.round_trip_dump(new_config, open(self.config_path, "w", encoding="utf-8"), indent=None, block_seq_indent=2)
|
yaml.round_trip_dump(new_config, open(self.config_path, "w", encoding="utf-8"), indent=None, block_seq_indent=2)
|
||||||
self.data = new_config
|
self.data = new_config
|
||||||
except yaml.scanner.ScannerError as e:
|
except yaml.scanner.ScannerError as e:
|
||||||
|
|
@ -125,6 +127,20 @@ class Config:
|
||||||
util.print_stacktrace()
|
util.print_stacktrace()
|
||||||
logger.error(f"Webhooks Error: {e}")
|
logger.error(f"Webhooks Error: {e}")
|
||||||
|
|
||||||
|
self.BeyondHD = None
|
||||||
|
if "bhd" in self.data:
|
||||||
|
if self.data["bhd"] is not None:
|
||||||
|
logger.info("Connecting to BHD API...")
|
||||||
|
try:
|
||||||
|
self.BeyondHD = BeyondHD(self, {
|
||||||
|
"apikey": self.util.check_for_attribute(self.data, "apikey", parent="bhd", throw=True)
|
||||||
|
})
|
||||||
|
except Failed as e:
|
||||||
|
logger.error(e)
|
||||||
|
self.notify(e,'BHD')
|
||||||
|
logger.info(f"BHD Connection {'Failed' if self.BeyondHD is None else 'Successful'}")
|
||||||
|
|
||||||
|
|
||||||
#nohardlinks
|
#nohardlinks
|
||||||
self.nohardlinks = None
|
self.nohardlinks = None
|
||||||
if "nohardlinks" in self.data and self.args['tag_nohardlinks']:
|
if "nohardlinks" in self.data and self.args['tag_nohardlinks']:
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ class Qbt:
|
||||||
if x.url.startswith('http'):
|
if x.url.startswith('http'):
|
||||||
status = x.status
|
status = x.status
|
||||||
msg = x.msg.upper()
|
msg = x.msg.upper()
|
||||||
exception = ["DOWN","UNREACHABLE","BAD GATEWAY"]
|
exception = ["DOWN","UNREACHABLE","BAD GATEWAY","TRACKER UNAVAILABLE"]
|
||||||
#Add any potential unregistered torrents to a list
|
#Add any potential unregistered torrents to a list
|
||||||
if x.status == 4 and all(x not in msg for x in exception):
|
if x.status == 4 and all(x not in msg for x in exception):
|
||||||
t_obj_unreg.append(torrent)
|
t_obj_unreg.append(torrent)
|
||||||
|
|
@ -349,6 +349,42 @@ class Qbt:
|
||||||
del_tor_cont = 0
|
del_tor_cont = 0
|
||||||
pot_unreg = 0
|
pot_unreg = 0
|
||||||
pot_unr_summary = ''
|
pot_unr_summary = ''
|
||||||
|
|
||||||
|
def del_unregistered():
|
||||||
|
nonlocal dry_run,loglevel,del_tor,del_tor_cont,t_name,msg_up,tracker,t_cat,t_msg,t_status,torrent
|
||||||
|
body = []
|
||||||
|
body += print_line(util.insert_space(f'Torrent Name: {t_name}',3),loglevel)
|
||||||
|
body += print_line(util.insert_space(f'Status: {msg_up}',9),loglevel)
|
||||||
|
body += print_line(util.insert_space(f'Tracker: {tracker["url"]}',8),loglevel)
|
||||||
|
attr = {
|
||||||
|
"function":"rem_unregistered",
|
||||||
|
"title":"Removing Unregistered Torrents",
|
||||||
|
"torrent_name":t_name,
|
||||||
|
"torrent_category":t_cat,
|
||||||
|
"torrent_status": msg_up,
|
||||||
|
"torrent_tracker": tracker["url"],
|
||||||
|
"notifiarr_indexer": tracker["notifiarr"],
|
||||||
|
}
|
||||||
|
if t_count > 1:
|
||||||
|
# Checks if any of the original torrents are working
|
||||||
|
if '' in t_msg or 2 in t_status:
|
||||||
|
if not dry_run: torrent.delete(hash=torrent.hash, delete_files=False)
|
||||||
|
attr["torrents_deleted_and_contents"] = False
|
||||||
|
body += print_line(util.insert_space(f'Deleted .torrent but NOT content files.',8),loglevel)
|
||||||
|
del_tor += 1
|
||||||
|
else:
|
||||||
|
if not dry_run: self.tor_delete_recycle(torrent)
|
||||||
|
attr["torrents_deleted_and_contents"] = True
|
||||||
|
body += print_line(util.insert_space(f'Deleted .torrent AND content files.',8),loglevel)
|
||||||
|
del_tor_cont += 1
|
||||||
|
else:
|
||||||
|
if not dry_run: self.tor_delete_recycle(torrent)
|
||||||
|
attr["torrents_deleted_and_contents"] = True
|
||||||
|
body += print_line(util.insert_space(f'Deleted .torrent AND content files.',8),loglevel)
|
||||||
|
del_tor_cont += 1
|
||||||
|
attr["body"] = "\n".join(body)
|
||||||
|
self.config.send_notifications(attr)
|
||||||
|
|
||||||
if self.config.args['rem_unregistered']:
|
if self.config.args['rem_unregistered']:
|
||||||
separator(f"Removing Unregistered Torrents", space=False, border=False)
|
separator(f"Removing Unregistered Torrents", space=False, border=False)
|
||||||
unreg_msgs = [
|
unreg_msgs = [
|
||||||
|
|
@ -356,18 +392,11 @@ class Qbt:
|
||||||
'TORRENT NOT FOUND',
|
'TORRENT NOT FOUND',
|
||||||
'TORRENT IS NOT FOUND',
|
'TORRENT IS NOT FOUND',
|
||||||
'NOT REGISTERED',
|
'NOT REGISTERED',
|
||||||
'HTTPS://BEYOND-HD.ME/TORRENTS',
|
|
||||||
'NOT EXIST',
|
'NOT EXIST',
|
||||||
'UNKNOWN TORRENT',
|
'UNKNOWN TORRENT',
|
||||||
'REDOWNLOAD',
|
|
||||||
'PACKS',
|
|
||||||
'REPACKED',
|
|
||||||
'PACK',
|
|
||||||
'TRUMP',
|
'TRUMP',
|
||||||
'RETITLED',
|
'RETITLED',
|
||||||
'PRE-RETAIL',
|
'TRUNCATED'
|
||||||
'FULL SEASON',
|
|
||||||
'MASS REMOVAL'
|
|
||||||
]
|
]
|
||||||
for torrent in self.torrentvalid:
|
for torrent in self.torrentvalid:
|
||||||
check_tags = util.get_list(torrent.tags)
|
check_tags = util.get_list(torrent.tags)
|
||||||
|
|
@ -387,6 +416,13 @@ class Qbt:
|
||||||
msg_up = x.msg.upper()
|
msg_up = x.msg.upper()
|
||||||
#Tag any potential unregistered torrents
|
#Tag any potential unregistered torrents
|
||||||
if not any(m in msg_up for m in unreg_msgs) and x.status == 4 and 'issue' not in check_tags:
|
if not any(m in msg_up for m in unreg_msgs) and x.status == 4 and 'issue' not in check_tags:
|
||||||
|
#Check for unregistered torrents using BHD API if the tracker is BHD
|
||||||
|
if 'tracker.beyond-hd.me' in torrent.tracker and self.config.BeyondHD is not None:
|
||||||
|
json = {"info_hash": torrent_hash}
|
||||||
|
response = self.config.BeyondHD.search(json)
|
||||||
|
if response['total_results'] <= 1:
|
||||||
|
del_unregistered()
|
||||||
|
break
|
||||||
pot_unr = ''
|
pot_unr = ''
|
||||||
pot_unr += (util.insert_space(f'Torrent Name: {t_name}',3)+'\n')
|
pot_unr += (util.insert_space(f'Torrent Name: {t_name}',3)+'\n')
|
||||||
pot_unr += (util.insert_space(f'Status: {msg_up}',9)+'\n')
|
pot_unr += (util.insert_space(f'Status: {msg_up}',9)+'\n')
|
||||||
|
|
@ -408,44 +444,12 @@ class Qbt:
|
||||||
self.config.send_notifications(attr)
|
self.config.send_notifications(attr)
|
||||||
if not dry_run: torrent.add_tags(tags='issue')
|
if not dry_run: torrent.add_tags(tags='issue')
|
||||||
if any(m in msg_up for m in unreg_msgs) and x.status == 4:
|
if any(m in msg_up for m in unreg_msgs) and x.status == 4:
|
||||||
body = []
|
del_unregistered()
|
||||||
body += print_line(util.insert_space(f'Torrent Name: {t_name}',3),loglevel)
|
|
||||||
body += print_line(util.insert_space(f'Status: {msg_up}',9),loglevel)
|
|
||||||
body += print_line(util.insert_space(f'Tracker: {tracker["url"]}',8),loglevel)
|
|
||||||
attr = {
|
|
||||||
"function":"rem_unregistered",
|
|
||||||
"title":"Removing Unregistered Torrents",
|
|
||||||
"torrent_name":t_name,
|
|
||||||
"torrent_category":t_cat,
|
|
||||||
"torrent_status": msg_up,
|
|
||||||
"torrent_tracker": tracker["url"],
|
|
||||||
"notifiarr_indexer": tracker["notifiarr"],
|
|
||||||
}
|
|
||||||
if t_count > 1:
|
|
||||||
# Checks if any of the original torrents are working
|
|
||||||
if '' in t_msg or 2 in t_status:
|
|
||||||
if not dry_run: torrent.delete(hash=torrent.hash, delete_files=False)
|
|
||||||
attr["torrents_deleted_and_contents"] = False
|
|
||||||
body += print_line(util.insert_space(f'Deleted .torrent but NOT content files.',8),loglevel)
|
|
||||||
del_tor += 1
|
|
||||||
else:
|
|
||||||
if not dry_run: self.tor_delete_recycle(torrent)
|
|
||||||
attr["torrents_deleted_and_contents"] = True
|
|
||||||
body += print_line(util.insert_space(f'Deleted .torrent AND content files.',8),loglevel)
|
|
||||||
del_tor_cont += 1
|
|
||||||
else:
|
|
||||||
if not dry_run: self.tor_delete_recycle(torrent)
|
|
||||||
attr["torrents_deleted_and_contents"] = True
|
|
||||||
body += print_line(util.insert_space(f'Deleted .torrent AND content files.',8),loglevel)
|
|
||||||
del_tor_cont += 1
|
|
||||||
attr["body"] = "\n".join(body)
|
|
||||||
self.config.send_notifications(attr)
|
|
||||||
if del_tor >=1 or del_tor_cont >=1:
|
if del_tor >=1 or del_tor_cont >=1:
|
||||||
if del_tor >= 1: print_line(f"{'Did not delete' if dry_run else 'Deleted'} {del_tor} .torrent{'s' if del_tor > 1 else ''} but not content files.",loglevel)
|
if del_tor >= 1: print_line(f"{'Did not delete' if dry_run else 'Deleted'} {del_tor} .torrent{'s' if del_tor > 1 else ''} but not content files.",loglevel)
|
||||||
if del_tor_cont >= 1: print_line(f"{'Did not delete' if dry_run else 'Deleted'} {del_tor_cont} .torrent{'s' if del_tor_cont > 1 else ''} AND content files.",loglevel)
|
if del_tor_cont >= 1: print_line(f"{'Did not delete' if dry_run else 'Deleted'} {del_tor_cont} .torrent{'s' if del_tor_cont > 1 else ''} AND content files.",loglevel)
|
||||||
else:
|
else:
|
||||||
print_line('No unregistered torrents found.',loglevel)
|
print_line('No unregistered torrents found.',loglevel)
|
||||||
|
|
||||||
if (pot_unreg > 0):
|
if (pot_unreg > 0):
|
||||||
separator(f"{pot_unreg} Potential Unregistered torrents found", space=False, border=False,loglevel=loglevel)
|
separator(f"{pot_unreg} Potential Unregistered torrents found", space=False, border=False,loglevel=loglevel)
|
||||||
print_multiline(pot_unr_summary.rstrip(),loglevel)
|
print_multiline(pot_unr_summary.rstrip(),loglevel)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue