changeset 602 | 1454282a8b45 |
parent 431 | 18b4dd650ef8 |
child 604 | e85042d18b48 |
582:0260b3b71d71 | 602:1454282a8b45 |
---|---|
21 from cubicweb.web import INTERNAL_FIELD_VALUE, eid_param, stdmsgs |
21 from cubicweb.web import INTERNAL_FIELD_VALUE, eid_param, stdmsgs |
22 from cubicweb.web.widgets import StaticComboBoxWidget |
22 from cubicweb.web.widgets import StaticComboBoxWidget |
23 from cubicweb.web.form import FormMixIn |
23 from cubicweb.web.form import FormMixIn |
24 |
24 |
25 _ = unicode |
25 _ = unicode |
26 |
26 |
27 def begin_form(w, entity, redirectvid, redirectpath=None, msg=None): |
27 def begin_form(w, entity, redirectvid, redirectpath=None, msg=None): |
28 w(u'<form method="post" action="%s">\n' % entity.req.build_url('edit')) |
28 w(u'<form method="post" action="%s">\n' % entity.req.build_url('edit')) |
29 w(u'<fieldset>\n') |
29 w(u'<fieldset>\n') |
30 w(u'<input type="hidden" name="__redirectvid" value="%s"/>\n' % redirectvid) |
30 w(u'<input type="hidden" name="__redirectvid" value="%s"/>\n' % redirectvid) |
31 w(u'<input type="hidden" name="__redirectpath" value="%s"/>\n' % ( |
31 w(u'<input type="hidden" name="__redirectpath" value="%s"/>\n' % ( |
40 |
40 |
41 class SecurityManagementView(EntityView): |
41 class SecurityManagementView(EntityView): |
42 """display security information for a given entity""" |
42 """display security information for a given entity""" |
43 id = 'security' |
43 id = 'security' |
44 title = _('security') |
44 title = _('security') |
45 |
45 |
46 def cell_call(self, row, col): |
46 def cell_call(self, row, col): |
47 self.req.add_js('cubicweb.edition.js') |
47 self.req.add_js('cubicweb.edition.js') |
48 self.req.add_css('cubicweb.acl.css') |
48 self.req.add_css('cubicweb.acl.css') |
49 entity = self.entity(row, col) |
49 entity = self.entity(row, col) |
50 w = self.w |
50 w = self.w |
51 _ = self.req._ |
51 _ = self.req._ |
52 w(u'<h1><span class="etype">%s</span> <a href="%s">%s</a></h1>' |
52 w(u'<h1><span class="etype">%s</span> <a href="%s">%s</a></h1>' |
53 % (entity.dc_type().capitalize(), |
53 % (entity.dc_type().capitalize(), |
88 w(u'<td>%s</td>' % u', '.join(l)) |
88 w(u'<td>%s</td>' % u', '.join(l)) |
89 rqlexprs = entity.e_schema.get_rqlexprs(access_type) |
89 rqlexprs = entity.e_schema.get_rqlexprs(access_type) |
90 w(u'<td>%s</td>' % u'<br/>'.join(expr.expression for expr in rqlexprs)) |
90 w(u'<td>%s</td>' % u'<br/>'.join(expr.expression for expr in rqlexprs)) |
91 w(u'</tr>\n') |
91 w(u'</tr>\n') |
92 w(u'</table>') |
92 w(u'</table>') |
93 |
93 |
94 def owned_by_edit_form(self, entity): |
94 def owned_by_edit_form(self, entity): |
95 self.w('<h3>%s</h3>' % self.req._('ownership')) |
95 self.w('<h3>%s</h3>' % self.req._('ownership')) |
96 begin_form(self.w, entity, 'security', msg= _('ownerships have been changed')) |
96 begin_form(self.w, entity, 'security', msg= _('ownerships have been changed')) |
97 self.w(u'<table border="0">\n') |
97 self.w(u'<table border="0">\n') |
98 self.w(u'<tr><td>\n') |
98 self.w(u'<tr><td>\n') |
167 wdg = newperm.get_widget('name') |
167 wdg = newperm.get_widget('name') |
168 w(u'<tr><td>%s</td>\n' % wdg.edit_render(newperm)) |
168 w(u'<tr><td>%s</td>\n' % wdg.edit_render(newperm)) |
169 wdg = newperm.get_widget('label') |
169 wdg = newperm.get_widget('label') |
170 w(u'<td>%s</td>\n' % wdg.edit_render(newperm)) |
170 w(u'<td>%s</td>\n' % wdg.edit_render(newperm)) |
171 wdg = newperm.get_widget('require_group') |
171 wdg = newperm.get_widget('require_group') |
172 w(u'<td>%s</td>\n' % wdg.edit_render(newperm)) |
172 w(u'<td>%s</td>\n' % wdg.edit_render(newperm)) |
173 w(u'<td>%s</td></tr>\n' % self.button_ok()) |
173 w(u'<td>%s</td></tr>\n' % self.button_ok()) |
174 w(u'</table>') |
174 w(u'</table>') |
175 w(u'</fieldset></form>\n') |
175 w(u'</fieldset></form>\n') |
176 |
176 |
177 def button_ok(self): |
177 def button_ok(self): |
178 return (u'<input class="validateButton" type="submit" name="submit" value="%s"/>' |
178 return (u'<input class="validateButton" type="submit" name="submit" value="%s"/>' |
179 % self.req._(stdmsgs.BUTTON_OK)) |
179 % self.req._(stdmsgs.BUTTON_OK)) |
180 |
180 |
181 |
181 |
182 class ErrorView(AnyRsetView): |
182 class ErrorView(AnyRsetView): |
183 """default view when no result has been found""" |
183 """default view when no result has been found""" |
184 __selectors__ = (yes,) |
184 __selectors__ = (yes,) |
185 id = 'error' |
185 id = 'error' |
186 |
186 |
187 def page_title(self): |
187 def page_title(self): |
188 """returns a title according to the result set - used for the |
188 """returns a title according to the result set - used for the |
189 title in the HTML header |
189 title in the HTML header |
190 """ |
190 """ |
191 return self.req._('an error occured') |
191 return self.req._('an error occured') |
192 |
192 |
193 def call(self): |
193 def call(self): |
194 req = self.req.reset_headers() |
194 req = self.req.reset_headers() |
195 _ = req._ |
195 _ = req._; w = self.w |
196 ex = req.data.get('ex')#_("unable to find exception information")) |
196 ex = req.data.get('ex')#_("unable to find exception information")) |
197 excinfo = req.data.get('excinfo') |
197 excinfo = req.data.get('excinfo') |
198 title = _('an error occured') |
198 title = _('an error occured') |
199 self.w(u'<h2>%s</h2>' % title) |
199 w(u'<h2>%s</h2>' % title) |
200 if 'errmsg' in req.data: |
200 if 'errmsg' in req.data: |
201 ex = req.data['errmsg'] |
201 ex = req.data['errmsg'] |
202 exclass = None |
202 exclass = None |
203 else: |
203 else: |
204 exclass = ex.__class__.__name__ |
204 exclass = ex.__class__.__name__ |
205 ex = exc_message(ex, req.encoding) |
205 ex = exc_message(ex, req.encoding) |
206 if excinfo is not None and self.config['print-traceback']: |
206 if excinfo is not None and self.config['print-traceback']: |
207 if exclass is None: |
207 if exclass is None: |
208 self.w(u'<div class="tb">%s</div>' |
208 w(u'<div class="tb">%s</div>' |
209 % html_escape(ex).replace("\n","<br />")) |
209 % html_escape(ex).replace("\n","<br />")) |
210 else: |
210 else: |
211 self.w(u'<div class="tb">%s: %s</div>' |
211 w(u'<div class="tb">%s: %s</div>' |
212 % (exclass, html_escape(ex).replace("\n","<br />"))) |
212 % (exclass, html_escape(ex).replace("\n","<br />"))) |
213 self.w(u'<hr />') |
213 w(u'<hr />') |
214 self.w(u'<div class="tb">%s</div>' % html_traceback(excinfo, ex, '')) |
214 w(u'<div class="tb">%s</div>' % html_traceback(excinfo, ex, '')) |
215 else: |
215 else: |
216 self.w(u'<div class="tb">%s</div>' % (html_escape(ex).replace("\n","<br />"))) |
216 w(u'<div class="tb">%s</div>' % (html_escape(ex).replace("\n","<br />"))) |
217 # if excinfo is not None, it's probably not a bug |
217 # if excinfo is not None, it's probably not a bug |
218 if excinfo is None: |
218 if excinfo is None: |
219 return |
219 return |
220 vcconf = self.config.vc_config() |
220 vcconf = self.config.vc_config() |
221 self.w(u"<div>") |
221 w(u"<div>") |
222 eversion = vcconf.get('cubicweb', _('no version information')) |
222 eversion = vcconf.get('cubicweb', _('no version information')) |
223 # NOTE: tuple wrapping needed since eversion is itself a tuple |
223 # NOTE: tuple wrapping needed since eversion is itself a tuple |
224 self.w(u"<b>CubicWeb version:</b> %s<br/>\n" % (eversion,)) |
224 w(u"<b>CubicWeb version:</b> %s<br/>\n" % (eversion,)) |
225 for pkg in self.config.cubes(): |
225 for pkg in self.config.cubes(): |
226 pkgversion = vcconf.get(pkg, _('no version information')) |
226 pkgversion = vcconf.get(pkg, _('no version information')) |
227 self.w(u"<b>Package %s version:</b> %s<br/>\n" % (pkg, pkgversion)) |
227 w(u"<b>Package %s version:</b> %s<br/>\n" % (pkg, pkgversion)) |
228 self.w(u"</div>") |
228 w(u"</div>") |
229 # creates a bug submission link if SUBMIT_URL is set |
229 # creates a bug submission link if SUBMIT_URL is set |
230 submiturl = self.config['submit-url'] |
230 submiturl = self.config['submit-url'] |
231 if submiturl: |
231 if submiturl: |
232 binfo = text_error_description(ex, excinfo, req, eversion, |
232 binfo = text_error_description(ex, excinfo, req, eversion, |
233 [(pkg, vcconf.get(pkg, _('no version information'))) |
233 [(pkg, vcconf.get(pkg, _('no version information'))) |
234 for pkg in self.config.cubes()]) |
234 for pkg in self.config.cubes()]) |
235 self.w(u'<form action="%s" method="post">\n' % html_escape(submiturl)) |
235 w(u'<form action="%s" method="post">\n' % html_escape(submiturl)) |
236 self.w(u'<fieldset>\n') |
236 w(u'<fieldset>\n') |
237 self.w(u'<textarea class="hidden" name="description">%s</textarea>' % html_escape(binfo)) |
237 w(u'<textarea class="hidden" name="description">%s</textarea>' % html_escape(binfo)) |
238 self.w(u'<input type="hidden" name="description_format" value="text/rest"/>') |
238 w(u'<input type="hidden" name="description_format" value="text/rest"/>') |
239 self.w(u'<input type="hidden" name="__bugreporting" value="1"/>') |
239 w(u'<input type="hidden" name="__bugreporting" value="1"/>') |
240 self.w(u'<input type="submit" value="%s"/>' % _('Submit bug report')) |
240 w(u'<input type="submit" value="%s"/>' % _('Submit bug report')) |
241 self.w(u'</fieldset>\n') |
241 w(u'</fieldset>\n') |
242 self.w(u'</form>\n') |
242 w(u'</form>\n') |
243 submitmail = self.config['submit-mail'] |
243 submitmail = self.config['submit-mail'] |
244 if submitmail: |
244 if submitmail: |
245 binfo = text_error_description(ex, excinfo, req, eversion, |
245 binfo = text_error_description(ex, excinfo, req, eversion, |
246 [(pkg, vcconf.get(pkg, _('no version information'))) |
246 [(pkg, vcconf.get(pkg, _('no version information'))) |
247 for pkg in self.config.cubes()]) |
247 for pkg in self.config.cubes()]) |
248 self.w(u'<form action="%s" method="post">\n' % req.build_url('reportbug')) |
248 w(u'<form action="%s" method="post">\n' % req.build_url('reportbug')) |
249 self.w(u'<fieldset>\n') |
249 w(u'<fieldset>\n') |
250 self.w(u'<input type="hidden" name="description" value="%s"/>' % html_escape(binfo)) |
250 w(u'<input type="hidden" name="description" value="%s"/>' % html_escape(binfo)) |
251 self.w(u'<input type="hidden" name="__bugreporting" value="1"/>') |
251 w(u'<input type="hidden" name="__bugreporting" value="1"/>') |
252 self.w(u'<input type="submit" value="%s"/>' % _('Submit bug report by mail')) |
252 w(u'<input type="submit" value="%s"/>' % _('Submit bug report by mail')) |
253 self.w(u'</fieldset>\n') |
253 w(u'</fieldset>\n') |
254 self.w(u'</form>\n') |
254 w(u'</form>\n') |
255 |
255 |
256 |
256 |
257 def exc_message(ex, encoding): |
257 def exc_message(ex, encoding): |
258 try: |
258 try: |
259 return unicode(ex) |
259 return unicode(ex) |
260 except: |
260 except: |
261 try: |
261 try: |
262 return unicode(str(ex), encoding, 'replace') |
262 return unicode(str(ex), encoding, 'replace') |
263 except: |
263 except: |
264 return unicode(repr(ex), encoding, 'replace') |
264 return unicode(repr(ex), encoding, 'replace') |
265 |
265 |
266 def text_error_description(ex, excinfo, req, eversion, cubes): |
266 def text_error_description(ex, excinfo, req, eversion, cubes): |
267 binfo = rest_traceback(excinfo, html_escape(ex)) |
267 binfo = rest_traceback(excinfo, html_escape(ex)) |
268 binfo += u'\n\n:URL: %s\n' % req.url() |
268 binfo += u'\n\n:URL: %s\n' % req.url() |
269 if not '__bugreporting' in req.form: |
269 if not '__bugreporting' in req.form: |
270 binfo += u'\n:form params:\n' |
270 binfo += u'\n:form params:\n' |
288 controller = 'edit' |
288 controller = 'edit' |
289 id = 'systemepropertiesform' |
289 id = 'systemepropertiesform' |
290 title = _('site configuration') |
290 title = _('site configuration') |
291 require_groups = ('managers',) |
291 require_groups = ('managers',) |
292 category = 'startupview' |
292 category = 'startupview' |
293 |
293 |
294 def linkable(self): |
294 def linkable(self): |
295 return True |
295 return True |
296 |
296 |
297 def url(self): |
297 def url(self): |
298 """return the url associated with this view. We can omit rql here""" |
298 """return the url associated with this view. We can omit rql here""" |
299 return self.build_url('view', vid=self.id) |
299 return self.build_url('view', vid=self.id) |
300 |
300 |
301 def call(self, **kwargs): |
301 def call(self, **kwargs): |
302 """The default view representing the application's index""" |
302 """The default view representing the application's index""" |
303 self.req.add_js('cubicweb.edition.js') |
303 self.req.add_js('cubicweb.edition.js') |
304 self.req.add_css('cubicweb.preferences.css') |
304 self.req.add_css('cubicweb.preferences.css') |
305 vreg = self.vreg |
305 vreg = self.vreg |
320 for group, keys in mainopts.items(): |
320 for group, keys in mainopts.items(): |
321 mainopts[group] = self.form(keys, False) |
321 mainopts[group] = self.form(keys, False) |
322 for group, objects in groupedopts.items(): |
322 for group, objects in groupedopts.items(): |
323 for oid, keys in objects.items(): |
323 for oid, keys in objects.items(): |
324 groupedopts[group][oid] = self.form(keys, True) |
324 groupedopts[group][oid] = self.form(keys, True) |
325 |
325 |
326 w = self.w |
326 w = self.w |
327 req = self.req |
327 req = self.req |
328 _ = req._ |
328 _ = req._ |
329 w(u'<h1>%s</h1>\n' % _(self.title)) |
329 w(u'<h1>%s</h1>\n' % _(self.title)) |
330 w(self.error_message()) |
330 w(self.error_message()) |
350 if doc != docmsgid: |
350 if doc != docmsgid: |
351 w(u'<p class="description">%s</p>' % html_escape(doc)) |
351 w(u'<p class="description">%s</p>' % html_escape(doc)) |
352 w(form) |
352 w(form) |
353 w(u'</fieldset>') |
353 w(u'</fieldset>') |
354 w(u'</div>') |
354 w(u'</div>') |
355 |
355 |
356 |
356 |
357 |
357 |
358 @property |
358 @property |
359 @cached |
359 @cached |
360 def eprops_rset(self): |
360 def eprops_rset(self): |
361 return self.req.execute('Any P,K,V WHERE P is EProperty, P pkey K, P value V, NOT P for_user U') |
361 return self.req.execute('Any P,K,V WHERE P is EProperty, P pkey K, P value V, NOT P for_user U') |
362 |
362 |
363 @property |
363 @property |
364 def defined_keys(self): |
364 def defined_keys(self): |
365 values = {} |
365 values = {} |
366 for i, entity in enumerate(self.eprops_rset.entities()): |
366 for i, entity in enumerate(self.eprops_rset.entities()): |
367 values[entity.pkey] = i |
367 values[entity.pkey] = i |
368 return values |
368 return values |
369 |
369 |
370 def entity_for_key(self, key): |
370 def entity_for_key(self, key): |
371 values = self.defined_keys |
371 values = self.defined_keys |
372 if key in values: |
372 if key in values: |
373 entity = self.eprops_rset.get_entity(values[key], 0) |
373 entity = self.eprops_rset.get_entity(values[key], 0) |
374 else: |
374 else: |
389 if '?' in path: |
389 if '?' in path: |
390 path, params = path.split('?', 1) |
390 path, params = path.split('?', 1) |
391 w(u'<input type="hidden" name="__redirectparams" value="%s"/>\n' |
391 w(u'<input type="hidden" name="__redirectparams" value="%s"/>\n' |
392 % html_escape(params)) |
392 % html_escape(params)) |
393 w(u'<input type="hidden" name="__redirectpath" value="%s"/>\n' % path) |
393 w(u'<input type="hidden" name="__redirectpath" value="%s"/>\n' % path) |
394 #w(u'<input type="hidden" name="__redirectrql" value=""/>\n') |
394 #w(u'<input type="hidden" name="__redirectrql" value=""/>\n') |
395 w(u'<input type="hidden" name="__message" value="%s"/>\n' |
395 w(u'<input type="hidden" name="__message" value="%s"/>\n' |
396 % self.req._('changes applied')) |
396 % self.req._('changes applied')) |
397 w(u'<table><tr><td>\n') |
397 w(u'<table><tr><td>\n') |
398 |
398 |
399 w(u'<table>\n') |
399 w(u'<table>\n') |
400 for key in keys: |
400 for key in keys: |
401 w(u'<tr>\n') |
401 w(u'<tr>\n') |
402 self.form_row(w, key, splitlabel) |
402 self.form_row(w, key, splitlabel) |
403 w(u'</tr>\n') |
403 w(u'</tr>\n') |
407 w(self.button_cancel()) |
407 w(self.button_cancel()) |
408 w(u'</td></tr></table>\n') |
408 w(u'</td></tr></table>\n') |
409 w(u'</fieldset>\n') |
409 w(u'</fieldset>\n') |
410 w(u'</form>\n') |
410 w(u'</form>\n') |
411 return stream.getvalue() |
411 return stream.getvalue() |
412 |
412 |
413 def form_row(self, w, key, splitlabel): |
413 def form_row(self, w, key, splitlabel): |
414 entity = self.entity_for_key(key) |
414 entity = self.entity_for_key(key) |
415 eid = entity.eid |
415 eid = entity.eid |
416 if splitlabel: |
416 if splitlabel: |
417 w(u'<td class="label">%s</td>' % self.req._(key.split('.')[-1])) |
417 w(u'<td class="label">%s</td>' % self.req._(key.split('.')[-1])) |
432 w(u'<input type="hidden" name="eid" value="%s"/>' % eid) |
432 w(u'<input type="hidden" name="eid" value="%s"/>' % eid) |
433 w(u'<input type="hidden" name="%s" value="EProperty"/>' % eid_param('__type', eid)) |
433 w(u'<input type="hidden" name="%s" value="EProperty"/>' % eid_param('__type', eid)) |
434 w(u'<input type="hidden" name="%s" value="%s"/>' % (eid_param('pkey', eid), key)) |
434 w(u'<input type="hidden" name="%s" value="%s"/>' % (eid_param('pkey', eid), key)) |
435 w(u'<input type="hidden" name="%s" value="%s"/>' % (eid_param('edits-pkey', eid), '')) |
435 w(u'<input type="hidden" name="%s" value="%s"/>' % (eid_param('edits-pkey', eid), '')) |
436 |
436 |
437 |
437 |
438 class EpropertiesForm(SystemEpropertiesForm): |
438 class EpropertiesForm(SystemEpropertiesForm): |
439 id = 'epropertiesform' |
439 id = 'epropertiesform' |
440 title = _('preferences') |
440 title = _('preferences') |
441 require_groups = ('users', 'managers') # we don't want guests to be able to come here |
441 require_groups = ('users', 'managers') # we don't want guests to be able to come here |
442 __selectors__ = chainfirst(none_rset, |
442 __selectors__ = chainfirst(none_rset, |
443 chainall(one_line_rset, accept_rset)), |
443 chainall(one_line_rset, accept_rset)), |
444 accepts = ('EUser',) |
444 accepts = ('EUser',) |
445 |
445 |
447 def accept_rset(cls, req, rset, row, col): |
447 def accept_rset(cls, req, rset, row, col): |
448 if row is None: |
448 if row is None: |
449 row = 0 |
449 row = 0 |
450 score = super(EpropertiesForm, cls).accept_rset(req, rset, row, col) |
450 score = super(EpropertiesForm, cls).accept_rset(req, rset, row, col) |
451 # check current user is the rset user or he is in the managers group |
451 # check current user is the rset user or he is in the managers group |
452 if score and (req.user.eid == rset[row][col or 0] |
452 if score and (req.user.eid == rset[row][col or 0] |
453 or req.user.matching_groups('managers')): |
453 or req.user.matching_groups('managers')): |
454 return score |
454 return score |
455 return 0 |
455 return 0 |
456 |
456 |
457 @property |
457 @property |
458 def user(self): |
458 def user(self): |
459 if self.rset is None: |
459 if self.rset is None: |
460 return self.req.user |
460 return self.req.user |
461 return self.rset.get_entity(self.row or 0, self.col or 0) |
461 return self.rset.get_entity(self.row or 0, self.col or 0) |
462 |
462 |
463 @property |
463 @property |
464 @cached |
464 @cached |
465 def eprops_rset(self): |
465 def eprops_rset(self): |
466 return self.req.execute('Any P,K,V WHERE P is EProperty, P pkey K, P value V,' |
466 return self.req.execute('Any P,K,V WHERE P is EProperty, P pkey K, P value V,' |
467 'P for_user U, U eid %(x)s', {'x': self.user.eid}) |
467 'P for_user U, U eid %(x)s', {'x': self.user.eid}) |
474 eid = entity.eid |
474 eid = entity.eid |
475 w(u'<input type="hidden" name="%s" value="%s"/>' |
475 w(u'<input type="hidden" name="%s" value="%s"/>' |
476 % (eid_param('edits-for_user', eid), INTERNAL_FIELD_VALUE)) |
476 % (eid_param('edits-for_user', eid), INTERNAL_FIELD_VALUE)) |
477 w(u'<input type="hidden" name="%s" value="%s"/>' |
477 w(u'<input type="hidden" name="%s" value="%s"/>' |
478 % (eid_param('for_user', eid), self.user.eid)) |
478 % (eid_param('for_user', eid), self.user.eid)) |
479 |
479 |
480 |
480 |
481 |
481 |
482 |
482 |
483 class ProcessInformationView(StartupView): |
483 class ProcessInformationView(StartupView): |
484 id = 'info' |
484 id = 'info' |
485 title = _('server information') |
485 title = _('server information') |
486 require_groups = ('managers',) |
486 require_groups = ('managers',) |