# $Id: JamArtefact.py,v 1.24 2002/08/27 12:57:17 jmp Exp $ # Copyright 2001, 2002 by Fle3 Team and contributors # # This file is part of Fle3. # # Fle3 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. # # Fle3 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 Fle3; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA __version__ = '$Revision: 1.24 $'[11:-2] from types import StringType import time try: from PIL import Image PIL_imported = 1 except ImportError: PIL_imported = 0 import cStringIO import OFS import Globals from Globals import Persistent from AccessControl import ClassSecurityInfo from Thread import EventManager from TraversableWrapper import Traversable from common import add_dtml, reload_dtml, intersect_bool, get_roles from common import perm_view, perm_edit, perm_manage, perm_add_lo from common import roles_admin from common import roles_student, roles_tutor, roles_teacher from input_checks import render, normal_entry_tags class JamArtefact( Traversable, Persistent, EventManager, OFS.Folder.Folder, OFS.SimpleItem.Item ): """JamArtefact""" meta_type = 'JamArtefact' security= ClassSecurityInfo() security.declareObjectPublic() dtml_files = ( ('jam_artefact_index_html', 'Index page', 'ui/JamArtefact/index_html'), ('add_annotation_form', '', 'ui/JamArtefact/add_annotation_form'), ) def __init__(self, id_, parent_ids, name, data, content_type): self.id = id_ self.title = name EventManager.__init__(self) self.__name = name self.__data = data self.__censored = 0 self.__content_type = content_type # generate suitable thumbnail/icon depending on content_type subtype = content_type[content_type.find('/')+1:] content_type = content_type[:content_type.find('/')] if content_type == 'image': if not PIL_imported: print "Can't create thumbnail image. PIL not installed." try: s = cStringIO.StringIO(data) im = Image.open(s) im.thumbnail((60, 60)) if im.mode != 'RGB': im = im.convert('RGB') s = cStringIO.StringIO() im.save(s, "JPEG") s.seek(0) self.__thumbnail = s.read() except: self.__icon = 'images/jam_type_img' elif content_type == 'audio': self.__icon = 'images/jam_type_sound' elif content_type == 'text': if subtype == 'html': self.__icon = 'images/jam_type_html' else: self.__icon = 'images/jam_type_text' elif content_type == 'video': self.__icon = 'images/jam_type_video' elif content_type == 'application': # Ideally, we should have all archive format MIME types here.. if subtype in ('gnutar', 'zip', 'x-compress', 'x-compressed', 'x-gtar', 'x-tar', 'x-zip', 'x-zip-compressed', 'x-shar', 'x-bzip', 'x-bzip2', 'x-cpio'): self.__icon = 'images/jam_type_arch' else: self.__icon = 'images/jam_type_no' else: self.__icon = 'images/jam_type_no' self.__annotations = [] if type(parent_ids) == StringType: parent_ids = (parent_ids,) self.__parent_ids = parent_ids for tup in self.dtml_files: add_dtml(self, tup) security.declarePrivate('manage_afterAdd') def manage_afterAdd(self, item, container): """Set default permissions for roles.""" 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) self.manage_permission(perm_view, roles_student, 0) security.declareProtected(perm_manage, 'reload_dtml') def reload_dtml(self, REQUEST=None): """Reload dtml files from the file system.""" reload_dtml(self, self.dtml_files) if REQUEST: self.get_lang(('common',), REQUEST) return self.message_dialog( self, REQUEST, title=REQUEST['L_dtml_reloaded'], message=REQUEST['L_dtml_files_reloaded'], action='index_html') security.declareProtected(perm_view, 'index_html') def index_html(self, REQUEST): """Update reader status before showing the page.""" uname = repr(REQUEST.AUTHENTICATED_USER) self.update_reader(uname) self.uncache_unread_artefacts(uname) return self.jam_artefact_index_html(self, REQUEST) security.declareProtected(perm_view, 'get_children_artefacts') def get_children_artefacts(self): """Return a list of children artefacts.""" children = [] for ja in self.parent().get_children('JamArtefact'): if self.get_id() in ja.get_parent_ids(): children.append(ja) return children security.declareProtected(perm_view, 'get_name') def get_name(self, REQUEST=None): """Return name of the artefact.""" prefix = '' if self.__censored: if REQUEST: uname = str(REQUEST.AUTHENTICATED_USER) self.get_lang(('jam',),REQUEST) prefix = REQUEST['L_censored_name'] else: prefix = 'CENSORED' uname='' # If the person is not the author and is not a teacher, # we only show the prefix (the censored notice) if uname!=self.get_author() and \ not self.may_censor_jam_artefact(uname): return prefix prefix = prefix + ' / ' return prefix + self.__name # Return real name of the artefact, even when the artefact is censored. security.declarePrivate('get_real_name') def get_real_name(self): """Return name of the artefact.""" return self.__name security.declareProtected(perm_view, 'get_data') def get_data(self, REQUEST=None, RESPONSE=None): """Return actual data.""" if self.__censored: if not REQUEST or \ not self.may_censor_jam_artefact( str(REQUEST.AUTHENTICATED_USER)): return None if REQUEST: self.update_reader(repr(REQUEST.AUTHENTICATED_USER)) if REQUEST and RESPONSE: RESPONSE.setHeader('Content-Type', self.__content_type) return self.__data security.declarePrivate('get_real_data') def get_real_data(self): """Return actual data.""" return self.__data security.declareProtected(perm_view, 'get_content_type') def get_content_type(self): """Return content type.""" return self.__content_type security.declareProtected(perm_view, 'get_icon') def get_icon(self, REQUEST, RESPONSE): """Return icon.""" if self.__censored: return self.unrestrictedTraverse('images/jam_type_censored').data elif hasattr(self, '_' + self.__class__.__name__+ '__icon'): return self.unrestrictedTraverse(self.__icon).data else: RESPONSE.setHeader('Content-Type', 'image/jpeg') return self.__thumbnail security.declareProtected(perm_view, 'get_author') def get_author(self): """Return author (owner) of this item.""" return self.getOwner() security.declareProtected(perm_view, 'get_n_annotations') def get_n_annotations(self): """Return the number of annotations.""" return len(self.__annotations) security.declareProtected(perm_view, 'get_n_censored_annotations') def get_n_censored_annotations(self): """Return the number of censored annotations.""" n = 0 for t in self.__annotations: if t[3]: n += 1 return n security.declareProtected(perm_view, 'get_n_uncensored_annotations') def get_n_uncensored_annotations(self): """Return the number of uncensored annotations.""" n = 0 for t in self.__annotations: if not t[3]: n += 1 return n security.declareProtected(perm_view, 'get_annotations') def get_annotations(self, REQUEST): """Return list of annotation tuples.""" if self.__censored and \ not self.may_censor_jam_artefact(str(REQUEST.AUTHENTICATED_USER)): return [] # FIXME: This have to be changed when we have censoring # FIXME: on the annotation level. anns = [] for (who, when, what, censored, censorer) in self.__annotations: if censored: self.get_lang(('common','webtop'), REQUEST) stamp = time.strftime(REQUEST['L_short_date_format'], time.localtime(censored)) prefix = REQUEST['L_censored_annotation_body'] % (censorer, stamp) uname = str(REQUEST.AUTHENTICATED_USER) if uname != self.get_author() and \ not self.may_censor_jam_artefact(uname): what = prefix else: what = prefix + \ '