git » git-arr » commit 21522f8

Add embed data URI image blob support

author Vanya Sergeev
2013-10-13 13:30:25 UTC
committer Alberto Bertogli
2013-11-02 19:07:59 UTC
parent f62ca211ebf8badd17fef5d15d61eb8ff00875c1

Add embed data URI image blob support

git-arr +2 -0
git.py +5 -1
utils.py +28 -0
views/blob.html +3 -1

diff --git a/git-arr b/git-arr
index 8890563..9b3c246 100755
--- a/git-arr
+++ b/git-arr
@@ -176,6 +176,8 @@ def with_utils(f):
         'colorize_blob': utils.colorize_blob,
         'can_markdown': utils.can_markdown,
         'markdown_blob': utils.markdown_blob,
+        'can_embed_image': utils.can_embed_image,
+        'embed_image_blob': utils.embed_image_blob,
         'abort': bottle.abort,
         'smstr': git.smstr,
     }
diff --git a/git.py b/git.py
index f0e73ba..deddeba 100644
--- a/git.py
+++ b/git.py
@@ -325,7 +325,7 @@ class Repo:
             ref = self.branch
         return Tree(self, ref)
 
-    def blob(self, path, ref = None):
+    def blob(self, path, ref = None, raw = False):
         """Returns the contents of the given path."""
         if not ref:
             ref = self.branch
@@ -341,6 +341,10 @@ class Repo:
         if not head or head.strip().endswith('missing'):
             return None
 
+        # Raw option in case we need a binary blob and not a utf-8 encoded one.
+        if raw:
+            return out.fd.read()
+
         return out.read()
 
 
diff --git a/utils.py b/utils.py
index 9e3ca59..c7f63d0 100644
--- a/utils.py
+++ b/utils.py
@@ -17,6 +17,8 @@ try:
 except ImportError:
     markdown = None
 
+import base64
+
 def shorten(s, width = 60):
     if len(s) < 60:
         return s
@@ -52,6 +54,15 @@ def can_markdown(fname):
 
     return fname.endswith(".md")
 
+def can_embed_image(fname):
+    """True if we can embed image file in HTML, False otherwise."""
+
+    exts = [ 'jpg', 'jpeg', 'png', 'gif', 'svg' ]
+    if '.' in fname and fname.split('.')[-1] in exts:
+        return True
+
+    return False
+
 def colorize_diff(s):
     lexer = lexers.DiffLexer(encoding = 'utf-8')
     formatter = HtmlFormatter(encoding = 'utf-8',
@@ -82,3 +93,20 @@ def colorize_blob(fname, s):
 def markdown_blob(s):
     return markdown.markdown(s)
 
+def embed_image_blob(repo, dirname, fname):
+    ext_to_mimetype = {'jpg': 'image/jpeg',
+                       'jpeg': 'image/jpeg',
+                       'png': 'image/png',
+                       'gif': 'image/gif',
+                       'svg': 'image/svg+xml',}
+
+    mimetype = ext_to_mimetype[fname.split('.')[-1]]
+
+    # Unfortunately, bottle seems to require utf-8 encoded data.
+    # We have to refetch the blob with raw=True, because the utf-8 encoded
+    # version of the blob available in the bottle template discards binary data.
+    raw_blob = repo.blob(dirname + fname, raw = True)
+
+    return '<img style="max-width:100%;" src="data:{0};base64,{1}" />'.format( \
+                                    mimetype, base64.b64encode(raw_blob))
+
diff --git a/views/blob.html b/views/blob.html
index 6244fc7..320cc89 100644
--- a/views/blob.html
+++ b/views/blob.html
@@ -36,7 +36,9 @@
     <a href="">{{!fname.html}}</a>
 </h3>
 
-% if can_markdown(fname.unicode):
+% if can_embed_image(fname.unicode):
+{{!embed_image_blob(repo, dirname.raw, fname.raw)}}
+% elif can_markdown(fname.unicode):
 {{!markdown_blob(blob)}}
 % elif can_colorize(blob):
 {{!colorize_blob(fname.unicode, blob)}}