forked from solderpunk/AV-98
pour le moment incapable de décider si ansirenderer doit prendre le path du fichier ou directement le texte en input
This commit is contained in:
parent
ce65850987
commit
cd3177ac87
119
ansirenderer.py
119
ansirenderer.py
|
@ -9,6 +9,7 @@ import time
|
|||
import html
|
||||
import urllib
|
||||
import argparse
|
||||
import mimetypes
|
||||
from offutils import run,term_width
|
||||
try:
|
||||
from readability import Document
|
||||
|
@ -704,6 +705,8 @@ class GopherRenderer(AbstractRenderer):
|
|||
|
||||
|
||||
class FolderRenderer(GemtextRenderer):
|
||||
#it was initialized with:
|
||||
#self.renderer = FolderRenderer("",self.get_cache_path(),datadir=_DATA_DIR)
|
||||
def __init__(self,content,url,center=True,datadir=None):
|
||||
GemtextRenderer.__init__(self,content,url,center)
|
||||
self.datadir = datadir
|
||||
|
@ -1124,24 +1127,124 @@ class HtmlRenderer(AbstractRenderer):
|
|||
recursive_render(soup)
|
||||
return r.get_final(),links
|
||||
|
||||
def render(text,format):
|
||||
|
||||
# Mapping mimetypes with renderers
|
||||
# (any content with a mimetype text/* not listed here will be rendered with as GemText)
|
||||
_FORMAT_RENDERERS = {
|
||||
"text/gemini": GemtextRenderer,
|
||||
"text/html" : HtmlRenderer,
|
||||
"text/xml" : FeedRenderer,
|
||||
"application/xml" : FeedRenderer,
|
||||
"application/rss+xml" : FeedRenderer,
|
||||
"application/atom+xml" : FeedRenderer,
|
||||
"text/gopher": GopherRenderer,
|
||||
"image/*": ImageRenderer
|
||||
}
|
||||
def get_mime(path):
|
||||
#Beware, this one is really a shaddy ad-hoc function
|
||||
if path.startswith("mailto:"):
|
||||
mime = "mailto"
|
||||
elif os.path.isdir(path):
|
||||
mime = "Local Folder"
|
||||
elif path.endswith(".gmi"):
|
||||
mime = "text/gemini"
|
||||
elif shutil.which("file") :
|
||||
mime = run("file -b --mime-type %s", parameter=path).strip()
|
||||
mime2,encoding = mimetypes.guess_type(path,strict=False)
|
||||
#If we hesitate between html and xml, takes the xml one
|
||||
#because the FeedRendered fallback to HtmlRenderer
|
||||
if mime2 and mime != mime2 and "html" in mime and "xml" in mime2:
|
||||
mime = "text/xml"
|
||||
# If it’s a xml file, consider it as such, regardless of what file thinks
|
||||
elif path.endswith(".xml"):
|
||||
mime = "text/xml"
|
||||
#Some xml/html document are considered as octet-stream
|
||||
if mime == "application/octet-stream":
|
||||
mime = "text/xml"
|
||||
else:
|
||||
mime,encoding = mimetypes.guess_type(path,strict=False)
|
||||
#gmi Mimetype is not recognized yet
|
||||
if not mime and not shutil.which("file") :
|
||||
print("Cannot guess the mime type of the file. Please install \"file\".")
|
||||
print("(and send me an email, I’m curious of systems without \"file\" installed!")
|
||||
if mime.startswith("text") and mime not in _FORMAT_RENDERERS:
|
||||
if mime2 and mime2 in _FORMAT_RENDERERS:
|
||||
mime = mime2
|
||||
else:
|
||||
#by default, we consider it’s gemini except for html
|
||||
mime = "text/gemini"
|
||||
return mime
|
||||
|
||||
def set_renderer(content,url,mime):
|
||||
renderer = None
|
||||
if mime == "Local Folder":
|
||||
renderer = FolderRenderer("",url,datadir=_DATA_DIR)
|
||||
return renderer
|
||||
mime_to_use = []
|
||||
for m in _FORMAT_RENDERERS:
|
||||
if fnmatch.fnmatch(mime, m):
|
||||
mime_to_use.append(m)
|
||||
if len(mime_to_use) > 0:
|
||||
current_mime = mime_to_use[0]
|
||||
func = _FORMAT_RENDERERS[current_mime]
|
||||
if current_mime.startswith("text"):
|
||||
renderer = func(content,url)
|
||||
# We double check if the renderer is correct.
|
||||
# If not, we fallback to html
|
||||
# (this is currently only for XHTML, often being
|
||||
# mislabelled as xml thus RSS feeds)
|
||||
if not renderer.is_valid():
|
||||
func = _FORMAT_RENDERERS["text/html"]
|
||||
#print("Set (fallback)RENDERER to html instead of %s"%mime)
|
||||
renderer = func(content,url)
|
||||
else:
|
||||
#TODO: check this code and then remove one if.
|
||||
#we don’t parse text, we give the file to the renderer
|
||||
renderer = func(content,url)
|
||||
if not renderer.is_valid():
|
||||
renderer = None
|
||||
return renderer
|
||||
|
||||
|
||||
def render(input,format="auto",mime=None,url=None):
|
||||
if mime and not format or format=="auto":
|
||||
format = get_format(input)
|
||||
if format == "gemtext":
|
||||
r = GemtextRenderer(text,"https://ploum.net")
|
||||
r = GemtextRenderer(input,"https://ploum.net")
|
||||
elif format == "html":
|
||||
r = HtmlRenderer(text,"https://ploum.net")
|
||||
r.display()
|
||||
r = HtmlRenderer(input,"https://ploum.net")
|
||||
elif format == "feed":
|
||||
r = FeedRenderer(input,"https://ploum.net")
|
||||
elif format == "gopher":
|
||||
r = GopherRenderer(input,"https://ploum.net")
|
||||
elif format == "image":
|
||||
r = ImageRenderer(input,"https://ploum.net")
|
||||
elif format == "folder":
|
||||
r = FolderRenderer(input,"https://ploum.net")
|
||||
else:
|
||||
if not mime:
|
||||
mime = get_mime(input)
|
||||
r = set_renderer(input,url,mime)
|
||||
print("renderer is %s"%r)
|
||||
if r:
|
||||
r.display()
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--format", choices=["gemtext","html","feed","gopher","image","folder"],
|
||||
help="Renderer to use. Available: gemtext, html, feed, gopher, image, folder")
|
||||
parser.add_argument("--format", choices=["auto","gemtext","html","feed","gopher","image","folder"],
|
||||
help="Renderer to use. Available: auto, gemtext, html, feed, gopher, image, folder")
|
||||
## The argument needs to be a path to a file. If none, then stdin is used which allows
|
||||
## to pipe text directly into ansirenderer
|
||||
parser.add_argument("input",metavar="INPUT", nargs="?", type=argparse.FileType("r"),
|
||||
parser.add_argument("--url",metavar="URL", nargs="*",
|
||||
help="Original URL of the content")
|
||||
parser.add_argument("content",metavar="INPUT", nargs="*", type=argparse.FileType("r"),
|
||||
default=sys.stdin, help="Path to the text to render (default to stdin)")
|
||||
args = parser.parse_args()
|
||||
render(args.input.read(),args.format)
|
||||
print("Input: %s"%args.input)
|
||||
#TODO: find when we have a text or a path.
|
||||
# We cannot get mime from a text!
|
||||
#render(args.input.read(),format=args.format,url=args.url)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
84
offpunk.py
84
offpunk.py
|
@ -1,3 +1,4 @@
|
|||
#TODO: remove the set_renderer then try to run offpunk
|
||||
#!/usr/bin/env python3
|
||||
# Offpunk Offline Gemini client
|
||||
# Derived from AV-98 by Solderpunk,
|
||||
|
@ -26,7 +27,6 @@ import fnmatch
|
|||
import glob
|
||||
import hashlib
|
||||
import io
|
||||
import mimetypes
|
||||
import os
|
||||
import os.path
|
||||
import filecmp
|
||||
|
@ -159,18 +159,6 @@ standard_ports = {
|
|||
"https" : 443,
|
||||
"spartan": 300,
|
||||
}
|
||||
# Mapping mimetypes with renderers
|
||||
# (any content with a mimetype text/* not listed here will be rendered with as GemText)
|
||||
_FORMAT_RENDERERS = {
|
||||
"text/gemini": ansirenderer.GemtextRenderer,
|
||||
"text/html" : ansirenderer.HtmlRenderer,
|
||||
"text/xml" : ansirenderer.FeedRenderer,
|
||||
"application/xml" : ansirenderer.FeedRenderer,
|
||||
"application/rss+xml" : ansirenderer.FeedRenderer,
|
||||
"application/atom+xml" : ansirenderer.FeedRenderer,
|
||||
"text/gopher": ansirenderer.GopherRenderer,
|
||||
"image/*": ansirenderer.ImageRenderer
|
||||
}
|
||||
# Offpunk is organized as follow:
|
||||
# - a GeminiClient instance which handles the browsing of GeminiItems (= pages).
|
||||
# - There’s only one GeminiClient. Each page is a GeminiItem (name is historical, as
|
||||
|
@ -344,37 +332,6 @@ class GeminiItem():
|
|||
else:
|
||||
return []
|
||||
|
||||
def _set_renderer(self,mime=None):
|
||||
if self.local and os.path.isdir(self.get_cache_path()):
|
||||
self.renderer = ansirenderer.FolderRenderer("",self.get_cache_path(),datadir=_DATA_DIR)
|
||||
return
|
||||
if not mime:
|
||||
mime = self.get_mime()
|
||||
#we don’t even have a mime (so probably we don’t have a cache)
|
||||
if not mime:
|
||||
return
|
||||
mime_to_use = []
|
||||
for m in _FORMAT_RENDERERS:
|
||||
if fnmatch.fnmatch(mime, m):
|
||||
mime_to_use.append(m)
|
||||
if len(mime_to_use) > 0:
|
||||
current_mime = mime_to_use[0]
|
||||
func = _FORMAT_RENDERERS[current_mime]
|
||||
if current_mime.startswith("text"):
|
||||
self.renderer = func(self.get_body(),self.url)
|
||||
# We double check if the renderer is correct.
|
||||
# If not, we fallback to html
|
||||
# (this is currently only for XHTML, often being
|
||||
# mislabelled as xml thus RSS feeds)
|
||||
if not self.renderer.is_valid():
|
||||
func = _FORMAT_RENDERERS["text/html"]
|
||||
#print("Set (fallback)RENDERER to html instead of %s"%mime)
|
||||
self.renderer = func(self.get_body(),self.url)
|
||||
else:
|
||||
#we don’t parse text, we give the file to the renderer
|
||||
self.renderer = func(self.get_cache_path(),self.url)
|
||||
if not self.renderer.is_valid():
|
||||
self.renderer = None
|
||||
|
||||
def display(self,mode=None,grep=None):
|
||||
if not self.renderer:
|
||||
|
@ -415,45 +372,6 @@ class GeminiItem():
|
|||
return tmpf
|
||||
|
||||
|
||||
def get_mime(self):
|
||||
#Beware, this one is really a shaddy ad-hoc function
|
||||
if self.mime:
|
||||
return self.mime
|
||||
elif self.is_cache_valid():
|
||||
path = self.get_cache_path()
|
||||
if self.scheme == "mailto":
|
||||
mime = "mailto"
|
||||
elif os.path.isdir(path):
|
||||
mime = "Local Folder"
|
||||
elif path.endswith(".gmi"):
|
||||
mime = "text/gemini"
|
||||
elif shutil.which("file") :
|
||||
mime = run("file -b --mime-type %s", parameter=path).strip()
|
||||
mime2,encoding = mimetypes.guess_type(path,strict=False)
|
||||
#If we hesitate between html and xml, takes the xml one
|
||||
#because the FeedRendered fallback to HtmlRenderer
|
||||
if mime2 and mime != mime2 and "html" in mime and "xml" in mime2:
|
||||
mime = "text/xml"
|
||||
# If it’s a xml file, consider it as such, regardless of what file thinks
|
||||
elif path.endswith(".xml"):
|
||||
mime = "text/xml"
|
||||
#Some xml/html document are considered as octet-stream
|
||||
if mime == "application/octet-stream":
|
||||
mime = "text/xml"
|
||||
else:
|
||||
mime,encoding = mimetypes.guess_type(path,strict=False)
|
||||
#gmi Mimetype is not recognized yet
|
||||
if not mime and not shutil.which("file") :
|
||||
print("Cannot guess the mime type of the file. Please install \"file\".")
|
||||
print("(and send me an email, I’m curious of systems without \"file\" installed!")
|
||||
if mime.startswith("text") and mime not in _FORMAT_RENDERERS:
|
||||
if mime2 and mime2 in _FORMAT_RENDERERS:
|
||||
mime = mime2
|
||||
else:
|
||||
#by default, we consider it’s gemini except for html
|
||||
mime = "text/gemini"
|
||||
self.mime = mime
|
||||
return self.mime
|
||||
|
||||
def set_error(self,err):
|
||||
# If we get an error, we want to keep an existing cache
|
||||
|
|
Loading…
Reference in New Issue