def main(): config = load_config() parser = argparse.ArgumentParser( description='finds and downloads torrents from the Pirate Bay') parser.add_argument('-b', dest='browse', action='store_true', help='display in Browse mode') parser.add_argument('search', metavar='search', nargs='*', help='term to search for') parser.add_argument('-c', dest='category', metavar='category', help='specify a category to search', default='All') parser.add_argument('-s', dest='sort', metavar='sort', help='specify a sort option', default='SeedersDsc') parser.add_argument('-R', dest='recent', action='store_true', help='torrents uploaded in the last 48hours.' '*ignored in searches*') parser.add_argument('-l', dest='list_categories', action='store_true', help='list categories') parser.add_argument('--list_sorts', dest='list_sorts', action='store_true', help='list Sortable Types') parser.add_argument('-L', '--local', dest='database', help='an xml file containing the Pirate Bay database') parser.add_argument('-p', dest='pages', default=1, type=int, help='the number of pages to fetch ' "(doesn't work with --local)") parser.add_argument('-0', dest='first', action='store_true', help='choose the top result') parser.add_argument('-a', '--download-all', action='store_true', help='download all results') parser.add_argument('-t', '--transmission', action='store_true', help='open magnets with transmission-remote') parser.add_argument('-P', '--port', dest='port', help='transmission-remote rpc port. default is 9091') parser.add_argument('-C', '--custom', dest='command', help='open magnets with a custom command' ' (%%s will be replaced with the url)') parser.add_argument('-M', '--save-magnets', action='store_true', help='save magnets links as files') parser.add_argument('-T', '--save-torrents', action='store_true', help='save torrent files') parser.add_argument('-S', '--save-directory', type=str, metavar='DIRECTORY', help='directory where to save downloaded files' ' (if none is given $PWD will be used)') parser.add_argument('--disable-colors', dest='color', action='store_false', help='disable colored output') args = parser.parse_args() # figure out the mode - browse, search, top or recent if args.browse: args.mode = 'browse' elif args.recent: args.mode = 'recent' elif len(args.search) == 0: args.mode = 'top' else: args.mode = 'search' if (config.getboolean('Misc', 'colors') and not args.color or not config.getboolean('Misc', 'colors')): pirate.data.colored_output = False if args.save_directory: config.set('Save', 'directory', args.save_directory) transmission_command = ['transmission-remote'] if args.port: transmission_command.append(args.port) if args.transmission or config.getboolean('Misc', 'transmission'): ret = subprocess.call(transmission_command + ['-l'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) if ret != 0: print('Transmission is not running.') return if args.list_categories: cur_color = 'zebra_0' for key, value in sorted(pirate.data.categories.items()): cur_color = 'zebra_0' if cur_color == 'zebra_1' else 'zebra_1' print(str(value), '\t', key, sep='', color=cur_color) return if args.list_sorts: cur_color = 'zebra_0' for key, value in sorted(pirate.data.sorts.items()): cur_color = 'zebra_0' if cur_color == 'zebra_1' else 'zebra_1' print(str(value), '\t', key, sep='', color=cur_color) return if args.database or config.getboolean('LocalDB', 'enabled'): if args.database: path = args.database else: path = config.get('LocalDB', 'path') results = pirate.local.search(path, args.search) sizes, uploaded = [], [] else: results, mirrors = [], {'https://thepiratebay.mn'} try: req = request.Request('https://proxybay.co/list.txt', headers=pirate.data.default_headers) f = request.urlopen(req, timeout=pirate.data.default_timeout) except IOError: print('Could not fetch additional mirrors', color='WARN') else: if f.getcode() != 200: raise IOError('The proxy bay responded with an error.') mirrors = mirrors.union([i.decode('utf-8').strip() for i in f.readlines()][3:] ).difference(pirate.data.blacklist) for mirror in mirrors: try: print('Trying', mirror, end='... \n') results = pirate.torrent.remote( pages=args.pages, category=pirate.torrent.parse_category(args.category), sort=pirate.torrent.parse_sort(args.sort), mode=args.mode, terms=args.search, mirror=mirror ) except (urllib.error.URLError, socket.timeout, IOError, ValueError): print('Failed', color='WARN') else: site = mirror print('Ok', color='alt') break else: print('No available mirrors :(', color='WARN') return if len(results) == 0: print('No results') return pirate.print.search_results(results, local=args.database) if args.first: print('Choosing first result') choices = [0] elif args.download_all: print('Downloading all results') choices = range(len(results)) else: # New input loop to support different link options while True: print("\nSelect links (Type 'h' for more options" ", 'q' to quit)", end='\b', color='alt') try: l = input(': ') except KeyboardInterrupt: print('\nCancelled.') return try: code, choices = parse_torrent_command(l) # Act on option, if supplied print('') if code == 'h': print('Options:', '<links>: Download selected torrents', '[m<links>]: Save magnets as files', '[t<links>]: Save .torrent files', '[d<links>]: Get descriptions', '[f<links>]: Get files', '[p] Print search results', '[q] Quit', sep='\n') elif code == 'q': print('Bye.', color='alt') return elif code == 'd': pirate.print.descriptions(choices, results, site) elif code == 'f': pirate.print.file_lists(choices, results, site) elif code == 'p': pirate.print.search_results(results) elif code == 'm': pirate.torrent.save_magnets(choices, results, config.get( 'Save', 'directory')) elif code == 't': pirate.torrent.save_torrents(choices, results, config.get( 'Save', 'directory')) elif not l: print('No links entered!', color='WARN') else: break except Exception as e: print('Exception:', e, color='ERROR') choices = () save_to_file = False if args.save_magnets or config.getboolean('Save', 'magnets'): print('Saving selected magnets...') pirate.torrent.save_magnets(choices, results, config.get( 'Save', 'directory')) save_to_file = True if args.save_torrents or config.getboolean('Save', 'torrents'): print('Saving selected torrents...') pirate.torrent.save_torrents(choices, results, config.get( 'Save', 'directory')) save_to_file = True if save_to_file: return for choice in choices: url = results[int(choice)]['magnet'] if args.transmission or config.getboolean('Misc', 'transmission'): subprocess.call(transmission_command + ['--add', url]) elif args.command or config.get('Misc', 'openCommand'): command = config.get('Misc', 'openCommand') if args.command: command = args.command subprocess.call(parse_cmd(command, url)) else: webbrowser.open(url) if args.transmission or config.getboolean('Misc', 'transmission'): subprocess.call(transmission_command + ['-l'])
def main(): config = load_config() parser = argparse.ArgumentParser( description='finds and downloads torrents from the Pirate Bay') parser.add_argument('-b', dest='browse', action='store_true', help='display in Browse mode') parser.add_argument('search', metavar='search', nargs='*', help='term to search for') parser.add_argument('-c', dest='category', metavar='category', help='specify a category to search', default='All') parser.add_argument('-s', dest='sort', metavar='sort', help='specify a sort option', default='SeedersDsc') parser.add_argument('-R', dest='recent', action='store_true', help='torrents uploaded in the last 48hours.' '*ignored in searches*') parser.add_argument('-l', dest='list_categories', action='store_true', help='list categories') parser.add_argument('--list_sorts', dest='list_sorts', action='store_true', help='list Sortable Types') parser.add_argument('-L', '--local', dest='database', help='an xml file containing the Pirate Bay database') parser.add_argument('-p', dest='pages', default=1, help='the number of pages to fetch ' "(doesn't work with --local)") parser.add_argument('-0', dest='first', action='store_true', help='choose the top result') parser.add_argument('-a', '--download-all', action='store_true', help='download all results') parser.add_argument('-t', '--transmission', action='store_true', help='open magnets with transmission-remote') parser.add_argument('-P', '--port', dest='port', help='transmission-remote rpc port. default is 9091') parser.add_argument('-C', '--custom', dest='command', help='open magnets with a custom command' ' (%%s will be replaced with the url)') parser.add_argument('-M', '--save-magnets', action='store_true', help='save magnets links as files') parser.add_argument('-T', '--save-torrents', action='store_true', help='save torrent files') parser.add_argument('-S', '--save-directory', type=str, metavar='DIRECTORY', help='directory where to save downloaded files' ' (if none is given $PWD will be used)') parser.add_argument('--disable-colors', dest='color', action='store_false', help='disable colored output') args = parser.parse_args() if (config.getboolean('Misc', 'colors') and not args.color or not config.getboolean('Misc', 'colors')): pirate.data.colored_output = False if args.save_directory: config.set('Save', 'directory', args.save_directory) transmission_command = ['transmission-remote'] if args.port: transmission_command.append(args.port) if args.transmission or config.getboolean('Misc', 'transmission'): ret = subprocess.call(transmission_command + ['-l'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) if ret != 0: print('Transmission is not running.') return if args.list_categories: cur_color = 'zebra_0' for key, value in sorted(pirate.data.categories.items()): cur_color = 'zebra_0' if cur_color == 'zebra_1' else 'zebra_1' print(str(value), '\t', key, sep='', color=cur_color) return if args.list_sorts: cur_color = 'zebra_0' for key, value in sorted(pirate.data.sorts.items()): cur_color = 'zebra_0' if cur_color == 'zebra_1' else 'zebra_1' print(str(value), '\t', key, sep='', color=cur_color) return if args.database or config.getboolean('LocalDB', 'enabled'): if args.database: path = args.database else: path = config.get('LocalDB', 'path') mags = pirate.local.search(path, args.search) sizes, uploaded = [], [] else: mags, mirrors = [], {'https://thepiratebay.mn'} try: req = request.Request('https://proxybay.co/list.txt', headers=pirate.data.default_headers) f = request.urlopen(req, timeout=pirate.data.default_timeout) except IOError: print('Could not fetch additional mirrors', color='WARN') else: if f.getcode() != 200: raise IOError('The proxy bay responded with an error.') mirrors = mirrors.union([i.decode('utf-8').strip() for i in f.readlines()][3:] ).difference(pirate.data.blacklist) for mirror in mirrors: try: print('Trying', mirror, end='... ') mags, sizes, uploaded, ids = pirate.torrent.remote(args, mirror) except (urllib.error.URLError, socket.timeout, IOError, ValueError): print('Failed', color='WARN') else: site = mirror print('Ok', color='alt') break else: print('No available mirrors :(', color='WARN') return if not mags: print('No results') return pirate.print.search_results(mags, sizes, uploaded, local=args.database) if args.first: print('Choosing first result') choices = [0] elif args.download_all: print('Downloading all results') choices = range(len(mags)) else: # New input loop to support different link options while True: print("\nSelect links (Type 'h' for more options" ", 'q' to quit)", end='\b', color='alt') try: l = input(': ') except KeyboardInterrupt: print('\nCancelled.') return try: # Very permissive handling # Check for any occurances or d, f, p, t, m, or q cmd_code_match = re.search(r'([hdfpmtq])', l, flags=re.IGNORECASE) if cmd_code_match: code = cmd_code_match.group(0).lower() else: code = None # Clean up command codes # Substitute multiple consecutive spaces/commas for single # comma remove anything that isn't an integer or comma. # Turn into list l = re.sub(r'^[hdfp, ]*|[hdfp, ]*$', '', l) l = re.sub('[ ,]+', ',', l) l = re.sub('[^0-9,-]', '', l) parsed_input = l.split(',') # expand ranges choices = [] # loop will generate a list of lists for elem in parsed_input: left, sep, right = elem.partition('-') if right: choices.append(list(range(int(left), int(right) + 1))) elif left != '': choices.append([int(left)]) # flatten list choices = sum(choices, []) # the current code stores the choices as strings # instead of ints. not sure if necessary choices = [str(elem) for elem in choices] # Act on option, if supplied print('') if code == 'h': print('Options:', '<links>: Download selected torrents', '[m<links>]: Save magnets as files', '[t<links>]: Save .torrent files', '[d<links>]: Get descriptions', '[f<links>]: Get files', '[p] Print search results', '[q] Quit', sep='\n') elif code == 'q': print('Bye.', color='alt') return elif code == 'd': pirate.print.descriptions(choices, mags, site, ids) elif code == 'f': pirate.print.file_lists(choices, mags, site, ids) elif code == 'p': pirate.print.search_results(mags, sizes, uploaded) elif code == 'm': pirate.torrent.save_magnets(choices, mags, config.get( 'Save', 'directory')) elif code == 't': pirate.torrent.save_torrents(choices, mags, config.get( 'Save', 'directory')) elif not l: print('No links entered!', color='WARN') else: break except Exception as e: print('Exception:', e, color='ERROR') choices = () save_to_file = False if args.save_magnets or config.getboolean('Save', 'magnets'): print('Saving selected magnets...') pirate.torrent.save_magnets(choices, mags, config.get( 'Save', 'directory')) save_to_file = True if args.save_torrents or config.getboolean('Save', 'torrents'): print('Saving selected torrents...') pirate.torrent.save_torrents(choices, mags, config.get( 'Save', 'directory')) save_to_file = True if save_to_file: return for choice in choices: url = mags[int(choice)][0] if args.transmission or config.getboolean('Misc', 'transmission'): subprocess.call(transmission_command + ['--add', url]) elif args.command or config.get('Misc', 'openCommand'): command = config.get('Misc', 'openCommand') if args.command: command = args.command subprocess.call(parse_cmd(command, url)) else: webbrowser.open(url) if args.transmission or config.getboolean('Misc', 'transmission'): subprocess.call(transmission_command + ['-l'])