refactoring and cleanup: now accessing links directly from gi instead of hiding a go_to

This commit is contained in:
Lionel Dricot 2022-01-18 22:19:43 +01:00
parent bdd006c896
commit 14e5fbcc83
1 changed files with 50 additions and 29 deletions

View File

@ -141,6 +141,7 @@ _MIME_HANDLERS = {
} }
# monkey-patch Gemini support in urllib.parse # monkey-patch Gemini support in urllib.parse
# see https://github.com/python/cpython/blob/master/Lib/urllib/parse.py # see https://github.com/python/cpython/blob/master/Lib/urllib/parse.py
urllib.parse.uses_relative.append("gemini") urllib.parse.uses_relative.append("gemini")
@ -300,7 +301,7 @@ def render_html(body,width=80):
text = element.get_text().strip() text = element.get_text().strip()
link = element.get('href') link = element.get('href')
if link: if link:
links.append(link) links.append(link+" "+text)
link_id = " [%s] "%(len(links)) link_id = " [%s] "%(len(links))
rendered_body = "\x1b[34m\x1b[2m " + text + link_id + "\x1b[0m" rendered_body = "\x1b[34m\x1b[2m " + text + link_id + "\x1b[0m"
else: else:
@ -354,6 +355,11 @@ def render_html(body,width=80):
r_body += "\n" r_body += "\n"
return r_body,links return r_body,links
_FORMAT_RENDERERS = {
"text/gemini": render_gemtext,
"text/html" : render_html,
"text/xml" : render_html
}
# Offpunk is organized as following: # Offpunk is organized as following:
# - a GeminiClient instance which handles the browsing of GeminiItem. # - a GeminiClient instance which handles the browsing of GeminiItem.
# - Theres only one GeminiClient. Each page is a GeminiItem (name is historical, as # - Theres only one GeminiClient. Each page is a GeminiItem (name is historical, as
@ -487,13 +493,9 @@ class GeminiItem():
print("ERROR: NOCACHE for %s" %self._cache_path) print("ERROR: NOCACHE for %s" %self._cache_path)
return error return error
#def set_renderer(self,renderer): # This method is used to load once the list of links in a gi
# self.renderer = renderer def __make_links(self,links):
def get_links(self):
if self.links:
return self.links
self.links = [] self.links = []
r_body,links = self.renderer(self.get_body())
for l in links: for l in links:
#split between link and potential name #split between link and potential name
splitted = l.split(maxsplit=1) splitted = l.split(maxsplit=1)
@ -504,8 +506,21 @@ class GeminiItem():
else: else:
newgi = GeminiItem(url) newgi = GeminiItem(url)
self.links.append(newgi) self.links.append(newgi)
def get_links(self):
if not self.links:
r_body = self.get_rendered_body()
return self.links return self.links
def get_link(self,nb):
if not self.links:
r_body = self.get_rendered_body()
if len(self.links) < nb:
print("Index too high! No link %s for %s" %(nb,self.url))
return None
else:
return self.links[nb-1]
# Red title above rendered content # Red title above rendered content
def _make_terminal_title(self): def _make_terminal_title(self):
title = self.get_title() title = self.get_title()
@ -522,13 +537,12 @@ class GeminiItem():
def get_rendered_body(self): def get_rendered_body(self):
if not self.renderer: if not self.renderer:
mime = self.get_mime() mime = self.get_mime()
if mime == "text/gemini": if mime in _FORMAT_RENDERERS:
self.renderer = render_gemtext self.renderer = _FORMAT_RENDERERS[mime]
elif mime == "text/html":
self.renderer = render_html
if self.renderer: if self.renderer:
body = self.get_body() body = self.get_body()
r_body, links = self.renderer(body) r_body, links = self.renderer(body)
self.__make_links(links)
to_return = self._make_terminal_title() + r_body to_return = self._make_terminal_title() + r_body
return to_return return to_return
else: else:
@ -564,7 +578,6 @@ class GeminiItem():
f.write(body) f.write(body)
f.close() f.close()
def get_mime(self): def get_mime(self):
if self.is_cache_valid(): if self.is_cache_valid():
if self.local: if self.local:
@ -579,10 +592,10 @@ class GeminiItem():
mime = magic.from_file(path,mime=True) mime = magic.from_file(path,mime=True)
elif not _HAS_MAGIC : elif not _HAS_MAGIC :
print("Cannot guess the mime type of the file. Install Python-magic") print("Cannot guess the mime type of the file. Install Python-magic")
if mime.startswith("text"): if mime.startswith("text") and mime not in _FORMAT_RENDERERS:
#by default, we consider its gemini except for html #by default, we consider its gemini except for html
if "html" not in mime: #print("replacing MIME %s by gemini" %mime)
mime = "text/gemini" mime = "text/gemini"
self.mime = mime self.mime = mime
return self.mime return self.mime
@ -778,6 +791,8 @@ class GeminiClient(cmd.Cmd):
storing the response in a temporary file, choosing storing the response in a temporary file, choosing
and calling a handler program, and updating the history. and calling a handler program, and updating the history.
Nothing is returned.""" Nothing is returned."""
if not gi:
return
# Don't try to speak to servers running other protocols # Don't try to speak to servers running other protocols
if gi.scheme == "gopher" and not self.options.get("gopher_proxy", None)\ if gi.scheme == "gopher" and not self.options.get("gopher_proxy", None)\
and not self.sync_only: and not self.sync_only:
@ -1348,7 +1363,7 @@ you'll be able to transparently follow links to Gopherspace!""")
self.log["ipv6_bytes_recvd"] += size self.log["ipv6_bytes_recvd"] += size
def _get_active_tmpfile(self): def _get_active_tmpfile(self):
if self.gi.get_mime() in ["text/gemini","text/html"]: if self.gi.get_mime() in _FORMAT_RENDERERS:
return self.idx_filename return self.idx_filename
else: else:
return self.tmp_filename return self.tmp_filename
@ -1986,13 +2001,10 @@ Bookmarks are stored using the 'add' command."""
print("bookmarks command takes a single integer argument!") print("bookmarks command takes a single integer argument!")
return return
gi = GeminiItem("localhost:/" + bm_file,"Bookmarks") gi = GeminiItem("localhost:/" + bm_file,"Bookmarks")
# We dont display bookmarks if accessing directly one display = not self.sync_only
# or if in sync_only
display = not ( args or self.sync_only)
self._go_to_gi(gi,handle=display)
if args: if args:
# Use argument as a numeric index gi = gi.get_link(int(args))
self.default(line) self._go_to_gi(gi,handle=display)
def list_add_line(self,line,list): def list_add_line(self,line,list):
list_path = os.path.join(_DATA_DIR, "lists/%s.gmi"%list) list_path = os.path.join(_DATA_DIR, "lists/%s.gmi"%list)
@ -2008,19 +2020,28 @@ Bookmarks are stored using the 'add' command."""
list_path = os.path.join(_DATA_DIR, "lists/%s.gmi"%list) list_path = os.path.join(_DATA_DIR, "lists/%s.gmi"%list)
print("removing %s from %s not yet implemented"%(line,list)) print("removing %s from %s not yet implemented"%(line,list))
def list_go_to_line(self,line,list):
list_path = os.path.join(_DATA_DIR, "lists/%s.gmi"%list)
if not os.path.exists(list_path):
print("List %s does not exist. Create it with ""list create %s"""%(list,list))
return None
elif not line.isnumeric():
print("go_to_line requires a number as parameter")
return None
else:
gi = GeminiItem("localhost:/" + list_path,list)
gi = gi.get_link(line)
display = not self.sync_only
self._go_to_gi(gi,handle=display)
def list_show(self,list): def list_show(self,list):
list_path = os.path.join(_DATA_DIR, "lists/%s.gmi"%list) list_path = os.path.join(_DATA_DIR, "lists/%s.gmi"%list)
if not os.path.exists(list_path): if not os.path.exists(list_path):
print("List %s does not exist. Create it with ""list create %s"""%(list,list)) print("List %s does not exist. Create it with ""list create %s"""%(list,list))
else: else:
gi = GeminiItem("localhost:/" + list_path,list) gi = GeminiItem("localhost:/" + list_path,list)
# We dont display bookmarks if accessing directly one display = not self.sync_only
# or if in sync_only
display = not ( args or self.sync_only)
self._go_to_gi(gi,handle=display) self._go_to_gi(gi,handle=display)
if args:
# Use argument as a numeric index
self.default(line)
def list_create(self,list,title=None): def list_create(self,list,title=None):
listdir = os.path.join(_DATA_DIR,"lists") listdir = os.path.join(_DATA_DIR,"lists")