Making offpunk working for variable width. Thanks to Kelbot for pointing it was not working
This commit is contained in:
parent
ec8fb1fda6
commit
ff9adf4aea
112
offpunk.py
112
offpunk.py
|
@ -178,6 +178,9 @@ _MIME_HANDLERS = {
|
||||||
urllib.parse.uses_relative.append("gemini")
|
urllib.parse.uses_relative.append("gemini")
|
||||||
urllib.parse.uses_netloc.append("gemini")
|
urllib.parse.uses_netloc.append("gemini")
|
||||||
|
|
||||||
|
global TERM_WIDTH
|
||||||
|
TERM_WIDTH = 80
|
||||||
|
|
||||||
def fix_ipv6_url(url):
|
def fix_ipv6_url(url):
|
||||||
if not url:
|
if not url:
|
||||||
return
|
return
|
||||||
|
@ -226,14 +229,16 @@ class GemtextRenderer():
|
||||||
def is_valid(self):
|
def is_valid(self):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_body(self,readable=True):
|
def get_body(self,readable=True,width=None):
|
||||||
|
if not width:
|
||||||
|
width = TERM_WIDTH
|
||||||
if self.rendered_text == None :
|
if self.rendered_text == None :
|
||||||
self.rendered_text, self.links = self.render_gemtext(self.body)
|
self.rendered_text, self.links = self.render_gemtext(self.body,width=width)
|
||||||
return self.rendered_text
|
return self.rendered_text
|
||||||
|
|
||||||
def get_links(self):
|
def get_links(self):
|
||||||
if self.links == None :
|
if self.links == None :
|
||||||
self.rendered_text, self.links = self.render_gemtext(self.body)
|
rendered_text, self.links = self.render_gemtext(self.body)
|
||||||
return self.links
|
return self.links
|
||||||
|
|
||||||
def get_title(self):
|
def get_title(self):
|
||||||
|
@ -246,18 +251,20 @@ class GemtextRenderer():
|
||||||
self.title = line.strip("#").strip()
|
self.title = line.strip("#").strip()
|
||||||
return self.title
|
return self.title
|
||||||
if len(lines) > 0:
|
if len(lines) > 0:
|
||||||
# If not title found, we take the first 80 char
|
# If not title found, we take the first 50 char
|
||||||
# of the first line
|
# of the first line
|
||||||
title_line = lines[0].strip()
|
title_line = lines[0].strip()
|
||||||
if len(title_line) > 80:
|
if len(title_line) > 50:
|
||||||
title_line = title_line[:79] + "…"
|
title_line = title_line[:49] + "…"
|
||||||
self.title = title_line
|
self.title = title_line
|
||||||
return self.title
|
return self.title
|
||||||
else:
|
else:
|
||||||
self.title = "Empty Page"
|
self.title = "Empty Page"
|
||||||
return self.title
|
return self.title
|
||||||
|
|
||||||
def render_gemtext(self,gemtext, width=80):
|
def render_gemtext(self,gemtext, width=None):
|
||||||
|
if not width:
|
||||||
|
width = TERM_WIDTH
|
||||||
links = []
|
links = []
|
||||||
preformatted = False
|
preformatted = False
|
||||||
rendered_text = ""
|
rendered_text = ""
|
||||||
|
@ -339,29 +346,38 @@ class GopherRenderer():
|
||||||
def is_valid(self):
|
def is_valid(self):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_body(self,readable=True):
|
def get_body(self,readable=True,width=None):
|
||||||
|
if not width:
|
||||||
|
width = TERM_WIDTH
|
||||||
if self.rendered_text == None:
|
if self.rendered_text == None:
|
||||||
self.rendered_text,self.links = self.menu_or_text()
|
self.rendered_text,self.links = self.menu_or_text(width=width)
|
||||||
return self.rendered_text
|
return self.rendered_text
|
||||||
|
|
||||||
def get_links(self):
|
def get_links(self):
|
||||||
if self.links == None:
|
if self.links == None:
|
||||||
self.rendered_text,self.links = self.menu_or_text()
|
rendered_text,self.links = self.menu_or_text()
|
||||||
return self.links
|
return self.links
|
||||||
|
|
||||||
def get_title(self):
|
def get_title(self):
|
||||||
return "Gopher - No Title"
|
return "Gopher - No Title"
|
||||||
|
|
||||||
def menu_or_text(self):
|
def menu_or_text(self,width=None):
|
||||||
|
if not width:
|
||||||
|
width = TERM_WIDTH
|
||||||
try:
|
try:
|
||||||
render,links = self._render_goph()
|
render,links = self._render_goph(width=width)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
print("Error ",err)
|
print("Error ",err)
|
||||||
render = self.body
|
lines = self.body.split("\n")
|
||||||
|
render = ""
|
||||||
|
for line in lines:
|
||||||
|
render += textwrap.fill(line,width) + "\n"
|
||||||
links = []
|
links = []
|
||||||
return render,links
|
return render,links
|
||||||
|
|
||||||
def _render_goph(self):
|
def _render_goph(self,width=None):
|
||||||
|
if not width:
|
||||||
|
width = TERM_WIDTH
|
||||||
# This is copied straight from Agena (and thus from VF1)
|
# This is copied straight from Agena (and thus from VF1)
|
||||||
rendered_text = ""
|
rendered_text = ""
|
||||||
links = []
|
links = []
|
||||||
|
@ -369,7 +385,8 @@ class GopherRenderer():
|
||||||
#if line.strip() == ".":
|
#if line.strip() == ".":
|
||||||
# continue
|
# continue
|
||||||
if line.startswith("i"):
|
if line.startswith("i"):
|
||||||
rendered_text += line[1:].split("\t")[0] + "\r\n"
|
towrap = line[1:].split("\t")[0] + "\r\n"
|
||||||
|
rendered_text += textwrap.fill(towrap,width) + "\n"
|
||||||
elif not line.strip() in [".",""]:
|
elif not line.strip() in [".",""]:
|
||||||
parts = line.split("\t")
|
parts = line.split("\t")
|
||||||
parts[-1] = parts[-1].strip()
|
parts[-1] = parts[-1].strip()
|
||||||
|
@ -389,9 +406,11 @@ class GopherRenderer():
|
||||||
url = "gopher://%s%s/%s%s" %(host,port,itemtype,path)
|
url = "gopher://%s%s/%s%s" %(host,port,itemtype,path)
|
||||||
linkline = url + " " + name
|
linkline = url + " " + name
|
||||||
links.append(linkline)
|
links.append(linkline)
|
||||||
rendered_text += "[%s] "%len(links)+ name + "\n"
|
towrap = "[%s] "%len(links)+ name + "\n"
|
||||||
|
rendered_text += textwrap.fill(towrap,width) + "\n"
|
||||||
else:
|
else:
|
||||||
rendered_text += line +"\n"
|
towrap = line +"\n"
|
||||||
|
rendered_text += textwrap.fill(towrap,width) + "\n"
|
||||||
return rendered_text,links
|
return rendered_text,links
|
||||||
|
|
||||||
|
|
||||||
|
@ -408,10 +427,12 @@ class FeedRenderer():
|
||||||
self.render_feed(self.body)
|
self.render_feed(self.body)
|
||||||
return self.validity
|
return self.validity
|
||||||
|
|
||||||
def get_body(self,readable=True):
|
def get_body(self,readable=True,width=None):
|
||||||
|
if not width:
|
||||||
|
width = TERM_WIDTH
|
||||||
if readable:
|
if readable:
|
||||||
if not self.rendered_text:
|
if not self.rendered_text:
|
||||||
self.rendered_text = self.render_feed(self.body)
|
self.rendered_text = self.render_feed(self.body,width=width)
|
||||||
return self.rendered_text
|
return self.rendered_text
|
||||||
else:
|
else:
|
||||||
return self.render_feed(self.body,full=True)
|
return self.render_feed(self.body,full=True)
|
||||||
|
@ -426,7 +447,9 @@ class FeedRenderer():
|
||||||
self.render_feed(self.body)
|
self.render_feed(self.body)
|
||||||
return self.title
|
return self.title
|
||||||
|
|
||||||
def render_feed(self,content,full=False):
|
def render_feed(self,content,full=False,width=None):
|
||||||
|
if not width:
|
||||||
|
width = TERM_WIDTH
|
||||||
self.links = []
|
self.links = []
|
||||||
self.title = "RSS/Atom feed"
|
self.title = "RSS/Atom feed"
|
||||||
page = ""
|
page = ""
|
||||||
|
@ -446,34 +469,34 @@ class FeedRenderer():
|
||||||
else:
|
else:
|
||||||
t = "Unknown"
|
t = "Unknown"
|
||||||
title = "\x1b[1;4;34m%s (XML feed)\x1b[0m" %t
|
title = "\x1b[1;4;34m%s (XML feed)\x1b[0m" %t
|
||||||
self.title = textwrap.fill(title,80)
|
self.title = textwrap.fill(title,width)
|
||||||
page += self.title + "\n"
|
page += self.title + "\n"
|
||||||
if "subtitle" in parsed.feed:
|
if "subtitle" in parsed.feed:
|
||||||
page += textwrap.fill(parsed.feed.subtitle,80) + "\n\n"
|
page += textwrap.fill(parsed.feed.subtitle,width) + "\n\n"
|
||||||
if "link" in parsed.feed:
|
if "link" in parsed.feed:
|
||||||
self.links.append(parsed.feed.link)
|
self.links.append(parsed.feed.link)
|
||||||
line = "This is the feed for \x1b[34;2m%s [1]\x1b[0m" %parsed.feed.link
|
line = "This is the feed for \x1b[34;2m%s [1]\x1b[0m" %parsed.feed.link
|
||||||
page += textwrap.fill(line,80) + "\n"
|
page += textwrap.fill(line,width) + "\n"
|
||||||
if "updated" in parsed.feed:
|
if "updated" in parsed.feed:
|
||||||
line = "Last updated on %s" %parsed.feed.updated
|
line = "Last updated on %s" %parsed.feed.updated
|
||||||
page += textwrap.fill(line,80)
|
page += textwrap.fill(line,width)
|
||||||
page += "\n\n"
|
page += "\n\n"
|
||||||
if len(parsed.entries) < 1:
|
if len(parsed.entries) < 1:
|
||||||
self.validity = False
|
self.validity = False
|
||||||
for i in parsed.entries:
|
for i in parsed.entries:
|
||||||
self.links.append(i.link)
|
self.links.append(i.link)
|
||||||
line = "\x1b[34m%s [%s]\x1b[0m"%(i.title,len(self.links))
|
line = "\x1b[34m%s [%s]\x1b[0m"%(i.title,len(self.links))
|
||||||
page += textwrap.fill(line,80) + "\n"
|
page += textwrap.fill(line,width) + "\n"
|
||||||
line = ""
|
line = ""
|
||||||
if "author" in i:
|
if "author" in i:
|
||||||
line += "by %s "%i.author
|
line += "by %s "%i.author
|
||||||
if "published" in i:
|
if "published" in i:
|
||||||
line += "on %s"%i.published
|
line += "on %s"%i.published
|
||||||
page += textwrap.fill(line,80)
|
page += textwrap.fill(line,width)
|
||||||
page += "\n\n"
|
page += "\n\n"
|
||||||
if full:
|
if full:
|
||||||
if "summary" in i:
|
if "summary" in i:
|
||||||
page += textwrap.fill(i.summary,80)
|
page += textwrap.fill(i.summary,width)
|
||||||
page += "\n\n"
|
page += "\n\n"
|
||||||
return page
|
return page
|
||||||
|
|
||||||
|
@ -490,13 +513,15 @@ class HtmlRenderer():
|
||||||
def is_valid(self):
|
def is_valid(self):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_body(self,readable=True):
|
def get_body(self,readable=True,width=None):
|
||||||
|
if not width:
|
||||||
|
width = TERM_WIDTH
|
||||||
if self.rendered_text == None or not readable:
|
if self.rendered_text == None or not readable:
|
||||||
if readable:
|
if readable:
|
||||||
mode = "readable"
|
mode = "readable"
|
||||||
else:
|
else:
|
||||||
mode = "full"
|
mode = "full"
|
||||||
self.rendered_text, self.links = self.render_html(self.body,mode=mode)
|
self.rendered_text, self.links = self.render_html(self.body,mode=mode,width=width)
|
||||||
return self.rendered_text
|
return self.rendered_text
|
||||||
|
|
||||||
def get_links(self):
|
def get_links(self):
|
||||||
|
@ -515,7 +540,9 @@ class HtmlRenderer():
|
||||||
# Our own HTML engine (crazy, isn’t it?)
|
# Our own HTML engine (crazy, isn’t it?)
|
||||||
# Return [rendered_body, list_of_links]
|
# Return [rendered_body, list_of_links]
|
||||||
# mode is either quick, readable or full
|
# mode is either quick, readable or full
|
||||||
def render_html(self,body,mode="readable",width=80):
|
def render_html(self,body,mode="readable",width=None):
|
||||||
|
if not width:
|
||||||
|
width = TERM_WIDTH
|
||||||
if not _DO_HTML:
|
if not _DO_HTML:
|
||||||
print("HTML document detected. Please install python-bs4 and python-readability.")
|
print("HTML document detected. Please install python-bs4 and python-readability.")
|
||||||
return
|
return
|
||||||
|
@ -690,7 +717,7 @@ class HtmlRenderer():
|
||||||
first_line = lines.pop(0)
|
first_line = lines.pop(0)
|
||||||
if self.get_title()[:79] not in first_line:
|
if self.get_title()[:79] not in first_line:
|
||||||
title = "\x1b[1;34m\x1b[4m" + self.get_title() + "\x1b[0m""\n"
|
title = "\x1b[1;34m\x1b[4m" + self.get_title() + "\x1b[0m""\n"
|
||||||
title = textwrap.fill(title,80)
|
title = textwrap.fill(title,width)
|
||||||
r_body = title + "\n" + r_body
|
r_body = title + "\n" + r_body
|
||||||
return r_body,links
|
return r_body,links
|
||||||
|
|
||||||
|
@ -742,6 +769,14 @@ class GeminiItem():
|
||||||
self.local = False
|
self.local = False
|
||||||
if self.scheme == "gopher":
|
if self.scheme == "gopher":
|
||||||
if parsed.path and parsed.path[0] == "/" and len(parsed.path) > 1:
|
if parsed.path and parsed.path[0] == "/" and len(parsed.path) > 1:
|
||||||
|
splitted = parsed.path.split("/")
|
||||||
|
# We check if we have well a gopher type
|
||||||
|
if len(splitted[1]) == 1:
|
||||||
|
itemtype = parsed.path[1]
|
||||||
|
selector = parsed.path[2:]
|
||||||
|
else:
|
||||||
|
itemtype = "1"
|
||||||
|
selector = parsed.path
|
||||||
itemtype = parsed.path[1]
|
itemtype = parsed.path[1]
|
||||||
self.path = parsed.path[2:]
|
self.path = parsed.path[2:]
|
||||||
else:
|
else:
|
||||||
|
@ -755,6 +790,8 @@ class GeminiItem():
|
||||||
self.mime = "text/html"
|
self.mime = "text/html"
|
||||||
elif itemtype in ("9","g","I","s"):
|
elif itemtype in ("9","g","I","s"):
|
||||||
self.mime = None
|
self.mime = None
|
||||||
|
else:
|
||||||
|
self.mime = "text/gopher"
|
||||||
else:
|
else:
|
||||||
self.path = parsed.path
|
self.path = parsed.path
|
||||||
if parsed.query:
|
if parsed.query:
|
||||||
|
@ -921,7 +958,7 @@ class GeminiItem():
|
||||||
title += " (%s links) \x1b[0;31m(last accessed on %s)"%(nbr,str_last)
|
title += " (%s links) \x1b[0;31m(last accessed on %s)"%(nbr,str_last)
|
||||||
rendered_title = "\x1b[31m\x1b[1m"+ title + "\x1b[0m"
|
rendered_title = "\x1b[31m\x1b[1m"+ title + "\x1b[0m"
|
||||||
#FIXME: width to replace self.options["width"]
|
#FIXME: width to replace self.options["width"]
|
||||||
wrapped = textwrap.fill(rendered_title,80)
|
wrapped = textwrap.fill(rendered_title,TERM_WIDTH)
|
||||||
return wrapped + "\n"
|
return wrapped + "\n"
|
||||||
|
|
||||||
def _set_renderer(self,mime=None):
|
def _set_renderer(self,mime=None):
|
||||||
|
@ -1202,7 +1239,8 @@ class GeminiClient(cmd.Cmd):
|
||||||
"archives_size" : 100,
|
"archives_size" : 100,
|
||||||
"history_size" : 100
|
"history_size" : 100
|
||||||
}
|
}
|
||||||
|
global TERM_WIDTH
|
||||||
|
TERM_WIDTH = self.options["width"]
|
||||||
self.log = {
|
self.log = {
|
||||||
"start_time": time.time(),
|
"start_time": time.time(),
|
||||||
"requests": 0,
|
"requests": 0,
|
||||||
|
@ -2100,6 +2138,14 @@ class GeminiClient(cmd.Cmd):
|
||||||
if value.lower() not in ("ca", "tofu"):
|
if value.lower() not in ("ca", "tofu"):
|
||||||
print("TLS mode must be `ca` or `tofu`!")
|
print("TLS mode must be `ca` or `tofu`!")
|
||||||
return
|
return
|
||||||
|
elif option == "width":
|
||||||
|
if value.isnumeric():
|
||||||
|
value = int(value)
|
||||||
|
print("changing width to ",value)
|
||||||
|
global TERM_WIDTH
|
||||||
|
TERM_WIDTH = value
|
||||||
|
else:
|
||||||
|
print("%s is not a valid width (integer required)"%value)
|
||||||
elif value.isnumeric():
|
elif value.isnumeric():
|
||||||
value = int(value)
|
value = int(value)
|
||||||
elif value.lower() == "false":
|
elif value.lower() == "false":
|
||||||
|
|
Loading…
Reference in New Issue