# -*- coding: utf-8 # $Id$ # Copyright 2001, 2002 by IVA Team and contributors # # This file is part of IVA. # # IVA is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # IVA is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with IVA; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """Contains class JamSession, which is abstract base class for different JamSession types.""" __version__ = '$Revision$'[11:-2] from types import StringType from urllib import quote_plus import OFS, Globals, AccessControl from Globals import Persistent from AccessControl import ClassSecurityInfo from JamArtefact import JamArtefact from TraversableWrapper import TraversableWrapper from input_checks import is_valid_title from common import intersect_bool, translate from common import perm_view, perm_edit, perm_manage, perm_add_lo, \ roles_admin, roles_staff, roles_user class JamSession( TraversableWrapper, OFS.Folder.Folder, Persistent, AccessControl.Role.RoleManager, ): """JamSession""" meta_type = 'JamSession' security= ClassSecurityInfo() security.declareObjectPublic() def __init__(self, id_, name, description, start_artefact_name, start_artefact_data, start_artefact_content_type): """Construct JamSession.""" self.id = id_ self.title = '' self.__name = name self.__description = description # pass to manage_afterAdd self._t_name = start_artefact_name self._t_data = start_artefact_data self._t_ct = start_artefact_content_type security.declarePrivate('manage_afterAdd') def manage_afterAdd(self, item, container): """Set default permissions for roles.""" self.add_artefact(self._t_name, self._t_data, self._t_ct) del self._t_name del self._t_data del self._t_ct self.update_drawing() from common import roles_student, roles_tutor, roles_teacher from common import roles_admin self.manage_permission(perm_manage, roles_admin, 0) self.manage_permission(perm_edit, roles_teacher, 0) self.manage_permission(perm_add_lo, roles_student, 0) security.declareProtected(perm_view, 'get_name') def get_name(self): """Return name of the JamSession.""" return self.__name security.declareProtected(perm_view, 'get_description') def get_description(self): """Return desctiption of the JamSession.""" return self.__description security.declarePrivate('uncache_artefacts') def uncache_artefacts(self): if hasattr(self,'__cached_n_artefacts'): del self.__cached_n_artefacts if hasattr(self,'__cached_n_unread_artefacts'): del self.__cached_n_unread_artefacts security.declareProtected(perm_view, 'get_n_artefacts') def get_n_artefacts(self): """Return number of artefacts in this JamSession""" if hasattr(self, '__cached_n_artefacts'): return self.__cached_n_artefacts else: n = len(self.get_children('JamArtefact')) self.__cached_n_artefacts = n return n security.declarePrivate('uncache_unread_artefacts') def uncache_unread_artefacts(self, uname): if hasattr(self, '__cached_n_unread_artefacts'): if uname in self.__cached_n_unread_artefacts.keys(): del self.__cached_n_unread_artefacts.keys[uname] security.declareProtected(perm_view, 'get_n_unread_artefacts') def get_n_unread_artefacts(self, REQUEST): """Return number of unread artefacts in this JamSession""" uname = str(REQUEST.AUTHENTICATED_USER) if hasattr(self, '__cached_n_unread_artefacts'): if uname in self.__cached_n_unread_artefacts.keys(): return else: self.__cached_n_unread_artefacts = {} n = 0 for a in self.get_children('JamArtefact'): if not a.is_reader(uname): n += 1 self.__cached_n_unread_artefacts[uname] = n return n security.declareProtected(perm_view, 'get_starting_artefact_id') def get_starting_artefact_id(self): """Return ID of the starting artefact.""" return self.__starting_artefact_id security.declareProtected(perm_view, 'render') # This is called from DTML, return a list of lists (DTML # constructs a table using that information.) def render(self): """Render JamSession.""" return self.drawing security.declareProtected(perm_add_lo, 'add_artefact') def add_artefact(self, name, data, content_type, parent_ids=(), REQUEST=None): """Add new artefact to JamSession.""" # Jamming Course CourseManager # | | | id_ = 'ja' + self.parent().parent().parent().generate_id() if len(parent_ids) == 0: self.__starting_artefact_id = id_ self._setObject(id_, JamArtefact(id_, parent_ids, name, data, content_type)) ja = self.get_child(id_) if REQUEST: ja.update_reader(repr(REQUEST.AUTHENTICATED_USER)) return ja security.declareProtected(perm_view, 'index_html') def index_html(self, REQUEST): """ index page of jamsession """ self.updateStat(REQUEST, 'visit_jamming') return REQUEST.RESPONSE.redirect('jamsession_index_html') security.declareProtected(perm_add_lo, 'index_html_form_handler') def index_html_form_handler( self, REQUEST, parent_ids='invalid_id', ): """Redirect to add_artefact_form.""" if parent_ids == 'invalid_id': return self.message_dialog_error( self, REQUEST, title='Invalid input', message='Select some items first', action='index_html') from types import StringType if type(parent_ids) == StringType: parent_ids = (parent_ids,) REQUEST.RESPONSE.redirect('jam_add_artefact_form?parent_ids=%s' % ','.join(parent_ids)) # REQUEST.RESPONSE.redirect( # self.state_href(REQUEST, # 'add_artefact_form?parent_ids=%s' % # ','.join(parent_ids) # ) # ) security.declareProtected(perm_add_lo, 'add_artefact_form_handler') def add_artefact_form_handler( self, REQUEST, artefact_name = '', artefact_upload = None, parent_ids = (), submit = '', # submit buttons cancel = '', ): """Form handler for add_artefact_form.""" if submit: parent_ids = parent_ids.split(',') errors = [] artefact_name = artefact_name.strip() if not is_valid_title(artefact_name): errors.append(translate(self,'Name of the artefact',target=self.giveLanguage(REQUEST))) if not artefact_upload or len(artefact_upload.filename) == 0: errors.append(translate(self,'Upload file',target=self.giveLanguage(REQUEST))) if type(parent_ids) == StringType: parent_ids = (parent_ids,) # Some sanity checks to make sure that # a) there aren't errors in our code # b) some evil cracker is not modifying input if len(parent_ids) == 0: raise 'FLE Error', 'no parent_ids given' if self.get_type() in ('linear', 'tree'): if len(parent_ids) != 1: raise 'FLE Error', 'Only one parent should be given' existing_ids = [a.get_id() for a in self.get_children('JamArtefact')] for pid in parent_ids: if pid not in existing_ids: raise 'FLE Error', \ 'Trying to add artefact to non_existing artefact' if self.get_type() == 'linear': parent_id_list = [] for a in self.get_children('JamArtefact'): for pid in a.get_parent_ids(): parent_id_list.append(pid) if intersect_bool(parent_ids, parent_id_list): raise 'FLE Error', \ 'Trying to add artefact to non-last artefact.' # FIXME: Add checks for 'tree' and 'graph' types if len(errors) > 0: return self.message_dialog_error( self, REQUEST, title='Invalid input', message= translate(self,'Invalid fields',target=self.giveLanguage(REQUEST)) + ": '" + \ "' , '".join(errors) + "'", parent_ids=''.join(parent_ids), action='jam_add_artefact_form?parent_ids=%s' % ''.join(parent_ids)) data = artefact_upload.read() try: content_type = artefact_upload.headers['content-type'] except KeyError: content_type = '' self.add_artefact(artefact_name, data, content_type, parent_ids, REQUEST) self.updateStat(REQUEST, 'postedArtefacts') self.updateStat(REQUEST, 'jamming') self.update_drawing() self.uncache_artefacts() elif cancel: pass else: raise 'FLE Error', 'Unknown button' # Should never happen REQUEST.RESPONSE.redirect('index_html') Globals.default__class_init__(JamSession) # EOF