248 |
248 |
return is_accessible('workflows')
|
249 |
249 |
|
250 |
250 |
|
251 |
|
class RootDirectory(BackofficeRootDirectory):
|
252 |
|
_q_exports = ['', 'management', 'pending', 'statistics']
|
253 |
|
|
254 |
|
bounces = wcs.admin.bounces.BouncesDirectory()
|
255 |
|
categories = wcs.admin.categories.CategoriesDirectory()
|
256 |
|
forms = wcs.admin.forms.FormsDirectory()
|
257 |
|
logger = wcs.admin.logger.LoggerDirectory()
|
258 |
|
roles = wcs.admin.roles.RolesDirectory()
|
259 |
|
settings = wcs.admin.settings.SettingsDirectory()
|
260 |
|
users = wcs.admin.users.UsersDirectory()
|
261 |
|
workflows = wcs.admin.workflows.WorkflowsDirectory()
|
262 |
|
submission = submission.SubmissionDirectory()
|
263 |
|
|
264 |
|
menu_items = [
|
265 |
|
('management', N_('Pending Forms')),
|
266 |
|
('submission/', N_('Submission')),
|
267 |
|
('forms/', N_('Forms Workshop')),
|
268 |
|
('workflows/', N_('Workflows Workshop')),
|
269 |
|
('users/', N_('Users')),
|
270 |
|
('roles/', N_('Roles')),
|
271 |
|
('categories/', N_('Categories')),
|
272 |
|
('logger/', N_('Logs'), logger.is_visible),
|
273 |
|
('bounces/', N_('Bounces'), bounces.is_visible),
|
274 |
|
('settings/', N_('Settings')),
|
275 |
|
('/', N_('WCS Form Server'))
|
276 |
|
]
|
277 |
|
|
278 |
|
def check_admin_for_all(self):
|
279 |
|
admin_for_all_file_path = os.path.join(get_publisher().app_dir, 'ADMIN_FOR_ALL')
|
280 |
|
if not os.path.exists(os.path.join(admin_for_all_file_path)):
|
281 |
|
return False
|
282 |
|
admin_for_all_contents = open(admin_for_all_file_path).read()
|
283 |
|
if not admin_for_all_contents:
|
284 |
|
# empty file, access is granted to everybody
|
285 |
|
return True
|
286 |
|
if get_request().get_environ('REMOTE_ADDR', '') in admin_for_all_contents.splitlines():
|
287 |
|
# if the file is not empty it should contain the list of authorized
|
288 |
|
# IP addresses.
|
289 |
|
return True
|
290 |
|
return False
|
|
251 |
class ManagementDirectory(Directory):
|
|
252 |
_q_exports = ['', 'statistics']
|
291 |
253 |
|
292 |
|
def _q_access(self):
|
293 |
|
get_response().breadcrumb.append( ('backoffice/', _('Back Office')) )
|
294 |
|
req = get_request()
|
295 |
|
|
296 |
|
if self.check_admin_for_all():
|
297 |
|
get_response().filter['admin_for_all'] = True
|
298 |
|
return
|
299 |
|
|
300 |
|
if get_publisher().user_class.count() > 0:
|
301 |
|
user = req.user
|
302 |
|
if not user:
|
303 |
|
raise errors.AccessUnauthorizedError(
|
304 |
|
public_msg = _('Access to backoffice is restricted to authorized persons only. '\
|
305 |
|
'Please login.'))
|
306 |
|
if not user.can_go_in_backoffice():
|
307 |
|
raise errors.AccessForbiddenError()
|
308 |
|
|
309 |
|
get_response().filter['in_backoffice'] = True
|
310 |
|
|
311 |
|
def get_intro_text(self):
|
312 |
|
return _('''Welcome.''')
|
313 |
|
|
314 |
|
def generate_header_menu(self, selected=None):
|
315 |
|
s = ['<ul id="menu">\n']
|
316 |
|
for menu_item in self.get_menu_items():
|
317 |
|
if not 'icon' in menu_item:
|
318 |
|
continue
|
319 |
|
if menu_item.get('slug') == selected:
|
320 |
|
s.append('<li class="active">')
|
321 |
|
else:
|
322 |
|
s.append('<li>')
|
323 |
|
s.append('<a href="%(url)s">%(label)s</a></li>\n' % menu_item)
|
324 |
|
s.append('</ul>\n')
|
325 |
|
return ''.join(s)
|
|
254 |
def _q_traverse(self, path):
|
|
255 |
get_response().breadcrumb.append(('management/', _('Management')))
|
|
256 |
return super(ManagementDirectory, self)._q_traverse(path)
|
326 |
257 |
|
327 |
258 |
def _q_index(self):
|
328 |
|
html_top('/')
|
329 |
|
r = TemplateIO(html=True)
|
330 |
|
r += htmltext('<div class="bo-block"><p>%s</p></div>') % self.get_intro_text()
|
331 |
|
|
332 |
|
menu_items = self.get_menu_items()
|
333 |
|
r += htmltext('<ul class="apps">')
|
334 |
|
for menu_item in menu_items:
|
335 |
|
if not 'icon' in menu_item:
|
336 |
|
continue
|
337 |
|
r += htmltext('<li class="zone-%(icon)s"><a href="%(url)s">%(label)s</a></li>') % menu_item
|
338 |
|
for menu_item in menu_items:
|
339 |
|
if 'icon' in menu_item:
|
340 |
|
continue
|
341 |
|
r += htmltext('<li class="zone-no-icon"><a href="%(url)s">%(label)s</a></li>') % menu_item
|
342 |
|
r += htmltext('</ul>')
|
343 |
|
r += htmltext('<br class="clear">')
|
344 |
|
|
345 |
|
r += htmltext('<p id="for-more-info"></p>')
|
346 |
|
|
347 |
|
get_response().filter['sidebar'] = str(self.get_sidebar())
|
348 |
|
|
349 |
|
return r.getvalue()
|
350 |
|
|
351 |
|
|
352 |
|
def get_sidebar(self):
|
353 |
|
from qommon.admin.menu import get_vc_version
|
354 |
|
from wcs.admin.root import gpl
|
355 |
|
r = TemplateIO(html=True)
|
356 |
|
|
357 |
|
r += htmltext('<div class="bo-block">')
|
358 |
|
r += htmltext('<ul id="sidebar-actions">')
|
359 |
|
r += htmltext('<li><a href="statistics">%s</a></li>') % _('Global statistics')
|
360 |
|
r += htmltext('</ul>')
|
361 |
|
r += htmltext('</div>')
|
362 |
|
|
363 |
|
version = get_vc_version()
|
364 |
|
if version:
|
365 |
|
r += htmltext('<div class="bo-block"><p class="version-info">')
|
366 |
|
r += _('Version:')
|
367 |
|
r += ' '
|
368 |
|
r += version
|
369 |
|
r += htmltext('</p></div>')
|
370 |
|
|
371 |
|
r += htmltext('<div class="bo-block">')
|
372 |
|
r += gpl()
|
373 |
|
r += htmltext('</div>')
|
374 |
|
|
375 |
|
return r.getvalue()
|
376 |
|
|
377 |
|
def management(self):
|
378 |
|
get_response().breadcrumb.append(('management', _('Pending Forms')))
|
379 |
259 |
html_top('management', _('Pending Forms'))
|
380 |
260 |
get_response().filter['sidebar'] = self.get_sidebar()
|
381 |
261 |
r = TemplateIO(html=True)
|
... | ... | |
430 |
310 |
|
431 |
311 |
return r.getvalue()
|
432 |
312 |
|
|
313 |
def get_sidebar(self):
|
|
314 |
r = TemplateIO(html=True)
|
|
315 |
r += htmltext('<div class="bo-block">')
|
|
316 |
r += htmltext('<ul id="sidebar-actions">')
|
|
317 |
r += htmltext('<li><a href="statistics">%s</a></li>') % _('Global statistics')
|
|
318 |
r += htmltext('</ul>')
|
|
319 |
r += htmltext('</div>')
|
|
320 |
return r.getvalue()
|
433 |
321 |
|
434 |
322 |
def get_stats_sidebar(self):
|
435 |
323 |
get_response().add_javascript(['jquery.js'])
|
... | ... | |
466 |
354 |
|
467 |
355 |
return r.getvalue()
|
468 |
356 |
|
469 |
|
|
470 |
357 |
def statistics(self):
|
471 |
358 |
html_top('management', _('Global statistics'))
|
472 |
359 |
get_response().breadcrumb.append(('statistics', _('Global statistics')))
|
... | ... | |
511 |
398 |
|
512 |
399 |
return r.getvalue()
|
513 |
400 |
|
514 |
|
|
515 |
401 |
def category_global_stats(self, title, category_formdefs, counts):
|
516 |
402 |
r = TemplateIO(html=True)
|
517 |
403 |
category_formdefs_ids = [x.id for x in category_formdefs]
|
... | ... | |
535 |
421 |
r += htmltext('</div>')
|
536 |
422 |
return r.getvalue()
|
537 |
423 |
|
538 |
|
|
539 |
424 |
def display_forms(self, forms_list):
|
540 |
425 |
r = TemplateIO(html=True)
|
541 |
426 |
r += htmltext('<ul>')
|
... | ... | |
563 |
448 |
r += htmltext('</ul>')
|
564 |
449 |
return r.getvalue()
|
565 |
450 |
|
|
451 |
def _q_lookup(self, component):
|
|
452 |
return FormPage(component)
|
|
453 |
|
|
454 |
|
|
455 |
class RootDirectory(BackofficeRootDirectory):
|
|
456 |
_q_exports = ['', 'pending', 'statistics']
|
|
457 |
|
|
458 |
bounces = wcs.admin.bounces.BouncesDirectory()
|
|
459 |
categories = wcs.admin.categories.CategoriesDirectory()
|
|
460 |
forms = wcs.admin.forms.FormsDirectory()
|
|
461 |
logger = wcs.admin.logger.LoggerDirectory()
|
|
462 |
roles = wcs.admin.roles.RolesDirectory()
|
|
463 |
settings = wcs.admin.settings.SettingsDirectory()
|
|
464 |
users = wcs.admin.users.UsersDirectory()
|
|
465 |
workflows = wcs.admin.workflows.WorkflowsDirectory()
|
|
466 |
submission = submission.SubmissionDirectory()
|
|
467 |
management = ManagementDirectory()
|
|
468 |
|
|
469 |
menu_items = [
|
|
470 |
('management/', N_('Pending Forms')),
|
|
471 |
('submission/', N_('Submission')),
|
|
472 |
('forms/', N_('Forms Workshop')),
|
|
473 |
('workflows/', N_('Workflows Workshop')),
|
|
474 |
('users/', N_('Users')),
|
|
475 |
('roles/', N_('Roles')),
|
|
476 |
('categories/', N_('Categories')),
|
|
477 |
('logger/', N_('Logs'), logger.is_visible),
|
|
478 |
('bounces/', N_('Bounces'), bounces.is_visible),
|
|
479 |
('settings/', N_('Settings')),
|
|
480 |
]
|
|
481 |
|
|
482 |
def _q_traverse(self, path):
|
|
483 |
get_response().add_javascript(['jquery.js'])
|
|
484 |
return super(RootDirectory, self)._q_traverse(path)
|
|
485 |
|
|
486 |
def check_admin_for_all(self):
|
|
487 |
admin_for_all_file_path = os.path.join(get_publisher().app_dir, 'ADMIN_FOR_ALL')
|
|
488 |
if not os.path.exists(os.path.join(admin_for_all_file_path)):
|
|
489 |
return False
|
|
490 |
admin_for_all_contents = open(admin_for_all_file_path).read()
|
|
491 |
if not admin_for_all_contents:
|
|
492 |
# empty file, access is granted to everybody
|
|
493 |
return True
|
|
494 |
if get_request().get_environ('REMOTE_ADDR', '') in admin_for_all_contents.splitlines():
|
|
495 |
# if the file is not empty it should contain the list of authorized
|
|
496 |
# IP addresses.
|
|
497 |
return True
|
|
498 |
return False
|
|
499 |
|
|
500 |
def _q_access(self):
|
|
501 |
get_response().breadcrumb.append( ('backoffice/', _('Back Office')) )
|
|
502 |
req = get_request()
|
|
503 |
|
|
504 |
if self.check_admin_for_all():
|
|
505 |
get_response().filter['admin_for_all'] = True
|
|
506 |
return
|
|
507 |
|
|
508 |
if get_publisher().user_class.count() > 0:
|
|
509 |
user = req.user
|
|
510 |
if not user:
|
|
511 |
raise errors.AccessUnauthorizedError(
|
|
512 |
public_msg = _('Access to backoffice is restricted to authorized persons only. '\
|
|
513 |
'Please login.'))
|
|
514 |
if not user.can_go_in_backoffice():
|
|
515 |
raise errors.AccessForbiddenError()
|
|
516 |
|
|
517 |
get_response().filter['in_backoffice'] = True
|
|
518 |
|
|
519 |
def get_intro_text(self):
|
|
520 |
return _('''Welcome.''')
|
|
521 |
|
|
522 |
def generate_header_menu(self, selected=None):
|
|
523 |
s = ['<ul id="menu">\n']
|
|
524 |
for menu_item in self.get_menu_items():
|
|
525 |
if not 'icon' in menu_item:
|
|
526 |
continue
|
|
527 |
if menu_item.get('slug') == selected:
|
|
528 |
s.append('<li class="active">')
|
|
529 |
else:
|
|
530 |
s.append('<li>')
|
|
531 |
s.append('<a href="%(url)s">%(label)s</a></li>\n' % menu_item)
|
|
532 |
s.append('</ul>\n')
|
|
533 |
return ''.join(s)
|
|
534 |
|
|
535 |
def _q_index(self):
|
|
536 |
html_top('/')
|
|
537 |
r = TemplateIO(html=True)
|
|
538 |
r += htmltext('<div class="bo-block"><p>%s</p></div>') % self.get_intro_text()
|
|
539 |
|
|
540 |
menu_items = self.get_menu_items()
|
|
541 |
r += htmltext('<ul class="apps">')
|
|
542 |
for menu_item in menu_items:
|
|
543 |
if not 'icon' in menu_item:
|
|
544 |
continue
|
|
545 |
r += htmltext('<li class="zone-%(icon)s"><a href="%(url)s">%(label)s</a></li>') % menu_item
|
|
546 |
for menu_item in menu_items:
|
|
547 |
if 'icon' in menu_item:
|
|
548 |
continue
|
|
549 |
r += htmltext('<li class="zone-no-icon"><a href="%(url)s">%(label)s</a></li>') % menu_item
|
|
550 |
r += htmltext('</ul>')
|
|
551 |
r += htmltext('<br class="clear">')
|
|
552 |
|
|
553 |
r += htmltext('<p id="for-more-info"></p>')
|
|
554 |
|
|
555 |
get_response().filter['sidebar'] = str(self.get_sidebar())
|
|
556 |
|
|
557 |
return r.getvalue()
|
|
558 |
|
|
559 |
def get_sidebar(self):
|
|
560 |
from qommon.admin.menu import get_vc_version
|
|
561 |
from wcs.admin.root import gpl
|
|
562 |
r = TemplateIO(html=True)
|
|
563 |
|
|
564 |
r += htmltext('<div class="bo-block">')
|
|
565 |
r += htmltext('<ul id="sidebar-actions">')
|
|
566 |
r += htmltext('<li><a href="management/statistics">%s</a></li>') % _('Global statistics')
|
|
567 |
r += htmltext('</ul>')
|
|
568 |
r += htmltext('</div>')
|
|
569 |
|
|
570 |
version = get_vc_version()
|
|
571 |
if version:
|
|
572 |
r += htmltext('<div class="bo-block"><p class="version-info">')
|
|
573 |
r += _('Version:')
|
|
574 |
r += ' '
|
|
575 |
r += version
|
|
576 |
r += htmltext('</p></div>')
|
|
577 |
|
|
578 |
r += htmltext('<div class="bo-block">')
|
|
579 |
r += gpl()
|
|
580 |
r += htmltext('</div>')
|
|
581 |
|
|
582 |
return r.getvalue()
|
|
583 |
|
566 |
584 |
def pending(self):
|
567 |
585 |
# kept as a redirection for compatibility with possible bookmarks
|
568 |
586 |
return redirect('.')
|
569 |
587 |
|
|
588 |
def statistics(self):
|
|
589 |
return redirect('management/statistics')
|
|
590 |
|
570 |
591 |
def _q_lookup(self, component):
|
571 |
592 |
if component in [str(x[0]).strip('/') for x in self.menu_items]:
|
572 |
593 |
if not is_accessible(component):
|
573 |
594 |
raise errors.AccessForbiddenError()
|
574 |
595 |
return getattr(self, component)
|
575 |
|
return FormPage(component)
|
|
596 |
if FormDef.has_key(component):
|
|
597 |
return redirect('management/%s/' % component)
|
|
598 |
return super(RootDirectory, self)._q_lookup(component)
|
576 |
599 |
|
577 |
600 |
def get_menu_items(self):
|
578 |
601 |
if not get_request().user:
|