forked from solderpunk/AV-98
Ok, it starts to work.
Offpunk is now able to display pages, pictures and follow links. A lot of TODO have been clearly identified. I think that the whole GeminiItem() object will be removed and URL will be accessed directly with a dict{url, renderer} to avoid redrawing all the time. Next challenge: remove GeminiItems!
This commit is contained in:
parent
72ea43a59c
commit
767ab82f29
|
@ -968,6 +968,7 @@ class HtmlRenderer(AbstractRenderer):
|
|||
if _RENDER_IMAGE and mode != "links_only" and imgurl:
|
||||
try:
|
||||
#4 followings line are there to translate the URL into cache path
|
||||
#TODO: do that with netcache
|
||||
g = GeminiItem(imgurl)
|
||||
img = g.get_cache_path()
|
||||
if imgdata:
|
||||
|
@ -1208,11 +1209,17 @@ def get_mime(path):
|
|||
|
||||
def renderer_from_file(path,url=None):
|
||||
mime = get_mime(path)
|
||||
if not url:
|
||||
url = path
|
||||
if os.path.exists(path):
|
||||
with open(path) as f:
|
||||
body = f.read()
|
||||
f.close()
|
||||
return set_renderer(body,url,mime)
|
||||
if mime.startswith("text/"):
|
||||
with open(path) as f:
|
||||
print("DEBUG: opening %s"%path)
|
||||
content = f.read()
|
||||
f.close()
|
||||
else:
|
||||
content = path
|
||||
return set_renderer(content,url,mime)
|
||||
else:
|
||||
return None
|
||||
|
||||
|
|
66
netcache.py
66
netcache.py
|
@ -635,20 +635,60 @@ def _fetch_gemini(url,timeout=DEFAULT_TIMEOUT,**kwargs):
|
|||
def fetch(url,**kwargs):
|
||||
url = normalize_url(url)
|
||||
path=None
|
||||
print_error = "print_error" in kwargs.keys() and kwargs["print_error"]
|
||||
if "://" in url:
|
||||
scheme = url.split("://")[0]
|
||||
if scheme not in standard_ports:
|
||||
print("%s is not a supported protocol"%scheme)
|
||||
elif scheme in ("http","https"):
|
||||
path=_fetch_http(url,**kwargs)
|
||||
elif scheme == "gopher":
|
||||
path=_fetch_gopher(url,**kwargs)
|
||||
elif scheme == "finger":
|
||||
path=_fetch_finger(url,**kwargs)
|
||||
elif scheme == "gemini":
|
||||
patch=_fetch_gemini(url,**kwargs)
|
||||
else:
|
||||
print("scheme %s not implemented yet")
|
||||
try:
|
||||
scheme = url.split("://")[0]
|
||||
if scheme not in standard_ports:
|
||||
print("%s is not a supported protocol"%scheme)
|
||||
elif scheme in ("http","https"):
|
||||
path=_fetch_http(url,**kwargs)
|
||||
elif scheme == "gopher":
|
||||
path=_fetch_gopher(url,**kwargs)
|
||||
elif scheme == "finger":
|
||||
path=_fetch_finger(url,**kwargs)
|
||||
elif scheme == "gemini":
|
||||
patch=_fetch_gemini(url,**kwargs)
|
||||
else:
|
||||
print("scheme %s not implemented yet")
|
||||
except UserAbortException:
|
||||
return
|
||||
except Exception as err:
|
||||
#TODO return the error !
|
||||
#gi.set_error(err)
|
||||
# Print an error message
|
||||
# we fail silently when sync_only
|
||||
if isinstance(err, socket.gaierror):
|
||||
if print_error:
|
||||
print("ERROR: DNS error!")
|
||||
elif isinstance(err, ConnectionRefusedError):
|
||||
if print_error:
|
||||
print("ERROR1: Connection refused!")
|
||||
elif isinstance(err, ConnectionResetError):
|
||||
if print_error:
|
||||
print("ERROR2: Connection reset!")
|
||||
elif isinstance(err, (TimeoutError, socket.timeout)):
|
||||
if print_error:
|
||||
print("""ERROR3: Connection timed out!
|
||||
Slow internet connection? Use 'set timeout' to be more patient.""")
|
||||
elif isinstance(err, FileExistsError):
|
||||
if print_error:
|
||||
print("""ERROR5: Trying to create a directory which already exists
|
||||
in the cache : """)
|
||||
print(err)
|
||||
elif _DO_HTTP and isinstance(err,requests.exceptions.SSLError):
|
||||
if print_error:
|
||||
print("""ERROR6: Bad SSL certificate:\n""")
|
||||
print(err)
|
||||
print("""\n If you know what you are doing, you can try to accept bad certificates with the following command:\n""")
|
||||
print("""set accept_bad_ssl_certificates True""")
|
||||
else:
|
||||
if print_error:
|
||||
import traceback
|
||||
print("ERROR4: " + str(type(err)) + " : " + str(err))
|
||||
print("\n" + str(err.with_traceback(None)))
|
||||
print(traceback.format_exc())
|
||||
return
|
||||
else:
|
||||
print("Not a supproted URL")
|
||||
return path
|
||||
|
|
60
offpunk.py
60
offpunk.py
|
@ -210,6 +210,7 @@ class GeminiItem():
|
|||
def cache_last_modified(self):
|
||||
return netcache.cache_last_modified(self.url)
|
||||
|
||||
#TODO : move to ansirenderer
|
||||
def get_body(self,as_file=False):
|
||||
if self.is_cache_valid():
|
||||
path = self.get_cache_path()
|
||||
|
@ -240,6 +241,7 @@ class GeminiItem():
|
|||
|
||||
# This method is used to load once the list of links in a gi
|
||||
# Links can be followed, after a space, by a description/title
|
||||
#TODO: check all calls of get_links then move it to ansirenderer
|
||||
def get_links(self,mode=None):
|
||||
links = []
|
||||
toreturn = []
|
||||
|
@ -275,6 +277,7 @@ class GeminiItem():
|
|||
toreturn.append(None)
|
||||
return toreturn
|
||||
|
||||
#TODO: should be in ansirenderer
|
||||
def get_link(self,nb):
|
||||
# == None allows to return False, even if the list is empty
|
||||
links = self.get_links()
|
||||
|
@ -284,6 +287,7 @@ class GeminiItem():
|
|||
else:
|
||||
return links[nb-1]
|
||||
|
||||
#TODO: should be in ansirenderer
|
||||
def get_subscribe_links(self):
|
||||
if self.renderer:
|
||||
subs = self.renderer.get_subscribe_links()
|
||||
|
@ -296,7 +300,7 @@ class GeminiItem():
|
|||
else:
|
||||
return []
|
||||
|
||||
|
||||
#TODO: should be in ansiless
|
||||
def display(self,mode=None,grep=None):
|
||||
if self.renderer and self.renderer.is_valid():
|
||||
if not mode:
|
||||
|
@ -591,6 +595,8 @@ class GeminiClient(cmd.Cmd):
|
|||
(hostname text, address text, fingerprint text,
|
||||
first_seen date, last_seen date, count integer)""")
|
||||
|
||||
#TODO: go_to_gi should take an URL as parameter, not gi
|
||||
#it should also only be called to really go, not for all links
|
||||
def _go_to_gi(self, gi, update_hist=True, check_cache=True, handle=True,\
|
||||
mode=None,limit_size=False):
|
||||
"""This method might be considered "the heart of Offpunk".
|
||||
|
@ -644,51 +650,11 @@ class GeminiClient(cmd.Cmd):
|
|||
return
|
||||
|
||||
elif not self.offline_only and not gi.local:
|
||||
try:
|
||||
params = {}
|
||||
params["timeout"] = self.options["short_timeout"]
|
||||
params["max_size"] = int(self.options["max_size_download"])*1000000
|
||||
cachepath = netcache.fetch(gi.url,**params)
|
||||
except UserAbortException:
|
||||
return
|
||||
except Exception as err:
|
||||
gi.set_error(err)
|
||||
# Print an error message
|
||||
# we fail silently when sync_only
|
||||
print_error = not self.sync_only
|
||||
if isinstance(err, socket.gaierror):
|
||||
self.log["dns_failures"] += 1
|
||||
if print_error:
|
||||
print("ERROR: DNS error!")
|
||||
elif isinstance(err, ConnectionRefusedError):
|
||||
self.log["refused_connections"] += 1
|
||||
if print_error:
|
||||
print("ERROR1: Connection refused!")
|
||||
elif isinstance(err, ConnectionResetError):
|
||||
self.log["reset_connections"] += 1
|
||||
if print_error:
|
||||
print("ERROR2: Connection reset!")
|
||||
elif isinstance(err, (TimeoutError, socket.timeout)):
|
||||
self.log["timeouts"] += 1
|
||||
if print_error:
|
||||
print("""ERROR3: Connection timed out!
|
||||
Slow internet connection? Use 'set timeout' to be more patient.""")
|
||||
elif isinstance(err, FileExistsError):
|
||||
print("""ERROR5: Trying to create a directory which already exists
|
||||
in the cache : """)
|
||||
print(err)
|
||||
elif _DO_HTTP and isinstance(err,requests.exceptions.SSLError):
|
||||
print("""ERROR6: Bad SSL certificate:\n""")
|
||||
print(err)
|
||||
print("""\n If you know what you are doing, you can try to accept bad certificates with the following command:\n""")
|
||||
print("""set accept_bad_ssl_certificates True""")
|
||||
else:
|
||||
if print_error:
|
||||
import traceback
|
||||
print("ERROR4: " + str(type(err)) + " : " + str(err))
|
||||
print("\n" + str(err.with_traceback(None)))
|
||||
print(traceback.format_exc())
|
||||
return
|
||||
params = {}
|
||||
params["timeout"] = self.options["short_timeout"]
|
||||
params["max_size"] = int(self.options["max_size_download"])*1000000
|
||||
params["print_error"] = not self.sync_only
|
||||
cachepath = netcache.fetch(gi.url,**params)
|
||||
|
||||
# Pass file to handler, unless we were asked not to
|
||||
if netcache.is_cache_valid(gi.url) :
|
||||
|
@ -696,7 +662,9 @@ class GeminiClient(cmd.Cmd):
|
|||
#TODO: take into account _RENDER_IMAGE
|
||||
if display and self.options["download_images_first"] \
|
||||
and not self.offline_only:
|
||||
|
||||
# We download images first
|
||||
#TODO: this should go into netcache
|
||||
for image in gi.get_images(mode=mode):
|
||||
if image and image.startswith("http"):
|
||||
img_gi = GeminiItem(image)
|
||||
|
|
Loading…
Reference in New Issue