changeset 8116:e4f743999d5c

lib: de-obfuscate nested functions in pygmentize_annotation and how they always pass an annotate_from_changeset_func to AnnotateHtmlFormatter These functions contain the only call to annotate_highlight, which contains the only call to AnnotateHtmlFormatter. annotate_highlight is thus clearly always passed an annotate_from_changeset_func.
author Mads Kiilerich <mads@kiilerich.com>
date Thu, 02 Jan 2020 22:18:59 +0100
parents 2c7308652445
children 1bc843007746
files kallithea/lib/annotate.py kallithea/lib/helpers.py
diffstat 2 files changed, 68 insertions(+), 80 deletions(-) [+]
line wrap: on
line diff
--- a/kallithea/lib/annotate.py	Thu Jan 02 22:09:13 2020 +0100
+++ b/kallithea/lib/annotate.py	Thu Jan 02 22:18:59 2020 +0100
@@ -33,7 +33,7 @@
 from kallithea.lib.vcs.utils import safe_unicode
 
 
-def annotate_highlight(filenode, annotate_from_changeset_func=None,
+def annotate_highlight(filenode, annotate_from_changeset_func,
         order=None, headers=None, **options):
     """
     Returns html portion containing annotated table with 3 columns: line
@@ -50,9 +50,9 @@
     """
     from kallithea.lib.pygmentsutils import get_custom_lexer
     options['linenos'] = True
-    formatter = AnnotateHtmlFormatter(filenode=filenode, order=order,
-        headers=headers,
-        annotate_from_changeset_func=annotate_from_changeset_func, **options)
+    formatter = AnnotateHtmlFormatter(filenode=filenode,
+        annotate_from_changeset_func=annotate_from_changeset_func, order=order,
+        headers=headers, **options)
     lexer = get_custom_lexer(filenode.extension) or filenode.lexer
     highlighted = highlight(safe_unicode(filenode.content), lexer, formatter)
     return highlighted
@@ -60,10 +60,10 @@
 
 class AnnotateHtmlFormatter(HtmlFormatter):
 
-    def __init__(self, filenode, annotate_from_changeset_func=None,
+    def __init__(self, filenode, annotate_from_changeset_func,
             order=None, **options):
         """
-        If ``annotate_from_changeset_func`` is passed it should be a function
+        ``annotate_from_changeset_func`` must be a function
         which returns string from the given changeset. For example, we may pass
         following function as ``annotate_from_changeset_func``::
 
@@ -100,15 +100,6 @@
             raise VCSError("This formatter expect FileNode parameter, not %r"
                 % type(filenode))
 
-    def annotate_from_changeset(self, changeset):
-        """
-        Returns full html line for single changeset per annotated line.
-        """
-        if self.annotate_from_changeset_func:
-            return self.annotate_from_changeset_func(changeset)
-        else:
-            return ''.join((changeset.id, '\n'))
-
     def _wrap_tablelinenos(self, inner):
         inner_lines = []
         lncount = 0
@@ -165,7 +156,7 @@
 #        ln_ = len(ls.splitlines())
 #        if  ln_cs > ln_:
 #            annotate_changesets = annotate_changesets[:ln_ - ln_cs]
-        annotate = ''.join((self.annotate_from_changeset(el[2]())
+        annotate = ''.join((self.annotate_from_changeset_func(el[2]())
                             for el in self.filenode.annotate))
         # in case you wonder about the seemingly redundant <div> here:
         # since the content in the other cell also is wrapped in a div,
--- a/kallithea/lib/helpers.py	Thu Jan 02 22:09:13 2020 +0100
+++ b/kallithea/lib/helpers.py	Thu Jan 02 22:18:59 2020 +0100
@@ -333,56 +333,56 @@
         code_highlight(safe_unicode(filenode.content), lexer, CodeHtmlFormatter(**kwargs))))
 
 
+def hsv_to_rgb(h, s, v):
+    if s == 0.0:
+        return v, v, v
+    i = int(h * 6.0)  # XXX assume int() truncates!
+    f = (h * 6.0) - i
+    p = v * (1.0 - s)
+    q = v * (1.0 - s * f)
+    t = v * (1.0 - s * (1.0 - f))
+    i = i % 6
+    if i == 0:
+        return v, t, p
+    if i == 1:
+        return q, v, p
+    if i == 2:
+        return p, v, t
+    if i == 3:
+        return p, q, v
+    if i == 4:
+        return t, p, v
+    if i == 5:
+        return v, p, q
+
+
+def gen_color(n=10000):
+    """generator for getting n of evenly distributed colors using
+    hsv color and golden ratio. It always return same order of colors
+
+    :returns: RGB tuple
+    """
+
+    golden_ratio = 0.618033988749895
+    h = 0.22717784590367374
+
+    for _unused in xrange(n):
+        h += golden_ratio
+        h %= 1
+        HSV_tuple = [h, 0.95, 0.95]
+        RGB_tuple = hsv_to_rgb(*HSV_tuple)
+        yield [str(int(x * 256)) for x in RGB_tuple]
+
+
 def pygmentize_annotation(repo_name, filenode, **kwargs):
     """
     pygmentize function for annotation
 
     :param filenode:
     """
-
+    cgenerator = gen_color()
     color_dict = {}
 
-    def gen_color(n=10000):
-        """generator for getting n of evenly distributed colors using
-        hsv color and golden ratio. It always return same order of colors
-
-        :returns: RGB tuple
-        """
-
-        def hsv_to_rgb(h, s, v):
-            if s == 0.0:
-                return v, v, v
-            i = int(h * 6.0)  # XXX assume int() truncates!
-            f = (h * 6.0) - i
-            p = v * (1.0 - s)
-            q = v * (1.0 - s * f)
-            t = v * (1.0 - s * (1.0 - f))
-            i = i % 6
-            if i == 0:
-                return v, t, p
-            if i == 1:
-                return q, v, p
-            if i == 2:
-                return p, v, t
-            if i == 3:
-                return p, q, v
-            if i == 4:
-                return t, p, v
-            if i == 5:
-                return v, p, q
-
-        golden_ratio = 0.618033988749895
-        h = 0.22717784590367374
-
-        for _unused in xrange(n):
-            h += golden_ratio
-            h %= 1
-            HSV_tuple = [h, 0.95, 0.95]
-            RGB_tuple = hsv_to_rgb(*HSV_tuple)
-            yield [str(int(x * 256)) for x in RGB_tuple]
-
-    cgenerator = gen_color()
-
     def get_color_string(cs):
         if cs in color_dict:
             col = color_dict[cs]
@@ -390,31 +390,28 @@
             col = color_dict[cs] = cgenerator.next()
         return "color: rgb(%s)! important;" % (', '.join(col))
 
-    def url_func(repo_name):
-
-        def _url_func(changeset):
-            author = escape(changeset.author)
-            date = changeset.date
-            message = escape(changeset.message)
-            tooltip_html = ("<b>Author:</b> %s<br/>"
-                            "<b>Date:</b> %s</b><br/>"
-                            "<b>Message:</b> %s") % (author, date, message)
+    def url_func(changeset):
+        author = escape(changeset.author)
+        date = changeset.date
+        message = escape(changeset.message)
+        tooltip_html = ("<b>Author:</b> %s<br/>"
+                        "<b>Date:</b> %s</b><br/>"
+                        "<b>Message:</b> %s") % (author, date, message)
 
-            lnk_format = show_id(changeset)
-            uri = link_to(
-                    lnk_format,
-                    url('changeset_home', repo_name=repo_name,
-                        revision=changeset.raw_id),
-                    style=get_color_string(changeset.raw_id),
-                    **{'data-toggle': 'popover',
-                       'data-content': tooltip_html}
-                  )
+        lnk_format = show_id(changeset)
+        uri = link_to(
+                lnk_format,
+                url('changeset_home', repo_name=repo_name,
+                    revision=changeset.raw_id),
+                style=get_color_string(changeset.raw_id),
+                **{'data-toggle': 'popover',
+                   'data-content': tooltip_html}
+              )
 
-            uri += '\n'
-            return uri
-        return _url_func
+        uri += '\n'
+        return uri
 
-    return literal(markup_whitespace(annotate_highlight(filenode, url_func(repo_name), **kwargs)))
+    return literal(markup_whitespace(annotate_highlight(filenode, url_func, **kwargs)))
 
 
 class _Message(object):