Skip to content

Commit

Permalink
feat: update tagging command tags and add site tag
Browse files Browse the repository at this point in the history
Signed-off-by: Devin Buhl <[email protected]>
  • Loading branch information
onedr0p committed Aug 24, 2023
1 parent a77bfeb commit c880a69
Showing 1 changed file with 109 additions and 66 deletions.
175 changes: 109 additions & 66 deletions qbittools/commands/tagging.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,63 +9,98 @@

import qbittools

DEFAULT_TAGS = [
'activity:',
'added:',
'dupe',
'not-linked',
'not-working',
'unregistered',
'tracker-down',
'domain:',
'site:',
]

UNREGISTERED_MATCHES = [
'unregistered',
'not authorized',
'not registered',
'not found',
'not exist',
'unknown',
'uploaded',
'upgraded',
'season pack',
'packs are available',
'pack is available',
'internal available',
'season pack out',
'dead',
'dupe',
'complete season uploaded',
'problem with',
'specifically banned',
'trumped',
'torrent existiert nicht',
'i\'m sorry dave, i can\'t do that' # weird stuff from racingforme
]

MAINTENANCE_MATCHES = [
'tracker is down',
'maintenance'
]

DHT_MATCHES = [
'** [DHT] **',
'** [PeX] **',
'** [LSD] **'
]

SITE_MAPPINGS = {
'animetorrents.me': { 'urls': ['animetorrents.me'] },
'avistaz': { 'urls': ['avistaz.to'] },
'beyond-hd': { 'urls': ['beyond-hd.me'] },
'blutopia': { 'urls': ['blutopia.cc', 'blutopia.xyz'] },
'broadcasthenet': { 'urls': ['landof.tv'] },
'cinemaz': { 'urls': ['cinemaz.to'] },
'exoticaz': { 'urls': ['exoticaz.to'] },
'filelist': { 'urls': ['filelist.io', 'flro.org'] },
'hd-space': { 'urls': ['hd-space.pw'] },
'hd-torrents': { 'urls': ['hdts-announce.ru'] },
'iptorrents': { 'urls': ['bgp.technology', 'empirehost.me', 'stackoverflow.tech'] },
'karagarga': { 'urls': ['karagarga.in'] },
'kraytracker': { 'urls': ['kraytracker.com'] },
'morethantv': { 'urls': ['morethantv.me'] },
'myanonamouse': { 'urls': ['myanonamouse.net'] },
'myspleen': { 'urls': ['myspleen.org'] },
'orpheus': { 'urls': ['home.opsfet.ch'] },
'passthepopcorn': { 'urls': ['passthepopcorn.me'] },
'privatehd': { 'urls': ['privatehd.to'] },
'redacted': { 'urls': ['flacsfor.me'] },
'scenetime': { 'urls': ['scenetime.com'] },
'torrentleech': { 'urls': ['tleechreload.org', 'torrentleech.org'] },
'torrentseeds': { 'urls': ['torrentseeds.org'] },
'uhdbits': { 'urls': ['uhdbits.org'] },
}

def site_name(domain, site_matches):
for site, data in site_matches.items():
if any(domain in url for url in data['urls']):
return site
return None

def __init__(args, logger):
client = qbittools.qbit_client(args)

today = datetime.today()
default_tags = [
'Not Working',
'added:',
'Unregistered',
'Tracker Down',
't:',
'Duplicates',
'activity:',
'Not Linked'
]

unregistered_matches = [
'unregistered',
'not authorized',
'not registered',
'not found',
'not exist',
'unknown',
'uploaded',
'upgraded',
'season pack',
'packs are available',
'pack is available',
'internal available',
'season pack out',
'dead',
'dupe',
'complete season uploaded',
'problem with',
'specifically banned',
'trumped',
'torrent existiert nicht',
'i\'m sorry dave, i can\'t do that' # weird stuff from racingforme
]

maintenance_matches = [
'tracker is down',
'maintenance'
]

dht_matches = [
'** [DHT] **',
'** [PeX] **',
'** [LSD] **'
]
extractTLD = tldextract.TLDExtract(cache_dir=None)

tag_hashes = collections.defaultdict(list)
tag_sizes = collections.defaultdict(int)
content_paths = []

if args.move_unregistered:
try:
client.torrents_create_category('Unregistered')
client.torrents_create_category('unregistered')
except qbittorrentapi.exceptions.Conflict409Error as e:
pass

Expand All @@ -78,7 +113,7 @@ def __init__(args, logger):
if args.tags:
filtered_torrents = list(filter(lambda x: any(y in x.tags for y in args.tags), filtered_torrents))

tags_to_delete = list(filter(lambda tag: any(tag.lower().startswith(x.lower()) for x in default_tags), client.torrents_tags()))
tags_to_delete = list(filter(lambda tag: any(tag.lower().startswith(x.lower()) for x in DEFAULT_TAGS), client.torrents_tags()))

if tags_to_delete:
hashes = list(map(lambda t: t.hash, filtered_torrents))
Expand Down Expand Up @@ -123,42 +158,49 @@ def __init__(args, logger):
elif diff.days > 180:
tags_to_add.append('activity:>180d')

if args.trackers or args.unregistered or args.tracker_down or args.not_working:
if args.sites or args.trackers or args.unregistered or args.tracker_down or args.not_working:
# trackers call is expensive for large amount of torrents
working = len(list(filter(lambda s: s.status == 2, t.trackers))) > 0
real_trackers = list(filter(lambda s: not s.url in dht_matches, t.trackers))
real_trackers = list(filter(lambda s: not s.url in DHT_MATCHES, t.trackers))

if args.trackers and len(real_trackers) > 0:
domain = tldextract.extract(sorted(real_trackers, key=lambda x: x.url)[0].url).registered_domain
if (args.domains or args.sites) and len(real_trackers) > 0:
domain = extractTLD(sorted(real_trackers, key=lambda x: x.url)[0].url).registered_domain
if len(domain) > 0:
tags_to_add.append(f"t:{domain}")
if args.domains:
tags_to_add.append(f"domain:{domain}")
if args.sites:
site = site_name(domain, SITE_MAPPINGS)
if site:
tags_to_add.append(f"site:{site}")
else:
tags_to_add.append(f"site:unknown")

if not working:
unregistered_matched = any(rt.msg.lower().startswith(x.lower()) for x in unregistered_matches for rt in real_trackers)
maintenance_matched = any(rt.msg.lower().startswith(x.lower()) for x in maintenance_matches for rt in real_trackers)
unregistered_matched = any(rt.msg.lower().startswith(x.lower()) for x in UNREGISTERED_MATCHES for rt in real_trackers)
maintenance_matched = any(rt.msg.lower().startswith(x.lower()) for x in MAINTENANCE_MATCHES for rt in real_trackers)

if args.unregistered and unregistered_matched:
tags_to_add.append('Unregistered')
tags_to_add.append('unregistered')

if args.move_unregistered and t.time_active > 60 and not t.category == 'Unregistered':
t.set_category(category='Unregistered')
if args.move_unregistered and t.time_active > 60 and not t.category == 'unregistered':
t.set_category(category='unregistered')
elif args.tracker_down and maintenance_matched:
tags_to_add.append('Tracker Down')
tags_to_add.append('tracker-down')
elif args.not_working:
tags_to_add.append('Not Working')
tags_to_add.append('not-working')

if args.duplicates:
match = [(infohash, path, size) for infohash, path, size in content_paths if path == t.content_path and not t.content_path == t.save_path]
if match:
tags_to_add.append("Duplicates")
tag_hashes["Duplicates"].append(match[0][0])
tags_to_add.append("dupe")
tag_hashes["dupe"].append(match[0][0])
if args.size:
tag_sizes["Duplicates"] += match[0][2]
tag_sizes["dupe"] += match[0][2]

content_paths.append((t.hash, t.content_path, t.size))

if args.not_linked and not utils.is_linked(t.content_path):
tags_to_add.append("Not Linked")
tags_to_add.append("not-linked")

for tag in tags_to_add:
tag_hashes[tag].append(t.hash)
Expand All @@ -184,15 +226,16 @@ def add_arguments(subparser):
parser.add_argument('-c', '--categories', nargs='*', metavar='mycategory', help='Filter by categories', required=False)
parser.add_argument('-t', '--tags', nargs='*', metavar='mytag', help='Filter by tags', required=False)

parser.add_argument('--move-unregistered', action='store_true', help='Move unregistered torrents to Unregistered category. Must be used with --unregistered')
parser.add_argument('--move-unregistered', action='store_true', help='Move unregistered torrents to unregistered category. Must be used with --unregistered')
parser.add_argument('--not-working', action='store_true', help='Tag torrents with not working tracker status. Significantly increases script execution time')
parser.add_argument('--unregistered', action='store_true', help='Tag torrents with unregistered tracker status message. Significantly increases script execution time')
parser.add_argument('--duplicates', action='store_true', help='Tag torrents with the same content path')
parser.add_argument('--added-on', action='store_true', help='Tag torrents with added date (last 24h, 7 days, 30 days, etc)')
parser.add_argument('--last-activity', action='store_true', help='Tag torrents with last activity date (last 24h, 7 days, 30 days, etc)')
parser.add_argument('--trackers', action='store_true', help='Tag torrents with tracker domains. Significantly increases script execution time')
parser.add_argument('--domains', action='store_true', help='Tag torrents with tracker domains. Significantly increases script execution time')
parser.add_argument('--tracker-down', action='store_true', help='Tag torrents with temporarily down trackers. Significantly increases script execution time')
parser.add_argument('--size', action='store_true', help='Add size of tagged torrents to created tags')
parser.add_argument('--not-linked', action='store_true', help='Tag torrents with files without hardlinks or symlinks, use with filtering by category/tag. Significantly increases script execution time')
parser.add_argument('--sites', action='store_true', help='Tag torrents with known site names. Significantly increases script execution time')

qbittools.add_default_args(parser)

0 comments on commit c880a69

Please sign in to comment.