1
0
mirror of https://git.sr.ht/~sotirisp/qute-gemini synced 2024-11-23 12:32:04 +01:00

Restructure code

This commit is contained in:
Sotiris Papatheodorou 2021-03-05 13:29:19 +02:00
parent abd2277095
commit 5da379e068

@ -51,6 +51,58 @@ def gemini_absolutise_url(base, relative):
def gemini_fetch_url(url):
"""
url: str URL to the article with gemini:// or no scheme
Retruns 2 strings.
On success returns the content and an empty error message.
On failure returns an empty content and an error message.
Adapted from gcat: https://github.com/aaronjanse/gcat
"""
parsed_url = urllib.parse.urlparse(url)
if not parsed_url.scheme:
url = "gemini://" + url
parsed_url = urllib.parse.urlparse(url)
if parsed_url.scheme != "gemini":
return "", "Received non-gemini:// URL: " + url
if parsed_url.port is not None:
useport = parsed_url.port
else:
useport = 1965
# Do the Gemini transaction
while True:
s = socket.create_connection((parsed_url.hostname, useport))
context = ssl.SSLContext(ssl.PROTOCOL_TLS)
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
s = context.wrap_socket(s, server_hostname = parsed_url.netloc)
s.sendall((url + "\r\n").encode("UTF-8"))
# Get header and check for redirects
fp = s.makefile("rb")
header = fp.readline().decode("UTF-8").strip()
status, mime = header.split()[:2]
# Follow redirects
if status.startswith("3"):
url = gemini_absolutise_url(url, mime)
parsed_url = urllib.parse.urlparse(url)
# Otherwise, we're done
else:
break
# Fail if transaction was not successful
if status.startswith("2"):
if mime == "text/gemini":
# Decode according to declared charset
mime, mime_opts = cgi.parse_header(mime)
body = fp.read()
body = body.decode(mime_opts.get("charset", "UTF-8"))
return body, ""
else:
return "", "Received non-gemini content: " + mime
else:
return "", "Received gemini status " + status
def gemtext_to_html(gemtext, title, url):
"""
Convert gemtext with the supplied title, downloaded from the supplied
@ -121,42 +173,10 @@ def gemtext_to_html(gemtext, title, url):
def open_gemini(url: str, open_args: str):
parsed_url = urllib.parse.urlparse(url)
if parsed_url.port is not None:
useport = parsed_url.port
else:
useport = 1965
# Do the Gemini transaction
while True:
s = socket.create_connection((parsed_url.hostname, useport))
context = ssl.SSLContext()
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
s = context.wrap_socket(s, server_hostname = parsed_url.netloc)
s.sendall((url + '\r\n').encode("UTF-8"))
# Get header and check for redirects
fp = s.makefile("rb")
header = fp.readline()
print(header.decode("UTF-8"), end="")
header = header.decode("UTF-8").strip()
status, mime = header.split()[:2]
# Follow redirects
if status.startswith("3"):
url = gemini_absolutise_url(url, mime)
parsed_url = urllib.parse.urlparse(url)
# Otherwise, we're done.
else:
break
# Fail if transaction was not successful
if status.startswith("2"):
if mime.startswith("text/"):
# Decode according to declared charset
mime, mime_opts = cgi.parse_header(mime)
body = fp.read()
gemini_text = body.decode(mime_opts.get("charset", "UTF-8"))
else:
sys.exit(1)
else:
# Get the Gemini content
content, error_msg = gemini_fetch_url(url)
if error_msg:
print(error_msg)
sys.exit(1)
# Convert to HTML in a temporary file
@ -164,23 +184,23 @@ def open_gemini(url: str, open_args: str):
tmp_filename = tmpf.name
tmpf.close()
with open(tmp_filename, 'w') as f:
f.write(gemtext_to_html(gemini_text, url, url))
f.write(gemtext_to_html(content, url, url))
# Open the HTML file in qutebrowser
with open(qute_fifo(), 'w') as qfifo:
print('open ' + open_args + ' file://' + tmp_filename, file=qfifo)
qfifo.write('open ' + open_args + ' file://' + tmp_filename)
def open_other(url: str, open_args: str):
with open(qute_fifo(), 'w') as qfifo:
print('open ' + open_args + ' ' + url, file=qfifo)
qfifo.write('open ' + open_args + ' ' + url)
if __name__ == "__main__":
# Open in the current or a new tab depending on the script name
if 'tab' in sys.argv[0]:
if sys.argv[0].endswith('-tab'):
open_args = '-t'
else:
open_args = ''