refactoring and cleanup: now accessing links directly from gi instead of hiding a go_to
This commit is contained in:
parent
bdd006c896
commit
14e5fbcc83
79
offpunk.py
79
offpunk.py
|
@ -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.
|
||||||
# - There’s only one GeminiClient. Each page is a GeminiItem (name is historical, as
|
# - There’s only one GeminiClient. Each page is a GeminiItem (name is historical, as
|
||||||
|
@ -487,13 +493,9 @@ class GeminiItem():
|
||||||
print("ERROR: NO CACHE for %s" %self._cache_path)
|
print("ERROR: NO CACHE 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 it’s gemini except for html
|
#by default, we consider it’s 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 don’t 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 don’t 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")
|
||||||
|
|
Loading…
Reference in New Issue