diff --git a/ansirenderer.py b/ansirenderer.py index cb769ba..e72f9ef 100644 --- a/ansirenderer.py +++ b/ansirenderer.py @@ -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 diff --git a/netcache.py b/netcache.py index ea144f2..e6e54c1 100755 --- a/netcache.py +++ b/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 diff --git a/offpunk.py b/offpunk.py index 02f5deb..1147554 100755 --- a/offpunk.py +++ b/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)