Show More
@@ -33,7 +33,7 b' from kallithea.lib.vcs.nodes import File' | |||||
33 | from kallithea.lib.vcs.utils import safe_unicode |
|
33 | from kallithea.lib.vcs.utils import safe_unicode | |
34 |
|
34 | |||
35 |
|
35 | |||
36 |
def annotate_highlight(filenode, annotate_from_changeset_func |
|
36 | def annotate_highlight(filenode, annotate_from_changeset_func, | |
37 | order=None, headers=None, **options): |
|
37 | order=None, headers=None, **options): | |
38 | """ |
|
38 | """ | |
39 | Returns html portion containing annotated table with 3 columns: line |
|
39 | Returns html portion containing annotated table with 3 columns: line | |
@@ -50,9 +50,9 b' def annotate_highlight(filenode, annotat' | |||||
50 | """ |
|
50 | """ | |
51 | from kallithea.lib.pygmentsutils import get_custom_lexer |
|
51 | from kallithea.lib.pygmentsutils import get_custom_lexer | |
52 | options['linenos'] = True |
|
52 | options['linenos'] = True | |
53 |
formatter = AnnotateHtmlFormatter(filenode=filenode, |
|
53 | formatter = AnnotateHtmlFormatter(filenode=filenode, | |
54 | headers=headers, |
|
54 | annotate_from_changeset_func=annotate_from_changeset_func, order=order, | |
55 | annotate_from_changeset_func=annotate_from_changeset_func, **options) |
|
55 | headers=headers, **options) | |
56 | lexer = get_custom_lexer(filenode.extension) or filenode.lexer |
|
56 | lexer = get_custom_lexer(filenode.extension) or filenode.lexer | |
57 | highlighted = highlight(safe_unicode(filenode.content), lexer, formatter) |
|
57 | highlighted = highlight(safe_unicode(filenode.content), lexer, formatter) | |
58 | return highlighted |
|
58 | return highlighted | |
@@ -60,10 +60,10 b' def annotate_highlight(filenode, annotat' | |||||
60 |
|
60 | |||
61 | class AnnotateHtmlFormatter(HtmlFormatter): |
|
61 | class AnnotateHtmlFormatter(HtmlFormatter): | |
62 |
|
62 | |||
63 |
def __init__(self, filenode, annotate_from_changeset_func |
|
63 | def __init__(self, filenode, annotate_from_changeset_func, | |
64 | order=None, **options): |
|
64 | order=None, **options): | |
65 | """ |
|
65 | """ | |
66 |
|
|
66 | ``annotate_from_changeset_func`` must be a function | |
67 | which returns string from the given changeset. For example, we may pass |
|
67 | which returns string from the given changeset. For example, we may pass | |
68 | following function as ``annotate_from_changeset_func``:: |
|
68 | following function as ``annotate_from_changeset_func``:: | |
69 |
|
69 | |||
@@ -100,15 +100,6 b' class AnnotateHtmlFormatter(HtmlFormatte' | |||||
100 | raise VCSError("This formatter expect FileNode parameter, not %r" |
|
100 | raise VCSError("This formatter expect FileNode parameter, not %r" | |
101 | % type(filenode)) |
|
101 | % type(filenode)) | |
102 |
|
102 | |||
103 | def annotate_from_changeset(self, changeset): |
|
|||
104 | """ |
|
|||
105 | Returns full html line for single changeset per annotated line. |
|
|||
106 | """ |
|
|||
107 | if self.annotate_from_changeset_func: |
|
|||
108 | return self.annotate_from_changeset_func(changeset) |
|
|||
109 | else: |
|
|||
110 | return ''.join((changeset.id, '\n')) |
|
|||
111 |
|
||||
112 | def _wrap_tablelinenos(self, inner): |
|
103 | def _wrap_tablelinenos(self, inner): | |
113 | inner_lines = [] |
|
104 | inner_lines = [] | |
114 | lncount = 0 |
|
105 | lncount = 0 | |
@@ -165,7 +156,7 b' class AnnotateHtmlFormatter(HtmlFormatte' | |||||
165 | # ln_ = len(ls.splitlines()) |
|
156 | # ln_ = len(ls.splitlines()) | |
166 | # if ln_cs > ln_: |
|
157 | # if ln_cs > ln_: | |
167 | # annotate_changesets = annotate_changesets[:ln_ - ln_cs] |
|
158 | # annotate_changesets = annotate_changesets[:ln_ - ln_cs] | |
168 | annotate = ''.join((self.annotate_from_changeset(el[2]()) |
|
159 | annotate = ''.join((self.annotate_from_changeset_func(el[2]()) | |
169 | for el in self.filenode.annotate)) |
|
160 | for el in self.filenode.annotate)) | |
170 | # in case you wonder about the seemingly redundant <div> here: |
|
161 | # in case you wonder about the seemingly redundant <div> here: | |
171 | # since the content in the other cell also is wrapped in a div, |
|
162 | # since the content in the other cell also is wrapped in a div, |
@@ -333,56 +333,56 b' def pygmentize(filenode, **kwargs):' | |||||
333 | code_highlight(safe_unicode(filenode.content), lexer, CodeHtmlFormatter(**kwargs)))) |
|
333 | code_highlight(safe_unicode(filenode.content), lexer, CodeHtmlFormatter(**kwargs)))) | |
334 |
|
334 | |||
335 |
|
335 | |||
|
336 | def hsv_to_rgb(h, s, v): | |||
|
337 | if s == 0.0: | |||
|
338 | return v, v, v | |||
|
339 | i = int(h * 6.0) # XXX assume int() truncates! | |||
|
340 | f = (h * 6.0) - i | |||
|
341 | p = v * (1.0 - s) | |||
|
342 | q = v * (1.0 - s * f) | |||
|
343 | t = v * (1.0 - s * (1.0 - f)) | |||
|
344 | i = i % 6 | |||
|
345 | if i == 0: | |||
|
346 | return v, t, p | |||
|
347 | if i == 1: | |||
|
348 | return q, v, p | |||
|
349 | if i == 2: | |||
|
350 | return p, v, t | |||
|
351 | if i == 3: | |||
|
352 | return p, q, v | |||
|
353 | if i == 4: | |||
|
354 | return t, p, v | |||
|
355 | if i == 5: | |||
|
356 | return v, p, q | |||
|
357 | ||||
|
358 | ||||
|
359 | def gen_color(n=10000): | |||
|
360 | """generator for getting n of evenly distributed colors using | |||
|
361 | hsv color and golden ratio. It always return same order of colors | |||
|
362 | ||||
|
363 | :returns: RGB tuple | |||
|
364 | """ | |||
|
365 | ||||
|
366 | golden_ratio = 0.618033988749895 | |||
|
367 | h = 0.22717784590367374 | |||
|
368 | ||||
|
369 | for _unused in xrange(n): | |||
|
370 | h += golden_ratio | |||
|
371 | h %= 1 | |||
|
372 | HSV_tuple = [h, 0.95, 0.95] | |||
|
373 | RGB_tuple = hsv_to_rgb(*HSV_tuple) | |||
|
374 | yield [str(int(x * 256)) for x in RGB_tuple] | |||
|
375 | ||||
|
376 | ||||
336 | def pygmentize_annotation(repo_name, filenode, **kwargs): |
|
377 | def pygmentize_annotation(repo_name, filenode, **kwargs): | |
337 | """ |
|
378 | """ | |
338 | pygmentize function for annotation |
|
379 | pygmentize function for annotation | |
339 |
|
380 | |||
340 | :param filenode: |
|
381 | :param filenode: | |
341 | """ |
|
382 | """ | |
342 |
|
383 | cgenerator = gen_color() | ||
343 | color_dict = {} |
|
384 | color_dict = {} | |
344 |
|
385 | |||
345 | def gen_color(n=10000): |
|
|||
346 | """generator for getting n of evenly distributed colors using |
|
|||
347 | hsv color and golden ratio. It always return same order of colors |
|
|||
348 |
|
||||
349 | :returns: RGB tuple |
|
|||
350 | """ |
|
|||
351 |
|
||||
352 | def hsv_to_rgb(h, s, v): |
|
|||
353 | if s == 0.0: |
|
|||
354 | return v, v, v |
|
|||
355 | i = int(h * 6.0) # XXX assume int() truncates! |
|
|||
356 | f = (h * 6.0) - i |
|
|||
357 | p = v * (1.0 - s) |
|
|||
358 | q = v * (1.0 - s * f) |
|
|||
359 | t = v * (1.0 - s * (1.0 - f)) |
|
|||
360 | i = i % 6 |
|
|||
361 | if i == 0: |
|
|||
362 | return v, t, p |
|
|||
363 | if i == 1: |
|
|||
364 | return q, v, p |
|
|||
365 | if i == 2: |
|
|||
366 | return p, v, t |
|
|||
367 | if i == 3: |
|
|||
368 | return p, q, v |
|
|||
369 | if i == 4: |
|
|||
370 | return t, p, v |
|
|||
371 | if i == 5: |
|
|||
372 | return v, p, q |
|
|||
373 |
|
||||
374 | golden_ratio = 0.618033988749895 |
|
|||
375 | h = 0.22717784590367374 |
|
|||
376 |
|
||||
377 | for _unused in xrange(n): |
|
|||
378 | h += golden_ratio |
|
|||
379 | h %= 1 |
|
|||
380 | HSV_tuple = [h, 0.95, 0.95] |
|
|||
381 | RGB_tuple = hsv_to_rgb(*HSV_tuple) |
|
|||
382 | yield [str(int(x * 256)) for x in RGB_tuple] |
|
|||
383 |
|
||||
384 | cgenerator = gen_color() |
|
|||
385 |
|
||||
386 | def get_color_string(cs): |
|
386 | def get_color_string(cs): | |
387 | if cs in color_dict: |
|
387 | if cs in color_dict: | |
388 | col = color_dict[cs] |
|
388 | col = color_dict[cs] | |
@@ -390,31 +390,28 b' def pygmentize_annotation(repo_name, fil' | |||||
390 | col = color_dict[cs] = cgenerator.next() |
|
390 | col = color_dict[cs] = cgenerator.next() | |
391 | return "color: rgb(%s)! important;" % (', '.join(col)) |
|
391 | return "color: rgb(%s)! important;" % (', '.join(col)) | |
392 |
|
392 | |||
393 |
def url_func( |
|
393 | def url_func(changeset): | |
394 |
|
394 | author = escape(changeset.author) | ||
395 |
de |
|
395 | date = changeset.date | |
396 |
|
|
396 | message = escape(changeset.message) | |
397 | date = changeset.date |
|
397 | tooltip_html = ("<b>Author:</b> %s<br/>" | |
398 | message = escape(changeset.message) |
|
398 | "<b>Date:</b> %s</b><br/>" | |
399 | tooltip_html = ("<b>Author:</b> %s<br/>" |
|
399 | "<b>Message:</b> %s") % (author, date, message) | |
400 | "<b>Date:</b> %s</b><br/>" |
|
|||
401 | "<b>Message:</b> %s") % (author, date, message) |
|
|||
402 |
|
400 | |||
403 |
|
|
401 | lnk_format = show_id(changeset) | |
404 |
|
|
402 | uri = link_to( | |
405 |
|
|
403 | lnk_format, | |
406 |
|
|
404 | url('changeset_home', repo_name=repo_name, | |
407 |
|
|
405 | revision=changeset.raw_id), | |
408 |
|
|
406 | style=get_color_string(changeset.raw_id), | |
409 |
|
|
407 | **{'data-toggle': 'popover', | |
410 |
|
|
408 | 'data-content': tooltip_html} | |
411 |
|
|
409 | ) | |
412 |
|
410 | |||
413 |
|
|
411 | uri += '\n' | |
414 |
|
|
412 | return uri | |
415 | return _url_func |
|
|||
416 |
|
413 | |||
417 |
return literal(markup_whitespace(annotate_highlight(filenode, url_func |
|
414 | return literal(markup_whitespace(annotate_highlight(filenode, url_func, **kwargs))) | |
418 |
|
415 | |||
419 |
|
416 | |||
420 | class _Message(object): |
|
417 | class _Message(object): |
General Comments 0
You need to be logged in to leave comments.
Login now