sane-bt-search: add a flag to sort by tracker reputation
This commit is contained in:
parent
6894d5828b
commit
1d8bee2856
|
@ -67,6 +67,22 @@ def parse_time(t: str) -> datetime:
|
||||||
return try_parse_time(t).astimezone() or epoch
|
return try_parse_time(t).astimezone() or epoch
|
||||||
|
|
||||||
|
|
||||||
|
# preference, best to worst
|
||||||
|
TRACKER_RANKS = [
|
||||||
|
'bakabt',
|
||||||
|
'nyaa.si',
|
||||||
|
'yts',
|
||||||
|
'internet archive',
|
||||||
|
# haven't sorted these
|
||||||
|
'1337x',
|
||||||
|
'kickasstorrents.to',
|
||||||
|
]
|
||||||
|
def tracker_rank(tracker: str):
|
||||||
|
if tracker.lower() in TRACKER_RANKS:
|
||||||
|
return TRACKER_RANKS.index(tracker.lower())
|
||||||
|
logger.warn(f"unknown tracker: {tracker!r}")
|
||||||
|
return len(TRACKER_RANKS)
|
||||||
|
|
||||||
DROP_CATS = { "dvd", "hd", "misc", "other", "sd", "uhd" }
|
DROP_CATS = { "dvd", "hd", "misc", "other", "sd", "uhd" }
|
||||||
MANGA_CATS = { "books", "comics", "ebook" }
|
MANGA_CATS = { "books", "comics", "ebook" }
|
||||||
VIDEO_CATS = { "anime", "movies", "tv" }
|
VIDEO_CATS = { "anime", "movies", "tv" }
|
||||||
|
@ -95,26 +111,29 @@ class Filter:
|
||||||
self.manga = manga
|
self.manga = manga
|
||||||
self.video = video
|
self.video = video
|
||||||
|
|
||||||
def filter(self, t: 'Torrent', default: bool = False) -> bool:
|
def filter(self, torrents: list['Torrent']) -> list['Torrent']:
|
||||||
|
return [t for t in torrents if self.is_match(t)]
|
||||||
|
|
||||||
|
def is_match(self, t: 'Torrent', default: bool = False) -> bool:
|
||||||
valid = True
|
valid = True
|
||||||
valid = valid and (not self.h265 or self.filter_h265(t))
|
valid = valid and (not self.h265 or self.is_h265(t))
|
||||||
valid = valid and (not self.manga or self.filter_manga(t, default))
|
valid = valid and (not self.manga or self.is_manga(t, default))
|
||||||
valid = valid and (not self.video or self.filter_video(t, default))
|
valid = valid and (not self.video or self.is_video(t, default))
|
||||||
return valid
|
return valid
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def filter_h265(t: 'Torrent') -> bool:
|
def is_h265(t: 'Torrent') -> bool:
|
||||||
meta = t.title.lower()
|
meta = t.title.lower()
|
||||||
return "h265" in meta \
|
return "h265" in meta \
|
||||||
or "x265" in meta \
|
or "x265" in meta \
|
||||||
or "HEVC" in meta
|
or "HEVC" in meta
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def filter_manga(t: 'Torrent', default: bool = False) -> bool:
|
def is_manga(t: 'Torrent', default: bool = False) -> bool:
|
||||||
return is_cat(t.categories, MANGA_CATS, default)
|
return is_cat(t.categories, MANGA_CATS, default)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def filter_video(t: 'Torrent', default: bool = False) -> bool:
|
def is_video(t: 'Torrent', default: bool = False) -> bool:
|
||||||
return is_cat(t.categories, VIDEO_CATS, default)
|
return is_cat(t.categories, VIDEO_CATS, default)
|
||||||
|
|
||||||
|
|
||||||
|
@ -208,15 +227,12 @@ class Client:
|
||||||
|
|
||||||
return sorted(torrents, reverse=True)
|
return sorted(torrents, reverse=True)
|
||||||
|
|
||||||
|
def sort_results(torrents: list[Torrent], by: str) -> list[Torrent]:
|
||||||
def filter_results(results: list[Torrent], filter: Filter, top: int | None) -> list[Torrent]:
|
if by == 'seeders':
|
||||||
"""
|
return sorted(torrents, key=lambda t: (t.seeders, t), reverse=True)
|
||||||
take the complete query and filter further based on CLI options
|
elif by == 'source':
|
||||||
"""
|
return sorted(torrents, key=lambda t: (-tracker_rank(t.tracker), t), reverse=True)
|
||||||
results = [t for t in results if filter.filter(t)]
|
assert False, f"unknown sort method: {by}"
|
||||||
if top is not None:
|
|
||||||
results = results[:top]
|
|
||||||
return results
|
|
||||||
|
|
||||||
def format_results(all_results: list[Torrent], filtered_results: list[Torrent], json: bool):
|
def format_results(all_results: list[Torrent], filtered_results: list[Torrent], json: bool):
|
||||||
if json:
|
if json:
|
||||||
|
@ -236,6 +252,7 @@ def main(args: list[str]):
|
||||||
parser = argparse.ArgumentParser(description='search torrent trackers')
|
parser = argparse.ArgumentParser(description='search torrent trackers')
|
||||||
parser.add_argument('--full', action='store_true', help='show all results')
|
parser.add_argument('--full', action='store_true', help='show all results')
|
||||||
parser.add_argument('--top', help='how many results to show (default: 5)')
|
parser.add_argument('--top', help='how many results to show (default: 5)')
|
||||||
|
parser.add_argument('--sort-by', default='seeders', help='how to rank matches (seeders, source)')
|
||||||
parser.add_argument('--json', action='store_true', help='output results in json')
|
parser.add_argument('--json', action='store_true', help='output results in json')
|
||||||
parser.add_argument('--verbose', action='store_true')
|
parser.add_argument('--verbose', action='store_true')
|
||||||
parser.add_argument('--h265', action='store_true', help='show only H.265/HEVC results (might cause false negatives)')
|
parser.add_argument('--h265', action='store_true', help='show only H.265/HEVC results (might cause false negatives)')
|
||||||
|
@ -252,13 +269,13 @@ def main(args: list[str]):
|
||||||
all_results = client.query(args.query)
|
all_results = client.query(args.query)
|
||||||
|
|
||||||
filter = Filter(h265=args.h265, manga=args.manga, video=args.video)
|
filter = Filter(h265=args.h265, manga=args.manga, video=args.video)
|
||||||
filtered_results = filter_results(
|
filtered_results = filter.filter(all_results)
|
||||||
all_results,
|
ordered_results = sort_results(filtered_results, args.sort_by)
|
||||||
filter,
|
|
||||||
None if args.full else int(args.top or "5"),
|
|
||||||
)
|
|
||||||
|
|
||||||
format_results(all_results, filtered_results, args.json)
|
if not args.full:
|
||||||
|
ordered_results = ordered_results[:int(args.top or "5")]
|
||||||
|
|
||||||
|
format_results(all_results, ordered_results, args.json)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main(sys.argv[1:])
|
main(sys.argv[1:])
|
||||||
|
|
Loading…
Reference in New Issue
Block a user