From 93a04733da7b46659a6d353befbca24052b7bb86 Mon Sep 17 00:00:00 2001 From: Mathieu PATUREL Date: Mon, 2 Jan 2017 18:03:24 +1100 Subject: [PATCH] better handling of 404. Still not perfect --- MarkdownLivePreview.tasks | 21 ++++++++++++--------- functions.py | 4 ++-- image_manager.py | 28 +++++++++++++++++++++------- md_in_popup.py | 2 +- sample.md | 6 ++++++ 5 files changed, 42 insertions(+), 19 deletions(-) diff --git a/MarkdownLivePreview.tasks b/MarkdownLivePreview.tasks index b4767d3..d63639e 100644 --- a/MarkdownLivePreview.tasks +++ b/MarkdownLivePreview.tasks @@ -2,9 +2,8 @@ Fast: ☐ sync scroll @needsUpdate(because of images) ☐ regive focus to the right markdown view - ☐ bug when empty `src` - ☐ call settings listener on_new too - ☐ try/except for 404 + ☐ call settings listener on_new too - might be too heavy + ☐ use alt attribute for 404 error Medium: ☐ auto refresh preview if loading images @@ -15,13 +14,17 @@ Long: ☐ fix #4 ☐ support hanchor (TOC) @big +Unknown: + ☐ check how many times is the show_html function called ___________________ Archive: - ✔ preview.set_scratch(True) @done (17-01-02 16:41) @project(Fast) - ✔ set the title of the preview @done (17-01-02 16:38) @project(Fast) - ✔ preview.wordWrap => True @done (17-01-02 16:31) @project(Fast) - ✔ clean the code (syntax) @done (17-01-02 16:27) @project(Medium) - ✔ add 404 image @done (17-01-02 16:27) @project(Medium) - ✔ load images from internet (`https:`) @done (17-01-02 15:51) @project(todo) + ✔ try/except for 404 @done Mon 02 Jan 2017 at 18:03 @project(Fast) + ✔ fix bug when empty `src` @done Mon 02 Jan 2017 at 17:15 @project(Fast) + ✔ preview.set_scratch(True) @done Mon 02 Jan 2017 at 16:58 + ✔ set the title of the preview @done Mon 02 Jan 2017 at 16:58 + ✔ preview.wordWrap => True @done Mon 02 Jan 2017 at 16:58 + ✔ clean the code (syntax) @done Mon 02 Jan 2017 at 16:58 + ✔ add 404 image @done Mon 02 Jan 2017 at 16:57 + ✔ load images from internet (`https:`) @done Mon 02 Jan 2017 at 16:57 diff --git a/functions.py b/functions.py index 85aafe3..96842e8 100644 --- a/functions.py +++ b/functions.py @@ -12,7 +12,7 @@ def to_base64(path=None, content=None): try: with open(path, 'rb') as fp: content = fp.read() - except FileNotFoundError: + except (FileNotFoundError, OSError): return to_base64(file404) return 'data:image/png;base64,' + ''.join([chr(el) for el in list(base64.standard_b64encode(content))]) @@ -34,9 +34,9 @@ def mini(val, min): def get_content_till(string, char_to_look_for, start=0): i = start while i < len(string): - i += 1 if string[i] == char_to_look_for: return string[start:i], i + i += 1 def get_view_content(view): return view.substr(sublime.Region(0, view.size())) diff --git a/image_manager.py b/image_manager.py index 3fa8325..09b6e95 100644 --- a/image_manager.py +++ b/image_manager.py @@ -2,7 +2,7 @@ import os.path from threading import Thread -import urllib.request +import urllib.request, urllib.error import sublime from .functions import * @@ -13,7 +13,19 @@ SEPARATOR = '---%cache%--' def get_base64_saver(loading, url): def callback(content): + if isinstance(content, urllib.error.HTTPError): + if content.getcode() == 404: + loading[url] = 404 + return + elif isinstance(content, urllib.error.URLError): + if (content.reason.errno == 11001 and + content.reason.strerror == 'getaddrinfo failed'): + loading[url] = 404 + return + return sublime.error_message('An unexpected error has occured: ' + + str(content)) loading[url] = to_base64(content=content) + return callback def get_cache_for(imageurl): @@ -37,9 +49,12 @@ class ImageLoader(Thread): self.callback = callback def run(self): - page = urllib.request.urlopen(self.url, None, TIMEOUT) - # self.callback(self.url, page.read()) - self.callback(page.read()) + try: + page = urllib.request.urlopen(self.url, None, TIMEOUT) + except Exception as e: + self.callback(e) + else: + self.callback(page.read()) class ImageManager(object): @@ -53,14 +68,11 @@ class ImageManager(object): # run an other request >>> image = ImageManager.get('http://domain.com/image.png') 'data:image/png;base64,....' - """ loading = {} @staticmethod def get(imageurl, user_callback=None): - # if imageurl in ImageManager.loading.keys(): - # return None cached = get_cache_for(imageurl) if cached: @@ -69,6 +81,8 @@ class ImageManager(object): # return None (the file is still loading, already made a request) # return string the base64 of the url (which is going to be cached) temp_cached = ImageManager.loading[imageurl] + if temp_cached == 404: + return to_base64('404.png') if temp_cached: cache(imageurl, temp_cached) del ImageManager.loading[imageurl] diff --git a/md_in_popup.py b/md_in_popup.py index a99926d..762d3b5 100644 --- a/md_in_popup.py +++ b/md_in_popup.py @@ -138,7 +138,7 @@ def create_preview(window, md_view): return preview def show_html(md_view, preview): - html = '{}'.format(get_style(), + html = '\n{}'.format(get_style(), pre_with_br(markdown2.markdown(get_view_content(md_view), extras=['fenced-code-blocks', 'no-code-highlighting']))) diff --git a/sample.md b/sample.md index c41a0d5..977b065 100644 --- a/sample.md +++ b/sample.md @@ -1,3 +1,9 @@ # DuckDuckGo - The Search engine you'll fall in love with ![DuckDUckGo](http://www.articpost.com/wp-content/uploads/2014/08/DuckDuckGo-Search-Engine.jpg) + +![image](http://afterishtar.pl/images/100x100.gif) + +![image](http://erewer.omc/dsfdsf) + +This is a test