@@ -37,55 +37,76 @@ threadpool_max_requests = 10
##option to use threads of process
use_threadpool = true
use = egg:Paste#http
host = 0.0.0.0
port = 5000
[app:main]
use = egg:rhodecode
full_stack = true
static_files = true
lang=en
cache_dir = %(here)s/data
index_dir = %(here)s/data/index
app_instance_uuid = develop
cut_off_limit = 256000
force_https = false
commit_parse_limit = 25
use_gravatar = true
container_auth_enabled = false
proxypass_auth_enabled = false
## overwrite schema of clone url
# available vars:
# scheme - http/https
# user - current user
# pass - password
# netloc - network location
# path - usually repo_name
# clone_uri = {scheme}://{user}{pass}{netloc}{path}
## available vars:
## scheme - http/https
## user - current user
## pass - password
## netloc - network location
## path - usually repo_name
#clone_uri = {scheme}://{user}{pass}{netloc}{path}
## issue tracking mapping for commits messages
## uncomment url_pat, issue_server, issue_prefix to enable
## pattern to get the issues from commit messages
## default one used here is #1234
#url_pat = (?:^#|\s#)(\w+)
## server url to the issue, each {id} will be replaced with id
## fetched from the regex
#issue_server = https://myissueserver.com/issue/{id}
## prefix to add to link to indicate it's an url
## #314 will be replaced by <issue_prefix><id>
#issue_prefix = #
####################################
### CELERY CONFIG ####
use_celery = false
broker.host = localhost
broker.vhost = rabbitmqhost
broker.port = 5672
broker.user = rabbitmq
broker.password = qweqwe
celery.imports = rhodecode.lib.celerylib.tasks
celery.result.backend = amqp
celery.result.dburi = amqp://
celery.result.serialier = json
#celery.send.task.error.emails = true
#celery.amqp.task.result.expires = 18000
celeryd.concurrency = 2
#celeryd.log.file = celeryd.log
celeryd.log.level = debug
celeryd.max.tasks.per.child = 1
host = 127.0.0.1
port = 8001
app_instance_uuid = prod1234
commit_parse_limit = 50
@@ -37,56 +37,77 @@ threadpool_max_requests = 10
app_instance_uuid = ${app_instance_uuid}
"""Helper functions
Consists of functions to typically be used within templates, but also
available to Controllers. This module is available to both as 'h'.
"""
import random
import hashlib
import StringIO
import urllib
import math
import logging
from datetime import datetime
from pygments.formatters.html import HtmlFormatter
from pygments import highlight as code_highlight
from pylons import url, request, config
from pylons.i18n.translation import _, ungettext
from hashlib import md5
from webhelpers.html import literal, HTML, escape
from webhelpers.html.tools import *
from webhelpers.html.builder import make_tag
from webhelpers.html.tags import auto_discovery_link, checkbox, css_classes, \
end_form, file, form, hidden, image, javascript_link, link_to, \
link_to_if, link_to_unless, ol, required_legend, select, stylesheet_link, \
submit, text, password, textarea, title, ul, xml_declaration, radio
from webhelpers.html.tools import auto_link, button_to, highlight, \
js_obfuscate, mail_to, strip_links, strip_tags, tag_re
from webhelpers.number import format_byte_size, format_bit_size
from webhelpers.pylonslib import Flash as _Flash
from webhelpers.pylonslib.secure_form import secure_form
from webhelpers.text import chop_at, collapse, convert_accented_entities, \
convert_misc_entities, lchop, plural, rchop, remove_formatting, \
replace_whitespace, urlify, truncate, wrap_paragraphs
from webhelpers.date import time_ago_in_words
from webhelpers.paginate import Page
from webhelpers.html.tags import _set_input_attrs, _set_id_attr, \
convert_boolean_attrs, NotGiven, _make_safe_id_component
from rhodecode.lib.annotate import annotate_highlight
from rhodecode.lib.utils import repo_name_slug
from rhodecode.lib import str2bool, safe_unicode, safe_str, get_changeset_safe
from rhodecode.lib.markup_renderer import MarkupRenderer
log = logging.getLogger(__name__)
def _reset(name, value=None, id=NotGiven, type="reset", **attrs):
Reset button
_set_input_attrs(attrs, type, name, value)
_set_id_attr(attrs, id, name)
convert_boolean_attrs(attrs, ["disabled"])
return HTML.input(**attrs)
reset = _reset
safeid = _make_safe_id_component
def FID(raw_id, path):
Creates a uniqe ID for filenode based on it's hash of path and revision
it's safe to use in urls
:param raw_id:
:param path:
return 'C-%s-%s' % (short_id(raw_id), md5(path).hexdigest()[:12])
@@ -719,37 +722,64 @@ def fancy_file_stats(stats):
if l_type == 'd' and not a_v:
return ' '.join(map(map_getter, ['tr', 'br', 'tl', 'bl']))
d_a = '<div class="added %s" style="width:%s%%">%s</div>' % (cgen('a'),
a_p, a_v)
d_d = '<div class="deleted %s" style="width:%s%%">%s</div>' % (cgen('d'),
d_p, d_v)
return literal('<div style="width:%spx">%s%s</div>' % (width, d_a, d_d))
def urlify_text(text):
import re
url_pat = re.compile(r'''(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]'''
'''|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+)''')
def url_func(match_obj):
url_full = match_obj.groups()[0]
return '<a href="%(url)s">%(url)s</a>' % ({'url':url_full})
return literal(url_pat.sub(url_func, text))
def urlify_commit(text):
import traceback
try:
conf = config['app_conf']
URL_PAT = re.compile(r'%s' % conf.get('url_pat'))
if URL_PAT:
ISSUE_SERVER = conf.get('issue_server')
ISSUE_PREFIX = conf.get('issue_prefix')
issue_id = match_obj.groups()[0]
return ' <a href="%(url)s">%(issue-prefix)s%(id-repr)s</a>' % (
{'url':ISSUE_SERVER.replace('{id}',issue_id),
'id-repr':issue_id,
'issue-prefix':ISSUE_PREFIX,
'serv':ISSUE_SERVER,
}
)
return literal(URL_PAT.sub(url_func, text))
except:
log.error(traceback.format_exc())
pass
return text
def rst(source):
return literal('<div class="rst-block">%s</div>' %
MarkupRenderer.rst(source))
def rst_w_mentions(source):
Wrapped rst renderer with @mention highlighting
:param source:
MarkupRenderer.rst_with_mentions(source))
@@ -2125,50 +2125,48 @@ h3.files_location {
padding: 5px;
#changeset_content .container {
min-height: 120px;
font-size: 1.2em;
overflow: hidden;
#changeset_compare_view_content .compare_view_commits {
width: auto !important;
#changeset_compare_view_content .compare_view_commits td {
padding: 0px 0px 0px 12px !important;
#changeset_content .container .right {
float: right;
width: 25%;
text-align: right;
#changeset_content .container .left .message {
font-style: italic;
color: #556CB5;
white-space: pre-wrap;
#changeset_content .container .left .message a:hover {
text-decoration: none;
.cs_files .cur_cs {
margin: 10px 2px;
font-weight: bold;
.cs_files .node {
float: left;
.cs_files .changes {
color:#003367;
.cs_files .changes .added {
background-color: #BBFFBB;
text-align: center;
@@ -27,57 +27,57 @@ ${c.repo_name} ${_('Changelog')} - ${c.r
<div class="table">
% if c.pagination:
<div id="graph">
<div id="graph_nodes">
<canvas id="graph_canvas"></canvas>
</div>
<div id="graph_content">
<div class="container_header">
${h.form(h.url.current(),method='get')}
<div class="info_box" style="float:left">
${h.submit('set',_('Show'),class_="ui-btn")}
${h.text('size',size=1,value=c.size)}
<span class="rev">${_('revisions')}</span>
${h.end_form()}
<div style="float:right">${h.select('branch_filter',c.branch_name,c.branch_filters)}</div>
<div id="rev_range_container" style="display:none"></div>
%for cnt,cs in enumerate(c.pagination):
<div id="chg_${cnt+1}" class="container">
<div class="left">
<div class="date">
${h.checkbox(cs.short_id,class_="changeset_range")}
<span>${_('commit')} ${cs.revision}: ${h.short_id(cs.raw_id)}@${cs.date}</span>
<span class="tooltip" title="${cs.date}"><a href="${h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id)}">${cs.revision}:${h.short_id(cs.raw_id)}</a></span>
<div class="author">
<div class="gravatar">
<img alt="gravatar" src="${h.gravatar_url(h.email(cs.author),16)}"/>
<div title="${cs.author}" class="user">${h.person(cs.author)}</div>
<div class="message">${h.link_to(h.wrap_paragraphs(cs.message),h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id))}</div>
<div class="message">${h.urlify_commit(h.wrap_paragraphs(cs.message))}</div>
<div class="right">
<div id="${cs.raw_id}_changes_info" class="changes">
<span id="${cs.raw_id}" class="changed_total tooltip" title="${_('Affected number of files, click to show more details')}">${len(cs.affected_files)}</span>
%if len(cs.parents)>1:
<div class="merge">${_('merge')}</div>
%endif
%if cs.parents:
%for p_cs in reversed(cs.parents):
<div class="parent">${_('Parent')} ${p_cs.revision}: ${h.link_to(h.short_id(p_cs.raw_id),
h.url('changeset_home',repo_name=c.repo_name,revision=p_cs.raw_id),title=p_cs.message)}
%endfor
%else:
<div class="parent">${_('No parents')}</div>
<span class="logtags">
%if cs.branch:
<span class="branchtag" title="${'%s %s' % (_('branch'),cs.branch)}">
${h.link_to(cs.branch,h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id))}</span>
%for tag in cs.tags:
@@ -31,49 +31,49 @@
<div class="diff-menu-wrapper">
<img class="diff-menu-activate" style="cursor: pointer" alt="diff-menu" src="${h.url('/images/icons/script_gear.png')}" />
<div class="diff-menu" style="display:none">
<ul>
<li>${h.link_to(_('raw diff'),h.url('raw_changeset_home',repo_name=c.repo_name,revision=c.changeset.raw_id,diff='show'))}</li>
<li>${h.link_to(_('download diff'),h.url('raw_changeset_home',repo_name=c.repo_name,revision=c.changeset.raw_id,diff='download'))}</li>
<li>${c.ignorews_url()}</li>
<li>${c.context_url()}</li>
</ul>
<div class="comments-number" style="float:right;padding-right:5px">${len(c.comments)} comment(s) (${c.inline_cnt} ${_('inline')})</div>
<div id="changeset_content">
<div class="container">
<img alt="gravatar" src="${h.gravatar_url(h.email(c.changeset.author),20)}"/>
<span>${h.person(c.changeset.author)}</span><br/>
<span><a href="mailto:${h.email_or_none(c.changeset.author)}">${h.email_or_none(c.changeset.author)}</a></span><br/>
<div class="message">${h.link_to(h.wrap_paragraphs(c.changeset.message),h.url('changeset_home',repo_name=c.repo_name,revision=c.changeset.raw_id))}</div>
<div class="message">${h.urlify_commit(h.wrap_paragraphs(c.changeset.message))}</div>
<div class="changes">
% if len(c.changeset.affected_files) <= c.affected_files_cut_off:
<span class="removed" title="${_('removed')}">${len(c.changeset.removed)}</span>
<span class="changed" title="${_('changed')}">${len(c.changeset.changed)}</span>
<span class="added" title="${_('added')}">${len(c.changeset.added)}</span>
% else:
<span class="removed" title="${_('affected %s files') % len(c.changeset.affected_files)}">!</span>
<span class="changed" title="${_('affected %s files') % len(c.changeset.affected_files)}">!</span>
<span class="added" title="${_('affected %s files') % len(c.changeset.affected_files)}">!</span>
% endif
%if len(c.changeset.parents)>1:
<div class="merge">
${_('merge')}<img alt="merge" src="${h.url('/images/icons/arrow_join.png')}"/>
%if c.changeset.parents:
%for p_cs in reversed(c.changeset.parents):
@@ -20,49 +20,49 @@
<%def name="main()">
<div class="box">
<!-- box / title -->
<div class="title">
${self.breadcrumbs()}
<div id="body" class="diffblock">
<div class="code-header cv">
<h3 class="code-header-title">${_('Compare View')}</h3>
<div>
${_('Changesets')} - r${c.cs_ranges[0].revision}:${h.short_id(c.cs_ranges[0].raw_id)} -> r${c.cs_ranges[-1].revision}:${h.short_id(c.cs_ranges[-1].raw_id)}
<div id="changeset_compare_view_content">
<table class="compare_view_commits noborder">
%for cs in c.cs_ranges:
<tr>
<td><div class="gravatar"><img alt="gravatar" src="${h.gravatar_url(h.email(cs.author),14)}"/></div></td>
<td>${h.link_to('r%s:%s' % (cs.revision,h.short_id(cs.raw_id)),h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id))}</td>
<td><div class="author">${h.person(cs.author)}</div></td>
<td><span class="tooltip" title="${h.age(cs.date)}">${cs.date}</span></td>
<td><div class="message">${h.link_to(h.wrap_paragraphs(cs.message),h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id))}</div></td>
<td><div class="message">${h.urlify_commit(h.wrap_paragraphs(c.changeset.message))}</div></td>
</tr>
</table>
<div style="font-size:1.1em;font-weight: bold;clear:both;padding-top:10px">${_('Files affected')}</div>
<div class="cs_files">
<div class="cur_cs">r${cs}</div>
%for change,filenode,diff,cs1,cs2,st in c.changes[cs.raw_id]:
<div class="cs_${change}">${h.link_to(h.safe_unicode(filenode.path),h.url.current(anchor=h.FID(cs.raw_id,filenode.path)))}</div>
<%namespace name="comment" file="/changeset/changeset_file_comment.html"/>
<%namespace name="diff_block" file="/changeset/diff_block.html"/>
##${comment.comment_inline_form(cs)}
## diff block
<h3 style="border:none;padding-top:8px;">${'r%s:%s' % (cs.revision,h.short_id(cs.raw_id))}</h3>
${diff_block.diff_block(c.changes[cs.raw_id])}
##${comment.comments(cs)}
## -*- coding: utf-8 -*-
%if c.repo_changesets:
<table class="table_disp">
<th class="left">${_('commit message')}</th>
<th class="left">${_('revision')}</th>
<th class="left">${_('age')}</th>
<th class="left">${_('author')}</th>
<th class="left">${_('branch')}</th>
<th class="left">${_('tags')}</th>
%for cnt,cs in enumerate(c.repo_changesets):
<tr class="parity${cnt%2}">
<td>
<div><pre><a href="${h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id)}">r${cs.revision}:${h.short_id(cs.raw_id)}</a></pre></div>
</td>
${h.link_to(h.truncate(cs.message,50),
h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id),
title=cs.message)}
<td><span class="tooltip" title="${cs.date}">
${h.age(cs.date)}</span>
<td title="${cs.author}">${h.person(cs.author)}</td>
<td><div><pre><a href="${h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id)}">r${cs.revision}:${h.short_id(cs.raw_id)}</a></pre></div></td>
<span class="branchtag">${cs.branch}</span>
</span>
<span class="tagtag">${tag}</span>
<script type="text/javascript">
YUE.onDOMReady(function(){
YUE.delegate("shortlog_data","click",function(e, matchedEl, container){
ypjax(e.target.href,"shortlog_data",function(){tooltip_activate();});
YUE.preventDefault(e);
},'.pager_link');
});
Status change: