BHD Integration for unregistered torrents #70

This commit is contained in:
bobokun 2021-12-27 14:53:24 -05:00
parent b42ef3328c
commit 2d0b7b675b
No known key found for this signature in database
GPG key ID: 9665BA6CF5DC2671
4 changed files with 102 additions and 44 deletions

View file

@ -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
View 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()

View file

@ -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']:

View file

@ -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,65 +349,9 @@ class Qbt:
del_tor_cont = 0 del_tor_cont = 0
pot_unreg = 0 pot_unreg = 0
pot_unr_summary = '' pot_unr_summary = ''
if self.config.args['rem_unregistered']:
separator(f"Removing Unregistered Torrents", space=False, border=False) def del_unregistered():
unreg_msgs = [ nonlocal dry_run,loglevel,del_tor,del_tor_cont,t_name,msg_up,tracker,t_cat,t_msg,t_status,torrent
'UNREGISTERED',
'TORRENT NOT FOUND',
'TORRENT IS NOT FOUND',
'NOT REGISTERED',
'HTTPS://BEYOND-HD.ME/TORRENTS',
'NOT EXIST',
'UNKNOWN TORRENT',
'REDOWNLOAD',
'PACKS',
'REPACKED',
'PACK',
'TRUMP',
'RETITLED',
'PRE-RETAIL',
'FULL SEASON',
'MASS REMOVAL'
]
for torrent in self.torrentvalid:
check_tags = util.get_list(torrent.tags)
#Remove any potential unregistered torrents Tags that are no longer unreachable.
if 'issue' in check_tags:
if not dry_run: torrent.remove_tags(tags='issue')
for torrent in self.torrentissue:
t_name = torrent.name
t_cat = self.torrentinfo[t_name]['Category']
t_count = self.torrentinfo[t_name]['count']
t_msg = self.torrentinfo[t_name]['msg']
t_status = self.torrentinfo[t_name]['status']
check_tags = util.get_list(torrent.tags)
for x in torrent.trackers:
if x.url.startswith('http'):
tracker = self.config.get_tags([x.url])
msg_up = x.msg.upper()
#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:
pot_unr = ''
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'Tracker: {tracker["url"]}',8)+'\n')
pot_unr += (util.insert_space(f"Added Tag: 'issue'",6)+'\n')
pot_unr_summary += pot_unr
pot_unreg += 1
attr = {
"function":"potential_rem_unregistered",
"title":"Potential Unregistered Torrents",
"body": pot_unr,
"torrent_name":t_name,
"torrent_category":t_cat,
"torrent_add_tag": "issue",
"torrent_status": msg_up,
"torrent_tracker": tracker["url"],
"notifiarr_indexer": tracker["notifiarr"],
}
self.config.send_notifications(attr)
if not dry_run: torrent.add_tags(tags='issue')
if any(m in msg_up for m in unreg_msgs) and x.status == 4:
body = [] body = []
body += print_line(util.insert_space(f'Torrent Name: {t_name}',3),loglevel) 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'Status: {msg_up}',9),loglevel)
@ -440,12 +384,72 @@ class Qbt:
del_tor_cont += 1 del_tor_cont += 1
attr["body"] = "\n".join(body) attr["body"] = "\n".join(body)
self.config.send_notifications(attr) self.config.send_notifications(attr)
if self.config.args['rem_unregistered']:
separator(f"Removing Unregistered Torrents", space=False, border=False)
unreg_msgs = [
'UNREGISTERED',
'TORRENT NOT FOUND',
'TORRENT IS NOT FOUND',
'NOT REGISTERED',
'NOT EXIST',
'UNKNOWN TORRENT',
'TRUMP',
'RETITLED',
'TRUNCATED'
]
for torrent in self.torrentvalid:
check_tags = util.get_list(torrent.tags)
#Remove any potential unregistered torrents Tags that are no longer unreachable.
if 'issue' in check_tags:
if not dry_run: torrent.remove_tags(tags='issue')
for torrent in self.torrentissue:
t_name = torrent.name
t_cat = self.torrentinfo[t_name]['Category']
t_count = self.torrentinfo[t_name]['count']
t_msg = self.torrentinfo[t_name]['msg']
t_status = self.torrentinfo[t_name]['status']
check_tags = util.get_list(torrent.tags)
for x in torrent.trackers:
if x.url.startswith('http'):
tracker = self.config.get_tags([x.url])
msg_up = x.msg.upper()
#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:
#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 += (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'Tracker: {tracker["url"]}',8)+'\n')
pot_unr += (util.insert_space(f"Added Tag: 'issue'",6)+'\n')
pot_unr_summary += pot_unr
pot_unreg += 1
attr = {
"function":"potential_rem_unregistered",
"title":"Potential Unregistered Torrents",
"body": pot_unr,
"torrent_name":t_name,
"torrent_category":t_cat,
"torrent_add_tag": "issue",
"torrent_status": msg_up,
"torrent_tracker": tracker["url"],
"notifiarr_indexer": tracker["notifiarr"],
}
self.config.send_notifications(attr)
if not dry_run: torrent.add_tags(tags='issue')
if any(m in msg_up for m in unreg_msgs) and x.status == 4:
del_unregistered()
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)