##// END OF EJS Templates
diff parser: prefer git headers over old unified diff headers...
diff parser: prefer git headers over old unified diff headers Makes the diff show both rename and chmod info and the diff.

File last commit:

r3776:13241a40 beta
r3820:8df1bc51 beta
Show More
helpers.py
1343 lines | 46.2 KiB | text/x-python | PythonLexer
renamed project to rhodecode
r547 """Helper functions
Consists of functions to typically be used within templates, but also
available to Controllers. This module is available to both as 'h'.
"""
implemented user dashboards, and following system.
r734 import random
import hashlib
fixed line number look
r966 import StringIO
fixed problem with int. chars in gravatars
r1101 import urllib
fixed issues with repo pager
r1422 import math
#73 mapping of commited issues from commit message into issue tracker url.
r1837 import logging
merged + fixed pull request #62: Implemented metatags and visualisation options....
r2674 import re
Implemented patch from andrewsh ref #565 Add support for {netloc} and {scheme}...
r2836 import urlparse
final implementation of #210 journal filtering.
r3070 import textwrap
fixed problem with int. chars in gravatars
r1101
simplified str2bool, and moved safe_unicode out of helpers since it was not html specific function
r1154 from datetime import datetime
notification to commit author + gardening
r1716 from pygments.formatters.html import HtmlFormatter
renamed project to rhodecode
r547 from pygments import highlight as code_highlight
#21 added optional flag to disable gravatar, and use local icon
r1110 from pylons import url, request, config
renamed project to rhodecode
r547 from pylons.i18n.translation import _, ungettext
fixed problem with anchor links that contains non ascii chars...
r1832 from hashlib import md5
Code refactor number 2
r1022
renamed project to rhodecode
r547 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, \
garden
r1766 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
renamed project to rhodecode
r547 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
Fixed age, for new vcs implementation. Removed all obsolete date formatters...
r635 from webhelpers.date import time_ago_in_words
Unified the paginators for pylons and YUI....
r3776 from webhelpers.paginate import Page as _Page
fixes #65, Added reset buttons to edit forms
r698 from webhelpers.html.tags import _set_input_attrs, _set_id_attr, \
fixed some anchor id problems for changeset ranges
r1676 convert_boolean_attrs, NotGiven, _make_safe_id_component
fixes #65, Added reset buttons to edit forms
r698
moved soon-to-be-deleted code from vcs to rhodecode...
r1753 from rhodecode.lib.annotate import annotate_highlight
Add option to define custom lexers for custom extensions for code highlight in rcextension module
r3375 from rhodecode.lib.utils import repo_name_slug, get_custom_lexer
utils/conf...
r2109 from rhodecode.lib.utils2 import str2bool, safe_unicode, safe_str, \
Implemented show_id function that is a configurable way to display sha hashes in the changelog.
r3557 get_changeset_safe, datetime_to_time, time_to_datetime, AttributeDict,\
safe_int
#77 code review...
r1670 from rhodecode.lib.markup_renderer import MarkupRenderer
fix for issue #450. Rhodecode no longer will crash when bad revision is present in journal data.
r2323 from rhodecode.lib.vcs.exceptions import ChangesetDoesNotExistError
extend helper for better breadcrumbs for repo groups
r3012 from rhodecode.lib.vcs.backends.base import BaseChangeset, EmptyChangeset
Format datetime in notifications according to unified function
r2445 from rhodecode.config.conf import DATE_FORMAT, DATETIME_FORMAT
Implemented initial code-review status of changesets
r2217 from rhodecode.model.changeset_status import ChangesetStatusModel
Better descriptions of given permission overview in edit user view
r2532 from rhodecode.model.db import URL_SEP, Permission
#77 code review...
r1670
#73 mapping of commited issues from commit message into issue tracker url.
r1837 log = logging.getLogger(__name__)
implements #308 rewrote diffs to enable displaying full diff on each file...
r1789
Added rewritten validators module + tests
r2466 html_escape_table = {
"&": "&",
'"': """,
"'": "'",
">": ">",
"<": "&lt;",
}
def html_escape(text):
"""Produce entities within text."""
Use lightweight revisions in journal by default
r2958 return "".join(html_escape_table.get(c, c) for c in text)
Added rewritten validators module + tests
r2466
imported patch 2260
r2162 def shorter(text, size=20):
postfix = '...'
if len(text) > size:
return text[:size - len(postfix)] + postfix
return text
fixes #65, Added reset buttons to edit forms
r698 def _reset(name, value=None, id=NotGiven, type="reset", **attrs):
simplified str2bool, and moved safe_unicode out of helpers since it was not html specific function
r1154 """
Reset button
Added message tooltip into journal revisions in push....
r899 """
fixes #65, Added reset buttons to edit forms
r698 _set_input_attrs(attrs, type, name, value)
_set_id_attr(attrs, id, name)
convert_boolean_attrs(attrs, ["disabled"])
return HTML.input(**attrs)
reset = _reset
fixed some anchor id problems for changeset ranges
r1676 safeid = _make_safe_id_component
implemented user dashboards, and following system.
r734
implements #308 rewrote diffs to enable displaying full diff on each file...
r1789
def FID(raw_id, path):
implements #307, configurable diffs...
r1776 """
fixed problem with anchor links that contains non ascii chars...
r1832 Creates a uniqe ID for filenode based on it's hash of path and revision
it's safe to use in urls
implements #308 rewrote diffs to enable displaying full diff on each file...
r1789
implements #307, configurable diffs...
r1776 :param raw_id:
:param path:
"""
fixed problem with anchor links that contains non ascii chars...
r1832
fixed comments issue on non-ascii file names
r2148 return 'C-%s-%s' % (short_id(raw_id), md5(safe_str(path)).hexdigest()[:12])
implements #307, configurable diffs...
r1776
implemented user dashboards, and following system.
r734 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()
added emulation of pull hook for git-backend, and dummy git-push hook
r2203 except AttributeError: # Python < 2.4
implemented user dashboards, and following system.
r734 token = hashlib.sha1(str(random.randrange(2 ** 128))).hexdigest()
session[token_key] = token
if hasattr(session, 'save'):
session.save()
return session[token_key]
imported patch 2260
r2162
renamed project to rhodecode
r547 class _GetError(object):
Added message tooltip into journal revisions in push....
r899 """Get error from form_errors, and represent it as span wrapped error
message
source code cleanup: remove trailing white space, normalize file endings
r1203
Added message tooltip into journal revisions in push....
r899 :param field_name: field to fetch errors for
:param form_errors: form errors dict
"""
renamed project to rhodecode
r547
def __call__(self, field_name, form_errors):
tmpl = """<span class="error_msg">%s</span>"""
Added h.tooltip to all places that tooltip_title is used....
r2427 if form_errors and field_name in form_errors:
renamed project to rhodecode
r547 return literal(tmpl % form_errors.get(field_name))
get_error = _GetError()
imported patch 2260
r2162
renamed project to rhodecode
r547 class _ToolTip(object):
Hacking for git support,and new faster repo scan
r631
renamed project to rhodecode
r547 def __call__(self, tooltip_title, trim_at=50):
Added h.tooltip to all places that tooltip_title is used....
r2427 """
Special function just to wrap our text into nice formatted
added wrapping of long tooltips in index page
r905 autowrapped text
source code cleanup: remove trailing white space, normalize file endings
r1203
fixed @repo into :repo for docs...
r604 :param tooltip_title:
renamed project to rhodecode
r547 """
Added h.tooltip to all places that tooltip_title is used....
r2427 tooltip_title = escape(tooltip_title)
tooltip_title = tooltip_title.replace('<', '&lt;').replace('>', '&gt;')
return tooltip_title
renamed project to rhodecode
r547 tooltip = _ToolTip()
imported patch 2260
r2162
renamed project to rhodecode
r547 class _FilesBreadCrumbs(object):
Hacking for git support,and new faster repo scan
r631
renamed project to rhodecode
r547 def __call__(self, repo_name, rev, paths):
fixes for #99, added casting to unicode for int chars as utf-8 files
r955 if isinstance(paths, str):
fixes for issues #137 and #116 safe_unicode is now default for handling file names
r1176 paths = safe_unicode(paths)
renamed project to rhodecode
r547 url_l = [link_to(repo_name, url('files_home',
repo_name=repo_name,
Reimplemented file-browser using partial-ajax...
r2686 revision=rev, f_path=''),
class_='ypjax-link')]
renamed project to rhodecode
r547 paths_l = paths.split('/')
fixed python2.5 incompatible enumerate calls
r740 for cnt, p in enumerate(paths_l):
renamed project to rhodecode
r547 if p != '':
implements #308 rewrote diffs to enable displaying full diff on each file...
r1789 url_l.append(link_to(p,
garden
r1766 url('files_home',
repo_name=repo_name,
revision=rev,
f_path='/'.join(paths_l[:cnt + 1])
Reimplemented file-browser using partial-ajax...
r2686 ),
class_='ypjax-link'
garden
r1766 )
)
renamed project to rhodecode
r547
return literal('/'.join(url_l))
files_breadcrumbs = _FilesBreadCrumbs()
Added message tooltip into journal revisions in push....
r899
imported patch 2260
r2162
renamed project to rhodecode
r547 class CodeHtmlFormatter(HtmlFormatter):
imported patch 2260
r2162 """
My code Html Formatter for source codes
fixed line number look
r966 """
renamed project to rhodecode
r547
def wrap(self, source, outfile):
return self._wrap_div(self._wrap_pre(self._wrap_code(source)))
def _wrap_code(self, source):
fixed python2.5 incompatible enumerate calls
r740 for cnt, it in enumerate(source):
renamed project to rhodecode
r547 i, t = it
fixed line number look
r966 t = '<div id="L%s">%s</div>' % (cnt + 1, t)
renamed project to rhodecode
r547 yield i, t
fixed line number look
r966
def _wrap_tablelinenos(self, inner):
dummyoutfile = StringIO.StringIO()
lncount = 0
for t, line in inner:
if t:
lncount += 1
dummyoutfile.write(line)
fl = self.linenostart
mw = len(str(lncount + fl - 1))
sp = self.linenospecial
st = self.linenostep
la = self.lineanchors
aln = self.anchorlinenos
nocls = self.noclasses
if sp:
lines = []
for i in range(fl, fl + lncount):
if i % st == 0:
if i % sp == 0:
if aln:
lines.append('<a href="#%s%d" class="special">%*d</a>' %
(la, i, mw, i))
else:
lines.append('<span class="special">%*d</span>' % (mw, i))
else:
if aln:
lines.append('<a href="#%s%d">%*d</a>' % (la, i, mw, i))
else:
lines.append('%*d' % (mw, i))
else:
lines.append('')
ls = '\n'.join(lines)
else:
lines = []
for i in range(fl, fl + lncount):
if i % st == 0:
if aln:
lines.append('<a href="#%s%d">%*d</a>' % (la, i, mw, i))
else:
lines.append('%*d' % (mw, i))
else:
lines.append('')
ls = '\n'.join(lines)
# in case you wonder about the seemingly redundant <div> here: since the
# content in the other cell also is wrapped in a div, some browsers in
# some configurations seem to mess up the formatting...
if nocls:
yield 0, ('<table class="%stable">' % self.cssclass +
'<tr><td><div class="linenodiv" '
'style="background-color: #f0f0f0; padding-right: 10px">'
'<pre style="line-height: 125%">' +
Fixed problem with anchor link positioning when passed in ranges....
r1320 ls + '</pre></div></td><td id="hlcode" class="code">')
fixed line number look
r966 else:
yield 0, ('<table class="%stable">' % self.cssclass +
'<tr><td class="linenos"><div class="linenodiv"><pre>' +
Fixed problem with anchor link positioning when passed in ranges....
r1320 ls + '</pre></div></td><td id="hlcode" class="code">')
fixed line number look
r966 yield 0, dummyoutfile.getvalue()
yield 0, '</td></tr></table>'
renamed project to rhodecode
r547 def pygmentize(filenode, **kwargs):
Add option to define custom lexers for custom extensions for code highlight in rcextension module
r3375 """
pygmentize function using pygments
source code cleanup: remove trailing white space, normalize file endings
r1203
fixed @repo into :repo for docs...
r604 :param filenode:
renamed project to rhodecode
r547 """
Add option to define custom lexers for custom extensions for code highlight in rcextension module
r3375 lexer = get_custom_lexer(filenode.extension) or filenode.lexer
return literal(code_highlight(filenode.content, lexer,
CodeHtmlFormatter(**kwargs)))
renamed project to rhodecode
r547
fixes #326 some html special chars where not escaped in diffs + code garden in helpers
r1781
changes for #56
r1171 def pygmentize_annotation(repo_name, filenode, **kwargs):
fixes #326 some html special chars where not escaped in diffs + code garden in helpers
r1781 """
pygmentize function for annotation
source code cleanup: remove trailing white space, normalize file endings
r1203
fixed @repo into :repo for docs...
r604 :param filenode:
renamed project to rhodecode
r547 """
Hacking for git support,and new faster repo scan
r631
renamed project to rhodecode
r547 color_dict = {}
fixes #326 some html special chars where not escaped in diffs + code garden in helpers
r1781
Fixed whoosh daemon, for depracated walk method
r947 def gen_color(n=10000):
source code cleanup: remove trailing white space, normalize file endings
r1203 """generator for getting n of evenly distributed colors using
Fixed whoosh daemon, for depracated walk method
r947 hsv color and golden ratio. It always return same order of colors
source code cleanup: remove trailing white space, normalize file endings
r1203
Fixed whoosh daemon, for depracated walk method
r947 :returns: RGB tuple
Hacking for git support,and new faster repo scan
r631 """
removed colorsys import
r1461
def hsv_to_rgb(h, s, v):
fixes #326 some html special chars where not escaped in diffs + code garden in helpers
r1781 if s == 0.0:
return v, v, v
i = int(h * 6.0) # XXX assume int() truncates!
removed colorsys import
r1461 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
fixes #326 some html special chars where not escaped in diffs + code garden in helpers
r1781 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
removed colorsys import
r1461
renamed project to rhodecode
r547 golden_ratio = 0.618033988749895
h = 0.22717784590367374
Fixed whoosh daemon, for depracated walk method
r947
Fixed problem with anchor link positioning when passed in ranges....
r1320 for _ in xrange(n):
renamed project to rhodecode
r547 h += golden_ratio
h %= 1
HSV_tuple = [h, 0.95, 0.95]
removed colorsys import
r1461 RGB_tuple = hsv_to_rgb(*HSV_tuple)
fixes #326 some html special chars where not escaped in diffs + code garden in helpers
r1781 yield map(lambda x: str(int(x * 256)), RGB_tuple)
renamed project to rhodecode
r547
cgenerator = gen_color()
Hacking for git support,and new faster repo scan
r631
renamed project to rhodecode
r547 def get_color_string(cs):
fixes #326 some html special chars where not escaped in diffs + code garden in helpers
r1781 if cs in color_dict:
renamed project to rhodecode
r547 col = color_dict[cs]
else:
col = color_dict[cs] = cgenerator.next()
return "color: rgb(%s)! important;" % (', '.join(col))
Hacking for git support,and new faster repo scan
r631
changes for #56
r1171 def url_func(repo_name):
wrap_paragraph was to slow for toolip generation and was removed.
r1352
changes for #56
r1171 def _url_func(changeset):
wrap_paragraph was to slow for toolip generation and was removed.
r1352 author = changeset.author
date = changeset.date
message = tooltip(changeset.message)
Hacking for git support,and new faster repo scan
r631
wrap_paragraph was to slow for toolip generation and was removed.
r1352 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 % (author, date, message)
changes for #56
r1171 lnk_format = '%5s:%s' % ('r%s' % changeset.revision,
short_id(changeset.raw_id))
uri = link_to(
lnk_format,
url('changeset_home', repo_name=repo_name,
revision=changeset.raw_id),
style=get_color_string(changeset.raw_id),
class_='tooltip',
title=tooltip_html
)
Hacking for git support,and new faster repo scan
r631
changes for #56
r1171 uri += '\n'
return uri
return _url_func
return literal(annotate_highlight(filenode, url_func(repo_name), **kwargs))
Hacking for git support,and new faster repo scan
r631
fixes #326 some html special chars where not escaped in diffs + code garden in helpers
r1781
fixed following js snipet. It' can be called multiple times now next to each repository...
r999 def is_following_repo(repo_name, user_id):
from rhodecode.model.scm import ScmModel
return ScmModel().is_following_repo(repo_name, user_id)
renamed project to rhodecode
r547 flash = _Flash()
Fixed age, for new vcs implementation. Removed all obsolete date formatters...
r635 #==============================================================================
Make rhodecode use author/username filter from vcs instead of mercurial
r1356 # SCM FILTERS available via h.
Fixed age, for new vcs implementation. Removed all obsolete date formatters...
r635 #==============================================================================
Added VCS into rhodecode core for faster and easier deployments of new versions
r2007 from rhodecode.lib.vcs.utils import author_name, author_email
utils/conf...
r2109 from rhodecode.lib.utils2 import credentials_filter, age as _age
added changeset status into changelog view
r2239 from rhodecode.model.db import User, ChangesetStatus
renamed project to rhodecode
r547
Implemented show_id function that is a configurable way to display sha hashes in the changelog.
r3557 age = lambda x, y=False: _age(x, y)
renamed project to rhodecode
r547 capitalize = lambda x: x.capitalize()
Make rhodecode use author/username filter from vcs instead of mercurial
r1356 email = author_email
Fixes for raw_id, needed for git...
r636 short_id = lambda x: x[:12]
Fixes issue #201...
r1373 hide_credentials = lambda x: ''.join(credentials_filter(x))
#48 rewrote action logger, translated action logger messages, added some extra messages. Linked and showed pushed revisions in logs
r660
fixes issue #320....
r1764
Implemented show_id function that is a configurable way to display sha hashes in the changelog.
r3557 def show_id(cs):
"""
Configurable function that shows ID
by default it's r123:fffeeefffeee
:param cs: changeset instance
"""
from rhodecode import CONFIG
Mads Kiilerich
config: rename options to show_revision_number and show_sha_length...
r3651 def_len = safe_int(CONFIG.get('show_sha_length', 12))
show_rev = str2bool(CONFIG.get('show_revision_number', True))
Implemented show_id function that is a configurable way to display sha hashes in the changelog.
r3557
raw_id = cs.raw_id[:def_len]
if show_rev:
return 'r%s:%s' % (cs.revision, raw_id)
else:
return '%s' % (raw_id)
Vincent Duvert
Added a translatable date formatter for every date displayed.
r2416 def fmt_date(date):
if date:
Format datetime in notifications according to unified function
r2445 _fmt = _(u"%a, %d %b %Y %H:%M:%S").encode('utf8')
return date.strftime(_fmt).decode('utf8')
Added h.tooltip to all places that tooltip_title is used....
r2427
Vincent Duvert
Added a translatable date formatter for every date displayed.
r2416 return ""
optimized speed for browsing git changesets
r1959 def is_git(repository):
if hasattr(repository, 'alias'):
_type = repository.alias
elif hasattr(repository, 'repo_type'):
_type = repository.repo_type
else:
_type = repository
return _type == 'git'
def is_hg(repository):
if hasattr(repository, 'alias'):
_type = repository.alias
elif hasattr(repository, 'repo_type'):
_type = repository.repo_type
else:
_type = repository
return _type == 'hg'
garden
r1767 def email_or_none(author):
fixes issue #531, when extracting user email, we check it against the database,...
r2725 # extract email from the commit string
garden
r1767 _email = email(author)
if _email != '':
fixes issue #531, when extracting user email, we check it against the database,...
r2725 # check it against RhodeCode database, and use the MAIN email for this
# user
user = User.get_by_email(_email, case_insensitive=True, cache=True)
if user is not None:
return user.email
garden
r1767 return _email
fixes issue #320....
r1764
# See if it contains a username we can get an email from
garden
r1767 user = User.get_by_username(author_name(author), case_insensitive=True,
fixes issue #320....
r1764 cache=True)
if user is not None:
return user.email
# No valid email, not a valid user in the system, none!
return None
fixes #326 some html special chars where not escaped in diffs + code garden in helpers
r1781
Implemented #532....
r2731 def person(author, show_attr="username_and_name"):
fixes issue #320....
r1764 # attr to return from fetched user
Implemented #532....
r2731 person_getter = lambda usr: getattr(usr, show_attr)
fixes #326 some html special chars where not escaped in diffs + code garden in helpers
r1781
garden
r1767 # Valid email in the attribute passed, see if they're in the system
_email = email(author)
if _email != '':
user = User.get_by_email(_email, case_insensitive=True, cache=True)
fixes issue #320....
r1764 if user is not None:
return person_getter(user)
# Maybe it's a username?
garden
r1767 _author = author_name(author)
user = User.get_by_username(_author, case_insensitive=True,
fixes issue #320....
r1764 cache=True)
if user is not None:
return person_getter(user)
h.person, if author name is empty, use email as a fallback
r3766 # Still nothing? Just pass back the author name if any, else the email
return _author or _email
fixes issue #320....
r1764
optimized speed for browsing git changesets
r1959
Implemented #532....
r2731 def person_by_id(id_, show_attr="username_and_name"):
Implemented basic locking functionality....
r2726 # attr to return from fetched user
Implemented #532....
r2731 person_getter = lambda usr: getattr(usr, show_attr)
Implemented basic locking functionality....
r2726
#maybe it's an ID ?
if str(id_).isdigit() or isinstance(id_, int):
id_ = int(id_)
user = User.get(id_)
if user is not None:
return person_getter(user)
return id_
merged + fixed pull request #62: Implemented metatags and visualisation options....
r2674 def desc_stylize(value):
"""
converts tags from value into html equivalent
:param value:
"""
value = re.sub(r'\[see\ \=\>\ *([a-zA-Z0-9\/\=\?\&\ \:\/\.\-]*)\]',
'<div class="metatag" tag="see">see =&gt; \\1 </div>', value)
value = re.sub(r'\[license\ \=\>\ *([a-zA-Z0-9\/\=\?\&\ \:\/\.\-]*)\]',
'<div class="metatag" tag="license"><a href="http:\/\/www.opensource.org/licenses/\\1">\\1</a></div>', value)
fixes issue #715 Meta-Tagging [requires => Repo-123] not working
r3156 value = re.sub(r'\[(requires|recommends|conflicts|base)\ \=\>\ *([a-zA-Z0-9\-\/]*)\]',
merged + fixed pull request #62: Implemented metatags and visualisation options....
r2674 '<div class="metatag" tag="\\1">\\1 =&gt; <a href="/\\2">\\2</a></div>', value)
fixed #623: Lang meta-tag doesn't work with C#/C++
r2965 value = re.sub(r'\[(lang|language)\ \=\>\ *([a-zA-Z\-\/\#\+]*)\]',
merged + fixed pull request #62: Implemented metatags and visualisation options....
r2674 '<div class="metatag" tag="lang">\\2</div>', value)
value = re.sub(r'\[([a-z]+)\]',
'<div class="metatag" tag="\\1">\\1</div>', value)
return value
Mads Kiilerich
helpers: show boolean value of value as icon, not just the True and False singletons
r3627 def boolicon(value):
"""Returns boolean value of a value, represented as small html image of true/false
Added ldap info on admin users, added bool2icon helper for nicer representation of...
r712 icons
source code cleanup: remove trailing white space, normalize file endings
r1203
Mads Kiilerich
helpers: show boolean value of value as icon, not just the True and False singletons
r3627 :param value: value
Added ldap info on admin users, added bool2icon helper for nicer representation of...
r712 """
Mads Kiilerich
helpers: show boolean value of value as icon, not just the True and False singletons
r3627 if value:
removed obsolete _static flag from url, and fixed urls in webhelpers
r1050 return HTML.tag('img', src=url("/images/icons/accept.png"),
alt=_('True'))
Mads Kiilerich
helpers: show boolean value of value as icon, not just the True and False singletons
r3627 else:
removed obsolete _static flag from url, and fixed urls in webhelpers
r1050 return HTML.tag('img', src=url("/images/icons/cancel.png"),
alt=_('False'))
Added ldap info on admin users, added bool2icon helper for nicer representation of...
r712
Use lightweight revisions in journal by default
r2958 def action_parser(user_log, feed=False, parse_cs=False):
speed up generating changesets in journal log...
r2012 """
This helper will action_map the specified string action into translated
#48 rewrote action logger, translated action logger messages, added some extra messages. Linked and showed pushed revisions in logs
r660 fancy names with icons and links
source code cleanup: remove trailing white space, normalize file endings
r1203
Added message tooltip into journal revisions in push....
r899 :param user_log: user log instance
fixed unicode problems with file paths....
r1087 :param feed: use output for feeds (no html and fancy icons)
added experimental lightweight param to journal
r2950 :param parse_cs: parse Changesets into VCS instances
#48 rewrote action logger, translated action logger messages, added some extra messages. Linked and showed pushed revisions in logs
r660 """
Use lightweight revisions in journal by default
r2958
#48 rewrote action logger, translated action logger messages, added some extra messages. Linked and showed pushed revisions in logs
r660 action = user_log.action
action logger upgrade, for working with migrations
r840 action_params = ' '
#48 rewrote action logger, translated action logger messages, added some extra messages. Linked and showed pushed revisions in logs
r660
x = action.split(':')
if len(x) > 1:
action, action_params = x
Added fork name to journal...
r718 def get_cs_links():
speed up generating changesets in journal log...
r2012 revs_limit = 3 # display this amount always
revs_top_limit = 50 # show upto this amount of changesets hidden
revs_ids = action_params.split(',')
fixed cs_links for deleted repos
r2014 deleted = user_log.repository is None
if deleted:
return ','.join(revs_ids)
fixed vcs import....
r953 repo_name = user_log.repository.repo_name
another major codes rewrite:...
r1045
fix for issue #450. Rhodecode no longer will crash when bad revision is present in journal data.
r2323 def lnk(rev, repo_name):
added experimental lightweight param to journal
r2950 if isinstance(rev, BaseChangeset) or isinstance(rev, AttributeDict):
fixes #645 Fix git handler when doing delete remote branch...
r2998 lazy_cs = True
if getattr(rev, 'op', None) and getattr(rev, 'ref_name', None):
lazy_cs = False
lbl = '?'
if rev.op == 'delete_branch':
lbl = '%s' % _('Deleted branch: %s') % rev.ref_name
title = ''
elif rev.op == 'tag':
lbl = '%s' % _('Created tag: %s') % rev.ref_name
title = ''
_url = '#'
else:
lbl = '%s' % (rev.short_id[:8])
_url = url('changeset_home', repo_name=repo_name,
revision=rev.raw_id)
title = tooltip(rev.message)
fix for issue #450. Rhodecode no longer will crash when bad revision is present in journal data.
r2323 else:
Use lightweight revisions in journal by default
r2958 ## changeset cannot be found/striped/removed etc.
Added lightweight journal option for visual
r2952 lbl = ('%s' % rev)[:12]
fix for issue #450. Rhodecode no longer will crash when bad revision is present in journal data.
r2323 _url = '#'
title = _('Changeset not found')
Use lightweight revisions in journal by default
r2958 if parse_cs:
return link_to(lbl, _url, title=title, class_='tooltip')
new tooltip implementation...
r2971 return link_to(lbl, _url, raw_id=rev.raw_id, repo_name=repo_name,
fixes #645 Fix git handler when doing delete remote branch...
r2998 class_='lazy-cs' if lazy_cs else '')
added emulation of pull hook for git-backend, and dummy git-push hook
r2203
show correct values for compare view when multiple git tags are pushed
r3507 def _get_op(rev_txt):
_op = None
_name = rev_txt
if len(rev_txt.split('=>')) == 2:
_op, _name = rev_txt.split('=>')
return _op, _name
added emulation of pull hook for git-backend, and dummy git-push hook
r2203 revs = []
if len(filter(lambda v: v != '', revs_ids)) > 0:
Use lightweight revisions in journal by default
r2958 repo = None
fix for issue #450. Rhodecode no longer will crash when bad revision is present in journal data.
r2323 for rev in revs_ids[:revs_top_limit]:
show correct values for compare view when multiple git tags are pushed
r3507 _op, _name = _get_op(rev)
fixes #645 Fix git handler when doing delete remote branch...
r2998
Use lightweight revisions in journal by default
r2958 # we want parsed changesets, or new log store format is bad
added experimental lightweight param to journal
r2950 if parse_cs:
try:
Use lightweight revisions in journal by default
r2958 if repo is None:
repo = user_log.repository.scm_instance
_rev = repo.get_changeset(rev)
revs.append(_rev)
added experimental lightweight param to journal
r2950 except ChangesetDoesNotExistError:
log.error('cannot find revision %s in this repo' % rev)
revs.append(rev)
continue
else:
Use lightweight revisions in journal by default
r2958 _rev = AttributeDict({
added experimental lightweight param to journal
r2950 'short_id': rev[:12],
'raw_id': rev,
Use lightweight revisions in journal by default
r2958 'message': '',
fixes #645 Fix git handler when doing delete remote branch...
r2998 'op': _op,
'ref_name': _name
added experimental lightweight param to journal
r2950 })
Use lightweight revisions in journal by default
r2958 revs.append(_rev)
Removed all string concat for exchange of ''.join()
r1359 cs_links = []
speed up generating changesets in journal log...
r2012 cs_links.append(" " + ', '.join(
[lnk(rev, repo_name) for rev in revs[:revs_limit]]
)
)
show correct values for compare view when multiple git tags are pushed
r3507 _op1, _name1 = _get_op(revs_ids[0])
_op2, _name2 = _get_op(revs_ids[-1])
_rev = '%s...%s' % (_name1, _name2)
Added compare view into journal, fixed wrong function call to show compare view
r1009
speed up generating changesets in journal log...
r2012 compare_view = (
' <div class="compare_view tooltip" title="%s">'
'<a href="%s">%s</a> </div>' % (
_('Show all combined changesets %s->%s') % (
shorten the journal compare tooltip
r2954 revs_ids[0][:12], revs_ids[-1][:12]
speed up generating changesets in journal log...
r2012 ),
url('changeset_home', repo_name=repo_name,
show correct values for compare view when multiple git tags are pushed
r3507 revision=_rev
speed up generating changesets in journal log...
r2012 ),
_('compare view')
)
)
Added compare view into journal, fixed wrong function call to show compare view
r1009
speed up generating changesets in journal log...
r2012 # if we have exactly one more than normally displayed
# just display it, takes less space than displaying
# "and 1 more revisions"
if len(revs_ids) == revs_limit + 1:
Aras Pranckevicius
journal: polish
r1979 rev = revs[revs_limit]
speed up generating changesets in journal log...
r2012 cs_links.append(", " + lnk(rev, repo_name))
Aras Pranckevicius
journal: polish
r1979
# hidden-by-default ones
speed up generating changesets in journal log...
r2012 if len(revs_ids) > revs_limit + 1:
uniq_id = revs_ids[0]
html_tmpl = (
'<span> %s <a class="show_more" id="_%s" '
'href="#more">%s</a> %s</span>'
)
fixed unicode problems with file paths....
r1087 if not feed:
speed up generating changesets in journal log...
r2012 cs_links.append(html_tmpl % (
_('and'),
uniq_id, _('%s more') % (len(revs_ids) - revs_limit),
_('revisions')
)
)
added icons to journal, extend show more to actually show more pushed revisions,
r808
fixed unicode problems with file paths....
r1087 if not feed:
Aras Pranckevicius
journal: polish
r1979 html_tmpl = '<span id="%s" style="display:none">, %s </span>'
fixed unicode problems with file paths....
r1087 else:
html_tmpl = '<span id="%s"> %s </span>'
speed up generating changesets in journal log...
r2012 morelinks = ', '.join(
[lnk(rev, repo_name) for rev in revs[revs_limit:]]
)
Aras Pranckevicius
journal: polish
r1979
speed up generating changesets in journal log...
r2012 if len(revs_ids) > revs_top_limit:
Aras Pranckevicius
journal: polish
r1979 morelinks += ', ...'
cs_links.append(html_tmpl % (uniq_id, morelinks))
hidden compare view link for single revision push
r1024 if len(revs) > 1:
Removed all string concat for exchange of ''.join()
r1359 cs_links.append(compare_view)
return ''.join(cs_links)
implemented user dashboards, and following system.
r734
Added fork name to journal...
r718 def get_fork_name():
fixed vcs import....
r953 repo_name = action_params
formatting change on helper, remove str() call
r2914 _url = url('summary_home', repo_name=repo_name)
return _('fork name %s') % link_to(action_params, _url)
fixed vcs import....
r953
Implemented #467 Journal logs comments on changesets...
r2375 def get_user_name():
user_name = action_params
return user_name
def get_users_group():
group_name = action_params
return group_name
- added action when someone closes pull request in journal...
r2609 def get_pull_request():
pull_request_id = action_params
Implemented better support for Wildcard queries...
r3063 deleted = user_log.repository is None
if deleted:
repo_name = user_log.repository_name
else:
repo_name = user_log.repository.repo_name
- added action when someone closes pull request in journal...
r2609 return link_to(_('Pull request #%s') % pull_request_id,
url('pullrequest_show', repo_name=repo_name,
pull_request_id=pull_request_id))
Implemented #467 Journal logs comments on changesets...
r2375 # action : translated str, callback(extractor), icon
action_map = {
fixed ico for pull request comment
r2491 'user_deleted_repo': (_('[deleted] repository'),
None, 'database_delete.png'),
'user_created_repo': (_('[created] repository'),
None, 'database_add.png'),
'user_created_fork': (_('[created] repository as fork'),
None, 'arrow_divide.png'),
'user_forked_repo': (_('[forked] repository'),
get_fork_name, 'arrow_divide.png'),
'user_updated_repo': (_('[updated] repository'),
None, 'database_edit.png'),
'admin_deleted_repo': (_('[delete] repository'),
None, 'database_delete.png'),
'admin_created_repo': (_('[created] repository'),
None, 'database_add.png'),
'admin_forked_repo': (_('[forked] repository'),
None, 'arrow_divide.png'),
'admin_updated_repo': (_('[updated] repository'),
None, 'database_edit.png'),
'admin_created_user': (_('[created] user'),
get_user_name, 'user_add.png'),
'admin_updated_user': (_('[updated] user'),
get_user_name, 'user_edit.png'),
fixed tests and missing replacements from 5f1850e4712a
r3415 'admin_created_users_group': (_('[created] user group'),
fixed ico for pull request comment
r2491 get_users_group, 'group_add.png'),
fixed tests and missing replacements from 5f1850e4712a
r3415 'admin_updated_users_group': (_('[updated] user group'),
fixed ico for pull request comment
r2491 get_users_group, 'group_edit.png'),
'user_commented_revision': (_('[commented] on revision in repository'),
get_cs_links, 'comment_add.png'),
- added action when someone closes pull request in journal...
r2609 'user_commented_pull_request': (_('[commented] on pull request for'),
get_pull_request, 'comment_add.png'),
'user_closed_pull_request': (_('[closed] pull request for'),
get_pull_request, 'tick.png'),
fixed ico for pull request comment
r2491 'push': (_('[pushed] into'),
get_cs_links, 'script_add.png'),
'push_local': (_('[committed via RhodeCode] into repository'),
get_cs_links, 'script_edit.png'),
'push_remote': (_('[pulled from remote] into repository'),
get_cs_links, 'connect.png'),
'pull': (_('[pulled] from'),
None, 'down_16.png'),
'started_following_repo': (_('[started following] repository'),
None, 'heart_add.png'),
'stopped_following_repo': (_('[stopped following] repository'),
None, 'heart_delete.png'),
Implemented #467 Journal logs comments on changesets...
r2375 }
#48 rewrote action logger, translated action logger messages, added some extra messages. Linked and showed pushed revisions in logs
r660
fixed unicode problems with file paths....
r1087 action_str = action_map.get(action, action)
if feed:
action = action_str[0].replace('[', '').replace(']', '')
else:
speed up generating changesets in journal log...
r2012 action = action_str[0]\
.replace('[', '<span class="journal_highlight">')\
.replace(']', '</span>')
#109, added manual pull of changes for repositories that have remote location filled in....
r1114
speed up generating changesets in journal log...
r2012 action_params_func = lambda: ""
fixed journal look & feel
r1052
#109, added manual pull of changes for repositories that have remote location filled in....
r1114 if callable(action_str[1]):
fixed journal look & feel
r1052 action_params_func = action_str[1]
fixed vcs import....
r953
Implemented #467 Journal logs comments on changesets...
r2375 def action_parser_icon():
action = user_log.action
action_params = None
x = action.split(':')
optimized speed for browsing git changesets
r1959
Implemented #467 Journal logs comments on changesets...
r2375 if len(x) > 1:
action, action_params = x
added icons to journal, extend show more to actually show more pushed revisions,
r808
Implemented #467 Journal logs comments on changesets...
r2375 tmpl = """<img src="%s%s" alt="%s"/>"""
ico = action_map.get(action, ['', '', ''])[2]
return literal(tmpl % ((url('/images/icons/')), ico, action))
# returned callbacks we need to call to get
return [lambda: literal(action), action_params_func, action_parser_icon]
#48 rewrote action logger, translated action logger messages, added some extra messages. Linked and showed pushed revisions in logs
r660
Fixed age, for new vcs implementation. Removed all obsolete date formatters...
r635 #==============================================================================
renamed project to rhodecode
r547 # PERMS
Fixed age, for new vcs implementation. Removed all obsolete date formatters...
r635 #==============================================================================
renamed project to rhodecode
r547 from rhodecode.lib.auth import HasPermissionAny, HasPermissionAll, \
Group management delegation:...
r3222 HasRepoPermissionAny, HasRepoPermissionAll, HasReposGroupPermissionAll, \
HasReposGroupPermissionAny
renamed project to rhodecode
r547
optimized speed for browsing git changesets
r1959
Fixed age, for new vcs implementation. Removed all obsolete date formatters...
r635 #==============================================================================
renamed project to rhodecode
r547 # GRAVATAR URL
Fixed age, for new vcs implementation. Removed all obsolete date formatters...
r635 #==============================================================================
renamed project to rhodecode
r547
def gravatar_url(email_address, size=30):
fixes issue #674, alternative gravatar url had an error when there was no valid email in commit data
r3080 from pylons import url # doh, we need to re-import url to mock it later
#763 gravatar helper function should fallback into default image if somehow email provided is empty.
r3367 _def = 'anonymous@rhodecode.org'
use_gravatar = str2bool(config['app_conf'].get('use_gravatar'))
email_address = email_address or _def
if (not use_gravatar or not email_address or email_address == _def):
fixes issue #674, alternative gravatar url had an error when there was no valid email in commit data
r3080 f = lambda a, l: min(l, key=lambda x: abs(x - a))
return url("/images/user%s.png" % f(size, [14, 16, 20, 24, 30]))
#763 gravatar helper function should fallback into default image if somehow email provided is empty.
r3367 if use_gravatar and config['app_conf'].get('alternative_gravatar_url'):
fixes issue #543, un-broken alternative gravatar option...
r2751 tmpl = config['app_conf'].get('alternative_gravatar_url', '')
Implemented patch from andrewsh ref #565 Add support for {netloc} and {scheme}...
r2836 parsed_url = urlparse.urlparse(url.current(qualified=True))
fixes issue #543, un-broken alternative gravatar option...
r2751 tmpl = tmpl.replace('{email}', email_address)\
Implemented patch from andrewsh ref #565 Add support for {netloc} and {scheme}...
r2836 .replace('{md5email}', hashlib.md5(email_address.lower()).hexdigest()) \
.replace('{netloc}', parsed_url.netloc)\
.replace('{scheme}', parsed_url.scheme)\
fixes issue #543, un-broken alternative gravatar option...
r2751 .replace('{size}', str(size))
return tmpl
patched gravatar url generation to properly support new https force flag from settings.
r946 ssl_enabled = 'https' == request.environ.get('wsgi.url_scheme')
renamed project to rhodecode
r547 default = 'identicon'
baseurl_nossl = "http://www.gravatar.com/avatar/"
baseurl_ssl = "https://secure.gravatar.com/avatar/"
baseurl = baseurl_ssl if ssl_enabled else baseurl_nossl
Hacking for git support,and new faster repo scan
r631
fixed problem with int. chars in gravatars
r1101 if isinstance(email_address, unicode):
#hashlib crashes on unicode items
Unicode fixes, added safe_str method for global str() operations +better test sandboxing
r1401 email_address = safe_str(email_address)
renamed project to rhodecode
r547 # construct the url
gravatar_url = baseurl + hashlib.md5(email_address.lower()).hexdigest() + "?"
speed up generating changesets in journal log...
r2012 gravatar_url += urllib.urlencode({'d': default, 's': str(size)})
renamed project to rhodecode
r547
return gravatar_url
Added dedicated repo pager to support reversed new way slicing method of vcs and get_changesets method
r1098
Unified the paginators for pylons and YUI....
r3776 class Page(_Page):
"""
Custom pager to match rendering style with YUI paginator
"""
def _get_pos(self, cur_page, max_page, items):
edge = (items / 2) + 1
if (cur_page <= edge):
radius = max(items / 2, items - cur_page)
elif (max_page - cur_page) < edge:
radius = (items - 1) - (max_page - cur_page)
else:
radius = items / 2
left = max(1, (cur_page - (radius)))
right = min(max_page, cur_page + (radius))
return left, cur_page, right
def _range(self, regexp_match):
"""
Return range of linked pages (e.g. '1 2 [3] 4 5 6 7 8').
Arguments:
regexp_match
A "re" (regular expressions) match object containing the
radius of linked pages around the current page in
regexp_match.group(1) as a string
This function is supposed to be called as a callable in
re.sub.
"""
radius = int(regexp_match.group(1))
# Compute the first and last page number within the radius
# e.g. '1 .. 5 6 [7] 8 9 .. 12'
# -> leftmost_page = 5
# -> rightmost_page = 9
leftmost_page, _cur, rightmost_page = self._get_pos(self.page,
self.last_page,
(radius * 2) + 1)
nav_items = []
# Create a link to the first page (unless we are on the first page
# or there would be no need to insert '..' spacers)
if self.page != self.first_page and self.first_page < leftmost_page:
nav_items.append(self._pagerlink(self.first_page, self.first_page))
# Insert dots if there are pages between the first page
# and the currently displayed page range
if leftmost_page - self.first_page > 1:
# Wrap in a SPAN tag if nolink_attr is set
text = '..'
if self.dotdot_attr:
text = HTML.span(c=text, **self.dotdot_attr)
nav_items.append(text)
for thispage in xrange(leftmost_page, rightmost_page + 1):
# Hilight the current page number and do not use a link
if thispage == self.page:
text = '%s' % (thispage,)
# Wrap in a SPAN tag if nolink_attr is set
if self.curpage_attr:
text = HTML.span(c=text, **self.curpage_attr)
nav_items.append(text)
# Otherwise create just a link to that page
else:
text = '%s' % (thispage,)
nav_items.append(self._pagerlink(thispage, text))
# Insert dots if there are pages between the displayed
# page numbers and the end of the page range
if self.last_page - rightmost_page > 1:
text = '..'
# Wrap in a SPAN tag if nolink_attr is set
if self.dotdot_attr:
text = HTML.span(c=text, **self.dotdot_attr)
nav_items.append(text)
# Create a link to the very last page (unless we are on the last
# page or there would be no need to insert '..' spacers)
if self.page != self.last_page and rightmost_page < self.last_page:
nav_items.append(self._pagerlink(self.last_page, self.last_page))
return self.separator.join(nav_items)
def pager(self, format='~2~', page_param='page', partial_param='partial',
show_if_single_page=False, separator=' ', onclick=None,
symbol_first='<<', symbol_last='>>',
symbol_previous='<', symbol_next='>',
link_attr={'class': 'pager_link'},
curpage_attr={'class': 'pager_curpage'},
dotdot_attr={'class': 'pager_dotdot'}, **kwargs):
self.curpage_attr = curpage_attr
self.separator = separator
self.pager_kwargs = kwargs
self.page_param = page_param
self.partial_param = partial_param
self.onclick = onclick
self.link_attr = link_attr
self.dotdot_attr = dotdot_attr
# Don't show navigator if there is no more than one page
if self.page_count == 0 or (self.page_count == 1 and not show_if_single_page):
return ''
from string import Template
# Replace ~...~ in token format by range of pages
result = re.sub(r'~(\d+)~', self._range, format)
# Interpolate '%' variables
result = Template(result).safe_substitute({
'first_page': self.first_page,
'last_page': self.last_page,
'page': self.page,
'page_count': self.page_count,
'items_per_page': self.items_per_page,
'first_item': self.first_item,
'last_item': self.last_item,
'item_count': self.item_count,
'link_first': self.page > self.first_page and \
self._pagerlink(self.first_page, symbol_first) or '',
'link_last': self.page < self.last_page and \
self._pagerlink(self.last_page, symbol_last) or '',
'link_previous': self.previous_page and \
self._pagerlink(self.previous_page, symbol_previous) \
or HTML.span(symbol_previous, class_="yui-pg-previous"),
'link_next': self.next_page and \
self._pagerlink(self.next_page, symbol_next) \
or HTML.span(symbol_next, class_="yui-pg-next")
})
return literal(result)
Added dedicated repo pager to support reversed new way slicing method of vcs and get_changesets method
r1098 #==============================================================================
When creating a remote repository, with credentials filled, it's good to hide username and password from the clone url. Only administrators can see this in repository settings page
r1342 # REPO PAGER, PAGER FOR REPOSITORY
Added dedicated repo pager to support reversed new way slicing method of vcs and get_changesets method
r1098 #==============================================================================
class RepoPage(Page):
def __init__(self, collection, page=1, items_per_page=20,
implemented #44 - branch filtering in changelog, aka branch browser...
r1656 item_count=None, url=None, **kwargs):
Added dedicated repo pager to support reversed new way slicing method of vcs and get_changesets method
r1098
"""Create a "RepoPage" instance. special pager for paging
repository
"""
self._url_generator = url
# Safe the kwargs class-wide so they can be used in the pager() method
self.kwargs = kwargs
# Save a reference to the collection
self.original_collection = collection
self.collection = collection
# The self.page is the number of the current page.
# The first page has the number 1!
try:
speed up generating changesets in journal log...
r2012 self.page = int(page) # make it int() if we get it as a string
Added dedicated repo pager to support reversed new way slicing method of vcs and get_changesets method
r1098 except (ValueError, TypeError):
self.page = 1
self.items_per_page = items_per_page
# Unless the user tells us how many items the collections has
# we calculate that ourselves.
if item_count is not None:
self.item_count = item_count
else:
self.item_count = len(self.collection)
# Compute the number of the first and last available page
if self.item_count > 0:
self.first_page = 1
fixed issues with repo pager
r1422 self.page_count = int(math.ceil(float(self.item_count) /
self.items_per_page))
Added dedicated repo pager to support reversed new way slicing method of vcs and get_changesets method
r1098 self.last_page = self.first_page + self.page_count - 1
auto white-space removal
r1818 # Make sure that the requested page number is the range of
garden
r1766 # valid pages
Added dedicated repo pager to support reversed new way slicing method of vcs and get_changesets method
r1098 if self.page > self.last_page:
self.page = self.last_page
elif self.page < self.first_page:
self.page = self.first_page
# Note: the number of items on this page can be less than
# items_per_page if the last page is not full
fixed issues with repo pager
r1422 self.first_item = max(0, (self.item_count) - (self.page *
items_per_page))
self.last_item = ((self.item_count - 1) - items_per_page *
(self.page - 1))
Added dedicated repo pager to support reversed new way slicing method of vcs and get_changesets method
r1098
#77 code review...
r1670 self.items = list(self.collection[self.first_item:self.last_item + 1])
implemented #44 - branch filtering in changelog, aka branch browser...
r1656
Added dedicated repo pager to support reversed new way slicing method of vcs and get_changesets method
r1098 # Links to previous and next page
if self.page > self.first_page:
self.previous_page = self.page - 1
else:
self.previous_page = None
if self.page < self.last_page:
self.next_page = self.page + 1
else:
self.next_page = None
# No items available
else:
self.first_page = None
self.page_count = 0
self.last_page = None
self.first_item = None
self.last_item = None
self.previous_page = None
self.next_page = None
self.items = []
# This is a subclass of the 'list' type. Initialise the list now.
implemented #44 - branch filtering in changelog, aka branch browser...
r1656 list.__init__(self, reversed(self.items))
Added dedicated repo pager to support reversed new way slicing method of vcs and get_changesets method
r1098
moved tooltip function from the for loop and from templates to helpers
r990 def changed_tooltip(nodes):
When creating a remote repository, with credentials filled, it's good to hide username and password from the clone url. Only administrators can see this in repository settings page
r1342 """
Generates a html string for changed nodes in changeset page.
It limits the output to 30 entries
auto white-space removal
r1818
When creating a remote repository, with credentials filled, it's good to hide username and password from the clone url. Only administrators can see this in repository settings page
r1342 :param nodes: LazyNodesGenerator
"""
moved tooltip function from the for loop and from templates to helpers
r990 if nodes:
pref = ': <br/> '
suf = ''
if len(nodes) > 30:
suf = '<br/>' + _(' and %s more') % (len(nodes) - 30)
Implemented --stat for changelog
r1257 return literal(pref + '<br/> '.join([safe_unicode(x.path)
for x in nodes[:30]]) + suf)
moved tooltip function from the for loop and from templates to helpers
r990 else:
return ': ' + _('No Files')
Changes for repo groups
r1159
Mads Kiilerich
breadcrumbs: make repo names link to summary pages
r3599 def repo_link(groups_and_repos):
When creating a remote repository, with credentials filled, it's good to hide username and password from the clone url. Only administrators can see this in repository settings page
r1342 """
Makes a breadcrumbs link to repo within a group
joins &raquo; on each group to create a fancy link
auto white-space removal
r1818
When creating a remote repository, with credentials filled, it's good to hide username and password from the clone url. Only administrators can see this in repository settings page
r1342 ex::
group >> subgroup >> repo
auto white-space removal
r1818
When creating a remote repository, with credentials filled, it's good to hide username and password from the clone url. Only administrators can see this in repository settings page
r1342 :param groups_and_repos:
extend helper for better breadcrumbs for repo groups
r3012 :param last_url:
When creating a remote repository, with credentials filled, it's good to hide username and password from the clone url. Only administrators can see this in repository settings page
r1342 """
Mads Kiilerich
breadcrumbs: make repo names link to summary pages
r3599 groups, just_name, repo_name = groups_and_repos
last_url = url('summary_home', repo_name=repo_name)
last_link = link_to(just_name, last_url)
Changes for repo groups
r1159
Mads Kiilerich
breadcrumbs: make repo names link to summary pages
r3599 def make_link(group):
return link_to(group.name,
url('repos_group_home', group_name=group.group_name))
return literal(' &raquo; '.join(map(make_link, groups) + ['<span>%s</span>' % last_link]))
Implemented --stat for changelog
r1257
optimized speed for browsing git changesets
r1959
Implemented --stat for changelog
r1257 def fancy_file_stats(stats):
When creating a remote repository, with credentials filled, it's good to hide username and password from the clone url. Only administrators can see this in repository settings page
r1342 """
Displays a fancy two colored bar for number of added/deleted
lines of code on file
auto white-space removal
r1818
When creating a remote repository, with credentials filled, it's good to hide username and password from the clone url. Only administrators can see this in repository settings page
r1342 :param stats: two element list of added/deleted lines of code
"""
Implemented generation of changesets based...
r2995 def cgen(l_type, a_v, d_v):
ui
r2118 mapping = {'tr': 'top-right-rounded-corner-mid',
'tl': 'top-left-rounded-corner-mid',
'br': 'bottom-right-rounded-corner-mid',
'bl': 'bottom-left-rounded-corner-mid'}
optimized speed for browsing git changesets
r1959 map_getter = lambda x: mapping[x]
Implemented --stat for changelog
r1257
if l_type == 'a' and d_v:
#case when added and deleted are present
return ' '.join(map(map_getter, ['tl', 'bl']))
if l_type == 'a' and not d_v:
return ' '.join(map(map_getter, ['tr', 'br', 'tl', 'bl']))
if l_type == 'd' and a_v:
return ' '.join(map(map_getter, ['tr', 'br']))
if l_type == 'd' and not a_v:
return ' '.join(map(map_getter, ['tr', 'br', 'tl', 'bl']))
Implemented generation of changesets based...
r2995 a, d = stats[0], stats[1]
width = 100
if a == 'b':
#binary mode
b_d = '<div class="bin%s %s" style="width:100%%">%s</div>' % (d, cgen('a', a_v='', d_v=0), 'bin')
b_a = '<div class="bin1" style="width:0%%">%s</div>' % ('bin')
return literal('<div style="width:%spx">%s%s</div>' % (width, b_a, b_d))
t = stats[0] + stats[1]
unit = float(width) / (t or 1)
# needs > 9% of width to be visible or 0 to be hidden
a_p = max(9, unit * a) if a > 0 else 0
d_p = max(9, unit * d) if d > 0 else 0
p_sum = a_p + d_p
if p_sum > width:
#adjust the percentage to be == 100% since we adjusted to 9
if a_p > d_p:
a_p = a_p - (p_sum - width)
else:
d_p = d_p - (p_sum - width)
a_v = a if a > 0 else ''
d_v = d if d > 0 else ''
optimized speed for browsing git changesets
r1959 d_a = '<div class="added %s" style="width:%s%%">%s</div>' % (
Implemented generation of changesets based...
r2995 cgen('a', a_v, d_v), a_p, a_v
optimized speed for browsing git changesets
r1959 )
d_d = '<div class="deleted %s" style="width:%s%%">%s</div>' % (
Implemented generation of changesets based...
r2995 cgen('d', a_v, d_v), d_p, d_v
optimized speed for browsing git changesets
r1959 )
Implemented --stat for changelog
r1257 return literal('<div style="width:%spx">%s%s</div>' % (width, d_a, d_d))
Links in summary page are now active
r1438
don't use double literal() calls on urlify functions
r3399 def urlify_text(text_, safe=True):
urlify commit function also should extract normal links
r3398 """
Extrac urls from text and make html links out of them
:param text_:
"""
Links in summary page are now active
r1438
garden
r1766 url_pat = re.compile(r'''(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]'''
'''|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+)''')
Links in summary page are now active
r1438
def url_func(match_obj):
url_full = match_obj.groups()[0]
added repository name into issue tracker link to support different projects issues tracker mapping
r1868 return '<a href="%(url)s">%(url)s</a>' % ({'url': url_full})
don't use double literal() calls on urlify functions
r3399 _newtext = url_pat.sub(url_func, text_)
if safe:
return literal(_newtext)
return _newtext
implemented #44 - branch filtering in changelog, aka branch browser...
r1656
optimized speed for browsing git changesets
r1959
added links to revisions in commit messages
r1913 def urlify_changesets(text_, repository):
fixed issue with escaping < and > in changeset commits
r2111 """
Extract revision ids from changeset and make link from them
more detailed logging on auth system...
r2125
fixed issue with escaping < and > in changeset commits
r2111 :param text_:
urlify commit function also should extract normal links
r3398 :param repository: repo name to build the URL with
fixed issue with escaping < and > in changeset commits
r2111 """
revision extraction function shouldn't be so eager, just extract commits that are...
r3385 from pylons import url # doh, we need to re-import url to mock it later
fixed urlify changesets regex + tests
r3405 URL_PAT = re.compile(r'(^|\s)([0-9a-fA-F]{12,40})($|\s)')
added links to revisions in commit messages
r1913
def url_func(match_obj):
fixed urlify changesets regex + tests
r3405 rev = match_obj.groups()[1]
pref = match_obj.groups()[0]
suf = match_obj.groups()[2]
added links to revisions in commit messages
r1913 tmpl = (
'%(pref)s<a class="%(cls)s" href="%(url)s">'
fixed urlify changesets regex + tests
r3405 '%(rev)s</a>%(suf)s'
added links to revisions in commit messages
r1913 )
return tmpl % {
'pref': pref,
'cls': 'revision-link',
'url': url('changeset_home', repo_name=repository, revision=rev),
'rev': rev,
revision extraction function shouldn't be so eager, just extract commits that are...
r3385 'suf': suf
added links to revisions in commit messages
r1913 }
newtext = URL_PAT.sub(url_func, text_)
return newtext
added repository name into issue tracker link to support different projects issues tracker mapping
r1868
optimized speed for browsing git changesets
r1959
Aras Pranckevicius
changelog: make messages be links again, and somewhat co-exist with issue tracker links (those are bold now)
r1878 def urlify_commit(text_, repository=None, link_=None):
fixed issues when urlify commit created empty links when link_ param was empty
r2028 """
Parses given text message and makes proper links.
issues are linked to given issue-server, and rest is a changeset link
if link_ is given, in other case it's a plain text
:param text_:
:param repository:
:param link_: changeset link
"""
#73 mapping of commited issues from commit message into issue tracker url.
r1837 import traceback
urlify commit function also should extract normal links
r3398 from pylons import url # doh, we need to re-import url to mock it later
more detailed logging on auth system...
r2125
fixed issue with escaping < and > in changeset commits
r2111 def escaper(string):
return string.replace('<', '&lt;').replace('>', '&gt;')
more detailed logging on auth system...
r2125
speed up generating changesets in journal log...
r2012 def linkify_others(t, l):
added links to revisions in commit messages
r1913 urls = re.compile(r'(\<a.*?\<\/a\>)',)
links = []
for e in urls.split(t):
if not urls.match(e):
speed up generating changesets in journal log...
r2012 links.append('<a class="message-link" href="%s">%s</a>' % (l, e))
added links to revisions in commit messages
r1913 else:
white space cleanup
r1944 links.append(e)
added links to revisions in commit messages
r1913 return ''.join(links)
more detailed logging on auth system...
r2125
fixed issue with escaping < and > in changeset commits
r2111 # urlify changesets - extrac revisions and make link out of them
Zachary Auclair
Allowing multiple issue servers to be autolinked in the changeset view;...
r2865 newtext = urlify_changesets(escaper(text_), repository)
fixed issue with escaping < and > in changeset commits
r2111
urlify commit function also should extract normal links
r3398 # extract http/https links and make them real urls
don't use double literal() calls on urlify functions
r3399 newtext = urlify_text(newtext, safe=False)
urlify commit function also should extract normal links
r3398
#73 mapping of commited issues from commit message into issue tracker url.
r1837 try:
don't use global pylons config
r3382 from rhodecode import CONFIG
conf = CONFIG
added repository name into issue tracker link to support different projects issues tracker mapping
r1868
Zachary Auclair
Allowing multiple issue servers to be autolinked in the changeset view;...
r2865 # allow multiple issue servers to be used
valid_indices = [
#518 multiple issues patterns...
r2866 x.group(1)
for x in map(lambda x: re.match(r'issue_pat(.*)', x), conf.keys())
if x and 'issue_server_link%s' % x.group(1) in conf
and 'issue_prefix%s' % x.group(1) in conf
]
Zachary Auclair
Allowing multiple issue servers to be autolinked in the changeset view;...
r2865
#518 multiple issues patterns...
r2866 log.debug('found issue server suffixes `%s` during valuation of: %s'
% (','.join(valid_indices), newtext))
added repository name into issue tracker link to support different projects issues tracker mapping
r1868
Zachary Auclair
Allowing multiple issue servers to be autolinked in the changeset view;...
r2865 for pattern_index in valid_indices:
#518 multiple issues patterns...
r2866 ISSUE_PATTERN = conf.get('issue_pat%s' % pattern_index)
ISSUE_SERVER_LNK = conf.get('issue_server_link%s' % pattern_index)
ISSUE_PREFIX = conf.get('issue_prefix%s' % pattern_index)
Zachary Auclair
Allowing multiple issue servers to be autolinked in the changeset view;...
r2865
#518 multiple issues patterns...
r2866 log.debug('pattern suffix `%s` PAT:%s SERVER_LINK:%s PREFIX:%s'
% (pattern_index, ISSUE_PATTERN, ISSUE_SERVER_LNK,
ISSUE_PREFIX))
Zachary Auclair
Allowing multiple issue servers to be autolinked in the changeset view;...
r2865
URL_PAT = re.compile(r'%s' % ISSUE_PATTERN)
added repository name into issue tracker link to support different projects issues tracker mapping
r1868
#73 mapping of commited issues from commit message into issue tracker url.
r1837 def url_func(match_obj):
fixes issue with whitespace for referenced tasks in commit messages
r1912 pref = ''
if match_obj.group().startswith(' '):
pref = ' '
changed default issue tracker links pattern
r1933 issue_id = ''.join(match_obj.groups())
added class into issue tracker link
r1840 tmpl = (
fixes issue with whitespace for referenced tasks in commit messages
r1912 '%(pref)s<a class="%(cls)s" href="%(url)s">'
UI fixes...
r1865 '%(issue-prefix)s%(id-repr)s'
added class into issue tracker link
r1840 '</a>'
)
added repository name into issue tracker link to support different projects issues tracker mapping
r1868 url = ISSUE_SERVER_LNK.replace('{id}', issue_id)
if repository:
url = url.replace('{repo}', repository)
Added optional repo_name into issue tracker url to get just the name of repo without group prefix
r2339 repo_name = repository.split(URL_SEP)[-1]
url = url.replace('{repo_name}', repo_name)
Zachary Auclair
Allowing multiple issue servers to be autolinked in the changeset view;...
r2865
added links to revisions in commit messages
r1913 return tmpl % {
fixes issue with whitespace for referenced tasks in commit messages
r1912 'pref': pref,
added repository name into issue tracker link to support different projects issues tracker mapping
r1868 'cls': 'issue-tracker-link',
'url': url,
'id-repr': issue_id,
'issue-prefix': ISSUE_PREFIX,
'serv': ISSUE_SERVER_LNK,
added links to revisions in commit messages
r1913 }
Zachary Auclair
Allowing multiple issue servers to be autolinked in the changeset view;...
r2865 newtext = URL_PAT.sub(url_func, newtext)
#518 multiple issues patterns...
r2866 log.debug('processed prefix:`%s` => %s' % (pattern_index, newtext))
white space cleanup
r1944
Zachary Auclair
Allowing multiple issue servers to be autolinked in the changeset view;...
r2865 # if we actually did something above
don't check for url issue links, since we always want to linkify changeset into a repo link, fixes issue...
r2956 if link_:
# wrap not links into final link => link_
newtext = linkify_others(newtext, link_)
Don't catch all exceptions
r3631 except Exception:
#73 mapping of commited issues from commit message into issue tracker url.
r1837 log.error(traceback.format_exc())
pass
yet another fix for commit linkifications
r2966 return literal(newtext)
#77 code review...
r1670
added repository name into issue tracker link to support different projects issues tracker mapping
r1868
#77 code review...
r1670 def rst(source):
implements #308 rewrote diffs to enable displaying full diff on each file...
r1789 return literal('<div class="rst-block">%s</div>' %
garden
r1766 MarkupRenderer.rst(source))
implements #308 rewrote diffs to enable displaying full diff on each file...
r1789
added repository name into issue tracker link to support different projects issues tracker mapping
r1868
@mention highlighting
r1769 def rst_w_mentions(source):
"""
Wrapped rst renderer with @mention highlighting
auto white-space removal
r1818
@mention highlighting
r1769 :param source:
"""
implements #308 rewrote diffs to enable displaying full diff on each file...
r1789 return literal('<div class="rst-block">%s</div>' %
MarkupRenderer.rst_with_mentions(source))
Implemented initial code-review status of changesets
r2217
def changeset_status(repo, revision):
return ChangesetStatusModel().get_status(repo, revision)
added changeset status into changelog view
r2239
def changeset_status_lbl(changeset_status):
return dict(ChangesetStatus.STATUSES).get(changeset_status)
Better descriptions of given permission overview in edit user view
r2532
def get_permission_name(key):
return dict(Permission.PERMS).get(key)
final implementation of #210 journal filtering.
r3070
def journal_filter_help():
return _(textwrap.dedent('''
Example filter terms:
repository:vcs
username:marcin
action:*push*
ip:127.0.0.1
date:20120101
date:[20120101100000 TO 20120102]
Generate wildcards using '*' character:
"repositroy:vcs*" - search everything starting with 'vcs'
"repository:*vcs*" - search for repository containing 'vcs'
Optional AND / OR operators in queries
"repository:vcs OR repository:test"
"username:test AND repository:test*"
'''))
- #683 fixed difference between messages about not mapped repositories
r3110
def not_mapped_error(repo_name):
flash(_('%s repository is not mapped to db perhaps'
' it was created or renamed from the filesystem'
' please run the application again'
' in order to rescan repositories') % repo_name, category='error')
Added UserIpMap interface for allowed IP addresses and IP restriction access...
r3125
def ip_range(ip_addr):
from rhodecode.model.db import UserIpMap
s, e = UserIpMap._get_ip_range(ip_addr)
return '%s - %s' % (s, e)