From 1ef62c2c3044b5b11dae92a08be5d83a780392b4 Mon Sep 17 00:00:00 2001 From: Matt Singleton Date: Sun, 16 Jan 2022 20:56:29 -0600 Subject: handle error codes and network errors --- gemini.py | 99 ++++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 60 insertions(+), 39 deletions(-) (limited to 'gemini.py') diff --git a/gemini.py b/gemini.py index e820619..275eab9 100644 --- a/gemini.py +++ b/gemini.py @@ -12,16 +12,31 @@ def htmlescape(text: str) -> str: return text.replace('<', '<').replace('>', '>') -def gem2html(gem: str) -> str: - template = string.Template(open('page_template.html').read()) - body = io.StringIO() - parser = fsm.Parser(gem.split('\n'), body) - parser.parse() - html = template.substitute( - body=body.getvalue(), - charset='utf-8', - lang='en', - ) +def gem2html(gem: dict) -> str: + params = { + 'charset': 'utf-8', + 'lang': 'en', + 'css': open('style.css').read() + } + if gem['status'][0] == '2': + template = string.Template(open('page_template.html').read()) + body = io.StringIO() + parser = fsm.Parser(gem['body'].split('\n'), body) + parser.parse() + params['body'] = body.getvalue() + else: + template = string.Template(open('error_template.html').read()) + if gem['status'] == '00': + params['status'] = 'CLIENT ERROR' + elif gem['status'][0] == '4': + params['status'] = gem['status'] + ' TEMPORARY FAILURE' + elif gem['status'][0] == '5': + params['status'] = gem['status'] + ' PERMANENT FAILURE' + else: + params['status'] = 'UNHANDLED STATUS {}'.format(gem['status']) + params['meta'] = gem['meta'] + + html = template.substitute(params) with open('latest.html', 'w') as fp: fp.write(html) return html @@ -42,8 +57,8 @@ def get(url: str, follow_redirects: bool = True) -> dict: while response['status'][0] == '3': count += 1 if count > 20: - raise Exception('Redirect loop') - print('redirect: {}'.format(response['meta'])) + return {'status': '00', 'meta': 'Too many redirects'} + print('{status} {meta}'.format(**response)) response = _get(response['meta']) return response @@ -72,30 +87,36 @@ def _get(url: str) -> dict: url_parts.fragment, )) } - context = ssl.create_default_context() - context.check_hostname = False - context.verify_mode = ssl.CERT_NONE - port = 1965 if url_parts.port is None else url_parts.port - with socket.create_connection((url_parts.hostname, port)) as sock: - with context.wrap_socket(sock, server_hostname=url_parts.hostname) as ssock: - ssock.sendall('{url}\r\n'.format(url=url).encode('utf8')) - fp = ssock.makefile(mode='rb') - header = fp.readline(1027) - parts = header.decode('utf8').split(None, 1) - status = parts[0] - if len(parts) == 1: - meta = '' - else: - meta = parts[1] - if status[0] != '2': - return { - 'status': status, - 'meta': meta.strip(), - } - meta_params = _parse_meta(meta) - body = fp.read() - return { - 'status': status, - 'meta': meta.strip(), - 'body': body.decode(meta_params.get('charset', 'utf8')), - } + try: + context = ssl.create_default_context() + context.check_hostname = False + context.verify_mode = ssl.CERT_NONE + port = 1965 if url_parts.port is None else url_parts.port + with socket.create_connection((url_parts.hostname, port)) as sock: + with context.wrap_socket(sock, server_hostname=url_parts.hostname) as ssock: + ssock.sendall('{url}\r\n'.format(url=url).encode('utf8')) + fp = ssock.makefile(mode='rb') + header = fp.readline(1027) + parts = header.decode('utf8').split(None, 1) + status = parts[0] + if len(parts) == 1: + meta = '' + else: + meta = parts[1] + if status[0] != '2': + return { + 'status': status, + 'meta': meta.strip(), + } + meta_params = _parse_meta(meta) + body = fp.read() + return { + 'status': status, + 'meta': meta.strip(), + 'body': body.decode(meta_params.get('charset', 'utf8')), + } + except Exception as ex: + return { + 'status': '00', + 'meta': '{}'.format(ex), + } -- cgit v1.2.3