##// END OF EJS Templates
added permission functions to webhelpers, updated dbmanage permissions
marcink -
r307:504feff5 default
parent child Browse files
Show More
@@ -1,142 +1,143 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 # database managment for hg app
4 4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
5 5
6 6 # This program is free software; you can redistribute it and/or
7 7 # modify it under the terms of the GNU General Public License
8 8 # as published by the Free Software Foundation; version 2
9 9 # of the License or (at your opinion) any later version of the license.
10 10 #
11 11 # This program is distributed in the hope that it will be useful,
12 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 14 # GNU General Public License for more details.
15 15 #
16 16 # You should have received a copy of the GNU General Public License
17 17 # along with this program; if not, write to the Free Software
18 18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 19 # MA 02110-1301, USA.
20 20
21 21 """
22 22 Created on April 10, 2010
23 23 database managment and creation for hg app
24 24 @author: marcink
25 25 """
26 26
27 27 from os.path import dirname as dn, join as jn
28 28 import os
29 29 import sys
30 30 ROOT = dn(dn(dn(os.path.realpath(__file__))))
31 31 sys.path.append(ROOT)
32 32
33 33 from pylons_app.lib.auth import get_crypt_password
34 34 from pylons_app.model import init_model
35 35 from pylons_app.model.db import User, Permission
36 36 from pylons_app.model.meta import Session, Base
37 37 from sqlalchemy.engine import create_engine
38 38 import logging
39 39
40 40 log = logging.getLogger('db manage')
41 41 log.setLevel(logging.DEBUG)
42 42 console_handler = logging.StreamHandler()
43 43 console_handler.setFormatter(logging.Formatter("%(asctime)s.%(msecs)03d"
44 44 " %(levelname)-5.5s [%(name)s] %(message)s"))
45 45 log.addHandler(console_handler)
46 46
47 47 class DbManage(object):
48 48 def __init__(self, log_sql):
49 49 self.dbname = 'hg_app.db'
50 50 dburi = 'sqlite:////%s' % jn(ROOT, self.dbname)
51 51 engine = create_engine(dburi, echo=log_sql)
52 52 init_model(engine)
53 53 self.sa = Session()
54 54 self.db_exists = False
55 55
56 56 def check_for_db(self, override):
57 57 log.info('checking for exisiting db')
58 58 if os.path.isfile(jn(ROOT, self.dbname)):
59 59 self.db_exists = True
60 60 log.info('database exisist')
61 61 if not override:
62 62 raise Exception('database already exists')
63 63
64 64 def create_tables(self, override=False):
65 65 """
66 66 Create a auth database
67 67 """
68 68 self.check_for_db(override)
69 69 if override:
70 70 log.info("database exisist and it's going to be destroyed")
71 71 if self.db_exists:
72 72 os.remove(jn(ROOT, self.dbname))
73 73 Base.metadata.create_all(checkfirst=override)
74 74 log.info('Created tables for %s', self.dbname)
75 75
76 76 def admin_prompt(self):
77 77 import getpass
78 78 username = raw_input('Specify admin username:')
79 79 password = getpass.getpass('Specify admin password:')
80 80 self.create_user(username, password, True)
81 81
82 82 def create_user(self, username, password, admin=False):
83 83
84 84 log.info('creating default user')
85 85 #create default user for handling default permissions.
86 86 def_user = User()
87 87 def_user.username = 'default'
88 88 def_user.password = 'default'
89 89 def_user.name = 'default'
90 90 def_user.lastname = 'default'
91 91 def_user.email = 'default@default'
92 92 def_user.admin = False
93 93 def_user.active = False
94 94
95 95 self.sa.add(def_user)
96 96
97 97 log.info('creating administrator user %s', username)
98 98 new_user = User()
99 99 new_user.username = username
100 100 new_user.password = get_crypt_password(password)
101 101 new_user.name = 'Hg'
102 102 new_user.lastname = 'Admin'
103 103 new_user.email = 'admin@localhost'
104 104 new_user.admin = admin
105 105 new_user.active = True
106 106
107 107 try:
108 108 self.sa.add(new_user)
109 109 self.sa.commit()
110 110 except:
111 111 self.sa.rollback()
112 112 raise
113 113
114 114 def create_permissions(self):
115 115 #module.(access|create|change|delete)_[name]
116 116 #module.(read|write|owner)
117 117 perms = [('repository.none', 'Repository no access'),
118 118 ('repository.read', 'Repository read access'),
119 119 ('repository.write', 'Repository write access'),
120 120 ('repository.admin', 'Repository admin access'),
121 ('hg.admin', 'Hg Administrator'),
121 122 ]
122 123
123 124 for p in perms:
124 125 new_perm = Permission()
125 126 new_perm.permission_name = p[0]
126 127 new_perm.permission_longname = p[1]
127 128 try:
128 129 self.sa.add(new_perm)
129 130 self.sa.commit()
130 131 except:
131 132 self.sa.rollback()
132 133 raise
133 134
134 135
135 136
136 137 if __name__ == '__main__':
137 138 dbmanage = DbManage(log_sql=True)
138 139 dbmanage.create_tables(override=True)
139 140 dbmanage.admin_prompt()
140 141 dbmanage.create_permissions()
141 142
142 143
@@ -1,300 +1,305 b''
1 1 """Helper functions
2 2
3 3 Consists of functions to typically be used within templates, but also
4 4 available to Controllers. This module is available to both as 'h'.
5 5 """
6 6 from pygments.formatters import HtmlFormatter
7 7 from pygments import highlight as code_highlight
8 8 from pylons import url, app_globals as g
9 9 from pylons.i18n.translation import _, ungettext
10 10 from vcs.utils.annotate import annotate_highlight
11 11 from webhelpers.html import literal, HTML, escape
12 12 from webhelpers.html.tools import *
13 13 from webhelpers.html.builder import make_tag
14 14 from webhelpers.html.tags import auto_discovery_link, checkbox, css_classes, \
15 15 end_form, file, form, hidden, image, javascript_link, link_to, link_to_if, \
16 16 link_to_unless, ol, required_legend, select, stylesheet_link, submit, text, \
17 17 password, textarea, title, ul, xml_declaration, radio
18 18 from webhelpers.html.tools import auto_link, button_to, highlight, js_obfuscate, \
19 19 mail_to, strip_links, strip_tags, tag_re
20 20 from webhelpers.number import format_byte_size, format_bit_size
21 21 from webhelpers.pylonslib import Flash as _Flash
22 22 from webhelpers.pylonslib.secure_form import secure_form
23 23 from webhelpers.text import chop_at, collapse, convert_accented_entities, \
24 24 convert_misc_entities, lchop, plural, rchop, remove_formatting, \
25 25 replace_whitespace, urlify, truncate, wrap_paragraphs
26 26
27 27
28 28 #Custom helpers here :)
29 29 class _Link(object):
30 30 '''
31 31 Make a url based on label and url with help of url_for
32 32 @param label:name of link if not defined url is used
33 33 @param url: the url for link
34 34 '''
35 35
36 36 def __call__(self, label='', *url_, **urlargs):
37 37 if label is None or '':
38 38 label = url
39 39 link_fn = link_to(label, url(*url_, **urlargs))
40 40 return link_fn
41 41
42 42 link = _Link()
43 43
44 44 class _GetError(object):
45 45
46 46 def __call__(self, field_name, form_errors):
47 47 tmpl = """<span class="error_msg">%s</span>"""
48 48 if form_errors and form_errors.has_key(field_name):
49 49 return literal(tmpl % form_errors.get(field_name))
50 50
51 51 get_error = _GetError()
52 52
53 53 def recursive_replace(str, replace=' '):
54 54 """
55 55 Recursive replace of given sign to just one instance
56 56 @param str: given string
57 57 @param replace:char to find and replace multiple instances
58 58
59 59 Examples::
60 60 >>> recursive_replace("Mighty---Mighty-Bo--sstones",'-')
61 61 'Mighty-Mighty-Bo-sstones'
62 62 """
63 63
64 64 if str.find(replace * 2) == -1:
65 65 return str
66 66 else:
67 67 str = str.replace(replace * 2, replace)
68 68 return recursive_replace(str, replace)
69 69
70 70 class _ToolTip(object):
71 71
72 72 def __call__(self, tooltip_title, trim_at=50):
73 73 """
74 74 Special function just to wrap our text into nice formatted autowrapped
75 75 text
76 76 @param tooltip_title:
77 77 """
78 78
79 79 return literal(wrap_paragraphs(tooltip_title, trim_at)\
80 80 .replace('\n', '<br/>'))
81 81
82 82 def activate(self):
83 83 """
84 84 Adds tooltip mechanism to the given Html all tooltips have to have
85 85 set class tooltip and set attribute tooltip_title.
86 86 Then a tooltip will be generated based on that
87 87 All with yui js tooltip
88 88 """
89 89
90 90 js = '''
91 91 YAHOO.util.Event.onDOMReady(function(){
92 92 function toolTipsId(){
93 93 var ids = [];
94 94 var tts = YAHOO.util.Dom.getElementsByClassName('tooltip');
95 95
96 96 for (var i = 0; i < tts.length; i++) {
97 97 //if element doesn not have and id autgenerate one for tooltip
98 98
99 99 if (!tts[i].id){
100 100 tts[i].id='tt'+i*100;
101 101 }
102 102 ids.push(tts[i].id);
103 103 }
104 104 return ids
105 105 };
106 106 var myToolTips = new YAHOO.widget.Tooltip("tooltip", {
107 107 context: toolTipsId(),
108 108 monitorresize:false,
109 109 xyoffset :[0,0],
110 110 autodismissdelay:300000,
111 111 hidedelay:5,
112 112 showdelay:20,
113 113 });
114 114
115 115 //Mouse Over event disabled for new repositories since they dont
116 116 //have last commit message
117 117 myToolTips.contextMouseOverEvent.subscribe(
118 118 function(type, args) {
119 119 var context = args[0];
120 120 var txt = context.getAttribute('tooltip_title');
121 121 if(txt){
122 122 return true;
123 123 }
124 124 else{
125 125 return false;
126 126 }
127 127 });
128 128
129 129
130 130 // Set the text for the tooltip just before we display it. Lazy method
131 131 myToolTips.contextTriggerEvent.subscribe(
132 132 function(type, args) {
133 133
134 134
135 135 var context = args[0];
136 136
137 137 var txt = context.getAttribute('tooltip_title');
138 138 this.cfg.setProperty("text", txt);
139 139
140 140
141 141 // positioning of tooltip
142 142 var tt_w = this.element.clientWidth;
143 143 var tt_h = this.element.clientHeight;
144 144
145 145 var context_w = context.offsetWidth;
146 146 var context_h = context.offsetHeight;
147 147
148 148 var pos_x = YAHOO.util.Dom.getX(context);
149 149 var pos_y = YAHOO.util.Dom.getY(context);
150 150
151 151 var display_strategy = 'top';
152 152 var xy_pos = [0,0];
153 153 switch (display_strategy){
154 154
155 155 case 'top':
156 156 var cur_x = (pos_x+context_w/2)-(tt_w/2);
157 157 var cur_y = pos_y-tt_h-4;
158 158 xy_pos = [cur_x,cur_y];
159 159 break;
160 160 case 'bottom':
161 161 var cur_x = (pos_x+context_w/2)-(tt_w/2);
162 162 var cur_y = pos_y+context_h+4;
163 163 xy_pos = [cur_x,cur_y];
164 164 break;
165 165 case 'left':
166 166 var cur_x = (pos_x-tt_w-4);
167 167 var cur_y = pos_y-((tt_h/2)-context_h/2);
168 168 xy_pos = [cur_x,cur_y];
169 169 break;
170 170 case 'right':
171 171 var cur_x = (pos_x+context_w+4);
172 172 var cur_y = pos_y-((tt_h/2)-context_h/2);
173 173 xy_pos = [cur_x,cur_y];
174 174 break;
175 175 default:
176 176 var cur_x = (pos_x+context_w/2)-(tt_w/2);
177 177 var cur_y = pos_y-tt_h-4;
178 178 xy_pos = [cur_x,cur_y];
179 179 break;
180 180
181 181 }
182 182
183 183 this.cfg.setProperty("xy",xy_pos);
184 184
185 185 });
186 186
187 187 //Mouse out
188 188 myToolTips.contextMouseOutEvent.subscribe(
189 189 function(type, args) {
190 190 var context = args[0];
191 191
192 192 });
193 193 });
194 194 '''
195 195 return literal(js)
196 196
197 197 tooltip = _ToolTip()
198 198
199 199 class _FilesBreadCrumbs(object):
200 200
201 201 def __call__(self, repo_name, rev, paths):
202 202 url_l = [link_to(repo_name, url('files_home',
203 203 repo_name=repo_name,
204 204 revision=rev, f_path=''))]
205 205 paths_l = paths.split('/')
206 206
207 207 for cnt, p in enumerate(paths_l, 1):
208 208 if p != '':
209 209 url_l.append(link_to(p, url('files_home',
210 210 repo_name=repo_name,
211 211 revision=rev,
212 212 f_path='/'.join(paths_l[:cnt]))))
213 213
214 214 return literal(' / '.join(url_l))
215 215
216 216 files_breadcrumbs = _FilesBreadCrumbs()
217 217
218 218 def pygmentize(filenode, **kwargs):
219 219 """
220 220 pygmentize function using pygments
221 221 @param filenode:
222 222 """
223 223 return literal(code_highlight(filenode.content, filenode.lexer, HtmlFormatter(**kwargs)))
224 224
225 225 def pygmentize_annotation(filenode, **kwargs):
226 226 """
227 227 pygmentize function for annotation
228 228 @param filenode:
229 229 """
230 230
231 231 color_dict = g.changeset_annotation_colors
232 232 def gen_color():
233 233 import random
234 234 return [str(random.randrange(10, 235)) for _ in xrange(3)]
235 235 def get_color_string(cs):
236 236 if color_dict.has_key(cs):
237 237 col = color_dict[cs]
238 238 else:
239 239 color_dict[cs] = gen_color()
240 240 col = color_dict[cs]
241 241 return "color: rgb(%s) ! important;" % (', '.join(col))
242 242
243 243 def url_func(changeset):
244 244 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>"
245 245
246 246 tooltip_html = tooltip_html % (changeset.author,
247 247 changeset.date,
248 248 tooltip(changeset.message))
249 249 lnk_format = 'r%s:%s' % (changeset.revision,
250 250 changeset.raw_id)
251 251 uri = link_to(
252 252 lnk_format,
253 253 url('changeset_home', repo_name='test',
254 254 revision=changeset.raw_id),
255 255 style=get_color_string(changeset.raw_id),
256 256 class_='tooltip',
257 257 tooltip_title=tooltip_html
258 258 )
259 259
260 260 uri += '\n'
261 261 return uri
262 262 return literal(annotate_highlight(filenode, url_func, **kwargs))
263 263
264 264 def repo_name_slug(value):
265 265 """
266 266 Return slug of name of repository
267 267 """
268 268 slug = urlify(value)
269 269 for c in """=[]\;'"<>,/~!@#$%^&*()+{}|:""":
270 270 slug = slug.replace(c, '-')
271 271 slug = recursive_replace(slug, '-')
272 272 return slug
273 273
274 274 flash = _Flash()
275 275
276 276
277 277 #===============================================================================
278 278 # MERCURIAL FILTERS available via h.
279 279 #===============================================================================
280 280
281 281
282 282 from mercurial import util
283 283 from mercurial.templatefilters import age as _age, person as _person
284 284
285 285 age = lambda x:_age(x)
286 286 capitalize = lambda x: x.capitalize()
287 287 date = lambda x: util.datestr(x)
288 288 email = util.email
289 289 person = lambda x: _person(x)
290 290 hgdate = lambda x: "%d %d" % x
291 291 isodate = lambda x: util.datestr(x, '%Y-%m-%d %H:%M %1%2')
292 292 isodatesec = lambda x: util.datestr(x, '%Y-%m-%d %H:%M:%S %1%2')
293 293 localdate = lambda x: (x[0], util.makedate()[1])
294 294 rfc822date = lambda x: util.datestr(x, "%a, %d %b %Y %H:%M:%S %1%2")
295 295 rfc3339date = lambda x: util.datestr(x, "%Y-%m-%dT%H:%M:%S%1:%2")
296 296 time_ago = lambda x: util.datestr(_age(x), "%a, %d %b %Y %H:%M:%S %1%2")
297 297
298 298
299 #===============================================================================
300 # PERMS
301 #===============================================================================
302 from pylons_app.lib.auth import HasPermissionAny, HasPermissionAll, \
303 HasRepoPermissionAny, HasRepoPermissionAll
299 304
300 305
General Comments 0
You need to be logged in to leave comments. Login now