Add actual support for reading local files, use it for bookmarks.

This commit is contained in:
Solderpunk 2023-11-14 00:15:32 +01:00
parent c6886d7eb9
commit 588d599cb4
1 changed files with 34 additions and 28 deletions

62
av98.py
View File

@ -318,7 +318,7 @@ However, you can use `set gopher_proxy hostname:port` to tell it about a
Gopher-to-Gemini proxy (such as a running Agena instance), in which case
you'll be able to transparently follow links to Gopherspace!""")
return
elif gi.scheme not in ("gemini", "gopher"):
elif gi.scheme not in ("file", "gemini", "gopher"):
print("Sorry, no support for {} links.".format(gi.scheme))
return
@ -328,8 +328,10 @@ you'll be able to transparently follow links to Gopherspace!""")
self._go_to_gi(new_gi)
return
# Use cache, or hit the network if resource is not cached
if check_cache and self.options["cache"] and self.cache.check(gi.url):
# Use local file, use cache, or hit the network if resource is not cached
if gi.scheme == "file":
mime, body, tmpfile = self._handle_local_file(gi)
elif check_cache and self.options["cache"] and self.cache.check(gi.url):
mime, body, tmpfile = self.cache.get(gi.url)
self.log["cache_hits"] += 1
else:
@ -372,6 +374,16 @@ Slow internet connection? Use 'set timeout' to be more patient.""")
else:
ui_out.error("ERROR: " + str(err))
def _handle_local_file(self, gi):
if gi.path.endswith(".gmi"): # TODO: be better about this
mime = "text/gemini"
with open(gi.path, "r") as fp:
body = fp.read()
else:
mime, noise = mimetypes.guess_type(gi.path)
body = None
return mime, body, gi.path
def _fetch_over_network(self, gi):
# Be careful with client certificates!
@ -405,22 +417,19 @@ Slow internet connection? Use 'set timeout' to be more patient.""")
print("Remaining unidentified.")
self.client_certs.pop(gi.host)
# Is this a local file?
if not gi.host:
address, f = None, open(gi.path, "rb")
else:
try:
address, f = self._send_request(gi)
except Exception as err:
if isinstance(err, socket.gaierror):
self.log["dns_failures"] += 1
elif isinstance(err, ConnectionRefusedError):
self.log["refused_connections"] += 1
elif isinstance(err, ConnectionResetError):
self.log["reset_connections"] += 1
elif isinstance(err, (TimeoutError, socket.timeout)):
self.log["timeouts"] += 1
raise err
# Send request to server
try:
address, f = self._send_request(gi)
except Exception as err:
if isinstance(err, socket.gaierror):
self.log["dns_failures"] += 1
elif isinstance(err, ConnectionRefusedError):
self.log["refused_connections"] += 1
elif isinstance(err, ConnectionResetError):
self.log["reset_connections"] += 1
elif isinstance(err, (TimeoutError, socket.timeout)):
self.log["timeouts"] += 1
raise err
# Spec dictates <META> should not exceed 1024 bytes,
# so maximum valid header length is 1027 bytes.
@ -1052,8 +1061,7 @@ Slow internet connection? Use 'set timeout' to be more patient.""")
self._go_to_gi(gi)
# or a local file
elif os.path.exists(os.path.expanduser(line)):
gi = GeminiItem(None, None, os.path.expanduser(line),
"1", line, False)
gi = GeminiItem("file://" + os.path.abspath(os.path.expanduser(line)))
self._go_to_gi(gi)
# If this isn't a mark, treat it as a URL
else:
@ -1338,13 +1346,11 @@ Bookmarks are stored using the 'add' command."""
if len(args.split()) > 1 or (args and not args.isnumeric()):
print("bookmarks command takes a single integer argument!")
return
with open(bm_file, "r") as fp:
body = fp.read()
gi = GeminiItem("localhost/" + bm_file)
self._handle_gemtext(body, gi, display = not args)
if args:
# Use argument as a numeric index
self.default(line)
gi = GeminiItem("file://" + os.path.abspath(bm_file))
self._go_to_gi(gi, update_hist=False, handle = not args)
if args:
# Use argument as a numeric index
self.default(line)
### Help
def do_help(self, arg):