Changeset - 5da1286ddd28
[Not reviewed]
beta
0 3 0
Marcin Kuzminski - 15 years ago 2011-01-27 23:01:16
marcin@python-works.com
#107 added single line highlight
3 files changed with 6 insertions and 2 deletions:
0 comments (0 inline, 0 general)
rhodecode/lib/helpers.py
Show inline comments
 
@@ -35,385 +35,385 @@ def _reset(name, value=None, id=NotGiven
 
    """
 
    _set_input_attrs(attrs, type, name, value)
 
    _set_id_attr(attrs, id, name)
 
    convert_boolean_attrs(attrs, ["disabled"])
 
    return HTML.input(**attrs)
 

	
 
reset = _reset
 

	
 

	
 
def get_token():
 
    """Return the current authentication token, creating one if one doesn't
 
    already exist.
 
    """
 
    token_key = "_authentication_token"
 
    from pylons import session
 
    if not token_key in session:
 
        try:
 
            token = hashlib.sha1(str(random.getrandbits(128))).hexdigest()
 
        except AttributeError: # Python < 2.4
 
            token = hashlib.sha1(str(random.randrange(2 ** 128))).hexdigest()
 
        session[token_key] = token
 
        if hasattr(session, 'save'):
 
            session.save()
 
    return session[token_key]
 

	
 
class _GetError(object):
 
    """Get error from form_errors, and represent it as span wrapped error
 
    message
 
    
 
    :param field_name: field to fetch errors for
 
    :param form_errors: form errors dict
 
    """
 

	
 
    def __call__(self, field_name, form_errors):
 
        tmpl = """<span class="error_msg">%s</span>"""
 
        if form_errors and form_errors.has_key(field_name):
 
            return literal(tmpl % form_errors.get(field_name))
 

	
 
get_error = _GetError()
 

	
 
def recursive_replace(str, replace=' '):
 
    """Recursive replace of given sign to just one instance
 
    
 
    :param str: given string
 
    :param replace: char to find and replace multiple instances
 
        
 
    Examples::
 
    >>> recursive_replace("Mighty---Mighty-Bo--sstones",'-')
 
    'Mighty-Mighty-Bo-sstones'
 
    """
 

	
 
    if str.find(replace * 2) == -1:
 
        return str
 
    else:
 
        str = str.replace(replace * 2, replace)
 
        return recursive_replace(str, replace)
 

	
 
class _ToolTip(object):
 

	
 
    def __call__(self, tooltip_title, trim_at=50):
 
        """Special function just to wrap our text into nice formatted 
 
        autowrapped text
 
        
 
        :param tooltip_title:
 
        """
 

	
 
        return wrap_paragraphs(escape(tooltip_title), trim_at)\
 
                       .replace('\n', '<br/>')
 

	
 
    def activate(self):
 
        """Adds tooltip mechanism to the given Html all tooltips have to have 
 
        set class `tooltip` and set attribute `tooltip_title`.
 
        Then a tooltip will be generated based on that. All with yui js tooltip
 
        """
 

	
 
        js = '''
 
        YAHOO.util.Event.onDOMReady(function(){
 
            function toolTipsId(){
 
                var ids = [];
 
                var tts = YAHOO.util.Dom.getElementsByClassName('tooltip');
 
                
 
                for (var i = 0; i < tts.length; i++) {
 
                    //if element doesn't not have and id autogenerate one for tooltip
 
                    
 
                    if (!tts[i].id){
 
                        tts[i].id='tt'+i*100;
 
                    }
 
                    ids.push(tts[i].id);
 
                }
 
                return ids        
 
            };
 
            var myToolTips = new YAHOO.widget.Tooltip("tooltip", { 
 
                context: toolTipsId(),
 
                monitorresize:false,
 
                xyoffset :[0,0],
 
                autodismissdelay:300000,
 
                hidedelay:5,
 
                showdelay:20,
 
            });
 
            
 
            // Set the text for the tooltip just before we display it. Lazy method
 
            myToolTips.contextTriggerEvent.subscribe( 
 
                 function(type, args) { 
 

	
 
                        var context = args[0]; 
 
                        
 
                        //positioning of tooltip
 
                        var tt_w = this.element.clientWidth;//tooltip width
 
                        var tt_h = this.element.clientHeight;//tooltip height
 
                        
 
                        var context_w = context.offsetWidth;
 
                        var context_h = context.offsetHeight;
 
                        
 
                        var pos_x = YAHOO.util.Dom.getX(context);
 
                        var pos_y = YAHOO.util.Dom.getY(context);
 

	
 
                        var display_strategy = 'right';
 
                        var xy_pos = [0,0];
 
                        switch (display_strategy){
 
                        
 
                            case 'top':
 
                                var cur_x = (pos_x+context_w/2)-(tt_w/2);
 
                                var cur_y = (pos_y-tt_h-4);
 
                                xy_pos = [cur_x,cur_y];                                
 
                                break;
 
                            case 'bottom':
 
                                var cur_x = (pos_x+context_w/2)-(tt_w/2);
 
                                var cur_y = pos_y+context_h+4;
 
                                xy_pos = [cur_x,cur_y];                                
 
                                break;
 
                            case 'left':
 
                                var cur_x = (pos_x-tt_w-4);
 
                                var cur_y = pos_y-((tt_h/2)-context_h/2);
 
                                xy_pos = [cur_x,cur_y];                                
 
                                break;
 
                            case 'right':
 
                                var cur_x = (pos_x+context_w+4);
 
                                var cur_y = pos_y-((tt_h/2)-context_h/2);
 
                                xy_pos = [cur_x,cur_y];                                
 
                                break;
 
                             default:
 
                                var cur_x = (pos_x+context_w/2)-(tt_w/2);
 
                                var cur_y = pos_y-tt_h-4;
 
                                xy_pos = [cur_x,cur_y];                                
 
                                break;                             
 
                                 
 
                        }
 

	
 
                        this.cfg.setProperty("xy",xy_pos);
 

	
 
                  });
 
                  
 
            //Mouse out 
 
            myToolTips.contextMouseOutEvent.subscribe(
 
                function(type, args) {
 
                    var context = args[0];
 
                    
 
                });
 
        });
 
        '''
 
        return literal(js)
 

	
 
tooltip = _ToolTip()
 

	
 
class _FilesBreadCrumbs(object):
 

	
 
    def __call__(self, repo_name, rev, paths):
 
        if isinstance(paths, str):
 
            paths = paths.decode('utf-8')
 
        url_l = [link_to(repo_name, url('files_home',
 
                                        repo_name=repo_name,
 
                                        revision=rev, f_path=''))]
 
        paths_l = paths.split('/')
 
        for cnt, p in enumerate(paths_l):
 
            if p != '':
 
                url_l.append(link_to(p, url('files_home',
 
                                            repo_name=repo_name,
 
                                            revision=rev,
 
                                            f_path='/'.join(paths_l[:cnt + 1]))))
 

	
 
        return literal('/'.join(url_l))
 

	
 
files_breadcrumbs = _FilesBreadCrumbs()
 

	
 
class CodeHtmlFormatter(HtmlFormatter):
 

	
 
    def wrap(self, source, outfile):
 
        return self._wrap_div(self._wrap_pre(self._wrap_code(source)))
 

	
 
    def _wrap_code(self, source):
 
        for cnt, it in enumerate(source):
 
            i, t = it
 
            t = '<div id="#S-%s">%s</div>' % (cnt + 1, t)
 
            t = '<div id="L-%s">%s</div>' % (cnt + 1, t)
 
            yield i, t
 
def pygmentize(filenode, **kwargs):
 
    """pygmentize function using pygments
 
    
 
    :param filenode:
 
    """
 

	
 
    return literal(code_highlight(filenode.content,
 
                                  filenode.lexer, CodeHtmlFormatter(**kwargs)))
 

	
 
def pygmentize_annotation(filenode, **kwargs):
 
    """pygmentize function for annotation
 
    
 
    :param filenode:
 
    """
 

	
 
    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
 
        """
 
        import colorsys
 
        golden_ratio = 0.618033988749895
 
        h = 0.22717784590367374
 

	
 
        for c in xrange(n):
 
            h += golden_ratio
 
            h %= 1
 
            HSV_tuple = [h, 0.95, 0.95]
 
            RGB_tuple = colorsys.hsv_to_rgb(*HSV_tuple)
 
            yield map(lambda x:str(int(x * 256)), RGB_tuple)
 

	
 
    cgenerator = gen_color()
 

	
 
    def get_color_string(cs):
 
        if color_dict.has_key(cs):
 
            col = color_dict[cs]
 
        else:
 
            col = color_dict[cs] = cgenerator.next()
 
        return "color: rgb(%s)! important;" % (', '.join(col))
 

	
 
    def url_func(changeset):
 
        tooltip_html = "<div style='font-size:0.8em'><b>Author:</b>" + \
 
        " %s<br/><b>Date:</b> %s</b><br/><b>Message:</b> %s<br/></div>"
 

	
 
        tooltip_html = tooltip_html % (changeset.author,
 
                                               changeset.date,
 
                                               tooltip(changeset.message))
 
        lnk_format = '%5s:%s' % ('r%s' % changeset.revision,
 
                                 short_id(changeset.raw_id))
 
        uri = link_to(
 
                lnk_format,
 
                url('changeset_home', repo_name=changeset.repository.name,
 
                    revision=changeset.raw_id),
 
                style=get_color_string(changeset.raw_id),
 
                class_='tooltip',
 
                title=tooltip_html
 
              )
 

	
 
        uri += '\n'
 
        return uri
 
    return literal(annotate_highlight(filenode, url_func, **kwargs))
 

	
 
def repo_name_slug(value):
 
    """Return slug of name of repository
 
    This function is called on each creation/modification
 
    of repository to prevent bad names in repo
 
    """
 

	
 
    slug = remove_formatting(value)
 
    slug = strip_tags(slug)
 

	
 
    for c in """=[]\;'"<>,/~!@#$%^&*()+{}|: """:
 
        slug = slug.replace(c, '-')
 
    slug = recursive_replace(slug, '-')
 
    slug = collapse(slug, '-')
 
    return slug
 

	
 
def get_changeset_safe(repo, rev):
 
    from vcs.backends.base import BaseRepository
 
    from vcs.exceptions import RepositoryError
 
    if not isinstance(repo, BaseRepository):
 
        raise Exception('You must pass an Repository '
 
                        'object as first argument got %s', type(repo))
 

	
 
    try:
 
        cs = repo.get_changeset(rev)
 
    except RepositoryError:
 
        from rhodecode.lib.utils import EmptyChangeset
 
        cs = EmptyChangeset()
 
    return cs
 

	
 

	
 
flash = _Flash()
 

	
 

	
 
#==============================================================================
 
# MERCURIAL FILTERS available via h.
 
#==============================================================================
 
from mercurial import util
 
from mercurial.templatefilters import person as _person
 

	
 
def _age(curdate):
 
    """turns a datetime into an age string."""
 

	
 
    if not curdate:
 
        return ''
 

	
 
    from datetime import timedelta, datetime
 

	
 
    agescales = [("year", 3600 * 24 * 365),
 
                 ("month", 3600 * 24 * 30),
 
                 ("day", 3600 * 24),
 
                 ("hour", 3600),
 
                 ("minute", 60),
 
                 ("second", 1), ]
 

	
 
    age = datetime.now() - curdate
 
    age_seconds = (age.days * agescales[2][1]) + age.seconds
 
    pos = 1
 
    for scale in agescales:
 
        if scale[1] <= age_seconds:
 
            if pos == 6:pos = 5
 
            return time_ago_in_words(curdate, agescales[pos][0]) + ' ' + _('ago')
 
        pos += 1
 

	
 
    return _('just now')
 

	
 
age = lambda  x:_age(x)
 
capitalize = lambda x: x.capitalize()
 
email = util.email
 
email_or_none = lambda x: util.email(x) if util.email(x) != x else None
 
person = lambda x: _person(x)
 
short_id = lambda x: x[:12]
 

	
 

	
 
def bool2icon(value):
 
    """Returns True/False values represented as small html image of true/false
 
    icons
 
    
 
    :param value: bool value
 
    """
 

	
 
    if value is True:
 
        return HTML.tag('img', src="/images/icons/accept.png", alt=_('True'))
 

	
 
    if value is False:
 
        return HTML.tag('img', src="/images/icons/cancel.png", alt=_('False'))
 

	
 
    return value
 

	
 

	
 
def action_parser(user_log):
 
    """This helper will map the specified string action into translated
 
    fancy names with icons and links
 
    
 
    :param user_log: user log instance
 
    """
 

	
 
    action = user_log.action
 
    action_params = ' '
 

	
 
    x = action.split(':')
 

	
 
    if len(x) > 1:
 
        action, action_params = x
 

	
 
    def get_cs_links():
 
        revs_limit = 5 #display this amount always
 
        revs_top_limit = 50 #show upto this amount of changesets hidden
 
        revs = action_params.split(',')
 
        repo_name = user_log.repository.repo_name
 
        from rhodecode.model.scm import ScmModel
 

	
 
        message = lambda rev: get_changeset_safe(ScmModel().get(repo_name),
 
                                                 rev).message
 

	
 
        cs_links = " " + ', '.join ([link_to(rev,
 
                url('changeset_home',
 
                repo_name=repo_name,
 
                revision=rev), title=tooltip(message(rev)),
 
                class_='tooltip') for rev in revs[:revs_limit] ])
 
        if len(revs) > revs_limit:
 
            uniq_id = revs[0]
 
            html_tmpl = ('<span> %s '
 
            '<a class="show_more" id="_%s" href="#">%s</a> '
 
            '%s</span>')
 
            cs_links += html_tmpl % (_('and'), uniq_id, _('%s more') \
 
                                        % (len(revs) - revs_limit),
 
                                        _('revisions'))
rhodecode/public/css/pygments.css
Show inline comments
 
div.codeblock {
 
    overflow: auto;
 
    padding: 0px;
 
    border: 1px solid #ccc;
 
    background: #f8f8f8;
 
    font-size: 100%;
 
    line-height: 100%;
 
    /* new */
 
    line-height: 125%;
 
}
 
div.codeblock .code-header{
 
	border-bottom: 1px solid #CCCCCC;
 
	background: #EEEEEE;
 
	padding:10px 0 10px 0;
 
}
 
div.codeblock .code-header .revision{
 
	margin-left:25px;
 
	font-weight: bold;
 
}
 
div.codeblock .code-header .commit{
 
	margin-left:25px;
 
	font-weight: normal;
 
	white-space:pre;
 
}
 

	
 
div.codeblock .code-body table{
 
    width: 0 !important;    
 
}
 
div.code-body {
 
	background-color: #FFFFFF;
 
}
 
div.code-body pre .match{
 
	background-color: #FAFFA6;
 
}
 
div.code-body pre .break{
 
	background-color: #DDE7EF;
 
	width: 100%;
 
	color: #747474;
 
	display: block;
 
	
 
}
 
div.annotatediv{
 
	margin-left:2px;
 
	margin-right:4px;
 
}
 
.code-highlight {
 
    padding: 0px;
 
    margin-top: 5px;
 
    margin-bottom: 5px;
 
    border-left: 2px solid #ccc;
 
}
 
.code-highlight pre, .linenodiv pre { 
 
	padding: 5px;
 
    margin: 0;
 
}
 
.code-highlight pre div:target { 
 
    background-color: #FFFFBE !important;
 
}
 
    
 
.linenos a { text-decoration: none; }
 

	
 
.code { display: block; }
 
.code-highlight .hll { background-color: #ffffcc }
 
.code-highlight .c { color: #408080; font-style: italic } /* Comment */
 
.code-highlight .err { border: 1px solid #FF0000 } /* Error */
 
.code-highlight .k { color: #008000; font-weight: bold } /* Keyword */
 
.code-highlight .o { color: #666666 } /* Operator */
 
.code-highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */
 
.code-highlight .cp { color: #BC7A00 } /* Comment.Preproc */
 
.code-highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */
 
.code-highlight .cs { color: #408080; font-style: italic } /* Comment.Special */
 
.code-highlight .gd { color: #A00000 } /* Generic.Deleted */
 
.code-highlight .ge { font-style: italic } /* Generic.Emph */
 
.code-highlight .gr { color: #FF0000 } /* Generic.Error */
 
.code-highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
 
.code-highlight .gi { color: #00A000 } /* Generic.Inserted */
 
.code-highlight .go { color: #808080 } /* Generic.Output */
 
.code-highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
 
.code-highlight .gs { font-weight: bold } /* Generic.Strong */
 
.code-highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
 
.code-highlight .gt { color: #0040D0 } /* Generic.Traceback */
 
.code-highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
 
.code-highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
 
.code-highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
 
.code-highlight .kp { color: #008000 } /* Keyword.Pseudo */
 
.code-highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
 
.code-highlight .kt { color: #B00040 } /* Keyword.Type */
 
.code-highlight .m { color: #666666 } /* Literal.Number */
 
.code-highlight .s { color: #BA2121 } /* Literal.String */
 
.code-highlight .na { color: #7D9029 } /* Name.Attribute */
 
.code-highlight .nb { color: #008000 } /* Name.Builtin */
 
.code-highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */
 
.code-highlight .no { color: #880000 } /* Name.Constant */
 
.code-highlight .nd { color: #AA22FF } /* Name.Decorator */
 
.code-highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */
 
.code-highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
 
.code-highlight .nf { color: #0000FF } /* Name.Function */
 
.code-highlight .nl { color: #A0A000 } /* Name.Label */
 
.code-highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
 
.code-highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
 
.code-highlight .nv { color: #19177C } /* Name.Variable */
 
.code-highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
 
.code-highlight .w { color: #bbbbbb } /* Text.Whitespace */
 
.code-highlight .mf { color: #666666 } /* Literal.Number.Float */
 
.code-highlight .mh { color: #666666 } /* Literal.Number.Hex */
 
.code-highlight .mi { color: #666666 } /* Literal.Number.Integer */
 
.code-highlight .mo { color: #666666 } /* Literal.Number.Oct */
 
.code-highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
 
.code-highlight .sc { color: #BA2121 } /* Literal.String.Char */
 
.code-highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
 
.code-highlight .s2 { color: #BA2121 } /* Literal.String.Double */
 
.code-highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
 
.code-highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
 
.code-highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
 
.code-highlight .sx { color: #008000 } /* Literal.String.Other */
 
.code-highlight .sr { color: #BB6688 } /* Literal.String.Regex */
 
.code-highlight .s1 { color: #BA2121 } /* Literal.String.Single */
 
.code-highlight .ss { color: #19177C } /* Literal.String.Symbol */
 
.code-highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
 
.code-highlight .vc { color: #19177C } /* Name.Variable.Class */
 
.code-highlight .vg { color: #19177C } /* Name.Variable.Global */
 
.code-highlight .vi { color: #19177C } /* Name.Variable.Instance */
 
.code-highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
rhodecode/templates/files/files_source.html
Show inline comments
 
<dl>
 
	<dt>${_('Revision')}</dt>
 
	<dd>
 
		${h.link_to("r%s:%s" % (c.files_list.last_changeset.revision,h.short_id(c.files_list.last_changeset.raw_id)),
 
						h.url('changeset_home',repo_name=c.repo_name,revision=c.files_list.last_changeset.raw_id))} 
 
	</dd>
 
	<dt>${_('Size')}</dt>
 
	<dd>${h.format_byte_size(c.files_list.size,binary=True)}</dd>
 
	<dt>${_('Mimetype')}</dt>
 
	<dd>${c.files_list.mimetype}</dd>
 
	<dt>${_('Options')}</dt>
 
	<dd>${h.link_to(_('show annotation'),
 
			h.url('files_annotate_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=c.f_path))}
 
		 / ${h.link_to(_('show as raw'),
 
			h.url('files_raw_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=c.f_path))}			
 
		 / ${h.link_to(_('download as raw'),
 
			h.url('files_rawfile_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=c.f_path))}
 
	</dd>
 
	<dt>${_('History')}</dt>
 
	<dd>
 
		<div>
 
		${h.form(h.url('files_diff_home',repo_name=c.repo_name,f_path=c.f_path),method='get')}
 
		${h.hidden('diff2',c.files_list.last_changeset.raw_id)}
 
		${h.select('diff1',c.files_list.last_changeset.raw_id,c.file_history)}
 
		${h.submit('diff','diff to revision',class_="ui-button")}
 
		${h.submit('show_rev','show at revision',class_="ui-button")}
 
		${h.end_form()}
 
		</div>
 
	</dd>
 
</dl>	
 

	
 
	
 
<div id="body" class="codeblock">
 
	<div class="code-header">
 
		<div class="revision">${c.files_list.name}@r${c.files_list.last_changeset.revision}:${h.short_id(c.files_list.last_changeset.raw_id)}</div>
 
		<div class="commit">"${c.files_list.last_changeset.message}"</div>
 
	</div>
 
	<div class="code-body">
 
		% if c.files_list.size < c.cut_off_limit:
 
			${h.pygmentize(c.files_list,linenos=True,anchorlinenos=True,lineanchors='S',cssclass="code-highlight")}
 
			${h.pygmentize(c.files_list,linenos=True,anchorlinenos=True,lineanchors='L',cssclass="code-highlight")}
 
		%else:
 
			${_('File is to big to display')} ${h.link_to(_('show as raw'),
 
			h.url('files_raw_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=c.f_path))}
 
		%endif
 
	</div>
 
</div>
 

	
 
<script type="text/javascript">
 
YAHOO.util.Event.onDOMReady(function(){
 
    YAHOO.util.Event.addListener('show_rev','click',function(e){
 
    	YAHOO.util.Event.preventDefault(e);
 
        var cs = YAHOO.util.Dom.get('diff1').value;
 
        var url = "${h.url('files_home',repo_name=c.repo_name,revision='__CS__',f_path=c.f_path)}".replace('__CS__',cs);
 
        window.location = url;
 
        });
 
   });
 
</script>
 
\ No newline at end of file
0 comments (0 inline, 0 general)