Files
@ f5c1eec9f376
Branch filter:
Location: kallithea/pylons_app/lib/helpers.py - annotation
f5c1eec9f376
12.0 KiB
text/x-python
rename repo2perm into repo_to_perm
added UserToPerm models for user global permissions
added UserToPerm models for user global permissions
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 | 564e40829f80 564e40829f80 564e40829f80 564e40829f80 564e40829f80 be4621c6de58 be4621c6de58 ea893ffb7f00 be0096a02772 be4621c6de58 be4621c6de58 cd2ee462fc2c 01d0f363f36d be4621c6de58 be4621c6de58 be4621c6de58 cd2ee462fc2c be4621c6de58 be4621c6de58 be4621c6de58 564e40829f80 564e40829f80 be4621c6de58 be4621c6de58 cd2ee462fc2c 564e40829f80 01d0f363f36d cd2ee462fc2c 564e40829f80 564e40829f80 564e40829f80 564e40829f80 564e40829f80 564e40829f80 564e40829f80 2e1247e62c5b 564e40829f80 564e40829f80 2e1247e62c5b 564e40829f80 564e40829f80 cd2ee462fc2c 564e40829f80 564e40829f80 564e40829f80 564e40829f80 564e40829f80 564e40829f80 564e40829f80 564e40829f80 cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c c4caeca9dd66 c4caeca9dd66 cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c c4caeca9dd66 d7aeae23c56d c4caeca9dd66 c4caeca9dd66 c4caeca9dd66 c4caeca9dd66 c4caeca9dd66 cd2ee462fc2c cd2ee462fc2c 6603c9891b91 cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c d7aeae23c56d d7aeae23c56d cd2ee462fc2c d7aeae23c56d cd2ee462fc2c 6603c9891b91 d7aeae23c56d d7aeae23c56d d7aeae23c56d d7aeae23c56d d7aeae23c56d d7aeae23c56d d7aeae23c56d d7aeae23c56d d7aeae23c56d d7aeae23c56d d7aeae23c56d 6603c9891b91 d7aeae23c56d 68dc70295a76 d7aeae23c56d d7aeae23c56d d7aeae23c56d d7aeae23c56d d7aeae23c56d d7aeae23c56d d7aeae23c56d d7aeae23c56d d7aeae23c56d d7aeae23c56d d7aeae23c56d d7aeae23c56d d7aeae23c56d d7aeae23c56d d7aeae23c56d d7aeae23c56d d7aeae23c56d d7aeae23c56d d7aeae23c56d d7aeae23c56d d7aeae23c56d d7aeae23c56d 68dc70295a76 68dc70295a76 68dc70295a76 68dc70295a76 68dc70295a76 68dc70295a76 d7aeae23c56d d7aeae23c56d d7aeae23c56d 6603c9891b91 cd2ee462fc2c d7aeae23c56d 6603c9891b91 6603c9891b91 6603c9891b91 6603c9891b91 6603c9891b91 6603c9891b91 cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c 2dc0c8e4f384 2dc0c8e4f384 2dc0c8e4f384 5827c739b0bd 5827c739b0bd 5827c739b0bd 5827c739b0bd 2dc0c8e4f384 2dc0c8e4f384 2dc0c8e4f384 5827c739b0bd 5827c739b0bd 5827c739b0bd 5827c739b0bd be0096a02772 2dc0c8e4f384 01d0f363f36d cd2ee462fc2c cd2ee462fc2c be4621c6de58 ea893ffb7f00 be4621c6de58 be4621c6de58 ea893ffb7f00 be4621c6de58 ea893ffb7f00 be4621c6de58 ea893ffb7f00 be4621c6de58 be4621c6de58 ea893ffb7f00 be4621c6de58 ea893ffb7f00 ea893ffb7f00 be4621c6de58 be4621c6de58 ea893ffb7f00 ea893ffb7f00 ea893ffb7f00 ea893ffb7f00 ea893ffb7f00 ea893ffb7f00 cd2ee462fc2c be4621c6de58 be4621c6de58 cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c cd2ee462fc2c be4621c6de58 6ada8c223374 6ada8c223374 6ada8c223374 6ada8c223374 6ada8c223374 6ada8c223374 0e5455fda8fd 6ada8c223374 6ada8c223374 6ada8c223374 cd2ee462fc2c 564e40829f80 237470e64bb8 237470e64bb8 237470e64bb8 237470e64bb8 237470e64bb8 237470e64bb8 237470e64bb8 237470e64bb8 237470e64bb8 237470e64bb8 237470e64bb8 237470e64bb8 237470e64bb8 237470e64bb8 237470e64bb8 237470e64bb8 237470e64bb8 237470e64bb8 237470e64bb8 237470e64bb8 237470e64bb8 237470e64bb8 504feff57b49 504feff57b49 504feff57b49 504feff57b49 504feff57b49 237470e64bb8 8c50b164fb58 8c50b164fb58 8c50b164fb58 8c50b164fb58 8c50b164fb58 237470e64bb8 8c50b164fb58 8c50b164fb58 8c50b164fb58 8c50b164fb58 8c50b164fb58 8c50b164fb58 8c50b164fb58 8c50b164fb58 8c50b164fb58 8c50b164fb58 8c50b164fb58 8c50b164fb58 8c50b164fb58 8c50b164fb58 8c50b164fb58 | """Helper functions
Consists of functions to typically be used within templates, but also
available to Controllers. This module is available to both as 'h'.
"""
from pygments.formatters import HtmlFormatter
from pygments import highlight as code_highlight
from pylons import url, app_globals as g
from pylons.i18n.translation import _, ungettext
from vcs.utils.annotate import annotate_highlight
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
#Custom helpers here :)
class _Link(object):
'''
Make a url based on label and url with help of url_for
@param label:name of link if not defined url is used
@param url: the url for link
'''
def __call__(self, label='', *url_, **urlargs):
if label is None or '':
label = url
link_fn = link_to(label, url(*url_, **urlargs))
return link_fn
link = _Link()
class _GetError(object):
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 literal(wrap_paragraphs(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 not have and id autgenerate 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,
});
//Mouse Over event disabled for new repositories since they dont
//have last commit message
myToolTips.contextMouseOverEvent.subscribe(
function(type, args) {
var context = args[0];
var txt = context.getAttribute('tooltip_title');
if(txt){
return true;
}
else{
return false;
}
});
// Set the text for the tooltip just before we display it. Lazy method
myToolTips.contextTriggerEvent.subscribe(
function(type, args) {
var context = args[0];
var txt = context.getAttribute('tooltip_title');
this.cfg.setProperty("text", txt);
// positioning of tooltip
var tt_w = this.element.clientWidth;
var tt_h = this.element.clientHeight;
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 = 'top';
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):
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, 1):
if p != '':
url_l.append(link_to(p, url('files_home',
repo_name=repo_name,
revision=rev,
f_path='/'.join(paths_l[:cnt]))))
return literal(' / '.join(url_l))
files_breadcrumbs = _FilesBreadCrumbs()
def pygmentize(filenode, **kwargs):
"""
pygmentize function using pygments
@param filenode:
"""
return literal(code_highlight(filenode.content, filenode.lexer, HtmlFormatter(**kwargs)))
def pygmentize_annotation(filenode, **kwargs):
"""
pygmentize function for annotation
@param filenode:
"""
color_dict = g.changeset_annotation_colors
def gen_color():
import random
return [str(random.randrange(10, 235)) for _ in xrange(3)]
def get_color_string(cs):
if color_dict.has_key(cs):
col = color_dict[cs]
else:
color_dict[cs] = gen_color()
col = color_dict[cs]
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 = 'r%s:%s' % (changeset.revision,
changeset.raw_id)
uri = link_to(
lnk_format,
url('changeset_home', repo_name='test',
revision=changeset.raw_id),
style=get_color_string(changeset.raw_id),
class_='tooltip',
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
"""
slug = urlify(value)
for c in """=[]\;'"<>,/~!@#$%^&*()+{}|:""":
slug = slug.replace(c, '-')
slug = recursive_replace(slug, '-')
return slug
flash = _Flash()
#===============================================================================
# MERCURIAL FILTERS available via h.
#===============================================================================
from mercurial import util
from mercurial.templatefilters import age as _age, person as _person
age = lambda x:_age(x)
capitalize = lambda x: x.capitalize()
date = lambda x: util.datestr(x)
email = util.email
person = lambda x: _person(x)
hgdate = lambda x: "%d %d" % x
isodate = lambda x: util.datestr(x, '%Y-%m-%d %H:%M %1%2')
isodatesec = lambda x: util.datestr(x, '%Y-%m-%d %H:%M:%S %1%2')
localdate = lambda x: (x[0], util.makedate()[1])
rfc822date = lambda x: util.datestr(x, "%a, %d %b %Y %H:%M:%S %1%2")
rfc3339date = lambda x: util.datestr(x, "%Y-%m-%dT%H:%M:%S%1:%2")
time_ago = lambda x: util.datestr(_age(x), "%a, %d %b %Y %H:%M:%S %1%2")
#===============================================================================
# PERMS
#===============================================================================
from pylons_app.lib.auth import HasPermissionAny, HasPermissionAll, \
HasRepoPermissionAny, HasRepoPermissionAll
#===============================================================================
# GRAVATAR URL
#===============================================================================
import hashlib
import urllib
def gravatar_url(email):
ssl_enabled = 'https' == request.environ.get('HTTP_X_URL_SCHEME')
default = 'identicon'
size = 32
baseurl_nossl = "http://www.gravatar.com/avatar/"
baseurl_ssl = "https://secure.gravatar.com/avatar/"
baseurl = baseurl_ssl if ssl_enabled else baseurl_nossl
# construct the url
gravatar_url = baseurl + hashlib.md5(email.lower()).hexdigest() + "?"
gravatar_url += urllib.urlencode({'d':default, 's':str(size)})
return gravatar_url
|