# -*- coding: utf-8
# $Id$
#
# Copyright 2001 - 2005 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
"""
Portfolio - A place for blog and assignments.
"""
__version__ = "$Revision$"[11:-2]
import Globals
import WebtopFolder
import Blog
from WebtopItem import WebtopItem
from AccessControl import ClassSecurityInfo
from common import perm_view, perm_edit, perm_manage, perm_add_lo
from common import translate
import time
from zope.interface import implements
from interfaces import IWebtopItem, IPortfolio, IStatistics, ICourseManager, IAssignmentProxy
from zope.component import adapter, getUtility
from zope.app.container.interfaces import IObjectAddedEvent
class Portfolio(
Blog.Blog,
WebtopFolder.WebtopFolder,
):
""" Portfolio holds assignments and blog """
meta_type = "Portfolio"
implements(IWebtopItem, IPortfolio)
security = ClassSecurityInfo()
security.declareObjectPublic()
portfolio_top = 1
def __init__(self, parent, name):
""" set id """
WebtopItem.__init__(self, parent, name)
self.id = 'portfolio'
security.declareProtected(perm_view, 'index_html')
def index_html(self, REQUEST=None):
""" index_page """
#getUtility(IStatistics)._viewedObject(REQUEST, self.getRelativeURL(self))
url = self.absolute_url()
if 'subgroups' in url:
return self.restrictedTraverse('wt_index_html.html')()
return self.restrictedTraverse('portfolio_index.html')()
security.declareProtected(perm_view, 'get_icon')
def get_icon(self):
""" icon """
return getattr(self.images, 'folder_gif.gif')
security.declareProtected(perm_view, 'get_icon_tag')
def get_icon_tag(self):
""" get icon tag """
return """""" % self.fle_root().absolute_url()
def get_icon_path(self):
""" return icon path """
return "folder_gif.gif"
security.declareProtected(perm_view, 'get_name')
def get_name(self):
""" always portfolio """
return "Portfolio"
security.declareProtected(perm_view, 'getAssignments')
def getAssignments(self):
""" return a list of assignments (folder?) """
return self.objectValues('AssignmentProxy')
security.declareProtected(perm_edit, 'createAssignmentProxy')
def createAssignmentProxy(self, a, c):
""" sets AssignmentProxy object """
proxy = AssignmentProxy(self, a, c)
proxy.id = a
self._setObject(a, proxy)
return proxy.__of__(self)
Globals.InitializeClass(Portfolio)
class AssignmentProxy(
WebtopFolder.WebtopFolder,
):
""" Assignment folder where user can submit it's work. """
meta_type = "AssignmentProxy"
security = ClassSecurityInfo()
security.declareObjectPublic()
implements(IAssignmentProxy)
def __init__(self, parent, assignment_id, course_id):
""" Construct AssignmentProxy """
WebtopItem.__init__(self, parent, '')
self.__assignment_id = assignment_id
self.__course_id = course_id
def __get_assignments(self):
""" return assignments folder """
try:
return getUtility(ICourseManager, context=self).get_child(self.__course_id).kodutood
except KeyError:
return None
def __get_assignment(self):
""" return assignment """
return getattr(self.__get_assignments(), self.__assignment_id, None)
security.declareProtected(perm_view, 'get_assignment')
def get_assignment(self):
""" return assignment """
return self.__get_assignment()
security.declareProtected(perm_view, 'get_name')
def get_name(self):
""" return assignment id """
asg = self.__get_assignment()
try:
return asg.getTitle()
except AttributeError:
pass
if not asg or asg.meta_type == 'AssignmentProxy':
# trigger folder deletion here if folder is empty
if len(self.objectValues()) == 0:
self.delete_me()
return "deleted assignment"
else:
if asg.getRawType() == 2: # groupwork
groups = asg.getGroups()
try:
if self.is_subgroup_id() not in groups:
if len(self.objectValues()) == 0:
self.delete_me()
return ""
return "deleted assignment"
except AttributeError:
#print "is_subgroup_id failed %s" % self.absolute_url()
return ""
return asg.getTitle()
getTitle = get_name
security.declareProtected(perm_view, 'get_description')
def get_description(self):
""" return assignment description """
asg = self.__get_assignment()
if not asg or asg.meta_type == 'AssignmentProxy':
return "deleted assignment"
else:
return asg.kirjeldus
security.declareProtected(perm_view, 'get_assignment_material')
def get_assignment_material(self):
""" return assignment material if set """
asg = self.__get_assignment()
if not asg or asg.meta_type == 'AssignmentProxy':
return ""
if asg.juhend == "": return ""
tulem = ""
elem = asg.juhend.split("/")
koht = self.fle_root()
try:
for obj in elem:
if len(obj)>0:
koht = getattr(koht, obj)
obj_nimi = koht.get_name()
tulem += ""+obj_nimi+""
except AttributeError:
asg.juhend = ""
tulem = ""
return tulem
security.declareProtected(perm_view, 'get_assignment_deadline')
def get_assignment_deadline(self, REQUEST):
""" return assignment deadline """
asg = self.__get_assignment()
if not asg or asg.meta_type == 'AssignmentProxy':
return ""
if asg.getRawType() == 0: return ""
if str(asg.loppaeg) == 'None':
asg.loppaeg = time.time()
message = translate(self, "Deadline:")+" "+time.strftime(translate(self,'timestamp_format',default="%H:%M %Y-%m-%d"), time.localtime(asg.loppaeg))
if hasattr(asg, 'lockFolder') and asg.lockFolder():
message += "
"+translate(self, "Folder will be locked after deadline.")
return message
security.declareProtected(perm_view, 'get_icon')
def get_icon(self):
""" icon """
return getattr(self.images, 'folder_gif.gif')
def get_icon_path(self):
""" icon path """
return 'folder_gif.gif'
security.declareProtected(perm_view, 'list_contents')
def hw_list_contents(self, REQUEST, jnr):
""" list contents + other webtop content if needed """
my_list = self.list_contents_request2(REQUEST)
other_list = []
hw = self.__get_assignment()
# hw, hw==self, isinstance(hw, AssignmentProxy)
if isinstance(hw, AssignmentProxy):
return my_list
hwID = hw.getAssignmentID()
if hwID:
users = hw.getReviewers(str(REQUEST.AUTHENTICATED_USER))
for user in users:
relurl = "fle_users/"+user+"/webtop/c"+str(jnr)+"/portfolio/"+hwID
#u_obj = getattr(self.fle_root(), 'fle_users').get_user_info(user)
#portfolio = u_obj.get_course_portfolio(jnr)
#o_hw = getattr(portfolio, hwID, None)
#if not o_hw: continue
other_list += self.list_contents_request2(REQUEST, relative=relurl)
return other_list+my_list
security.declareProtected(perm_view, 'is_assignment')
def is_assignment(self):
""" return 1 - this is assignment folder """
return 1
security.declareProtected(perm_view, 'is_folder_locked')
def is_folder_locked(self):
""" is assignment has deadline then after deadline don't allow users to change content """
hw = self.__get_assignment()
try:
if hw.lockFolder():
return time.time()>hw.loppaeg
except AttributeError:
return False
security.declareProtected(perm_view, 'quizLink')
def quizLink(self, REQUEST, course,userlocation):
""" if we need link to quiz solving """
if not self.myOwnWebtop(REQUEST): return ""
url = ""
asg = self.__get_assignment()
if not asg or asg.meta_type == 'AssignmentProxy':
return url
try:
quizID = asg.testiID
if not quizID:
return ""
quiz = getattr(course.testid, quizID)
if quiz.kasLubatudLahendada(REQUEST):
if quiz.kysiTyyp()==0:
url=quiz.absolute_url()+'/qtExplanationQuiz.html?userLocation='+userlocation
elif quiz.kysiTyyp()==1:
url = quiz.absolute_url()+'/qtAnsweringForm.html?userLocation='+userlocation
elif quiz.kysiTyyp()==2:
url=quiz.absolute_url()+'/qtExerciseForm.html?userLocation='+userlocation
except AttributeError:
pass
return url
security.declareProtected(perm_view, 'wordmapLink')
def wordmapLink(self, REQUEST, course,userlocation):
""" if we need link to wordmap making """
if not self.myOwnWebtop(REQUEST): return ""
url = ""
asg = self.__get_assignment()
if not asg or asg.meta_type == 'AssignmentProxy':
return url
try:
wmID = asg.wmID
if not wmID:
return ""
#wm = getattr(course.wordmaps, wmID)
url=self.wmcID
except AttributeError:
pass
return url
security.declareProtected(perm_view, 'explainWhy')
def explainWhy(self, REQUEST):
""" see YlTest """
asg = self.__get_assignment()
why = ""
if not asg or asg.meta_type == 'AssignmentProxy':
return why
quizID = asg.testiID
if not quizID:
return why
try:
quiz = getattr(asg.parent().parent().testid, quizID, None)
except AttributeError:
return why
if not quiz:
return why
why = quiz.explainWhy(REQUEST)
return why
Globals.InitializeClass(AssignmentProxy)
@adapter(IPortfolio, IObjectAddedEvent)
def added(obj, event):
obj.manage_permission('Change permissions', ('Owner', 'Teacher',), 1)