diff --git a/pirate/pirate.py b/pirate/pirate.py index b27742b..5cd3dd8 100755 --- a/pirate/pirate.py +++ b/pirate/pirate.py @@ -42,6 +42,7 @@ def parse_config_file(text): config.set('Misc', 'transmission-port', '') # for backward compatibility config.set('Misc', 'colors', 'true') config.set('Misc', 'mirror', pirate.data.default_mirror) + config.set('Misc', 'timeout', pirate.data.default_timeout) config.read_string(text) @@ -179,6 +180,8 @@ def parse_args(args_in): parser.add_argument('-m', '--mirror', type=str, nargs='+', help='the pirate bay mirror(s) to use') + parser.add_argument('-z', '--timeout', type=int, + help='timeout in seconds for http requests') parser.add_argument('-v', '--version', action='store_true', help='print pirate-get version number') @@ -220,6 +223,9 @@ def combine_configs(config, args): if not args.mirror: args.mirror = config.get('Misc', 'mirror').split() + if not args.timeout: + args.timeout = int(config.get('Misc', 'timeout')) + args.transmission_command = ['transmission-remote'] if args.endpoint: args.transmission_command.append(args.endpoint) @@ -258,14 +264,15 @@ def combine_configs(config, args): def connect_mirror(mirror, printer, args): try: printer.print('Trying', mirror, end='... ') - url = pirate.torrent.find_api(mirror) + url = pirate.torrent.find_api(mirror, args.timeout) results = pirate.torrent.remote( printer=printer, category=pirate.torrent.parse_category(printer, args.category), sort=pirate.torrent.parse_sort(printer, args.sort), mode=args.action, terms=args.search, - mirror=url) + mirror=url, + timeout=args.timeout) except (urllib.error.URLError, socket.timeout, IOError, ValueError) as e: printer.print('Failed', color='WARN', end=' ') printer.print('(', e, ')', sep='') @@ -286,7 +293,7 @@ def search_mirrors(printer, args): try: req = request.Request(pirate.data.mirror_list, headers=pirate.data.default_headers) - f = request.urlopen(req, timeout=pirate.data.default_timeout) + f = request.urlopen(req, timeout=args.timeout) except urllib.error.URLError as e: raise IOError('Could not fetch mirrors', e.reason) @@ -400,9 +407,9 @@ def pirate_main(args): printer.print('Bye.', color='alt') return elif code == 'd': - printer.descriptions(choices, results, site) + printer.descriptions(choices, results, site, args.timeout) elif code == 'f': - printer.file_lists(choices, results, site) + printer.file_lists(choices, results, site, args.timeout) elif code == 'p': printer.search_results(results) elif code == 'm': @@ -412,7 +419,8 @@ def pirate_main(args): pirate.torrent.copy_magnets(printer, choices, results) elif code == 't': pirate.torrent.save_torrents(printer, choices, results, - args.save_directory) + args.save_directory, + args.timeout) elif not cmd: printer.print('No links entered!', color='WARN') else: @@ -432,7 +440,8 @@ def pirate_main(args): if args.output == 'save_torrent_files': printer.print('Saving selected torrents...') pirate.torrent.save_torrents(printer, choices, - results, args.save_directory) + results, args.save_directory, + args.timeout) return for choice in choices: diff --git a/pirate/print.py b/pirate/print.py index 98b2b02..bac5548 100644 --- a/pirate/print.py +++ b/pirate/print.py @@ -95,16 +95,14 @@ class Printer: even = not even self.print(table) - def descriptions(self, chosen_links, results, site): - opener = request.build_opener(request.HTTPErrorProcessor) - + def descriptions(self, chosen_links, results, site, timeout): for link in chosen_links: result = results[link] req = request.Request( site + '/t.php?id=' + result['id'], headers=pirate.data.default_headers) req.add_header('Accept-encoding', 'gzip') - f = opener.open(req, timeout=pirate.data.default_timeout) + f = request.urlopen(req, timeout=timeout) if f.info().get('Content-Encoding') == 'gzip': f = gzip.GzipFile(fileobj=BytesIO(f.read())) @@ -119,9 +117,7 @@ class Printer: color='zebra_1') self.print(desc, color='zebra_0') - def file_lists(self, chosen_links, results, site): - opener = request.build_opener(request.HTTPErrorProcessor) - + def file_lists(self, chosen_links, results, site, timeout): # the API may returns object instead of list def get(obj): try: @@ -135,7 +131,7 @@ class Printer: site + '/f.php?id=' + result['id'], headers=pirate.data.default_headers) req.add_header('Accept-encoding', 'gzip') - f = opener.open(req, timeout=pirate.data.default_timeout) + f = request.urlopen(req, timeout=timeout) if f.info().get('Content-Encoding') == 'gzip': f = gzip.GzipFile(fileobj=BytesIO(f.read())) diff --git a/pirate/torrent.py b/pirate/torrent.py index c2b4468..088b463 100644 --- a/pirate/torrent.py +++ b/pirate/torrent.py @@ -64,7 +64,7 @@ def make_magnet(name, info_hash): info_hash, parse.quote(name, '')) -def remote(printer, category, sort, mode, terms, mirror): +def remote(printer, category, sort, mode, terms, mirror, timeout): results = [] # Catch the Ctrl-C exception and exit cleanly @@ -74,7 +74,7 @@ def remote(printer, category, sort, mode, terms, mirror): mirror, ' '.join(terms), category), headers=pirate.data.default_headers) try: - f = request.urlopen(req, timeout=pirate.data.default_timeout) + f = request.urlopen(req, timeout=timeout) except urllib.error.URLError as e: raise e @@ -94,13 +94,13 @@ def remote(printer, category, sort, mode, terms, mirror): sys.exit(0) -def find_api(mirror): +def find_api(mirror, timeout): # try common paths for path in ['', '/apip', '/api.php?url=']: req = request.Request(mirror + path + '/q.php?q=test&cat=0', headers=pirate.data.default_headers) try: - f = request.urlopen(req, timeout=pirate.data.default_timeout) + f = request.urlopen(req, timeout=timeout) if f.info().get_content_type() == 'application/json': return mirror + path except urllib.error.URLError: @@ -110,7 +110,7 @@ def find_api(mirror): req = request.Request(mirror + '/static/main.js', headers=pirate.data.default_headers) try: - f = request.urlopen(req, timeout=pirate.data.default_timeout) + f = request.urlopen(req, timeout=timeout) if f.info().get_content_type() == 'application/javascript': match = re.search("var server='([^']+)'", f.read().decode()) return mirror + match.group(1) @@ -120,27 +120,27 @@ def find_api(mirror): raise IOError('API not found') -def get_torrent(info_hash): +def get_torrent(info_hash, timeout): url = 'http://itorrents.org/torrent/{:X}.torrent' req = request.Request(url.format(info_hash), headers=pirate.data.default_headers) req.add_header('Accept-encoding', 'gzip') - torrent = request.urlopen(req, timeout=pirate.data.default_timeout) + torrent = request.urlopen(req, timeout=timeout) if torrent.info().get('Content-Encoding') == 'gzip': torrent = gzip.GzipFile(fileobj=BytesIO(torrent.read())) return torrent.read() -def save_torrents(printer, chosen_links, results, folder): +def save_torrents(printer, chosen_links, results, folder, timeout): for link in chosen_links: result = results[link] torrent_name = result['name'].replace('/', '_').replace('\\', '_') file = os.path.join(folder, torrent_name + '.torrent') try: - torrent = get_torrent(result['info_hash']) + torrent = get_torrent(result['info_hash'], timeout) except urllib.error.HTTPError as e: printer.print('There is no cached file for this torrent :(' ' \nCode: {} - {}'.format(e.code, e.reason),