iva/ 0040755 0000764 0000764 00000000000 10174031703 010701 5 ustar vahur vahur iva/COPYING 0100644 0000764 0000764 00000043131 10130153777 011743 0 ustar vahur vahur GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This program 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.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
iva/Course.py 0100644 0000764 0000764 00000147657 10173673364 012552 0 ustar vahur vahur # -*- coding: utf-8
# $Id: Course.py,v 1.6 2003/08/18 07:44:24 berlingo Exp $
#
# 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 Course, which represents one course, which has one or more CourseContexts, which in turn contain knowledge building conversations."""
__version__ = '$Revision: 1.6 $'[11:-2]
import time
import string, types
import OFS, Globals
from Globals import Persistent, Acquisition
import AccessControl
from AccessControl import ClassSecurityInfo
import copy
import re
import Kodutoo
try:
from Products.ZWiki.ZWikiPage import ZWikiPage
USE_ZWIKI = 1
except:
USE_ZWIKI = 0
from Jamming import Jamming
from TraversableWrapper import Traversable
from common import add_dtml, reload_dtml, intersect_bool, make_action, get_roles, get_local_roles, translate
from input_checks import strip_all, is_valid_title
from CourseContext import CourseContext
#from ThinkingTypeSetManager import ThinkingTypeSetManager as TTSM
from Thread import Thread
from Cruft import Cruft
from TempObjectManager import TempObjectManager
from input_checks import render, normal_entry_tags_and_link
from common import perm_view, perm_edit, perm_manage, perm_add_lo
from TestiHaldur import TestiHaldur
import WebtopTrash
# Each Course object contains (usually) one or more CourseContexts, which
# represent different aspects of the course.
# A Course contains information and services on one course implementation.
class Course(
Persistent,
Traversable,
Cruft,
OFS.Folder.Folder,
AccessControl.Role.RoleManager,
OFS.SimpleItem.Item,
Thread,
):
"""Course, contained within CourseManager, represents one course."""
meta_type = 'Course'
security = ClassSecurityInfo()
security.declareObjectPublic()
# Call courses/course_html (This way we avoid copying index_html
# to each instance of Course class.)
# ATTENTION: We don't exactly know how this works (for example,
# do we really need REQUEST ?)
#
#TODO: This could be done with a URL pointing to the course_html script.
#But if we need this default implementation, we could use
#restrictedTraverse('course_html') to activate Zope acquisition.
#FIX:bla?
security.declareProtected('View', 'index_html')
def index_html(self, REQUEST=None):
"""Default script"""
return REQUEST.RESPONSE.redirect('course_html')
# Parameters:
#
#- parent: should be a CourseManager
#
#- name: name of the Course
#
#- tts: list of ThinkingTypeSets (copies are made in manage_afterAdd)
#
#- teachers: list of users (of class UserInfo?) that are granted
#Teacher privileges
#
#- etc: other textual information
def __init__(
self,
parent, # Whatever you do, dont bind this to self.
name,
teachers,
description='',
organisation='',
methods='',
starting_date='',
ending_date='',
tootoaMuutused = {}
):
"""Constructor of the course."""
# Overriding all_meta_types is not not beautiful...but, hey!, it works!
#self.all_meta_types = (
# {'name': 'ThinkingTypeSet',
# 'action': 'get_id'},)
# Cache active members.
self.active_memb_cache = []
# Remove all HTML tags from parameters
name = strip_all(name)
description = strip_all(description)
methods = strip_all(methods)
organisation = strip_all(organisation)
Thread.__init__(self, parent) # Takes care of id and title.
for teacher in teachers:
self.set_roles(teacher, ('Teacher',))
self.__name = name # name of the course
self.__organisation = organisation
self.__description = description
self.__methods = methods
self.__starting_date = starting_date
self.__ending_date = ending_date
self.__credits = ''
self.__courseID = ''
self.course_category = 0
self.tootoaMuutused = tootoaMuutused
# This is for group folder path listings - show path up to course.
self.toplevel = 1
security.declarePrivate('manage_afterAdd')
#Each course should have its own copy of the ThinkingTypeSets,
#as the course administrator (teacher) should be able to edit them,
#create new ones and so forth. These changes must not propagate to
#other courses: hence the copying of the set.
def manage_afterAdd(self, item, container):
"""foo"""
from common import roles_student, roles_tutor, roles_teacher
from common import roles_admin
#add subgroup folder
from GroupFolder import GroupFolder
sgwt = GroupFolder(None,'Subgroups')
sgwt.id = 'subgroups'
sgwt._subgr_head = 1
self._setObject('subgroups', sgwt)
getattr(self, 'subgroups').manage_permission(perm_edit,('Manager',), 0)
#add folder for qt
self.manage_addProduct['OFSP'].manage_addFolder('testid')
# self._setObject('testid', TestiHaldur())
self.testid.id='testid'
# add jamming
self._setObject('jamming', Jamming('jamming'))
# add folder for assignments
#XXX: think not necessary to migrate since previous check was in for a long time
k=Kodutoo.KodutoodeKataloog()
k.id='kodutood'
self._setObject(k.id, k)
security.declareProtected(perm_view, 'addCourseWiki')
def addCourseWiki(self):
#We add wiki here
if USE_ZWIKI:
from Products.ZWiki.ZWikiPage import ZWikiPage
wikiobj = ZWikiPage(source_string='', __name__='WelCome')
wikiobj.NOT_CATALOGED = True #XXX: catalog gives error:TypeError: can only concatenate list (not "tuple") to list
newid = self._setObject('WelCome',wikiobj)
nw = getattr(self, newid)
# nw.title = self.get_name()
nw.manage_permission('Zwiki: Rename pages',[],0)
nw.manage_permission('Zwiki: Delete pages',[],0)
#XXX: change owner!
return "Refresh page!"
else:
return "ZWiki not installed"
security.declareProtected(perm_edit, 'lisa_grupp')
def lisa_grupp(self, grupinimi):
"""Lisab kursusesise grupi"""
from GroupFolder import GroupFolder
import Kalender
grupinimi=re.sub('[^a-zA-Z0-9]', '_', grupinimi)
if grupinimi[0] == "_": grupinimi="x"+grupinimi
if grupinimi[-2:] == "__": grupinimi += "x"
fol=GroupFolder(None, grupinimi)
while hasattr(self.subgroups, grupinimi):
grupinimi+='y'
fol.id=grupinimi
fol._is_subgroup = 1
self.subgroups._setObject(grupinimi, fol)
fol=fol.__of__(self.subgroups)
# fol.toplevel=1
# fol._setObject('trash', WebtopTrash.WebtopTrash())
# self.lisaGrupiKaust(grupinimi)
fol._setObject('syndmused', Kalender.KalendriSyndmusteKataloog())
fol.syndmused.id='syndmused'
fol.manage_permission(perm_edit, ('Manager','IVAAdmin','Teacher','User'),0)
# return "lisatud" + grupinimi
return fol
# security.declareProtected(perm_edit, 'add_subgroup_handler')
#XXX: security check. anyone shouldn't be able to add subgroup!
def add_subgroup_handler(self, REQUEST=None, subgroup_name='', add=1):
""" creating subgroup """
if not subgroup_name or not add:
return 0
sg = self.lisa_grupp(subgroup_name.strip())
if REQUEST is None:
return sg
else:
REQUEST.set('grname',sg.id)
return REQUEST.RESPONSE.redirect("workshop_subgroup_show?grname=%s" % sg.id)
def is_courseContext(self):
""" is course context? """
return
def kasTeadmuspajasKontekste(self):
"jah/ei"
return len(self.objectValues('CourseContext'))>0
def kasMeediapajasProjekte(self):
"jah/ei"
return len(self.jamming.objectValues('JamSession'))>0
def kysiOotajad(self, REQUEST=None):
"Kursusele registreerunud, keda pole veel kinnitatud"
if hasattr(self, 'ootajad'):
return self.ootajad
return []
security.declareProtected(perm_edit,'manage_pendingUsers_handler')
def manage_pendingUsers_handler(self, REQUEST, addtocourse='',deletefromlist='',pender=''):
"Lisamine vi kustutus"
#from Kirjakast import Kirjakast
temp = getattr(self.fle_root(), 'fle_users')
if not pender:
return self.message_dialog_error(self, REQUEST,
title="Error",
message='Please select some users first',
action='manage_pendingUsers')
if type(pender)==types.StringType:
pender=(pender,)
penders=self.kysiOotajad()
new_penders = []
if deletefromlist:
for x in pender:
puser = getattr(temp, x)
for y in penders:
if y.get_uname() == x: continue
new_penders.append(y)
if addtocourse:
print pender
for x in pender:
puser = getattr(temp, x)
self.add_student(puser.get_uname())
#XXX: this is not in message catalog!
mess_title = translate(self,'Added to course',target=self.giveLanguage(REQUEST))
mess_body = translate(self,'You have been added to course',target=self.giveLanguage(REQUEST))+' '+self.get_name()
puser.kirjad.saadaKiri(REQUEST,puser.get_uname(),puser.get_uname(),mess_title,mess_body,999999)
for x in penders:
if x.get_uname() not in pender:
print x.get_uname(), "---",pender
print "lisan", x.get_uname()
new_penders.append(x)
self.ootajad=new_penders
return REQUEST.RESPONSE.redirect('haldusleht')
def ootajastKursuseLiikmeks(self, REQUEST, kasutaja):
"Lisamine"
self.add_student(kasutaja.get_uname())
return 1
def lisaOotaja(self, REQUEST, ootaja):
"Kasutaja lisab end ootama"
if self.kysiStaatus()=='4': #automaatregistreerumine
self.ootajastKursuseLiikmeks(REQUEST, ootaja)
else:
m=self.kysiOotajad(REQUEST)
if ootaja not in m:
m.append(ootaja)
self.ootajad=m
return 0
def kasOotaja(self, nimi):
"Kas jooksev kasutaja on kursusele ootaja"
m=self.kysiOotajad()
kas=0
for x in m:
if nimi==x.get_uname():
kas=1
return kas
def lisaYlTest(self, REQUEST):
"Lisatakse lesannete test"
# XXX
from YlTest import YlTest
if not hasattr(self.testid, 'nr'):
self.testid.nr=0
while hasattr(self.testid.aq_self, 'test'+str(self.testid.nr)):
self.testid.nr=self.testid.nr+1
t=YlTest()
t.id="test"+str(self.testid.nr)
self.testid._setObject(t.id, t)
t.meta.language=self.giveLanguage(REQUEST)
# return str(t.id)
REQUEST.RESPONSE.redirect('testihaldus')
def testiMuutus(self, REQUEST, testinimi='', rename='', delete='',
export='', importdata='', results='', showhide='', randomize='',confirmation='',cancel=''):
"Testide haldus"
if importdata:
REQUEST.RESPONSE.redirect(self.find_URL_of_fle_root(REQUEST)+\
"/courses/"+ self.get_course_id_from_req(REQUEST)+"/testideImport")
return
if not testinimi:
return
if export:
REQUEST.RESPONSE.redirect(self.find_URL_of_fle_root(REQUEST)+\
"/courses/"+ self.get_course_id_from_req(REQUEST)+"/iva_ims_export?testinimi="+testinimi)
return
if rename:
if hasattr(self.testid, testinimi):
# REQUEST.RESPONSE.redirect("testid/"+testinimi+"/pealkirjaMuutmisVormHTML?liikumisURL="+\
# self.find_URL_of_fle_root(REQUEST)+"/testihaldus")
REQUEST.RESPONSE.redirect("testid/"+testinimi+"/ylTestSettingsForm?liikumisURL="+\
self.find_URL_of_fle_root(REQUEST)+"/testihaldus")
if delete:
if confirmation:
if hasattr(self.testid, testinimi):
self.testid._delObject(testinimi)
elif cancel:
return REQUEST.RESPONSE.redirect("testihaldus")
else:
return self.message_dialog2(self,REQUEST,
title="Confirmation",
message="Are you sure you want to delete quiz?",
option1_name="cancel",
option1_value="Cancel",
option2_value="Delete",
option2_name="confirmation",
extra_value_name='delete',
extra_values = ('yes',),
item_name='testinimi',
item_value=testinimi,
handler="testiMuutus")
REQUEST.RESPONSE.redirect("testihaldus")
if importdata:
REQUEST.RESPONSE.redirect("testid/"+testinimi+"/vahendus/tekstistYlesanneteLaadimiseVorm")
if export:
REQUEST.RESPONSE.redirect("testid/"+testinimi+"/vahendus/ylesandedTekstina")
if results:
REQUEST.RESPONSE.redirect("testid/"+testinimi+"/kasutajateTulemused")
if showhide:
#getattr(self.testid, testinimi).muudaAvatudTaitmiseks(REQUEST)
#REQUEST.RESPONSE.redirect(self.find_URL_of_fle_root(REQUEST)+"/testid/"+testinimi+"/lubadeViited")
REQUEST.RESPONSE.redirect("testid/"+testinimi+"/lubadeViited")
if randomize:
getattr(self.testid, testinimi).muudaKysimusteJuhuslikJarjekord()
# return "Muudetud"
REQUEST.RESPONSE.redirect(self.find_URL_of_fle_root(REQUEST)+"/testihaldus")
security.declarePublic('kustuta_grupp')
def kustuta_grupp(self, gnimi):
"Kustutab kursusesisese grupi"
self.subgroups._delObject(gnimi)
return "kustutatud"
security.declareProtected(perm_view, 'get_printable_name')
# No additional comments.
def get_printable_name(self):
"""Return name of the course."""
return self.__name
security.declareProtected(perm_view, 'get_bg_colour_name')
def get_bg_colour_name(self):
"""..."""
return 'gr'
# security.declareProtected(perm_view, 'get_name')
security.declarePublic('get_name')
# No additional comments.
def get_name(self):
"""Get course name."""
return self.__name
security.declareProtected(perm_view, 'get_organisation')
# No additional comments.
def get_organisation(self):
"""Get organisation name."""
return self.__organisation
security.declareProtected(perm_view, 'get_description')
# No additional comments.
def get_description(self):
"""Get description."""
return self.__description
security.declareProtected(perm_view,'render_description')
def render_description(self):
"""Render description."""
return render(
self.get_description(),
legal_tags=normal_entry_tags_and_link)
security.declareProtected(perm_view, 'get_methods')
# No additional comments.
def get_methods(self):
"""Get info on methods."""
return self.__methods
security.declareProtected(perm_view,'render_methods')
def render_methods(self):
"""Render methods."""
return render(
self.get_methods(),
legal_tags=normal_entry_tags_and_link)
def get_courseID(self):
""" get course id """
try:
return self.__courseID
except:
return ""
def set_courseID(self,courseID):
""" set course id(the other one) """
self.__courseID = courseID
def get_credits(self):
""" get credits info """
try:
return self.__credits
except:
return ""
def set_credits(self,credits):
""" set credits """
self.__credits = credits
# security.declareProtected(perm_view, 'get_teachers')
# No additional comments.
security.declarePublic('get_teachers')
def get_teachers(self):
"""Get teachers."""
retval = []
for (user, roles) in self.get_local_roles():
if 'Teacher' in roles:
retval.append(user)
return retval
security.declareProtected(perm_view, 'get_start_dd')
# No additional comments.
def get_start_dd(self):
"""Return starting day."""
if self.__starting_date:
return time.localtime(self.__starting_date)[2]
else:
return ''
security.declareProtected(perm_view, 'get_start_mm')
# No additional comments.
def get_start_mm(self):
"""Return starting month."""
if self.__starting_date:
return time.localtime(self.__starting_date)[1]
else:
return ''
security.declareProtected(perm_view, 'get_start_yyyy')
# No additional comments.
def get_start_yyyy(self):
"""Return starting year."""
if self.__starting_date:
return time.localtime(self.__starting_date)[0]
else:
return ''
security.declareProtected(perm_view, 'get_end_dd')
# No additional comments.
def get_end_dd(self):
"""Return ending day."""
if self.__ending_date:
return time.localtime(self.__ending_date)[2]
else:
return ''
security.declareProtected(perm_view, 'get_end_mm')
# No additional comments.
def get_end_mm(self):
"""Return ending month."""
if self.__ending_date:
return time.localtime(self.__ending_date)[1]
else:
return ''
security.declareProtected(perm_view, 'get_end_yyyy')
# No additional comments.
def get_end_yyyy(self):
"""Return ending year."""
if self.__ending_date:
return time.localtime(self.__ending_date)[0]
else:
return ''
# security.declareProtected(perm_view, 'get_printable_starting_date')
security.declarePublic('get_printable_starting_date')
#FIX:security check
# No additional comments.
def get_printable_starting_date(self, REQUEST):
"""Get starting date."""
return time.strftime(translate(self,'short_date_format',target=self.giveLanguage(REQUEST)),
time.localtime(self.__starting_date))
# security.declareProtected(perm_view, 'get_printable_ending_date')
security.declarePublic('get_printable_ending_date')
#FIX:security check
# No additional comments.
def get_printable_ending_date(self, REQUEST):
"""Get ending date."""
if self.__ending_date == 0: return ''
return time.strftime(translate(self,'short_date_format',target=self.giveLanguage(REQUEST)),
time.localtime(self.__ending_date))
security.declarePrivate('get_start_date')
def get_start_date(self):
return self.__starting_date
security.declarePrivate('get_end_date')
def get_end_date(self):
return self.__ending_date
security.declareProtected(perm_view, 'get_users')
def get_users(self, REQUEST):
"""Return dict with 2 members of attendees as UserInfo objects.
'active_d' is the list of active members.
'others_d' is the rest ..
[[UIObj'active1'], [UIObj'other1', UIObj'other2', ..]]"""
rv = {'active_d':[], 'others_d': []}
au = str(REQUEST.AUTHENTICATED_USER)
for uname in [(u[0]) for u in self.get_local_roles()]:
from Errors import FleError
try:
o = self.fle_users.get_user_info(uname)
if uname == au or uname in self.active_memb_cache:
rv['active_d'].append(o)
else:
rv['others_d'].append(o)
except FleError:
pass
return rv
security.declarePublic('get_n_users')
def get_n_users(self):
return len(self.get_all_users_id())
security.declareProtected(perm_view, 'get_all_users')
def get_all_users(self):
"""Return a list of all users on course."""
rv = []
for uname in self.get_all_users_id():
try:
rv.append(self.fle_users.get_user_info(uname))
except Exception:
pass
return rv
def kasutajateKodutoodeArhiiv(self, REQUEST):
"Arhiiv, kuhu paigutatakse kasutaja esitatud materjalid"
import tempfile
import zipfile
failinimi=tempfile.mktemp()
arhiiv=zipfile.ZipFile(failinimi,"w",zipfile.ZIP_DEFLATED)
kasutajad=self.get_all_users()
for x in kasutajad:
kc=getattr(x.webtop, 'c'+self.id)
for too in self.kodutood.objectValues():
if too.tyyp==1: #materjal
if hasattr(kc, 'esitlused'):
if hasattr(kc.esitlused, too.id):
tookataloog=getattr(kc.esitlused, too.id)
tookataloog.looArhiiv(REQUEST, arhiiv, x.id+'/')
if too.tyyp==2: #grupp
mitu=0
punkte=-1
for kg in x.kysiKursuseSisegrupid(self):
if kg.id in too.grupid:
esitluskaust=getattr(self.leiaGrupiKaust(kg.id), too.id)
esitluskaust.looArhiiv(REQUEST, arhiiv, kg.id+'/')
arhiiv.close()
file = open(failinimi,"rb")
export_data=file.read()
file.close()
import os
os.remove(failinimi)
REQUEST.RESPONSE.setHeader('Content-type','application/zip')
REQUEST.RESPONSE.setHeader('Content-disposition','attachment; filename=tooarhiiv.zip')
return export_data
def kysiCSV(self, REQUEST):
"Kasutaja salvestatud punktid"
REQUEST.RESPONSE.setHeader('Content-disposition','attachment; filename=grades.csv')
t="nimi"
kasutajad=self.get_all_users()
for too in self.kodutood.objectValues():
t+=","+too.id
t+=",koond"
for x in kasutajad:
kc=getattr(x.webtop, 'c'+self.id)
t+="\n"+x.get_id()
for too in self.kodutood.objectValues():
t+=","
if hasattr(kc, too.id):
t+=str(getattr(kc, too.id))
t+=","
if hasattr(kc, 'koondhinne'):
t+=str(kc.koondhinne)
return t
def fotogaKasutajad(self):
"kasutajad, kel on foto"
m=[]
for x in self.get_all_users():
if x.has_photo():
m.append(x)
return m
def fototaKasutajad(self):
"kasutajad, kel pole fotot"
m=[]
for x in self.get_all_users():
if not x.has_photo():
m.append(x)
return m
security.declareProtected(perm_view, 'get_all_users_id')
def get_all_users_id(self):
"""Return a list of all users on this course. Same thing as
get_all_users, but this one returns a list of id's of UserInfo
objects, not the UserInfo object reference."""
cl = []
for u in self.get_local_roles():
if 'Student' in u[1] or 'Teacher' in u[1]: cl.append(u[0])
return cl
# return [u[0] for u in self.get_local_roles()]
def kasutajad_sisegrupis(self, grupinimi,objektina=None):
"Sisegrupi rahva loetelu"
loetelu=[]
for u in getattr(self.subgroups, grupinimi).get_local_roles():
if ('User' in u[1]):
if objektina:
loetelu.append(self.fle_users.get_user_info(u[0]))
else:
loetelu.append(u[0])
return loetelu
def kasutajad_sisegrupis_objektina(self,grupinimi):
"""Return a list of all users on course."""
rv = []
grupplased=self.kasutajad_sisegrupis(grupinimi)
for uname in self.kasutajad_sisegrupis(grupinimi):
grupid = []
try:
tekst = ''
rv.append(self.fle_users.get_user_info(uname))
for sisegr in self.fle_users.get_user_info(uname).kysiKursuseSisegrupid(self):
if grupinimi != sisegr.get_name():
grupid.append(sisegr.get_name())
if len(grupid) == 1:
tekst += ' ('+grupid[0]+')'
if len(grupid)>1:
#tekst += ' ('
for gname in grupid:
if tekst:
tekst += ', '
tekst += gname
tekst = '( '+tekst
tekst += ')'
rv.append(tekst)
except Exception:
pass
return rv
def kasutajad_mitte_sisegrupis(self, grupinimi):
"Nimed, kes on kursusel, kuid mitte grupis"
kursuslased=self.get_all_users_id();
grupplased=self.kasutajad_sisegrupis(grupinimi)
mittegrupplased=[]
for u in kursuslased:
tekst = ''
grupid = []
if u not in grupplased:
tekst = ''
for sisegr in self.fle_users.get_user_info(u).kysiKursuseSisegrupid(self):
if grupinimi != sisegr.get_name():
grupid.append(sisegr.get_name())
if len(grupid) == 1:
tekst += ' (' + grupid[0] + ')'
if len(grupid) >1:
tekst += ' ('
i = 0
for gnimi in grupid:
if i != 0:
tekst += ', '
tekst += gnimi
i = i + 1
tekst += ')'
mittegrupplased.append(u)
mittegrupplased.append(tekst)
return mittegrupplased
def kasutajad_sisegruppidesse(self, grupinimi, REQUEST, sisse='', valja=''):
"Tostab kasutajaid gruppi ja valja"
if sisse:
if type(sisse) is types.StringType:
sisse=(sisse,)
for x in sisse:
self.lisa_sisegruppi(grupinimi, x)
if valja:
if type(valja) is types.StringType:
valja=(valja,)
for x in valja:
self.eemalda_sisegrupist(grupinimi, x)
REQUEST.RESPONSE.redirect("workshop_subgroup_show?grname=%s" % grupinimi)
#XXX: security check!
#security.declareProtected(perm_edit, 'workshop_subgroup_handler')
def workshop_subgroup_handler(self,REQUEST,groupName='',delete='',participants='',eventmanage='',sendmessage='',confirmation='',cancel=''):
""" workshop_subgroup form handler """
if not self.is_student(REQUEST) and not self.kas_opetaja(REQUEST):
return ""
if not groupName:
return self.message_dialog_error(
self, REQUEST,
title="Error",
message="no group selected",
action="workshop_subgroup")
if delete:
if confirmation:
self.kustuta_grupp(groupName)
elif cancel:
pass
else:
return self.message_dialog2(self,REQUEST,
title="Confirmation",
message="Are you sure you want to delete subgroup? There will be no undo!",
option1_name="cancel",
option1_value="Cancel",
option2_value="Delete",
option2_name="confirmation",
extra_value_name='delete',
extra_values = ('yes',),
item_name='groupName',
item_value=groupName,
handler="workshop_subgroup_handler")
return REQUEST.RESPONSE.redirect("workshop_subgroup")
if participants:
return REQUEST.RESPONSE.redirect("workshop_subgroup_show?grname="+groupName)
return "show participants..."
if eventmanage:
return REQUEST.RESPONSE.redirect("subgroups/"+groupName+"/syndmused/event_list?userLocation=Tootuba")
# return "Event management..."
if sendmessage:
curUser = self.jooksevKasutaja(REQUEST)
REQUEST.RESPONSE.redirect(curUser.absolute_url()+"/kirjad/createMail?userLocation=Tootuba")
kellele = ''
for x in self.kasutajad_sisegrupis(groupName):
if kellele:
kellele+=','
kellele+=x
REQUEST.SESSION.set('kellele',kellele)
# FIX: delete session variable
return curUser.kirjad.createMail()
return "sending messages..."
return "oioioi"
security.declareProtected(perm_edit, 'kustuta_sisegrupid')
# FIX: XXX REMOVE
def kustuta_sisegrupid(self, REQUEST, grupinimi=None):
"kustutab etteantud grupid"
if grupinimi:
if type(grupinimi) is types.StringType:
grupinimi=(grupinimi,)
for x in grupinimi:
self.kustuta_grupp(x)
REQUEST.RESPONSE.redirect("workshop_subgroup")
security.declareProtected(perm_view, 'get_users_with_role')
def get_users_with_role(self, role):
"""Return a list of participants who have a specified role."""
rv = []
for e in self.get_local_roles():
if role in e[1]:
# try:
rv.append(self.fle_users.get_user_info(e[0]))
# except Exception:
# pass
return rv
security.declareProtected(perm_edit, 'add_student')
#The person is added with Student role access.
# NOTE: This method is no longer needed, except in the test cases!
def add_student(self, name):
"""Add person to the course."""
# Check that user exists... Raises exception if not.
#XXX: is this really needed!? now commented out
# self.fle_users.get_user_info(name)
uinf = self.fle_users.get_user_info(name)
uinf.user_courselist_cache.append(self.get_id())
uinf._p_changed = True
self.set_roles(name, ('Student',))
security.declareProtected(perm_view, 'get_valid_roles')
# No additional comments.
def get_valid_roles(self):
"""Get the roles valid for persons added to the course."""
from CourseManager import course_level_roles
valid_roles = list(course_level_roles)
#valid_roles.append('Teacher')
return valid_roles
security.declareProtected(perm_manage, 'remove_person')
def remove_person(self, person):
"""Remove person from the course."""
# Check that user exists... Raises exception if not.
kasutaja=self.fle_users.get_user_info(person)
try:
kasutaja.user_courselist_cache.remove(self.get_id())
except:
pass
kasutaja._p_changed = True
#We have to do it the hard way since set_jooksev_kursus turns me away
kasutaja.jooksev_kursus=0
# We use the get_local_roles method, because we need to
# see if the user has a role attached to this course object
# specifically, and we don't want the roles in the acquisition
# tree to interfere.
if len(get_local_roles(self,person))==0:
raise FleError, ("User "+person+" does not belong to this course.")
self.__unset_roles((person,))
# Note: person _must_ be a sequence!
def __unset_roles(self, persons):
"""Unset roles of one user."""
self.manage_delLocalRoles(persons)
security.declareProtected(perm_view, 'has_role')
# No additional comments.
def has_role(self, person, role):
"""Return whether the user is in the specified role."""
return role in get_roles(self,person)
security.declareProtected(perm_view, 'get_teacher')
def get_teacher(self):
"""Get the name of the teacher (creator of the course)."""
for user,roles in self.get_local_roles():
if 'Teacher' in roles:
return user
raise 'Course has no teacher!'
security.declareProtected(perm_edit, 'set_roles')
# Note: roles _must_ be a sequence!
# Called from CourseManager.add_users_form_handler
def set_roles(self, person, roles):
"""Set roles of one person."""
self.__unset_roles(person)
self.manage_setLocalRoles(person, roles)
def lisa_sisegruppi(self, grupinimi, kasutajanimi):
""" Lisab kasutaja gruppi """
rols = getattr(self.subgroups, grupinimi).get_local_roles_for_userid(kasutajanimi)
if "User" not in rols:
rols = rols +("User",)
getattr(self.subgroups, grupinimi).manage_setLocalRoles(kasutajanimi, rols)
return kasutajanimi + "grupis"
def eemalda_sisegrupist(self, grupinimi, kasutajanimi):
""" Eemaldab kasutaja grupist """
roles = getattr(self.subgroups, grupinimi).get_local_roles_for_userid(kasutajanimi)
new_roles = ()
for x in roles:
if x == 'User': continue
new_roles += (x,)
if not new_roles:
getattr(self.subgroups, grupinimi).manage_delLocalRoles((kasutajanimi,))
else:
getattr(self.subgroups, grupinimi).manage_setLocalRoles(kasutajanimi,new_roles)
return kasutajanimi + "grupist"
# FIXME: input_checks: tt_set_name not checked
# FIXME: input_checks: two course contexts can have identical name.
security.declareProtected(perm_add_lo, 'add_course_context')
# Handler for add_course_context_form
def add_course_context(
self, my_name, description, tt_set_name,
description_long,
REQUEST,
use_roleplay='', # New in ZPTIVA
show_only_roleplay='',
# Submit buttons.
publish='',
cancel='',
):
"""Add CourseContext object."""
if publish:
error_fields = []
errors = []
my_name = my_name.strip()
if not is_valid_title(my_name):
error_fields.append(translate(self,'title of context',target=self.giveLanguage(REQUEST)))
if my_name in [x[1] for x in self.get_course_context_names()]:
errors.append(translate(self,"Name '%s' taken",target=self.giveLanguage(REQUEST)) % my_name)
# Variables 'description' and 'description_long' are not checked
# because render_description() and render_long_description()
# methods in CourseContext filter out unwanted HTML tags.
if len(error_fields) > 0 or len(errors) > 0:
msg = ", ".join(errors)
if len(error_fields) > 0:
msg = msg + " " + 'Invalid fields' + \
": '" + "' , '".join(error_fields) + "'"
return self.message_dialog_error(
self, REQUEST,
title='Invalid input',
message=msg,
action=apply(
make_action,
['add_course_context_form'] +
[(x, eval(x)) for x in
('my_name', 'description', 'tt_set_name',
'description_long')]))
uname=str(REQUEST.AUTHENTICATED_USER)
obj = CourseContext(
self, my_name, description, description_long, tt_set_name,
uname,)
obj.public = 1
if (show_only_roleplay)==1:
obj.__roleplay_only = 1
id = obj.get_id()
self._setObject(id, obj)
self.lisaSyndmus(REQUEST, 'konteksteLisatud')
try:
obj.changeOwnership(self.acl_users.getUser(uname).__of__(self.acl_users))
obj.manage_setLocalRoles(uname,('Owner',))
except:
pass
if REQUEST:
pagename=""
if use_roleplay:
pagename="course_setup_roleplay_form"
REQUEST.RESPONSE.redirect('%s/%s' % (str(id),pagename))
elif cancel:
return REQUEST.RESPONSE.redirect(REQUEST.URL1)
else:
raise "add_course_context called without 'publish' or 'cancel'"
security.declareProtected(perm_view, 'get_course_context_names')
# No additional comments.
def get_course_context_names(self):
"""Return a list of CourseContext names."""
retval = {}
for e in self.get_children('CourseContext'):
id = e.get_id()
name = e.get_name()
retval[id] = name
return retval.items()
#security.declareProtected(perm_view, 'get_n_notes')
def get_n_notes(self):
"""Returns a sum of all notes in all contexts."""
count = 0
for cc in self.get_course_contexts():
count += cc.get_n_notes()
return count
security.declareProtected(perm_view, 'get_n_unread_notes')
def get_n_unread_notes(self,uname):
"""Returns a sum of all unread notes in all contexts."""
count = 0
for cc in self.get_course_contexts():
count += cc.get_n_unread_notes(uname)
return count
security.declarePublic('update')
# Parameters are received from the form (apparently).
def update(
self,
name,
description,
organisation,
methods,
starting_date,
ending_date,
tekst,
logo=None,
staatus=0,
cCat = 0,
credits='',
courseID='',
):
"""Edit course information."""
self.__name = name
self.__description = description
self.__organisation = organisation
self.__methods = methods
self.__starting_date = starting_date
self.__ending_date = ending_date
self.paneTekst(tekst)
if logo:
self.paneLogo(logo)
self.paneStaatus(staatus)
self.setCourseCategory(int(cCat))
self.set_credits(credits)
self.set_courseID(courseID)
security.declareProtected(perm_view, 'get_course_contexts')
def get_course_contexts(self):
"""Return a list of all course contexts in this course."""
for abc in self.get_children('CourseContext'):
if not hasattr(abc, 'public'):
abc.public = 1
return self.get_children('CourseContext')
security.declareProtected(perm_view, 'get_course_context_ids_in_order')
def get_course_context_ids_in_order(self, id_list):
"""Return a list of ids of all course contexts in this course."""
return [o.get_id() for o in self.get_course_contexts_in_order(id_list)]
security.declareProtected(perm_edit, 'delete_course_context')
def context_form_handler(self,REQUEST,cc_id,staatus='', kustuta=''):
""" delete or change status """
import types
if type(cc_id) is types.StringType:
cc_id = ((cc_id),)
#if staatus and kustuta:
# raise 'IVA error','oops, both buttons athe same time in Knowledge building form'
for abc in cc_id:
self.hide_show_course_context(abc)
#if kustuta:
# for abc in cc_id:
# self.delete_course_context(abc)
return REQUEST.RESPONSE.redirect(self.absolute_url()+'/course_html')
security.declareProtected(perm_edit, 'delete_course_context')
def delete_course_context(self,id):
for c in self.get_children('CourseContext'):
if c.get_id() == id:
self._delObject(id)
return
security.declareProtected(perm_edit, 'hide_show_course_context')
def hide_show_course_context(self,id):
for c in self.get_children('CourseContext'):
if c.get_id() == id:
if c.public == 1:
c.public = 0
else:
c.public = 1
return
# FIXME: See the random comment below, random is not
# FIXME: probably the order that we really want.
security.declareProtected(perm_view, 'get_course_contexts_in_order')
def get_course_contexts_in_order(self, id_list):
"""Return a list of all course contexts in this course."""
contexts = {}
for c in self.get_children('CourseContext'):
contexts[c.get_id()] = c
try:
pass
except:
c.public = 1
retval = []
if id_list and id_list != ['']:
if type(id_list) == types.StringType:
id_list = (id_list, )
# Return courses contexts in a given order.
for identifier in id_list:
try:
retval.append(contexts[identifier])
del contexts[identifier]
except KeyError: # invalid id_list
pass
# If we still course contexts left (id_list is shorter
# than the actual number of course_contexts), append
# them to list in a random order.
for key in contexts.keys():
retval.append(contexts[key])
return retval
security.declarePublic('may_view_course')
def may_view_course(self, REQUEST):
"""Return boolean depending on wether user may or may not view
the course."""
from AccessControl.PermissionRole import rolesForPermissionOn
return intersect_bool(
get_roles(self,str(REQUEST.AUTHENTICATED_USER)),
rolesForPermissionOn(perm_view,self))
security.declareProtected(perm_view, 'may_add_course_context')
def may_add_course_context(self, person):
"""Return boolean depending on wether user may or may not add
a course context to the course."""
from AccessControl.PermissionRole import rolesForPermissionOn
return intersect_bool(
get_roles(self,person),
rolesForPermissionOn(perm_add_lo,self))
security.declareProtected(perm_view, 'may_edit_course')
def may_edit_course(self, person):
"""Return boolean depending on whether person can edit the course
or not."""
from AccessControl.PermissionRole import rolesForPermissionOn
return intersect_bool(
get_roles(self,person),
rolesForPermissionOn(perm_edit,self))
security.declareProtected(perm_view, 'active_members')
#FIXME: Why not "get_active_members"
def active_members(self):
"""Return a list of names of users who are active."""
return self.active_memb_cache
security.declareProtected(perm_view, 'has_group_folder')
def has_group_folder(self):
"""Return whether course has a group folder or not."""
return len(self.objectIds('GroupFolder'))>0
def add_folder(self, my_name):
from GroupFolder import GroupFolder
from GroupFolderProxy import GroupFolderProxy
new_id = 'gf'
fol = GroupFolder(None,my_name)
fol.id=new_id
self._setObject(new_id,fol)
fol=fol.__of__(self)
# self.make_group_folder_proxies(self.get_all_users())
proxy = GroupFolderProxy(None, # any sense?
self.get_name(),
self.get_id())
self.jamming._setObject('0', proxy)
return fol
def make_group_folder_proxies(self, users):
for user in users:
# user.webtop.add_link(self.get_name()+" (Shared)",self.get_url_to_object(self.gf),1)
user.webtop.add_group_folder_proxy(self.get_name(), self.get_id())
def remove_folder_link(self,users):
gf = self.get_child('gf')
for user in users:
fol = user.webtop
self.__recurse_remove_folder_link(fol, gf)
def __recurse_remove_folder_link(self, folder, gf):
for (_id, proxy_fol) in folder.objectItems('GroupFolderProxy'):
if proxy_fol.is_proxy_for(gf):
folder._delObject(_id)
for fol in folder.objectValues('WebtopFolder'):
self.__recurse_remove_folder_link(fol, gf)
security.declareProtected(perm_edit, 'teacher_export')
def teacher_export(self,REQUEST):
""" teacher export """
self.iva_ims_export(REQUEST)
security.declareProtected(perm_edit, 'iva_ims_export')
def iva_ims_export(self, REQUEST=None, testinimi='',teacherExporting=1):
""" Course or a quiz export. XML format. """
from ImportExportIMS import Kirjutus
from ImportExportIMS import kirjutaYldM
import tempfile, os
failinimi = tempfile.mktemp()
# self.fle_users.export_users(REQUEST,failinimi='ivaexport.zip',kursusega='jah',palju='self.fle_root().fle_users.get_users()')
if testinimi:
yld = kirjutaYldM()
yld.kirjutaYldmanifest(self.get_id(),'QTI test','imsqti_xmlv1p1','','qti.xml')
yld.lisaFaili(failinimi)
k= Kirjutus(self.fle_root(), self.get_id())
#k.looKursuseFail()
#k.exportQTI(failinimi,'')
parent = k.looTestiFail()
k.kirjutaTestid(parent,testinimi)
k.kirjutaTestidZipi(failinimi,'')
#k.pakiKursusFaili(failinimi)
# k.pakiTulemusFaili(failinimi,testsonly="testsonly")
else:
yld = kirjutaYldM()
yld.kirjutaYldmanifest(self.get_id(), self.get_description(),base=str(self.get_id())+"/")
yld.lisaFaili(failinimi)
k = Kirjutus(self.fle_root(), self.get_id())
k.looKursuseFail()
k.kirjutavCal(self.syndmused,'kursus','GROUP')
k.kirjutaWebtop(self.gf,tiitel='RAAMATURIIUL')
for sisegr in self.subgroups.objectValues('GroupFolder'):
k.kirjutaWebtop(sisegr,'SISEGRUPP:'+sisegr.get_name())
try:
k.kirjutavCal(sisegr.syndmused,sisegr.get_name(),'GROUP')
except:
pass
if not teacherExporting:
k.kirjutaKasutajaWebtop(self.get_all_users())
k.kirjutaKasutajaSyndmus(self.get_all_users())
self.fle_users.export_users(REQUEST,failinimi=failinimi,kursusega=self.get_id(),palju='kursus.get_all_users()')
k.kirjutaItem(k.organization, tiitel='KURSUSE KASUTAJAD',parameters='KURSUSE KASUTAJAD')
k.kirjutaResource(k.resources, 'imsent_xmlv1p1','users.xml')
k.exportQTI(failinimi,str(self.get_id())+"/",teacherExporting=teacherExporting)
k.exportPajad(failinimi,str(self.get_id())+"/",startonly=teacherExporting)
k.exportKodutood(self.kodutood,failinimi,str(self.get_id())+"/")
k.pakiKursusFaili(failinimi)
if REQUEST:
file = open(failinimi,"rb")
export_data=file.read()
file.close()
os.remove(failinimi)
REQUEST.RESPONSE.setHeader('Content-disposition','attachment; filename=ivaexport.zip')
REQUEST.RESPONSE.setHeader('content-type','application/zip')
return export_data
else:
import os
import shutil
name='iva_'+re.sub('[^a-zA-Z0-9]', '_', self.get_name())
name2 = name
number = 1
searched=0
print os.path.isfile(os.path.join(Globals.INSTANCE_HOME,'var',name+'.zip'))
print os.path.join(Globals.INSTANCE_HOME,'var',name+'.zip')
while os.path.isfile(os.path.join(Globals.INSTANCE_HOME,'var',name+'.zip')):
number = number + 1
name = name2+'_ver'+str(number)
searched=1
name += '.zip'
shutil.move(failinimi,os.path.join(Globals.INSTANCE_HOME,'var',name))
return self.get_name() + ' - ' + os.path.join(Globals.INSTANCE_HOME,'var',name)
def write_touchgraph_data(self,obj,type,children_types=None,extra_links=None):
links = ''
if children_types:
links = ' '.join(obj.objectIds(children_types))
if extra_links:
links = ' '.join((links,extra_links))
if not links:
links=' '
return obj.get_id()+'\t'+\
type+"\t"+\
self.REQUEST.BASE0+self.get_url_to_object(obj)+'\t'+\
obj.get_name()+'\t'\
+links+'\t'
# But should we protect it somehow?
# The Java client would then need authentication
def touchgraph_data(self):
"""This is a public method."""
data=self.write_touchgraph_data(self,"COURSE","CourseContext")
for ctx in self.objectValues("CourseContext"):
data=data+ctx.touchgraph_data()
return data+"[END DATA]"
def kysiSyndmusteKataloog(self):
"Lisatakse kui pole"
import Kalender
if not hasattr(self, 'syndmused'):
self._setObject('syndmused', Kalender.KalendriSyndmusteKataloog())
self.syndmused.id='syndmused'
return self.syndmused
def kysiTekst(self):
"Kursuse uudis/moto. Vastab tyhja kui pole"
if hasattr(self, 'teatetekst'): return self.teatetekst
else: return ""
def paneTekst(self, tekst):
"Teksti lisamine"
self.teatetekst=tekst
return "Lisatud "+tekst
def paneLogo(self, logo):
"Logo lisamine"
self.logo=logo
def kysiLogo(self):
"Pildi kahendandmed"
# XXX:weird hack
if hasattr(self, 'logo') and self.logo and self.logo.strip(): return self.logo
return None
def kysiLogoViide(self, REQUEST=None):
"Logo link, kui on"
if self.kysiLogo():
return ""
return ""
def paneAutomaatRegistreerumine(self, automaatRegistreerumine):
"Tunnuse salvestus"
self.automaatRegistreerumine=automaatRegistreerumine
def kysiAutomaatRegistreerumine(self):
"Vljastus, puudumise korral 0"
if hasattr(self, 'automaatRegistreerumine'):
return self.automaatRegistreerumine
return 0
def paneStaatus(self, staatus):
"staatuse salvestus"
self.staatus=staatus
def kysiStaatus(self):
"Staatuse ksimine"
if hasattr(self, 'staatus'):
return self.staatus
return 0
def kysiStaatusNimi(self, REQUEST):
"Staatuse nimi"
if hasattr(self,'staatus'):
return self.kysiStaatuseTekst(int(self.kysiStaatus()), REQUEST)
return 0
def kysiStaatuseValikud(self, REQUEST):
"Valikud rippmensse"
tulemus=""
for i in range(5):
tulemus=tulemus+"\n"
return tulemus
def tootoaKylastus(self, REQUEST, ala):
"Vastava alamtoa klastusaja sttimine"
if not hasattr(self, 'tootoaKylastused'):
self.tootoaKylastused={}
if not self.tootoaKylastused.has_key(ala):
self.tootoaKylastused[ala]={}
self.tootoaKylastused[ala][REQUEST.AUTHENTICATED_USER.getUserName()]=time.time()
self.tootoaKylastused=self.tootoaKylastused
return self.tootoaKylastused
def tootoaMuutus(self, ala):
"Alamtoas toimunud muutus"
if not hasattr(self, 'tootoaMuutused'):
self.tootoaMuutused={}
self.tootoaMuutused[ala]=time.time()
self._p_changed = True
return self.tootoaMuutused
def viimaneTootoaMuutus(self, ala):
"Muutuse lugemine"
try:
return self.tootoaMuutused[ala]
except KeyError:
return 0
def viimaneTootoaKylastus(self, REQUEST, ala):
"Viimane klastusaeg vastaval inimesel selle ala peal"
knimi=REQUEST.AUTHENTICATED_USER.getUserName()
if hasattr(self, 'tootoaKylastused'):
if self.tootoaKylastused.has_key(ala):
if self.tootoaKylastused[ala].has_key(knimi):
return self.tootoaKylastused[ala][knimi]
return 0
def kasMuudetudParastTootoaKylastust(self, REQUEST, ala):
"jah/ei"
return str(self.viimaneTootoaKylastus(REQUEST, ala)>self.viimaneTootoaMuutus(ala))+"!!"
security.declareProtected(perm_view, 'search_form_handler')
def search_form_handler(
self,
REQUEST,
cancel=None, # submit buttons
submit=None, #
get_name = None,
get_content= None
):
"""Search form handler."""
if (submit) and ((get_name) or (get_content)):
for s in 'get_name', 'get_content':
REQUEST.set(s, REQUEST[s])
if REQUEST['get_author_name'] == '___anyone___':
uname = str(self.REQUEST.AUTHENTICATED_USER)
if len(self.fle_users.get_user_info(uname).user_courses()) > 0:
REQUEST.set('get_author_name',
self.courses.get_unames_on_my_courses(REQUEST))
else:
REQUEST.set('get_author_name', uname)
else:
REQUEST.set('get_author_name', REQUEST['get_author_name'])
return self.wt_search_results(self, REQUEST)
elif cancel:
REQUEST.RESPONSE.redirect('index_html')
else:
REQUEST.RESPONSE.redirect(REQUEST['HTTP_REFERER'])
security.declareProtected(perm_view,'getCourseCategory')
def getCourseCategory(self):
return self.course_category
security.declarePrivate('setcourseCategory')
def setCourseCategory(self, id):
self.course_category = id
self._p_changed = 1
def get_n_artefacts(self):
""" number of artefacts on a course """
total = 0
for x in self.jamming.objectValues('JamSession'):
total += x.get_n_artefacts()
return total
def total_n_unseen_jams(self,REQUEST):
total = 0
for x in self.jamming.objectValues('JamSession'):
total += x.get_n_unread_artefacts(REQUEST)
return total
def isCourseAlive(self):
""" when was last input, new objects, artefacts? """
curtime = time.time()
aeg = curtime-86400*30
#XXX: go away!
if not hasattr(self, 'tootoaMuutused'):
self.tootoaMuutused = {}
if self.viimaneTootoaMuutus('teadmuspaja')aeg: aeg = self.viimaneTootoaMuutus('teadmuspaja')
if self.viimaneTootoaMuutus('meediapaja')>aeg: aeg = self.viimaneTootoaMuutus('meediapaja')
return aeg
def lastModify_printable(self,REQUEST):
""" returns printable last modification date """
return time.strftime(translate(self,'short_date_format',target=self.giveLanguage(REQUEST)),time.localtime(self.lastModify()))
def lastActive(self):
""" return last visit to course """
first = 1
for x in self.get_all_users():
if first:
aeg = x.last_active(self.get_id())
first = 0
if x.last_active(self.get_id())>aeg:
aeg = x.last_active(self.get_id())
return aeg
def lastActive_printable(self,REQUEST):
""" return last visit to course """
return time.strftime(translate(self,'short_date_format',target=self.giveLanguage(REQUEST)),time.localtime(self.lastActive()))
Globals.default__class_init__(Course)
# EOF
iva/CourseContext.py 0100644 0000764 0000764 00000041352 10172721725 014072 0 ustar vahur vahur # -*- coding: utf-8
# $Id: CourseContext.py,v 1.4 2003/08/18 07:44:24 berlingo Exp $
# 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 CourseContext, which represents one part of a Course."""
__version__ = "$Revision: 1.4 $"[11:-2]
import OFS, Globals
import AccessControl
import re, string, types
from Thread import Thread, EventManager
from common import reload_dtml, add_dtml, intersect_bool, make_action, get_roles
from input_checks import strip_all, render, is_valid_title, \
normal_entry_tags_and_link
from TraversableWrapper import TraversableWrapper, Traversable
from AccessControl import ClassSecurityInfo
from NoteDTML import NoteDTML
from Cruft import Cruft
from TempObjectManager import TempObjectManager
from common import perm_view, perm_edit, perm_manage, perm_add_lo, translate
import Course
# CourseContexts exist inside Courses. Each course has at least one
# context, since contexts in turn can contain Notes that form
# knowledge building threads.
class CourseContext(
EventManager,
TraversableWrapper,
Traversable,
Cruft,
Thread,
NoteDTML,
TempObjectManager,
):
"""Course Context."""
meta_type = 'CourseContext'
security = ClassSecurityInfo()
security.declareObjectPublic()
# Call courses/context_html (This way we avoid copying index_html
# to each instance of CourseContext class.)
security.declareProtected(perm_view, 'index_html')
def index_html(self, REQUEST):
"""index_html page."""
self.update_reader(str(REQUEST.AUTHENTICATED_USER))
return REQUEST.RESPONSE.redirect('context_html')
#return self.courses.context_html(self, REQUEST)
# @tts_name: id of the global knowledge type set that should
# be copied to this context. If set to '' or None, nothing is
# copied.
def __init__(
self, parent, my_name, description, descr_long, tts_name, author):
"""Construct the course context object."""
Thread.__init__(self, parent)
EventManager.__init__(self)
NoteDTML.__init__(self)
self.__name = strip_all(my_name) # Get rid of possible HTML tags
# Variables description and descr_long are not filtered because
# render_description() and get_long_description() methods do the
# filtering... (Why? To make it slower? At least this way it is
# easier to change tags that are filtered afterwards.)
self.__description = description
self.__author = author
self.__roleplay_in_use = 0
self.__roleplay = {}
self.__roleplay_only = 0
# Adds long course context description.
#
# Why don't we just use self.descr_long ? Is it too simple solution? ;)
# (ik/16.1.2002)
if not descr_long:
descr_long = ' '
self.manage_addDTMLDocument('descr_long', '', descr_long)
# Select the thinking type set to use for this course context.
if tts_name:
h = parent.fle_root().typesets
if not h.is_valid_tts(tts_name):
raise 'FLE Error', 'Non-existing thinking type set to use for Course Context.'
# Store the name, even if it's None
self._tt_set_id = tts_name
security.declarePrivate('manage_afterAdd')
def manage_afterAdd(self, item, container):
"""Set default permissions for different roles."""
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+('Owner',), 0)
self.manage_permission(perm_add_lo, roles_student, 0)
# self.manage_permission(perm_view, roles_student, 0)
if self._tt_set_id:
# Make a real copy of the global typeset.
tt_set = getattr(self.typesets, self._tt_set_id)
self._setObject(
self._tt_set_id,
tt_set.make_copy())
TempObjectManager.manage_afterAdd(self, item, container)
security.declareProtected(perm_view, 'get_author')
def get_author(self):
"""Return author name."""
return self.__author
def is_courseContext(self):
""" is course context? """
return 1
security.declareProtected(perm_view, 'may_edit_course_context')
def may_edit_course_context(self, person):
"""Return boolean depending on whether person can edit the course
context or not."""
from AccessControl.PermissionRole import rolesForPermissionOn
return intersect_bool(
get_roles(self,person),
rolesForPermissionOn(perm_edit,self))
security.declareProtected(perm_view, 'get_n_notes')
def get_n_notes(self):
"""Return number of notes in this CourseContext."""
n = 0
for note in self.get_children('Note'):
n += note.get_n_notes()
return n
# This is a stub that is needed, because when a note is published, it
# will call its parent's uncache_notes method. When a new thread is
# started, the call ends up here.
def uncache_notes(self):
pass
security.declareProtected(perm_view, 'get_n_unread_notes')
def get_n_unread_notes(self, uname):
"""Return number of unread notes in this CourseContext for given user."""
n = 0
for note in self.get_children('Note'):
n += note.get_n_unread_notes(uname)
return n
security.declareProtected(perm_view, 'get_printable_name')
# No additional comments.
def get_printable_name(self):
"""Return name of the CourseContext"""
return self.__name
security.declareProtected(perm_view, 'get_possible_follow_ups')
def get_possible_follow_ups(self):
return self.get_thinking_type_thread_start()
security.declareProtected(perm_view, 'get_thinking_type_thread_start')
def get_thinking_type_thread_start(self):
"""Gives list of thinking types that can start a thread."""
tts = self.get_thinking_type_set()
return tts.get_thinking_type_thread_start()
security.declareProtected(perm_view, 'get_thinking_type_set')
def get_thinking_type_set(self):
"""Return ThinkingTypeSet object."""
return self.get_child(self._tt_set_id)
security.declareProtected(perm_view, 'get_thinking_type_set_id')
def get_thinking_type_set_id(self):
"""Return ThinkingTypeSet id."""
return self._tt_set_id
security.declareProtected(perm_view, 'get_name')
# No additional comments.
def get_name(self):
"""Return name."""
return self.__name
security.declareProtected(perm_view, 'get_description')
# No additional comments.
def get_description(self):
"""Return description."""
return self.__description
security.declareProtected(perm_view,'render_description')
def render_description(self):
"""Render description."""
return render(
self.get_description(),
legal_tags=normal_entry_tags_and_link)
security.declareProtected(perm_view, 'get_long_description')
# No additional comments.
def get_long_description(self):
"""Return description."""
return self._getOb('descr_long')()
security.declareProtected(perm_view, 'is_long_description_empty')
def is_long_description_empty(self):
"""Does long description contain only white space?"""
return self.get_long_description().strip() == ''
security.declareProtected(perm_view,'render_long_description')
def render_long_description(self):
"""Render long description."""
return render(
self.get_long_description(),
legal_tags=normal_entry_tags_and_link)
## security.declareProtected(perm_view, 'get_title')
## # No additional comments.
## def get_title(self):
## """Return title."""
## return self.title
security.declareProtected(perm_view, 'get_course_ref')
def get_course_ref(self):
"""Return reference to the course of this CourseContext."""
return self.find_class_obj(Course.Course)
# The following three ugly utility functions are called from dtml files
# to help constructing sensible URLs in Knowledge building.
security.declarePublic('get_url1')
# Called from ui/CourseContext/repr_norm.dtml
def get_url1(self, REQUEST):
"""Return url to the course context object."""
url = REQUEST.URL0
m = re.match("^(.*/courses/.*?/.*?)/.", url)
return m.group(1)
security.declarePublic('get_url2')
# Called from ui/CourseContext/repr_in_course.dtml
# Actual final view: index_html of Course
def get_url2(self, REQUEST, course_context_id):
"""Return url to the course context object."""
url = REQUEST.URL1
return url + "/" + course_context_id
security.declarePublic('get_url3')
# Called from ui/CourseManager/course_context_location_path.dtml
def get_url3(self, REQUEST):
"""Return URL to the course object."""
url = REQUEST.URL0
m = re.match("^(.*/courses/.*?)/", url)
return m.group(1)
security.declarePublic('is_temporary')
def is_temporary(self):
"""This is here to diguise CourseContext objects as Note objects. ;)"""
return 0
security.declareProtected(perm_edit, 'edit_course_context')
def edit_course_context(self,
REQUEST,
my_name = '',
description = '',
description_long = '',
use_roleplay = 0,
show_only_roleplay = '',
delete = '',
cancel = '', # submit buttons
publish = '', #
):
"""Handler for ui/CourseContext/edit_course_context_form.dtml."""
if delete:
# return self.message_dialog2(self, REQUEST,
# title='Title for three',
# message='Are you sure you want to delete %s context' % self.get_name(),
# handler='delete_form_handler',
# option1_value='Delete',
# option1_name='delete',
# option2_value='Cancel',
# option2_name='cancel',
# )
return self.message_dialog2(
self, REQUEST,
title = 'Confirmation',
message = translate(self,'Are you sure you want to delete this course context:',target=self.giveLanguage(REQUEST)) + ' ' + \
self.get_name(),
handler = 'delete_form_handler',
extra_value_name = 'ctx_id',
extra_values = (self.get_id(),),
option1_value = 'Cancel',
option1_name = 'cancel',
option2_value = 'Ok',
option2_name = 'delete'
)
elif publish:
error_fields = []
errors = []
my_name = my_name.strip()
if not is_valid_title(my_name):
error_fields.append(translate(self,'title of context',self.giveLanguage(REQUEST)))
if my_name != self.get_name() and \
my_name in [x[1] for x in self.get_course_context_names()]:
errors.append(translate(self,"Name '%s' taken",target=self.giveLanguage(REQUEST)) % my_name,)
# Variables 'description' and 'description_long' are not checked
# because render_description() and render_long_description()
# methods filter out unwanted HTML tags.
if len(error_fields) > 0 or len(errors) > 0:
msg = ", ".join(errors)
if len(error_fields) > 0:
msg = msg + " " + 'Invalid fields' + \
": '" + "' , '".join(error_fields) + "'"
return self.message_dialog_error(
self, REQUEST,
title='Invalid input',
message=msg,
action=apply(
make_action,
['edit_course_context_form'] +
[(x, eval(x)) for x in
('my_name', 'description', 'description_long')]))
self.__name = my_name
self.__description = description
# Edit long course context description.
description_long_ob = self._getOb('descr_long')
description_long_ob.manage_edit(description_long,
'description_long')
# Set roles for users.
#XXX below line might be useful!?
# self.set_roleplay(publish=1, REQUEST=REQUEST)
# Use roleplay?
self.__roleplay_in_use = use_roleplay
self.__roleplay_only = show_only_roleplay
if use_roleplay:
return REQUEST.RESPONSE.redirect('course_setup_roleplay_form')
else:
return REQUEST.RESPONSE.redirect('index_html')
elif cancel:
return REQUEST.RESPONSE.redirect('index_html')
else:
raise 'FLE error', 'Unknown button'
security.declarePrivate('set_roleplay_use')
def set_roleplay_use(self, in_use):
"""Set whether or not this context uses roleplaying."""
self.__roleplay_in_use = in_use
security.declareProtected(perm_view, 'uses_roleplay_only')
def uses_roleplay_only(self):
""" true and roles only will be displayed """
return self.__roleplay_only
def set_roleplay_only(self, value):
self.__roleplay_only = value
security.declareProtected(perm_view, 'uses_roleplay')
def uses_roleplay(self):
"""Returns whether or not this context uses roleplaying."""
return self.__roleplay_in_use
security.declarePrivate('set_user_role_name')
def set_user_role_name(self, uname, role_name):
"""Set playrole for user given by user's uname."""
self.__roleplay[uname] = role_name
self._p_changed = 1
security.declareProtected(perm_edit, 'set_roleplay')
def set_roleplay(self,cancel='',publish='',REQUEST=None):
"""Sets up roleplaying for this context."""
if publish and REQUEST:
self.__roleplay={}
self.__roleplay_in_use = 1
for (key,val) in REQUEST.items():
if key.startswith('roleplay_'):
self.__roleplay[key[9:]]=val
self._p_changed=1
REQUEST.RESPONSE.redirect('index_html')
security.declareProtected(perm_view, 'get_nickname_with_role_name')
def get_nickname_with_role_name(self, uname):
"""Return role name (if exists) followed by nickname in parentheses.
If roleplay is not used in this CourseContext returns only nickname."""
nickname = self.fle_users.get_user_info(uname).firstAndLast(uname)
if self.uses_roleplay():
role = self.get_role_played_by_user(uname)
if self.uses_roleplay_only():
return role
return role + ' (' + nickname + ')'
else:
return nickname
security.declareProtected(perm_view, 'get_role_played_by_user')
def get_role_played_by_user(self,uname):
"""Returns the role of the specified user in
this context's roleplay."""
try:
return self.__roleplay[uname]
except AttributeError:
return ""
except KeyError:
return ""
security.declareProtected(perm_edit, 'delete_form_handler')
def delete_form_handler(
self,
REQUEST,
delete='',
cancel='',
):
"""Form handler that is called from message_dialog2."""
if delete:
id_ = self.get_id()
self.parent()._delObject(id_)
return REQUEST.RESPONSE.redirect("../index_html")
# XXX: maybe we need it, I don't know...
#return REQUEST.RESPONSE.redirect(self.state_href_remove_from_list(REQUEST, "../index_html", 'cc_order' + self.parent().get_id(), id_))
else:
return REQUEST.RESPONSE.redirect("index_html")
def touchgraph_data(self):
data=self.write_touchgraph_data(self,"CONTEXT","Note")
set = self.get_thinking_type_set()
for tt in set.get_thinking_types():
data=data+tt.touchgraph_data()
for note in self.objectValues("Note"):
data=data+note.touchgraph_data()
return data
Globals.InitializeClass(CourseContext)
# EOF
iva/CourseManager.py 0100644 0000764 0000764 00000112537 10166766406 014034 0 ustar vahur vahur # -*- coding: utf-8
# $Id: CourseManager.py,v 1.7 2003/08/18 07:44:24 berlingo Exp $
# 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 CourseManager, which acts as a factory object for Courses and also the container for the courses."""
__version__ = '$Revision: 1.7 $'[11:-2]
import re, string, time
import strptime
import OFS, Globals, AccessControl
from Globals import Persistent, PersistentMapping
import types
from Products.ZCatalog.ZCatalog import ZCatalog
# from TraversableWrapper import TraversableWrapper as TW
from TraversableWrapper import Traversable
from Course import Course
from common import new_reload_dtml, reload_dtml, add_dtml, iterate_fle_path, \
quote_html_hack, make_action
from common import perm_view, perm_edit, perm_manage, perm_add_lo, perm_access,\
roles_admin, roles_staff, roles_user, translate
from input_checks import is_valid_title
from Thread import Thread
from AccessControl import ClassSecurityInfo
from Cruft import Cruft
from common import course_level_roles
from common import roles_teacher, roles_tutor, roles_student
class IDManager(Thread):
security = ClassSecurityInfo()
def __init__(self):
self.__id_counter = 0L
# Overrides generate_id from Thread!
security.declarePrivate('generate_id')
def generate_id(self):
"""Return a probably random integer."""
self.__id_counter += 1L
return str(self.__id_counter)
# CourseManager exists in FLE/courses and contains all the courses
# that the FLE installation holds.
class CourseManager(
OFS.Folder.Folder,
Traversable,
Cruft,
Persistent,
AccessControl.Role.RoleManager,
OFS.SimpleItem.Item,
IDManager,
):
"""FLE Coursemanager."""
meta_type = 'CourseManager'
security = ClassSecurityInfo()
security.declareObjectPublic()
# No additional comments.
def __init__(self, id):
"""Construct Course manager object."""
self.id = id
self.title = ''
self.cCategories = PersistentMapping()
self.cCategories['groups'] = {}
IDManager.__init__(self)
for role in course_level_roles:
self._addRole(role)
from common import new_reload_dtml
# printers = PrinterManager('printers', 'PrinterManager')
# self._setObject('printers', printers)
catalog = ZCatalog('catalog_notes', 'ZCatalog for notes')
# indexes
catalog.addIndex('get_subject', 'TextIndex')
catalog.addIndex('get_body', 'TextIndex')
catalog.addIndex('get_author', 'FieldIndex')
catalog.addIndex('get_tt_id', 'FieldIndex')
# metadata
catalog.addColumn('get_subject')
catalog.addColumn('get_author')
catalog.addColumn('absolute_url')
self._setObject('catalog_notes', catalog)
self._p_changed = 1
security.declarePrivate('manage_afterAdd')
def manage_afterAdd(self, item, container):
"""Set default permissions for roles."""
self.manage_permission(perm_access, ('Manager','IVAAdmin','Student','Teacher'), 0)
self.manage_permission(perm_edit, ('Manager','IVAAdmin','Teacher'), 0)
self.manage_permission(perm_view, ('Manager','IVAAdmin','Teacher','Student'), 0)
self.manage_permission(perm_add_lo, ('Manager','IVAAdmin','Teacher'), 0)
try:
self.manage_permission('Zwiki: Add pages', ('Teacher','Owner',), 0)
self.manage_permission('Zwiki: Add wikis', ('Teacher','Owner',), 0)
self.manage_permission('Zwiki: Change page types', ('Teacher','Owner',), 0)
self.manage_permission('Zwiki: Delete pages', ('Teacher','Owner',), 0)
self.manage_permission('Zwiki: Edit pages', ('Teacher','Owner',), 0)
self.manage_permission('Zwiki: Rename pages', ('Teacher','Owner',), 0)
self.manage_permission('Zwiki: Reparent pages', ('Teacher','Owner',), 0)
except ValueError:
# we don't have zwiki around
pass
def get_text(self,elem):
""" olude sunnil ImportExport.py'st kopeeritud """
#XXX: this goes to common.py!
res=u''
for line in elem.childNodes:
res += line.nodeValue
return to_utf8(res)
security.declareProtected(perm_add_lo, 'add_course_impl')
def add_course_impl(self,teacher):
"""Implementation for add_course."""
obj = Course(
self,
'', # name
(teacher,),
'', # desc
'', # organisation
'', # methods
'', # starting_date
'', # ending_date
)
id = obj.id
self._setObject(id, obj)
return id
#security.declareProtected(perm_add_lo, 'add_course_form_handler')
security.declarePublic('add_course_form_handler')
# form handler for add_course_form_1_2.dtml
def add_course_form_handler(
self,
REQUEST,
course_id, my_name, desc, organisation, methods,
start_date, end_date,
creating_new_course='',
do_groupfolder='1',
cancel='', # submit buttons
add='', #
tekst='',
logo_upload=None,
staatus=0,
cCat = 0,
credits='',
courseID=''
):
"""Check user input data."""
# return str(self.REQUEST.AUTHENTICATED_USER.getUserName())
if cancel:
# cancel button press
if creating_new_course:
REQUEST.RESPONSE.redirect('index_html')
else:
REQUEST.RESPONSE.redirect('course_info?course_id=%s' % course_id)
return
elif not add: raise 'FLE Error', 'Unknown button'
# Ok, add button pressed
action=apply(
make_action,
['add_course_form_1_2'] +
[(x, eval(x)) for x in
('my_name', 'desc', 'organisation', 'methods',
'start_date', 'end_date')])
if course_id:
action += '&course_id=' + course_id
else:
action += '&creating_new_course=1'
my_name=my_name.strip()
if not is_valid_title(my_name):
return self.message_dialog_error(
self, REQUEST,
title='Invalid name',
message='Give valid name',
action=action)
if creating_new_course and my_name in [x.get_name()
for x in self.get_courses()]:
return self.message_dialog_error(
self, REQUEST,
title='Invalid name',
message="Name '%s' taken" % my_name,
action=action)
if not creating_new_course \
and my_name != self.get_child(course_id).get_name() \
and my_name in [x.get_name() for x in self.get_courses()]:
return self.message_dialog_error(
self, REQUEST,
title='Invalid name',
message="Name '%s' taken" % my_name,
action=action)
from common import convert_date # convert dates to time.time()-format
errors = []
if not start_date:
starting_date = 0
else:
try:
time_tuple = strptime.strptime(start_date,
translate(self,'short_date_format',target=self.giveLanguage(REQUEST)))
starting_date = convert_date(str(time_tuple[2]), # day
str(time_tuple[1]), # month
str(time_tuple[0])) # year
except: errors.append(translate(self,'Starting date:',target=self.giveLanguage(REQUEST)),)
if not end_date:
ending_date = 0
else:
try:
time_tuple = strptime.strptime(end_date,
translate(self,'short_date_format',target=self.giveLanguage(REQUEST)))
ending_date = convert_date(str(time_tuple[2]), # day
str(time_tuple[1]), # month
str(time_tuple[0])) # year
except: errors.append(translate(self,'Ending date:',target=self.giveLanguage(REQUEST)),)
organisation = organisation.strip()
if organisation and not is_valid_title(organisation):
errors.append(translate(self,'Organization',target=self.giveLanguage(REQUEST)))
# desc and methods are not checked because render_description() and
# render_methods() methods in Course filter out unwanted HTML tags.
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) + "'",
action=action)
# edit an existing course
if creating_new_course:
teacher = str(REQUEST.AUTHENTICATED_USER)
# This will raise an exception if the teacher does not exist.
teacher_obj = self.fle_root().fle_users.get_user_info(teacher)
# Create new course, then proceed with updating it with
# supplied data
course_id = self.add_course_impl(teacher)
teacher_obj.user_courselist_cache.append(course_id)
logo=None
try: #Opera puhul ajab puuduva pildi juures kägu
if len(logo_upload.filename)>0:
logo=logo_upload.read()
else:
logo=None
except:
pass
course_obj = self.get_child(course_id)
course_obj.update(
my_name,
desc,
organisation,
methods,
starting_date,
ending_date,
tekst,
logo,
staatus,
cCat,
credits,
courseID
)
# course_obj.kontrolliRyhmaLaud()
if creating_new_course:
if do_groupfolder:
course_obj.add_folder('CourseFolder')
else:
if do_groupfolder and not course_obj.has_group_folder():
course_obj.add_folder('CourseFolder')
# elif not do_groupfolder and course_obj.has_group_folder():
# course_obj._delObject('gf')
# REQUEST.RESPONSE.redirect('index_html')
# '%s/course_info?course_id=%s' % (course_id, course_id))
# REQUEST.RESPONSE.redirect(self.find_URL_of_fle_root(REQUEST)+'/courses/'+course_id+'/gf/course_info')
#return course_obj.kysiTekst()
if creating_new_course:
getattr(self.fle_root().fle_users, REQUEST.AUTHENTICATED_USER.getUserName()).set_jooksev_kursus(course_id,REQUEST.AUTHENTICATED_USER)
#return (self.find_URL_of_fle_root(REQUEST)+'/courses/filtreerimisvorm2')
#REQUEST.RESPONSE.redirect (self.find_URL_of_fle_root(REQUEST)+'/courses/'+course_id+"/filtreerimisvorm2/")
#REQUEST.RESPONSE.redirect("http://www.epl.ee/")
self.kontrolli_kursuse_kaust(self, REQUEST)
REQUEST.RESPONSE.redirect(self.fle_root().absolute_url()+"/courses/manage_participants?pnimi=")
else:
REQUEST.RESPONSE.redirect(course_obj.absolute_url()+'/gf/course_info')
# return "Tere"
#security.declareProtected(perm_edit, 'get_courses')
security.declarePublic('get_courses')
# No additional comments.
def get_courses(self, REQUEST=None):
"""Return a list of Course objects in this manager."""
doSort = 0
doFilter = 0
try:
doSort = int(REQUEST.sortc)
except AttributeError:
pass
try:
if int(REQUEST.filter):
# doSort = 99
doFilter = int(REQUEST.filter)
except AttributeError:
pass
if doSort: return self.sorted_course_list(doSort,doFilter)
else: return self.get_children('Course')
security.declareProtected(perm_edit, 'sorted_course_list')
def sorted_course_list(self, crit=1,filter=0):
list = self.get_children('Course')
sorted_list = []
tmp = []
for x in list:
a = []
if crit==1:
a.append(x.getCourseCategory())
a.append(x)
tmp.append(a)
elif crit==99 and filter:
if int(x.getCourseCategory())== filter:
a.append(x.get_name())
a.append(x)
tmp.append(a)
elif crit==10:
a.append(x.kysiStaatus())
a.append(x)
tmp.append(a)
elif crit==20:
a.append(len(x.get_all_users()))
a.append(x)
tmp.append(a)
elif crit==30:
a.append(x.lastModify())
a.append(x)
tmp.append(a)
elif crit==40:
a.append(x.lastActive())
a.append(x)
tmp.append(a)
elif crit==50:
a.append(x.get_n_notes())
a.append(x)
tmp.append(a)
elif crit==60:
a.append(x.get_n_artefacts())
a.append(x)
tmp.append(a)
else:
a.append(x.get_name())
a.append(x)
tmp.append(a)
tmp.sort()
for x in tmp:
sorted_list.append(x[1])
return sorted_list
security.declareProtected(perm_edit, 'get_user_ids_on_course')
def get_user_ids_on_course(self, course_id):
"""Return UserInfo ids (list) on a given course."""
return self.get_child(course_id).get_all_users_id()
def get_users_not_on_the_course(self, course_id, jarjestus="", omadus="", alates="", kuni=""):
"""Get all users who are not on the given course.
Return list of UserInfo objects."""
try:
course_obj = self.get_child(course_id)
except AttributeError:
raise 'FLE Error', 'Errorneous course id.'
attendees = course_obj.get_all_users()
if jarjestus=="":
all_users = self.fle_users.get_users()
if jarjestus=="kasutajanimi":
all_users = self.fle_users.get_users_sorted_by_uname()
non_att = []
for user in all_users:
if user not in attendees:
lisada=1
if omadus!="":
if alates != "":
if user.kysi_omadus(omadus)kuni and (user.kysi_omadus(omadus)[:len(kuni)]!=kuni):
lisada=0
if lisada:
non_att.append(user)
return non_att
#security.declareProtected(perm_edit, 'get_users_not_on_the_course')
# security.declarePublic('get_users_not_on_the_course')
# No additional comments
# def get_users_not_on_the_course(self, course_id):
# """Get all users who are not on the given course.
# Return list of UserInfo objects."""
# try:
# course_obj = self.get_child(course_id)
# except AttributeError:
# raise 'FLE Error', 'Errorneous course id.'
#
# attendees = course_obj.get_all_users()
# all_users = self.fle_users.get_users()
#
# non_att = []
#
# for user in all_users:
# if user not in attendees:
# non_att.append(user)
#
# return non_att
# FIXME: input_checks
#XXX:security.declareProtected(perm_edit, 'add_users_form_handler')
security.declarePublic('add_users_form_handler')
# handler for form add_course_form_2_2.dtml
def add_users_form_handler(
self, course_id,
REQUEST,
users_None='', # checkboxes
users_Teacher='',
users_Tutor='',
users_Student='',
None_to_Teacher='', # submit buttons
Teacher_to_None='',
None_to_Tutor='',
Tutor_to_None='',
None_to_Student='',
Student_to_None='',
Tutor_to_Teacher='',
Teacher_to_Tutor='',
Student_to_Tutor='',
Tutor_to_Student='',
):
"""Adding and removing users from a given course."""
from Kirjakast import Kirjakast
temp = getattr(self.fle_root(), 'fle_users')
if not self.kas_opetaja(REQUEST) and not REQUEST.AUTHENTICATED_USER.has_role('Manager'):
return ":-("
course = self.get_child(course_id)
for x in ('None_to_Teacher', # left/right
'Teacher_to_None',
'None_to_Tutor',
'Tutor_to_None',
'None_to_Student',
'Student_to_None',
'Tutor_to_Teacher', # up/down
'Teacher_to_Tutor',
'Student_to_Tutor',
'Tutor_to_Student'):
if eval(x):
m = re.match("^(.*)_to_(.*)", x)
old_role = m.group(1)
new_role = m.group(2)
if 'Student' in new_role and not self.isCourseReady(course):
return self.message_dialog_error(
title="Error",
message="Students can be added to the course when all required course information is submitted and course status is open(not preparing, not finished). Adding teachers is OK.",
action="manage_participants")
users = "users_%s" % old_role
if eval(users):
owners = [u[0] for u in self.get_local_roles()]
if type(eval(users)) is types.StringType:
exec '%s = [%s,]' % (users, users)
# if new_role == 'Teacher':
# for user in eval(users):
# uinf = self.fle_users.get_user_info(user)
# uinf.set_roles(('Teacher',))
# print uinf.getRoles()
if new_role == 'None':
for user in eval(users):
course.remove_person(user)
if course.has_group_folder():
course.remove_folder_link(
(self.fle_users.get_user_info(user),))
else:
for user in eval(users):
if user in owners:
new_roles = (new_role, 'Owner')
else:
new_roles = (new_role,)
#XXX:dublicate user_courselist_cache :(
uinf = self.fle_users.get_user_info(user)
if course.get_id() not in uinf.user_courselist_cache:
uinf.user_courselist_cache.append(course.get_id())
uinf._p_changed = True
course.set_roles(user, new_roles)
try:
koht = getattr(temp, user)
koht2 = getattr(koht, 'kirjad')
tlang = uinf.get_language()
teade=translate(self,'You have been added to course ',target=tlang)
koht2.saadaKiri(REQUEST, uinf.get_uname(), uinf.get_uname(), teade,' '+\
teade+": "+\
str(course.get_name())+' ',9999)
except:
pass
else:
return self.message_dialog_error(
self, REQUEST,
title='Error',
message='Please select some users first',
action='manage_participants')
REQUEST.RESPONSE.redirect('manage_participants')
#'add_course_form_2_2?course_id=' + course_id))
return
# Should be never reached.
return REQUEST
security.declareProtected(perm_manage, 'courses_form_handler')
# index_html form handler
#XXX: security check!
def courses_form_handler(
self,
REQUEST,
delete='', # form submit button
course_export='',
course_ids=None,
):
"""Form handler for courses index page."""
import types
if int(self.kas_opetaja(REQUEST))!=1:
if not self.fle_root().fle_users.is_power_user(REQUEST.AUTHENTICATED_USER):
return "Access denied"
if not course_ids:
return self.message_dialog_error(
self, REQUEST,
title='No course selected',
message='Please select a course from the course list.',
action='index_html')
if delete:
if type(course_ids) is types.StringType:
course_ids=(course_ids,)
return self.message_dialog2(
self, REQUEST,
title = 'Confirmation',
message = translate(self, 'Are you sure you want to delete the following courses:', target=self.giveLanguage(REQUEST)) + ' ' + \
', '.join([getattr(self, ci).get_name() for ci in course_ids]),
handler = 'delete_courses_form_handler',
extra_value_name = 'course_ids',
extra_values = course_ids,
option1_value = 'Cancel',
option1_name = 'cancel',
option2_value = 'Ok',
option2_name = 'delete')
#REQUEST.RESPONSE.redirect('index_html')
elif course_export:
if type(course_ids) is types.StringType:
course_ids=(course_ids,)
message = self.do_courses_export(course_ids)
message = translate(self,'Exported course(s) are save to following location:',target=self.giveLanguage(REQUEST))+message
return self.index_html(message=message)
else:
# This code should never be reached.
raise 'FLE Error', 'Unknown button'
security.declarePrivate('do_courses_export')
# index_html form handler
def do_courses_export(self,course_ids):
message = ""
for c_id in course_ids:
course = self.get_child(c_id)
message += ' ' + course.iva_ims_export(teacherExporting=0)
return message
# FIXME: input_checks
security.declareProtected(perm_manage, 'delete_courses_form_handler')
def delete_courses_form_handler(
self,
REQUEST,
course_ids,
delete='',
cancel='',
):
"""Form handler that is called from message_dialog2."""
if delete:
for course_id in course_ids:
for wt in [user.get_webtop() for user in
self.get_child(course_id).get_all_users()]:
wt.recursive_delete_group_folder_proxy(course_id)
[self.get_child(course_id).remove_person(user.get_uname()) for user in self.get_child(course_id).get_all_users()]
self._delObject(course_id)
elif cancel:
pass
else:
# This code should never be reached.
raise 'FLE Error', 'Unknown button'
REQUEST.RESPONSE.redirect('index_html')
security.declarePublic('has_courses')
def has_courses(self):
"""Return boolean describing whether there is an existing course on
the system."""
return not not self.get_children('Course')
def get_course_id_from_req(self, req):
"""Extract a course id from REQUEST. This is needed by
the CourseManager.course_selection dtml method."""
path = req.PATH_TRANSLATED
splitter = '/'
if splitter not in path:
splitter = '\\'
i = string.find(path, "courses")
ri = string.rfind(path, "courses")
if (i == -1) or (ri == -1):
return None
if (ri != i):
# There is more than one 'courses' word in path.
# We'll have to use the reverse one.
i = ri
plst = filter(lambda x:x, string.split(path[i:], splitter))
try:
return plst[1]
except IndexError:
return None
def get_formatted_current_date(self, REQUEST):
"""Return date formatted depending on user's language."""
return time.strftime(translate(self,'short_date_format',target=self.giveLanguage(REQUEST)), time.localtime())
def get_printable_starting_date(self, REQUEST):
""" return current time, no starting time for coursemanager """
return self.get_formatted_current_date(REQUEST)
def get_printable_ending_date(self, REQUEST):
""" return current time, no ending time fot coursemanaget.
this is here for course adding page """
return self.get_formatted_current_date(REQUEST)
def testideImport(self,REQUEST):
""" impordime testid"""
tulemus=""
return self.defaultRender(page=tulemus)
# security.declareProtected(perm_view, 'user_course_export')
security.declarePublic('user_course_export')
def user_course_export(self,REQUEST):
""" user exports its course for viewing offline """
print "xxx"
from ImportExportIMS import Kirjutus
from ImportExportIMS import kirjutaYldM
import tempfile, os
uname = REQUEST.AUTHENTICATED_USER.getUserName()
knr=self.fle_root().jooksva_kursuse_nr(self, REQUEST)
# knr=self.fle_root().jooksva_kursuse_nr(self, REQUEST)
knr = self.get_course_id_from_req(REQUEST)
kasutaja = self.fle_users.get_user_info(uname)
kasutaja = ((kasutaja),)
failinimi = tempfile.mktemp()
kursus = self.get_child(knr)
k = Kirjutus(self.fle_root(), kursus.get_id())
k.looKursuseFail()
k.kirjutaWebtop(kursus.gf, tiitel='RAAMATURIIUL')
k.kirjutavCal(kursus.syndmused, 'kursus','GROUP')
k.kirjutaKasutajaWebtop(kasutaja)
k.kirjutaKasutajaSyndmus(kasutaja)
# k.kirjutaWiki(getattr(kursus,'ivawiki'))
for sisegr in kursus.subgroups.objectValues('GroupFolder'):
sisegr_kasutajad = kursus.kasutajad_sisegrupis(sisegr.get_name())
if uname not in sisegr_kasutajad:
continue
k.kirjutaWebtop(sisegr,'SISEGRUPP')
try:
k.kirjutavCal(sisegr.syndmused,sisegr.get_name(),'GROUP')
except:
pass
k.kirjutaKasutajaWiki(kasutaja)
k.exportPajad(failinimi, str(kursus.get_name()+"/"))
k.pakiKursusFaili(failinimi,str(kursus.get_name()))
file = open(failinimi, "rb")
export_data=file.read()
file.close()
os.remove(failinimi)
REQUEST.RESPONSE.setHeader('content-type','application/zip')
REQUEST.RESPONSE.setHeader('Content-disposition','attachment; filename=iva_arhiiv.zip')
return export_data
security.declareProtected(perm_manage, 'export_all_courses')
def export_all_courses(self,REQUEST,allcourses=''):
""" exports all courses """
#XXX: def export_all_courses: not needed. we should get rid of it!
from ImportExportIMS import Kirjutus
from ImportExportIMS import kirjutaYldM
import tempfile, os
yld = kirjutaYldM()
failinimi = tempfile.mktemp()
if not allcourses:
for course in self.get_courses():
k = Kirjutus(self.fle_root(), course.get_id())
k.looKursuseFail()
k.kirjutaWebtop(course.gf, tiitel='RAAMATURIIUL')
k.kirjutavCal(course.syndmused,'kursus','GROUP')
for sisegr in course.subgroups.objectValues('GroupFolder'):
k.kirjutaWebtop(sisegr,'SISEGRUPP')
try:
k.kirjutavCal(sisegr.syndmused,sisegr.get_name(),'GROUP')
except:
pass
k.kirjutaWebtop(course.ryhmalauad,'RYHMALAUAD')
k.kirjutaKasutajaWebtop(course.get_all_users())
k.kirjutaKasutajaSyndmus(course.get_all_users())
k.exportQTI(failinimi,str(course.get_id())+"/")
#k.kirjutaWiki(getattr(course,'ivawiki'))
#k.kirjutaKasutajaWiki(course.get_all_users())
yld.kirjutaYldmanifest(course.get_id(),course.get_description(),base=str(course.get_id())+"/")
#k.pakiTulemusFaili(failinimi)
self.fle_users.export_users(REQUEST,failinimi=failinimi,kursusega=course.get_id(),palju='self.fle_root().fle_users.get_users()')
k.kirjutaItem(k.organization, tiitel='KURSUSE KASUTAJAD')
k.kirjutaResource(k.resources, 'imsent_xmlv1p1','users.xml')
k.pakiKursusFaili(failinimi)
yld.lisaFaili(failinimi)
file = open(failinimi,"rb")
export_data=file.read()
file.close()
os.remove(failinimi)
REQUEST.RESPONSE.setHeader('Content-disposition','attachment; filename=ivaexport.zip')
REQUEST.RESPONSE.setHeader('content-type','application/zip')
return export_data
def teacher_import_handler(self, REQUEST, file='', to_import=''):
""" Form handler for teacher """
kursusenr = self.get_course_id_from_req(REQUEST)
if not self.kas_opetaja(self, REQUEST):
return "Keelatud"
uname = REQUEST.AUTHENTICATED_USER.getUserName()
from ImportExportIMS import Importer
from ImportExport import Exporter
import tempfile, os
filename = tempfile.mktemp()
f = open(filename,"w+b")
f.write(file.read())
f.close()
import_data=None
imported = Importer(uname,self.fle_root(),'',getattr(self.fle_root().courses, kursusenr),kasuta_jooksvat=1)
imported.loadZip(filename)
element = imported.loadFile('imsmanifest.xml')
imported.processFile(self,element)
return REQUEST.RESPONSE.redirect(self.absolute_url()+'/'+str(kursusenr)+'/gf/course_info')
def import_form_handler(
self,
REQUEST,
file,
course_import='',
testsonly='',
wikionly='',
cancel='',
wiki_koht='',
):
"""Form handler for course importing."""
uname = REQUEST.AUTHENTICATED_USER.getUserName()
koht=wiki_koht[len(self.fle_root().absolute_url()):].split('/')
m = self.fle_root()
for x in koht:
if x:
m = getattr(m, x)
koht = m
# if not self.kas_opetaja(self, REQUEST):
# return "Keelatud juurdep22s"
if course_import:
from ImportExportIMS import Importer
from ImportExport import Exporter
import tempfile, os
filename = tempfile.mktemp()
f = open(filename,"w+b")
f.write(file.read())
f.close()
import_data=None
#exported = Exporter("Courses",filename)
if testsonly or wikionly:
# print u_wiki
if testsonly:
print "test ainult1"
imported = Importer(uname,self.fle_root(),'',getattr(self.fle_root().courses, self.get_course_id_from_req(REQUEST)),testonly=1,kasuta_jooksvat=1)
else:
print "test ainult2"
imported = Importer(uname,self.fle_root(),'',getattr(self.fle_root().courses, self.get_course_id_from_req(REQUEST)),userwikionly=koht)
else:
print "test ainult3"
imported = Importer(uname,self.fle_root())
imported.loadZip(filename)
element = imported.loadFile('imsmanifest.xml')
imported.processFile(self,element)
kala = "Import Course imported"
if wiki_koht:
REQUEST.RESPONSE.redirect(wiki_koht)
os.remove(filename)
return
if testsonly:
REQUEST.RESPONSE.redirect('testihaldus')
else:
REQUEST.RESPONSE.redirect('haldusleht')
os.remove(filename)
return
security.declareProtected(perm_manage,'import_form_handler2')
def import_form_handler2(self,REQUEST,zip='',importB=''):
""" imports from zip, located at zope instance's import folder """
if not importB:
return "x"
if not zip:
return "y"
uname = str(REQUEST.AUTHENTICATED_USER)
if importB:
from ImportExportIMS import Importer
from ImportExport import Exporter
import os, time
insthome = Globals.INSTANCE_HOME
oaeg_alg = time.time()
for names in zip:
zip_alg = time.time()
try:
path = os.path.join(insthome,'import')
filename = os.path.join(path,names)
except OSError:
return "z"
print filename
imported = Importer(uname,self.fle_root())
imported.loadZip(filename)
element = imported.loadFile('imsmanifest.xml')
imported.processFile(self,element)
zip_lopp = time.time()
print "Zip:",zip_lopp-zip_alg
oaeg_lopp = time.time()
print "Overall:", oaeg_lopp-oaeg_alg
return self.index_html(message="File(s) successfully imported.")
# return REQUEST.RESPONSE.redirect(self.fle_root().absolute_url()+'/courses/')
def coursesOpenToRegister(self, knimi):
"Kursuste loetelu, kus kasutaja veel pole"
cm=self.get_courses()
loetelu=[]
for c in cm:
leidub=0
rm=c.get_local_roles()
for r in rm:
if str(knimi)==r[0]:
leidub=1
if c.kasOotaja(knimi):
leidub=1
if (not leidub) and ((c.kysiStaatus()=='1') or (c.kysiStaatus()=='4')):
loetelu.append(c)
return loetelu
def kursusteleRegistreerimiseLeht(self, REQUEST,kursus=()):
"Kasutajate lisamine ootele"
import types
if type(kursus)==types.StringType:
kursus=(kursus,)
for x in kursus:
getattr(self, x).lisaOotaja(REQUEST, getattr(self.fle_root().fle_users, REQUEST.AUTHENTICATED_USER.getUserName()))
return REQUEST.RESPONSE.redirect('organizer_openCourses')
def kysiStaatuseTekst(self, arv, REQUEST):
"tekstide loetelu"
tekstid=(translate(self,'Preparation',target=self.giveLanguage(REQUEST)),
translate(self,'Open',target=self.giveLanguage(REQUEST)),
translate(self,'Closed',target=self.giveLanguage(REQUEST)),
translate(self,'Finished',target=self.giveLanguage(REQUEST)),
translate(self,'Automatic',target=self.giveLanguage(REQUEST)),)
return tekstid[arv]
def kysiStaatuseValikud(self, REQUEST):
"Valikud rippmenüüsse"
tulemus=""
for i in range(5):
tulemus=tulemus+"\n"
return tulemus
security.declareProtected(perm_view, 'get_unames_on_my_courses')
def get_unames_on_my_courses(self, REQUEST):
"""Return a list of unames (users that are on some course
than the caller."""
uname = str(REQUEST.AUTHENTICATED_USER)
uname_list = []
for course in self.get_courses():
unames_in_course = course.get_all_users_id()
if uname in unames_in_course:
uname_list += unames_in_course
retval = []
for uname in uname_list:
if uname not in retval:
retval.append(uname)
return retval
security.declareProtected(perm_manage, 'giveCategories')
def giveCategories(self):
#XXX: not needed!?
return self.cCategories.keys()
# security.declareProtected(perm_view,'getAllCategories')
def getAllCategories(self):
return self.cCategories['groups'].keys()
def getACat(self,id):
try:
return self.cCategories['relations'][str(id)]
except KeyError:
return None
# security.declareProtected(perm_view, 'treePrinter')
def treePrinter(self):
""" tree printer """
result = []
init = self.getCatForCat()
for x in init:
tmp = []
tmp.append('')
tmp.append(x)
result.append(tmp)
self.treeSlave(x,'-',result)
return result
# teachers are getting errors...
# security.declareProtected(perm_view,'getNameForID')
def getNameForID(self, id):
if id is not None and int(id) != 0:
return self.cCategories['groups'][int(id)]['Name']
else:
return ""
def getParentForID(self, id):
try:
return self.cCategories['groups'][id]['Parent']
except KeyError:
return ''
security.declarePrivate('addcCategory')
def addcCategory(self, newcat, undercat):
from random import random
id = int(round(random()*1000000000))
self.cCategories['groups'][id] = {'Name':newcat, 'Parent':undercat}
self.cCategories._p_changed = 1
security.declarePrivate('renameCategory')
def renameCategory(self, id, newname):
self.cCategories['groups'][int(id)]['Name'] = newname
self.cCategories._p_changed = 1
security.declarePrivate('removeCategory')
def removeCategory(self, id):
self.cCategories['groups'].pop(int(id))
self.cCategories._p_changed=1
security.declarePrivate('treeSlave')
def treeSlave(self,cat, sep,result):
for x in self.getCatForCat(cat):
tmp = []
tmp.append(sep)
tmp.append(x)
result.append(tmp)
self.treeSlave(x,sep+'-',result)
return result
def getCatForCat(self,parent=''):
#pass
cats = []
if parent == '': parent = 'None'
else: parent = str(parent)
for x in self.cCategories['groups'].keys():
if self.cCategories['groups'][x]['Parent'] == parent:
cats.append(x)
return cats
security.declareProtected(perm_manage,'manageCategories_handler')
def manageCategories_handler(self, REQUEST, saveB='', deleteB='', deletec='', newCat='', underCat='', renameB='', renaming='', newname=''):
""" creates or deletes course category """
if saveB:
if not underCat:
underCat = 'None'
if newCat:
self.addcCategory(newCat, underCat)
if deleteB:
if type(deletec)==types.StringType: deletec=(deletec,)
for dc in deletec:
self.removeCategory(dc)
if renameB and newname and renaming:
self.renameCategory(renaming, newname)
return REQUEST.RESPONSE.redirect(self.absolute_url()+'/manageCategories')
self.cCategories = PersistentMapping()
self.cCategories['groups'] = {}
# self.cCategories['relations'] = {}
self.cCategories._p_changed = 1
def isCourseReady(self,course=None):
""" if all course fields are filled """
if not course: return 0
if not int(course.kysiStaatus()) or int(course.kysiStaatus()==3): return 0
if not course.get_name() or not course.get_organisation() or not course.get_description() or not course.get_methods() or not course.get_start_date() or not course.get_end_date(): return 0
return 1
security.declareProtected(perm_manage,'ziplist')
def ziplist(self):
""" returns a list of importable zip-s """
import os
insthome = Globals.INSTANCE_HOME
try:
impath = os.path.join(insthome,'import')
except OSError:
return "no import folder found at %s" % insthome
files = []
for x in os.listdir(impath):
if x[-4:].lower() == '.zip':files.append(x)
return files
Globals.InitializeClass(CourseManager)
# EOF
iva/Cruft.py 0100644 0000764 0000764 00000054057 10172721725 012356 0 ustar vahur vahur # -*- coding: utf-8
# $Id: Cruft.py,v 1.9 2003/08/23 12:34:56 berlingo Exp $
#
# 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 Cruft, which is used as a placeholder for miscellaneous utility functions that many objects need."""
__version__ = "$Revision: 1.9 $"[11:-2]
from AccessControl import ClassSecurityInfo
from urllib import quote
from common import perm_view, perm_edit, perm_manage, perm_add_lo, translate
import re
import common
import time
from common import get_local_roles
import string
class Cruft:
"""Class containing miscellaneous methods that are
historical baggage, but possible be gotten rid of, or
at least implemented differently or somewhere else."""
security = ClassSecurityInfo()
security.declarePublic('find_URL_of_fle_root')
def find_URL_of_fle_root(self, REQUEST):
"""Return URL of our FLE installation."""
import FLE
from string import rfind
url = REQUEST.URL1
obj = self
while not isinstance(obj, FLE.FLE):
obj = obj.parent()
url = url[:rfind(url,'/')]
return url
def find_URL_of_user_info(self, REQUEST):
"""Return URL of UserInfo."""
import UserInfo
from string import rfind
url = REQUEST.URL1
obj = self
while not isinstance(obj, UserInfo.UserInfo):
obj = obj.parent()
url = url[:rfind(url,'/')]
return url
security.declarePublic('find_URL_of_webtop')
def find_URL_of_webtop(self, REQUEST):
"""Return URL of Webtop."""
import Webtop
from string import rfind
url = REQUEST.URL1
obj = self
while not isinstance(obj, Webtop.Webtop):
obj = obj.parent()
url = url[:rfind(url,'/')]
return url
security.declarePublic('find_URL_of_group_folder')
def find_URL_of_group_folder(self, REQUEST):
"""Return URL of toplevel group folder or group folder proxy."""
import GroupFolder
import GroupFolderProxy
from string import rfind
url = REQUEST.URL1
obj = self
while 1:
if isinstance(obj, GroupFolderProxy.GroupFolderProxy):
return url
if isinstance(obj, GroupFolder.GroupFolder):
return url
obj = obj.parent()
url = url[:rfind(url,'/')]
return url
security.declarePublic('find_URL_of_thread_start_node')
def find_URL_of_thread_start_node(self, REQUEST):
"""Return URL of starting note."""
import CourseContext
from string import rfind
url = REQUEST.URL1
obj = self
while not isinstance(obj.parent(), CourseContext.CourseContext):
obj = obj.parent()
url = url[:rfind(url,'/')]
return url
security.declarePublic('find_URL_of_course')
def find_URL_of_course(self, REQUEST):
"""Return URL of starting note."""
obj = self
while not obj.meta_type == 'Course':
obj = obj.parent()
return obj.absolute_url()
security.declarePublic('find_URL_of_course_context')
def find_URL_of_course_context(self, REQUEST):
"""Return URL of starting note."""
import CourseContext
from string import rfind
url = REQUEST.URL1
obj = self
while not isinstance(obj, CourseContext.CourseContext):
obj = obj.parent()
url = url[:rfind(url,'/')]
return url
security.declarePublic('is_student')
def is_student(self, REQUEST,nr=None, uname=''):
""" is give user is student in given course """
splitter = '/'
if splitter not in REQUEST.PATH_TRANSLATED:
splitter = '\\'
if nr is None:
nr = self.jooksva_kursuse_nr(REQUEST,uname)
ic = string.rfind(REQUEST.PATH_TRANSLATED, 'fle_users')
url = REQUEST.PATH_TRANSLATED
if ic == -1:
nr = self.fle_root().courses.get_course_id_from_req(REQUEST)
else:
i = ic
plst = filter(lambda x:x, string.split(url[i:], splitter))
nr = plst[3][1:]
if not hasattr(self.fle_root().courses, str(nr)):
return 0
checkname = str(REQUEST.AUTHENTICATED_USER)
if 'Student' in get_local_roles(getattr(self.fle_root().courses, nr),checkname):
return 1
try:
fm = getattr(self.fle_root().fle_users, checkname)
if fm.has_any_role(('IVAAdmin','Manager')):
return 1
except:
return 0
return 0
security.declarePublic('kas_opetaja')
def kas_opetaja(self,REQUEST,nr=None,uname=''):
""" If user is teacher. Additional role checks """
if nr is None:
nr = self.jooksva_kursuse_nr(REQUEST,uname)
if not hasattr(self.fle_root().courses, str(nr)):
return 0
if uname:
pass
#checkname = uname
else:
pass
checkname = str(REQUEST.AUTHENTICATED_USER)
if checkname in getattr(self.fle_root().courses, nr).get_teachers():
return 1
try:
fm = getattr(self.fle_root().fle_users, checkname)
#XXX: this sucks?
if fm.has_any_role(('IVAAdmin','Manager')):
return 1
except:
return 0
return 0
security.declarePublic('jooksva_kursuse_nimi')
def jooksva_kursuse_nimi(self,REQUEST,uname=''):
""" jooksva kursuse nimi """
nr = self.jooksva_kursuse_nr(REQUEST,uname)
try:
return str(getattr(self.fle_root().courses, nr).get_name())
except:
return "course not selected"
security.declarePublic('jooksva_kursuse_nr')
def jooksva_kursuse_nr(self,REQUEST,uname=''):
""" jooksva kursuse number """;
try:
if uname:
return str(getattr(self.fle_root().fle_users, uname).get_jooksev_kursus())
else:
return str(getattr(self.fle_root().fle_users, self.get_current_user(REQUEST)).get_jooksev_kursus())
except:
return 0
security.declarePublic('get_current_user')
def get_current_user(self, REQUEST):
"""Extract current user's name from the REQUEST object."""
if hasattr(REQUEST, 'kasutajanimi'):
return REQUEST.kasutajanimi
else:
return str(REQUEST.AUTHENTICATED_USER)
def salvestaKasutajanimi(self, REQUEST, nimi):
"""Kuna Python ei suuda alati AUTHENTICATED_USERit korralikult välja lugeda,
siis jäetakse nimi DTMLi kaudu meelde."""
REQUEST.kasutajanimi=nimi
return self.get_current_user(REQUEST)
security.declarePublic('urlquote')
def urlquote(self, text):
"""urlquote given text."""
return quote(text)
def get_url_to_object(self,obj):
# Make a list of parents without the Application object
# (from obj to FLE)
#XXX: remove me!
return obj.absolute_url()+'/'
objs = obj.aq_inner.aq_chain[:-1]
objs.reverse()
path='/'.join([x.getId() for x in objs])+'/'
return path
def get_object_of_url(self,url,base,remove_last=1):
#XXX: broken for VirtualHostMonster!
path=url.split('/')
if remove_last:
path.pop() # remove last entry
path.reverse()
if path[-1]=='http:': # remove protocol
path.pop()
path.pop()
path.pop() # remove first (root) entry
obj = base.fle_root()
#obj = base.getPhysicalRoot()
try:
while path:
oname=path.pop()
obj=getattr(obj,oname).__of__(obj)
return obj
except:
#raise 'Internal link error, object not found',str(obj)+' - '+oname
return None
def kasutajaURList(self, REQUEST):
"Kasutajanimi"
nimi=self.kasutajaNimi(REQUEST)
if nimi=="":
return nimi
if nimi==str(REQUEST.AUTHENTICATED_USER):
return ""
return "> " + ""+nimi+""
def algusURList(self, REQUEST, osa):
"URL soovitud loiguni"
x=REQUEST.URL0
if x.find(osa)==-1:
return ""
return x[:x.find(osa)+len(osa)]
def kasLopeb(self, tekst, otsitav):
"jah/ei"
# return tekst+" ja " + otsitav
return tekst.endswith(otsitav)
def myOwnWebtop(self, REQUEST):
"jah/ei"
return self.kasutajaNimi(REQUEST)==str(REQUEST.AUTHENTICATED_USER)
def kasutajaNimi(self, REQUEST):
"nimi"
aadress=REQUEST.URL0
nr=aadress.find('fle_users')
if nr==-1:
return ""
ots=aadress.find('/', nr+10)
nimi=aadress[nr+10:ots]
nimi = re.sub('%20', ' ',nimi)
return nimi
security.declarePublic('leiaKasutaja')
def leiaKasutaja(self, REQUEST):
"kasutaja objekt"
nimi=self.kasutajaNimi(REQUEST)
if hasattr(self.fle_root().fle_users, nimi):
return getattr(self.fle_root().fle_users, nimi)
return None
def jooksevKasutaja(self, REQUEST):
"Kasutajainfo objekt sisseloginud kasutaja kohta"
return getattr(self.fle_root().fle_users, str(REQUEST.AUTHENTICATED_USER))
def leheAvamisToimingud(self, REQUEST,uname=None):
"Tegevused iga lehe avamisel"
try:
self.seaKasutajaKeel(REQUEST)
self.jooksevKasutaja(REQUEST).update_active(self.jooksva_kursuse_nr(REQUEST,uname))
self.lisaSyndmus(REQUEST, "lehtiAvatud",kasutajanimi=uname)
self.kontrolli_kursuse_kaust(self, REQUEST)
except:
pass
return "tehtud"
def ajaMuutmisElemendid(self, elemendinimi, aeg=-1):
"Valikute kogum"
import YlTest
from YlTest import LahendusLuba
abi=LahendusLuba()
if aeg==-1:aeg=time.time()
m=time.localtime(aeg)
tulemus=abi.looValik(elemendinimi+"Aasta", m[0]-5, m[0]+10, m[0])
tulemus=tulemus+"-"+\
abi.looValik(elemendinimi+"Kuu", 1, 12, m[1])
tulemus=tulemus+"-"+\
abi.looValik(elemendinimi+"Paev", 1, 31, m[2])
tulemus=tulemus+" "+\
abi.looValik(elemendinimi+"Tund", 0, 23, m[3])
tulemus=tulemus+":"+\
abi.looValik(elemendinimi+"Minut", 0, 59, m[4], samm=5)
return tulemus
def seaKasutajaKeel(self, REQUEST):
"Kasutja keele määramine"
if hasattr(REQUEST, 'HTTP_ACCEPT_LANGUAGE'):
keeletekst=REQUEST['HTTP_ACCEPT_LANGUAGE']
keeled=keeletekst.split(",")
kasutaja=self.jooksevKasutaja(REQUEST)
if not kasutaja.kasKeelBrauserist():
return "Vahetusesoov puudub"
for x in keeled:
if x=='et': x='et_ee'
if x in ('et_ee', 'en'):
kasutaja.set_language(x)
return "Uus keel "+x
return "Keel puudub"
def set_undefined_page(self, message, REQUEST):
"""Set REQUEST.RESPONSE.redirect, so that we go to undefined page
and give an explanation."""
message = common.quote_html_hack(message)
REQUEST.RESPONSE.redirect("undefined_page?explanation=%s" % message)
security.declarePublic('to_str_list')
# Using eval would be simpler and more general, but
# we want to be paranoid.
def to_str_list(self, s):
"""Reverse str representation of list of strings back to list."""
return [x.strip() for x in s[1:-1].replace("'", "").split(',')]
def webtopi_sygavus(self,REQUEST):
""" to be removed. For wiki only"""
x = REQUEST.URL0.split("/")
if x[-3] == 'webtop':
return 1
return 0
def kasutajaasukoht(self, REQUEST,url=''):
"Kasutaja asukoht"
if url:
x = url
else:
x = REQUEST.URL0
if x.find('manage')>0: return "Haldus"
if x.find('WelCome')>0: return "Raamaturiiul" #Course ZWiki
if x.find('assignmentGrading')>0: return "Veebilaud"
if x.find('createMail')>0 or x.find('edit_user_form')>0 or x.find('show_user_info')>0: return 'Organizer'
if x.find('kalendriAasta')>0 or x.find('organizer')>0: return 'Organizer'
if x.find('course_info_user')>0: return "Veebilaud"
if x.find('course_index')>0 or x.find('course_info')>0: return 'Raamaturiiul'
if x.find('tootubade_leht')>0 or x.find('workshop_')>0: return "Tootuba"
if x.find('/courses/')>0:
if x.find('/testihaldus')>0 or x.find('/courses/index_html')>0 or self.kas_haldus(REQUEST,x): return "Haldus"
if not x.find('/gf/')>0 and x.find('/testid/')>0: return "Haldus"
if x.find('import_form_handler2')>0: return "Haldus"
if not x.find('/gf/')>0: return "Tootuba"
if x.find('/fle_users/')>0 and x.find('/webtop/')>0: return "Veebilaud"
if self.kas_haldus(REQUEST, x) or x.find('ootajateLoetelu')>0:
return 'Haldus'
else:
return 'Raamaturiiul'
def sisegrupiNimi(self, REQUEST):
"URList loetud grupi nimi"
x=REQUEST.URL0
if x.find('/subgroups/')>0:
algus=x.find('/subgroups/')
ots=x.find('/', algus+11)
if ots==-1:
tulemus=x[algus+11:]
else:
tulemus=x[algus+11:ots]
if tulemus == 'wt_index_html':
return "listing"
return tulemus
else:
return ""
security.declarePublic('kas_haldus')
def kas_haldus(self, REQUEST, veebiurl):
"kas sobib halduseks"
if re.match(".*/courses/[0-9]+/syndmused", veebiurl):
if self.kas_opetaja(self, REQUEST): return 1
else: return 0
laused=(
".*haldusleht",
".*testihaldus",
".*muuda_vorm",
".*kysimuse_vorm",
".*add_course_form",
".*sisegrupihaldus",
".*courses/index_html",
".*ylesandedMuutmisTabelina",
".*ylesanneteTyypideLoetelu",
".*pealkirjaMuutmisVormHTML",
".*muutmisVorm",
".*lubadeViited",
".*koigiLuba",
".*isikuLubadeLisamisVorm",
".*grupiLubadeLisamisVorm",
".*/filtreerimisvorm2",
".*/kasutajateTulemused",
".*/typesets",
".*/lahendusteStatistika",
".*/kodutood.*",
".*/manage.*",
".*qtCatalog.*",
".*testideImport.*",
#".*",
)
leitud=0
x=veebiurl
for lause in laused:
if re.match(lause, x):
leitud=1
return leitud
security.declarePublic('kas_kasutaja_haldus')
def kas_kasutaja_haldus(self, veebiurl):
"kas sobib halduseks"
laused=(
".*kasutajate_haldamise_vorm",
".*kasutajateLisamisFailiVorm",
".*kasutajaLehelt1",
".*kasutajadFailist2",
".*kasutajadFailist1",
".*erialadeHalduseVorm",
".*/kasutajaotsing",
".*/kasutajateKustutus.*",
#".*",
)
leitud=0
x=veebiurl
for lause in laused:
if re.match(lause, x):
leitud=1
return leitud
def lisaSyndmus(self, REQUEST, syndmus, kasutajanimi=None, lisaparameeter=None):
"Kasutaja statistika lisamine"
if(REQUEST == None):
return "REQUEST puudub"
if kasutajanimi is None:
kasutajanimi=self.get_current_user(REQUEST)
k=getattr(self.fle_root().fle_users, kasutajanimi).webtop
kv=getattr(k, 'c'+str(self.fle_root().jooksva_kursuse_nr(REQUEST,kasutajanimi)))
if not hasattr(kv.aq_inner, 'toimingud'):
kv.aq_inner.toimingud={}
if kv.aq_inner.toimingud.has_key(syndmus):
kv.aq_inner.toimingud[syndmus]=kv.aq_inner.toimingud[syndmus]+1
else:
kv.aq_inner.toimingud[syndmus]=1
kv.aq_inner.toimingud=kv.aq_inner.toimingud #kinnistus Zope tarvis
return kv.aq_inner.toimingud
security.declareProtected(perm_view, 'getUserStatistics')
def getUserStatistics(self):
try:
return getattr(self.aq_self, 'toimingud')
except AttributeError:
return None
def kasutajaTestiTulemused(self, REQUEST, kasutaja, knr):
"Kasutaja kõikide testide lühikokkuvõte"
kc=getattr(kasutaja.webtop, 'c'+str(knr))
knr = getattr(self.fle_root().fle_users, str(REQUEST.AUTHENTICATED_USER)).get_jooksev_kursus()
tmp = getattr(self.fle_root().courses, str(knr))
if not hasattr(kc, 'testivastused'):
return ""
kv=kc.testivastused
tulemus=""
for test in kv.objectValues():
try:
p_test = getattr(tmp.testid, str(test.id))
tulemus=tulemus+p_test.pealkiri+": "
except:
p_test = None
tulemus=tulemus+test.id+": "
try:
for variant in test.objectValues():
if p_test != None:
if p_test.kasLubatudLahendusiVaadata(REQUEST):
tulemus=tulemus+" "
tulemus+=variant.punktiArvutusLyhiHTML(REQUEST)
if p_test.kasLubatudLahendusiVaadata(REQUEST):
tulemus+="; "
else:
tulemus += "; "
# tulemus=tulemus+" "+variant.punktiArvutusLyhiHTML(REQUEST)+""
tulemus=tulemus+" "
except:
pass
return tulemus
def kysiURLParameeter(self, REQUEST, parameeter):
"Kui pole, siis tühi"
if hasattr(REQUEST, parameeter):
return REQUEST[parameeter]
return ""
def filtreeriKasutajad(self, REQUEST, loetelu, enimi="", pnimi="", knimi="", org="-1"):
"Kasutajate filtreerimine"
tulemus=[]
try:
org=int(org)
except:
org=-1
for kasutaja in loetelu:
korras=1
if not kasutaja.get_first_name().lower().startswith(enimi.lower()): korras=0
if not kasutaja.get_last_name().lower().startswith(pnimi.lower()): korras=0
if not kasutaja.get_uname().startswith(knimi.lower()): korras=0
if org!=-1:
if not kasutaja.get_organization().lower().startswith(self.fle_root().fle_users.getAffiliations()[int(org)].lower()): korras=0
if korras:
tulemus.append(kasutaja)
return tulemus
def zwiki_export(self,REQUEST,level,wiki_id):
""" zwiki manage form handler """
from ImportExportIMS import Kirjutus
from ImportExportIMS import kirjutaYldM
import tempfile, os
failinimi = tempfile.mktemp()
if not level: level=99999
# number = self.get_course_id_from_req(REQUEST)
number = 0
# nr = self.get_id()
# try:
# number = int(nr)
# except:
# number = int(nr[1:])
yld = kirjutaYldM()
yld.kirjutaYldmanifest(number,'WIKI',base=str(number)+'/')
yld.lisaFaili(failinimi)
k = Kirjutus(self.fle_root(), number)
k.looKursuseFail(0)
wikikoht=''
try:
wikikoht = getattr(self,wiki_id)
except:
pass
if wikikoht:
k.kirjutaWiki(wikikoht,'ZWiki',wikikoht.aq_inner.get_name(),wikikoht.wikiKaustEsimeneLeht(),palju=level)
# else:
# k.kirjutaKasutajaWiki((self.get_user_info(str(REQUEST.AUTHENTICATED_USER)),))
k.pakiKursusFaili(failinimi)
file = open(failinimi,"rb")
export_data=file.read()
file.close()
os.remove(failinimi)
REQUEST.RESPONSE.setHeader('Content-disposition','attachment; filename=zwikiexport.zip')
REQUEST.RESPONSE.setHeader('content-type','application/zip')
return export_data
security.declareProtected(perm_view, 'saadaEmail')
def saadaEmail(self,tomail,subject,message,saatja=''):
""" proovime saata kirja """
p_saatja = ''
if saatja:
p_saatja = saatja
if hasattr(self,'MFROM') and not p_saatja:
p_saatja = self.MFROM
if not p_saatja:
return 0
try:
mailhost = self.MailHost
mailhost.send(message,tomail,p_saatja,subject,encode='quoted-printable')
return 1
except:
return 0
def editSearchResultsURL(self,indexUrl):
"Otsingu tulemusele vastav URL"
url=''
nr=string.find( indexUrl, 'fle_users')
if(nr != -1):
url=self.fle_root().absolute_url()+'/'+indexUrl[nr:len(indexUrl)]
else:
nr=string.find( indexUrl, 'courses')
if(nr != -1):
url=self.fle_root().absolute_url()+'/'+indexUrl[nr:len(indexUrl)]
return url
def leivaPuru(self,REQUEST):
""" leivapuru """
#XXX:maybe we don't need this!
if REQUEST.URL0.find('kirjad')>0: return REQUEST['L_ic_mailbox']
if self.kasLopeb(REQUEST.URL1, 'webtop/c'+str(self.jooksva_kursuse_nr(self, REQUEST))):
return 'portfolio'
else:
return ""+'portfolio'+""
return "kala"
def numberToText(self, REQUEST, arv):
"Asendab punkti komaga, kui see vajalik"
tekst=str(arv)
eraldaja=translate(self, "decimal_separator", target=self.giveLanguage(REQUEST))
tekst=tekst.replace(".", eraldaja)
return tekst
def giveLanguage(self, REQUEST):
""" gives user language """
prev_lang = REQUEST.HTTP_ACCEPT_LANGUAGE
try:
if getattr(self.fle_root().fle_users, str(REQUEST.AUTHENTICATED_USER)).kasKeelBrauserist():
language = prev_lang
else:
language = getattr(self.fle_root().fle_users, str(REQUEST.AUTHENTICATED_USER)).get_language()
except:
language = prev_lang
#XXX: let's see if this works..
if language not in self.get_languages():
language = prev_lang
if language == 'et_ee':
language = 'et'
return language
def firstAndLast(self,uname='',req=None):
""" Give object author's first and last name """
if not uname and not req:
return ""
if not uname:
abc = req.AUTHENTICATED_USER
else:
abc = uname
try:
ui = self.fle_users.get_user_info(str(abc))
if ui.get_first_name()=='' and ui.get_last_name()=='':
nimi = abc
else:
nimi = ui.get_first_name()+" "+ui.get_last_name()
except:
nimi = uname
return nimi
def is_courseContext(self):
return 0
# EOF
iva/Downloader.py 0100644 0000764 0000764 00000004030 10130153777 013353 0 ustar vahur vahur # -*- coding: utf-8
# $Id: Downloader.py,v 1.4 2003/08/18 07:44:24 berlingo Exp $
#
# 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
"""This is the main module for FLE, containing the FLE class and the Zope factory method for creating a FLE installation inside Zope."""
__version__ = "$Revision: 1.4 $"[11:-2]
import os.path, string, time
import Globals
import AccessControl
import OFS
from OFS.Folder import Folder
from Cruft import Cruft
# This is the class for the FLE installation root object.
class Downloader(
Folder,
Cruft,
OFS.SimpleItem.Item,
):
"""Download assistant."""
security = AccessControl.ClassSecurityInfo()
security.declareObjectPublic()
def __bobo_traverse__(self, REQUEST, entry_name=None):
return self
def __call__(self,client=None,REQUEST={},RESPONSE=None, **kw):
#raise 'foo2','CALL CALLED: ' + str(REQUEST)
srcurl=REQUEST.get('src')
#raise 'foo',srcurl
obj=self.get_object_of_url(srcurl,self)
path=srcurl.split('/')
fname=path.pop()
if fname=='':
return obj.index_html(REQUEST,RESPONSE)
else:
try:
return apply(getattr(obj,fname),(REQUEST,))
except TypeError:
return apply(getattr(obj,fname),(REQUEST,RESPONSE))
Globals.InitializeClass(Downloader)
# EOF
iva/Errors.py 0100644 0000764 0000764 00000002151 10130153777 012533 0 ustar vahur vahur # -*- coding: utf-8
# $Id: Errors.py,v 1.4 2003/08/18 07:44:24 berlingo Exp $
#
# 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
"""Will contain the error classes FLE raises. Not currently in use."""
__version__ = "$Revision: 1.4 $"[11:-2]
class FleError(Exception):
def __init__(self, args):
Exception.__init__(self, args)
class UserAlreadyInGroup(FleError): pass
class NoSuchUser(FleError): pass
# EOF
iva/FLE.py 0100644 0000764 0000764 00000123540 10174031667 011674 0 ustar vahur vahur # -*- coding: utf-8
# $Id: FLE.py,v 1.4 2003/08/18 07:44:24 berlingo Exp $
#
# 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
"""This is the main module for FLE, containing the FLE class and the Zope factory method for creating a FLE installation inside Zope."""
__version__ = "$Revision: 1.4 $"[11:-2]
IVA_VERSION = "IVA 0.6-RC2"
import os.path, string, time
try:
from PIL import Image
PIL_imported = 1
except ImportError:
PIL_imported = 0
import Globals
from Products.PageTemplates.PageTemplateFile import PageTemplateFile
from Globals import Persistent, Acquisition, HTMLFile, PersistentMapping
import AccessControl
import OFS
from OFS.Folder import Folder
from Products.ZCatalog.ZCatalog import ZCatalog
from TraversableWrapper import TraversableWrapper as TW
from Cruft import Cruft
from ThinkingTypeSetManager import ThinkingTypeSetManager as TTSM
from UserManager import UserManager
from CourseManager import CourseManager
from Timer import Timer
from common import file_path, ui_path, translate
import Acquisition
import YlTest
from string import atoi
from common import add_dtml_obj, new_add_dtml_obj, add_image_obj, \
reload_dtml, add_dtml, reload_pt, add_pt_obj, add_pt
from common import perm_view, perm_edit, perm_manage, perm_add_lo, perm_access, \
roles_admin, roles_staff, roles_user
import common
import re
import YlHoidla
from YlHoidla import YlHoidla
try:
from Products.CMFCore.CookieCrumbler import CookieCrumbler, ATTEMPT_NONE, ATTEMPT_LOGIN, ATTEMPT_RESUME
CCAware = 1
except:
CCAware = 0
# This is the class for the FLE installation root object.
class FLE(
Folder,
TW,
Cruft,
Persistent,
AccessControl.Role.RoleManager,
OFS.SimpleItem.Item,
Timer,
):
"""FLE product."""
security = AccessControl.ClassSecurityInfo()
security.declareObjectPublic()
meta_type = 'IVA'
security.declareProtected(perm_manage, 'management_tab')
# management_tab = Globals.DTMLFile('ui/FLE/management_tab', globals())
management_tab = PageTemplateFile('ui/management_tab', globals())
management_tab._owner = None
manage_options=(
{'label' : 'Tools', 'action' : 'management_tab'},
) + OFS.Folder.Folder.manage_options
dtml_files = (
('style_css','','ui/style_css'),
('style_cssVeebilaud','','ui/style_cssVeebilaud'),
('style_cssRaamaturiiul','','ui/style_cssRaamaturiiul'),
('style_cssTootuba','','ui/style_cssTootuba'),
('style_cssHaldus','','ui/style_cssHaldus'),
('style_cssOrganizer','','ui/style_cssOrganizer'),
('js/checkAll2','','ui/js/checkAll2'),
('js/tree','','ui/js/tree'),
('js/ivaeditor', '', 'ui/js/ivaeditor'),
)
#index_html = Globals.HTMLFile("index_html", globals())
pt_files = ( # ZWiki files
('courses_list','list of courses','ui/courses_list'),
('password_form','','ui/password_form'),
('backlinks','ZWiki backlinks','ui/Wiki/backlinks.pt'),
('badtemplate','ZWiki ZPT','ui/Wiki/badtemplate.pt'),
('contentspage','ZWiki','ui/Wiki/contentspage.pt'),
('diffform','ZWiki','ui/Wiki/diffform.pt'),
('editform','ZWiki','ui/Wiki/editform.pt'),
('filterissues','ZWiki','ui/Wiki/filterissues.pt'),
('issuetracker','ZWiki ZPT','ui/Wiki/issuetracker.pt'),
('ratingform','ZWiki ZPT','ui/Wiki/ratingform.pt'),
('recentchanges','ZWiki','ui/Wiki/recentchanges.pt'),
('searchwiki','ZWiki','ui/Wiki/searchwiki.pt'),
('subscribeform','ZWiki','ui/Wiki/subscribeform.pt'),
('useroptions','ZWiki','ui/Wiki/useroptions.pt'),
('wikipage_macros','ZWiki','ui/Wiki/wikipage_macros.pt'),
('wikipage','ZWiki Page','ui/Wiki/wikipage.pt'),
('index_html','start page','ui/index_html'),
('start_page','start page','ui/start_page'),
('defaultRender','dummy page to display custom pages','ui/defaultRender'),
('changeEvent','','ui/changeEvent'),
('createMail','','ui/createMail'),
('event_index','','ui/event_index'),
('event_list','','ui/event_list'),
('haldusleht','','ui/haldusleht'),
('kontrolli_kursuse_kaust','','ui/kontrolli_kursuse_kaust'),
('mailbox_index','','ui/mailbox_index'),
('mail_index','','ui/mail_index'),
('mailStatus','','ui/mailStatus'),
('main_macro','','ui/main_macro'),
('manage_addAssignment','','ui/manage_addAssignment'),
('manage_addingUsers','','ui/manage_addingUsers'),
('manage_addIvaUsers','','ui/manage_addIvaUsers'),
('manage_affiliations','','ui/manage_affiliations'),
('manage_assignments','','ui/manage_assignments'),
('manage_changeAssignment','','ui/manage_changeAssignment'),
('manage_course_info','','ui/manage_course_info'),
('manage_gradeAssignment','','ui/manage_gradeAssignment'),
('manage_iva_setup','','ui/manage_iva_setup'),
('manage_ivaUsers','','ui/manage_ivaUsers'),
('manage_participants','','ui/manage_participants'),
('manage_userPermissions','','ui/manage_userPermissions'),
('manage_pendingUsers','','ui/manage_pendingUsers'),
('message_dialog','','ui/message_dialog'),
('message_dialog2','','ui/message_dialog2'),
('message_dialog_error','','ui/message_dialog_error'),
('organizer_calendar','','ui/organizer_calendar'),
('organizer_change_course','','ui/organizer_change_course'),
('organizer_index','','ui/organizer_index'),
('page_macro','','ui/page_macro'),
('sea_jooksev_kursus','','ui/sea_jooksev_kursus'),
('sharedDocs','','ui/sharedDocs'),
('standard_error_message','','ui/standard_error_message'),
('assignmentGrading','','ui/assignmentGrading'),
('testihaldus', '', 'ui/testihaldus'),
('tootubade_leht','','ui/tootubade_leht'),
('workshop_subgroup','','ui/workshop_subgroup'),
('workshop_subgroup_add','','ui/workshop_subgroup_add'),
('workshop_subgroup_list','','ui/workshop_subgroup_list'),
('workshop_subgroup_show','','ui/workshop_subgroup_show'),
('wt_add_folder','','ui/wt_add_folder'),
('wt_add_link','','ui/wt_add_link'),
('wt_add_memo','','ui/wt_add_memo'),
('wt_add_wiki','','ui/wt_add_wiki'),
('wt_index_html','','ui/wt_index_html'),
('wt_itemProperties','','ui/wt_itemProperties'),
('wt_manage','','ui/wt_manage'),
('wt_rename','','ui/wt_rename'),
('wt_upload','','ui/wt_upload'),
('wt_usercomments','','ui/wt_usercomments'),
('wt_userForm','','ui/wt_userForm'),
('wt_view_memo','','ui/wt_view_memo'),
('wt_zip_upload','','ui/wt_zip_upload'),
('ylAlus_muutmisVorm', '', 'ui/ylAlus_muutmisVorm'),
('ylMeta_vorm1', '', 'ui/ylMeta_vorm1'),
('ylesandedMuutmisTabelina', '', 'ui/ylesandedMuutmisTabelina'),
('ylOtsing', '', 'ui/ylOtsing'),
('ylOtsinguVorm', '', 'ui/ylOtsinguVorm'),
('ylTestSettingsForm', '', 'ui/ylTestSettingsForm'),
('ylBlankQuestion', '', 'ui/ylBlankQuestion'),
('ylAddPicture', '', 'ui/ylAddPicture'),
('ylTable', '', 'ui/ylTable'),
('qtChangeFormMatchingExercise', '', 'ui/qtChangeFormMatchingExercise'),
('qtChangeFormNumberSpaceExercise', '', 'ui/qtChangeFormNumberSpaceExercise'),
('qtChangeFormShortAnswerExercise', '', 'ui/qtChangeFormShortAnswerExercise'),
('qtChangeFormPercentExercise', '', 'ui/qtChangeFormPercentExercise'),
('qtTimeSettings', '', 'ui/qtTimeSettings'),
('qtTestAnswerTable', '', 'ui/qtTestAnswerTable'),
('qtTestAnswerCommentingTable', '', 'ui/qtTestAnswerCommentingTable'),
('qtTestAnswerStatistics', '', 'ui/qtTestAnswerStatistics'),
('qtUserResults', '', 'ui/qtUserResults'),
('qtExplanationQuiz', '', 'ui/qtExplanationQuiz'),
('qtAnsweringForm', '', 'ui/qtAnsweringForm'),
('qtAnswersSaved', '', 'ui/qtAnswersSaved'),
('qtExerciseForm', '', 'ui/qtExerciseForm'),
('qtExerciseAnswer', '', 'ui/qtExerciseAnswer'),
('courses/add_course_context_form','Add Course Context','ui/courses/add_course_context_form'),
('courses/context_html','Context index','ui/courses/context_html'),
('courses/course_html','Course Context list','ui/courses/course_html'),
('courses/course_info','','ui/courses/course_info'),
('courses/course_setup_roleplay_form','Roleplay setup','ui/courses/course_setup_roleplay_form'),
('courses/note_edit_form','Note editing form','ui/courses/note_edit_form'),
('courses/index_html','','ui/courses/index_html'),
('courses/note_preview_form','Note editing form','ui/courses/note_preview_form'),
('courses/note_index_html','Note viewing form','ui/courses/note_index_html'),
('courses/organizer_openCourses','','ui/courses/organizer_openCourses'),
('courses/printer_macro','Note printers','ui/courses/printer_macro'),
('courses/note_hide','Note printers','ui/courses/note_hide'),
('courses/jamming_index_html','Index page of jamming','ui/courses/jamming_index_html'),
('courses/jam_add_session_form','add jam session','ui/courses/jam_add_session_form'),
('courses/jamsession_index_html','Index page of jamsession','ui/courses/jamsession_index_html'),
('courses/jam_add_artefact_form','Add artefact form','ui/courses/jam_add_artefact_form'),
('courses/jam_artefact_index_html','Artefact index_html','ui/courses/jam_artefact_index_html'),
('courses/jam_add_annotation_form','Add artefact annotation form','ui/courses/jam_add_annotation_form'),
('courses/list_readers','Who has read it!?','ui/courses/list_readers'),
('courses/manage_import_form','Import course','ui/courses/manage_import_form'),
('courses/teacher_import_form','Import course(for teacher)','ui/courses/teacher_import_form'),
('courses/manageCategories','manage course categories','ui/courses/manageCategories'),
('courses/course_index','Welcome page for course','ui/courses/course_index'),
('courses/courseStatistics','Course statistics','ui/courses/courseStatistics'),
('courses/describeTTS','Describes thinkingtypeset','ui/courses/describeTTS'),
('typesets/edit_form_1_3','','ui/typesets/edit_form_1_3'),
('typesets/edit_form_2_3','','ui/typesets/edit_form_2_3'),
('typesets/edit_form_3_3','','ui/typesets/edit_form_3_3'),
('typesets/index_html','','ui/typesets/index_html'),
('typesets/tts_index','','ui/typesets/tts_index'),
('typesets/manage_import_form','Import typesets','ui/typesets/manage_import_form'),
('register_form','Register form','ui/register_form'),
('fle_users/course_info_user','Information about user actions','ui/fle_users/course_info_user'),
('fle_users/user_courses_info','Information about all user courses','ui/fle_users/user_courses_info'),
('fle_users/show_user_info','','ui/fle_users/show_user_info'),
('fle_users/edit_user_form','','ui/fle_users/edit_user_form'),
)
# NOTE: Since we use a python method index_html to do
# the redirection to the appropriate DTML method, EVERY FOLDER
# that the user access must have this index_html method
# (either through class inheritance or as its own dtml method,
# but not through acquisition from its containers). Acquisition
# cannot be used, since the object reference passed to the DTML
# method will point to the object where index_html was acquired.
# So all courses, contexts, notes, userinfos, webtops and webtopfolders
# and any other folderish objects must have this python method.
#security.declarePublic('index_html')
#def index_html(self,REQUEST):
# return self.ui.FLE.index_html(self,REQUEST)
# Parameters are received from the creation form at
# ui/FLE/creation_form.dtml
def __init__(
self, _id, title,
fle_admin, fle_admin_pwd,
fle_admin_first_name, fle_admin_last_name,
acl_users_mode, smtp_host, smtp_port=25, import_data=None,
_default_lang='en', _quota=3000000, mfrom='iva@htk.tpu.ee',
def_passwd=0,def_not_change=0,def_not_aff=0):
"""Construct FLE object."""
self.setup_timer()
errors = []
if not _id:
errors.append('ID not specified')
if not title:
errors.append('Title not specified')
# if not fle_admin:
# errors.append('Administrator user name not specified')
if not fle_admin_pwd and acl_users_mode=='create':
errors.append('Administrator password not specified')
if errors:
raise 'Insufficient form data',str(errors)
self.id = _id
self._default_lang=_default_lang
self._quota=_quota
self.title = title
self.mfrom = mfrom
self.def_asswd= int(def_passwd)
self.def_ot_change= int(def_not_change)
self.def_ot_aff= int(def_not_aff)
self._pending_users = PersistentMapping() # user list
self.__fle_root = ''
# The values are saved so that they can be used in
# manage_afterAdd (where they are also deleted...)
tmptbl = {}
tmptbl['initial_fle_admin'] = fle_admin
tmptbl['initial_fle_admin_pwd'] = fle_admin_pwd
tmptbl['initial_fle_admin_first_name'] = fle_admin_first_name
tmptbl['initial_fle_admin_last_name'] = fle_admin_last_name
tmptbl['acl_users_mode'] = (acl_users_mode=='create')
# Check that the fileupload exists and has a filename
if import_data and import_data.filename:
tmptbl['import_data'] = import_data
else:
tmptbl['import_data'] = None
# If not, set it to none, so we only need to check one
# thing if we need to decide whether we have a file or not.
import_data = None
self.tmptbl = tmptbl
if len(smtp_host)>0 and smtp_port:
from Products.MailHost import MailHost
mailhost = MailHost.MailHost()
mailhost._init(smtp_host, atoi(smtp_port))
self._setObject('MailHost', mailhost)
# Style sheets
# self.reload_style_sheets()
# Add images to images/
self.manage_addFolder('images', '')
from common import image_file_path
self.add_images(self.images, image_file_path)
# ZCatalog for webtop items
catalog = ZCatalog('catalog_webtop_items', 'ZCatalog for webtop items')
# indexes
catalog.addIndex('get_name', 'TextIndex')
catalog.addIndex('get_content', 'TextIndex')
catalog.addIndex('get_author', 'FieldIndex')
# metadata
catalog.addColumn('get_name')
catalog.addColumn('get_author')
catalog.addColumn('absolute_url')
self._setObject('catalog_webtop_items', catalog)
security.declarePrivate('manage_afterAdd')
# Executes a full FLE import if the export data was
# passed to the constructor (ie. uploaded via the creation
# form.
def manage_afterAdd(self, item, container):
"""Add roles to the root level Fle folder and do other
initialization tasks."""
if not hasattr(self.aq_self, 'qtCatalog'):
self._setObject('qtCatalog', YlHoidla())
if hasattr(self,'typesets'):
# If the typesets directory already exists, then this
# isn't the initial installation, but rather a rename
# or a move operation.
# Skip everything!
return
t = self.tmptbl
# Property telling whether or not we're using an external
# user folder.
# Ramifications:
# - new users are allowed to login
# - the user folder is read-only
self.manage_addProperty('allow_external_users', not t['acl_users_mode'], 'boolean')
# add properties for todos
self.manage_addProperty('todo_mode', 0, 'boolean')
self.manage_addProperty('todo_server', '', 'string')
self.manage_addProperty('todo_login', '', 'string')
self.manage_addProperty('todo_password', '', 'string')
self.manage_addProperty('Autoregister', 0, 'boolean')
# add property for developer controls
self.manage_addProperty('show_developer_controls', 0, 'boolean')
# add property for FLE version number
self.manage_addProperty('webtop_quota', 1, 'boolean')
self.manage_addProperty('webtop_quota_amount', self._quota, 'string')
self.manage_addProperty('default_language', self._default_lang, 'string')
self.manage_addProperty('IVA_VERSION', IVA_VERSION, 'string')
self.manage_addProperty('MFROM',self.mfrom,'string')
self.manage_addProperty('def_passwd',int(self.def_asswd),'boolean')
self.manage_addProperty('def_not_change',int(self.def_ot_change),'boolean')
self.manage_addProperty('def_not_aff',int(self.def_ot_aff),'boolean')
tts_manager = TTSM('typesets', '')
self._setObject('typesets', tts_manager)
tts_manager=tts_manager.__of__(self)
from Downloader import Downloader
self._setObject('download',Downloader())
self.manage_addFolder('uploads','Wiki uploads')
self.manage_addFolder('js','JavaScripts')
from common import fle_roles
for role in fle_roles:
self._addRole(role)
self._addRole('Items')
self.manage_permission(perm_access, ('Manager','IVAAdmin','Member','Owner') ,0)
self.manage_permission(perm_view, ('Authenticated','Manager','IVAAdmin','Member','Owner') ,0)
self.manage_permission(perm_edit, ('Manager',), 0)
self.manage_permission(perm_manage, roles_admin, 0)
self.manage_permission(perm_add_lo, roles_admin, 0)
try:
self.manage_permission('Zwiki: Add comments', roles_user+('Authenticated','Owner',), 0)
self.manage_permission('Zwiki: Add pages', ('Owner',), 0)
self.manage_permission('Zwiki: Add wikis', ('Owner',), 0)
self.manage_permission('Zwiki: Change page types', ('Owner',), 0)
self.manage_permission('Zwiki: Delete pages', ('Owner',), 0)
self.manage_permission('Zwiki: Edit pages', ('Owner',), 0)
self.manage_permission('Zwiki: Rename pages', ('Owner',), 0)
self.manage_permission('Zwiki: Reparent pages', ('Owner',), 0)
except ValueError:
pass
self.uploads.manage_permission('Add Documents, Images, and Files', roles_user+('Authenticated','Owner',), 0)
um_obj = UserManager('fle_users',
#'FLE User Manager')
'')
self._setObject('fle_users',
um_obj)
import_data = t['import_data']
# Create default knowledge type sets, whether importing
# or not.
tts_manager.load_default_sets()
# Let's do courses last, since if we're importing, we
# need to have the users already in place.
cm_obj = CourseManager('courses')
self._setObject('courses', cm_obj)
self.manage_addProduct['OFSP'].manage_addFolder('css')
#self.css._setObject('style_css', self.style_css)
# We don't need these any more.
del self.tmptbl
self.reload_pt()
# Set the zope manageable dtml objects of this class.
self.reload_dtml()
self.setDefaultPermissions()
#XXX: migrate me too!?
if CCAware:
self.addCookieCrumbler()
security.declareProtected(perm_manage, 'reload_pt')
def reload_pt(self, REQUEST=None):
""" reload ZopePageTemplates """
reload_pt(self, self.pt_files)
self.setDefaultPermissions()
if REQUEST:
return self.message_dialog(
self, REQUEST,
title="Reloaded",
message="All page templates reloaded",
action='index_html')
security.declarePublic('setDefaultPermissions')
def setDefaultPermissions(self):
""" doc"""
getattr(self.images,'iva_logo_trans').manage_permission('View',['Authenticated', 'Anonymous',], 1)
getattr(self.images,'start_top_bg').manage_permission('View',['Authenticated', 'Anonymous',], 1)
getattr(self.images,'start_bg').manage_permission('View',['Authenticated', 'Anonymous',], 1)
getattr(self,'register_form').manage_permission('View',['Authenticated', 'Anonymous',], 1)
getattr(self,'courses_list').manage_permission('View',['Authenticated', 'Anonymous',], 1)
try:
getattr(self,'style_css').manage_permission('View',['Authenticated', 'Anonymous',], 1)
except:
pass
getattr(self,'index_html').manage_permission('View',['Authenticated', 'Anonymous',], 1)
getattr(self,'start_page').manage_permission('View',['Authenticated', 'Anonymous',], 1)
getattr(self,'password_form').manage_permission(perm_view,['Authenticated', 'Anonymous',], 1)
# getattr(self,'style_css').manage_permission(perm_view,['Anonymous'],0)
getattr(self,'register_form').manage_permission(perm_view,['Anonymous'],0)
getattr(self,'images').manage_permission('View',['Anonymous',],1)
security.declareProtected(perm_manage, 'reload_dtml')
def reload_dtml(self, REQUEST=None):
"""Reloads dtml stuff."""
reload_dtml(self, self.dtml_files)
self.setDefaultPermissions()
if REQUEST:
return self.message_dialog(
self, REQUEST,
title='Reloaded',
message='dtml files reloaded',
action='index_html')
security.declareProtected(perm_manage, 'reload_typesets')
def reload_typesets(self,REQUEST=None):
"""Reload typesets."""
self.typesets.load_default_sets()
if REQUEST:
return self.message_dialog(
self, REQUEST,
title='Reloaded',
message='Knowledge type sets reloaded',
action='index_html')
security.declareProtected(perm_manage, 'reload_images')
def reload_images(self,REQUEST=None):
"""Reload images."""
for e in self.images.objectIds():
self.images.manage_delObjects(e)
from common import image_file_path
self.add_images(self.images, image_file_path)
if REQUEST:
return self.message_dialog(
self, REQUEST,
title='Reloaded',
message='Images reloaded',
action='index_html')
security.declarePrivate('add_images')
# fs_path is CVS path
def add_images(self, zope_path, fs_path):
"""Add images recursively."""
for e in os.listdir(fs_path):
full_path = os.path.join(fs_path, e)
if os.path.isdir(full_path):
if e == 'CVS': continue
if e == '.svn': continue
zope_path.manage_addFolder(e, '')
self.add_images(getattr(zope_path, e), full_path)
else:
# title (3rd parameter) will be used as an alt parameter
# inside HTML tag. (Override in DTML code when you
# want some alt text (i.e. almost always...))
# This can be like this for now .... -granbo
import re
m = re.match("^(.*)\.", e)
add_image_obj(zope_path, m.group(1), '', full_path)
security.declarePrivate('add_style_sheets')
def add_style_sheets(self, fs_path):
"""Add style sheets."""
for e in os.listdir(fs_path): # fetch all style sheets
if e[-4:] != 'dtml':
continue
if e == 'personal_style_sheet.dtml': # This goes under UserInfo
continue # object (see UserInfo.py).
full_path = os.path.join(fs_path, e)
if os.path.isdir(full_path):
continue # skip the CVS directory
# get the code
f = open(full_path)
code = f.read()
f.close()
security.declareProtected(perm_manage, 'reload_all')
def reload_all(self, REQUEST=None):
"""Reload all dtml, style sheet, image, printer, and
translation files."""
self.IVA_VERSION = IVA_VERSION
# self.reload_all_dtml()
self.reload_images()
self.reload_pt()
self.reload_typesets()
self.reload_all_dtml()
if REQUEST:
return self.message_dialog(
self, REQUEST,
title='Reloaded',
message='Reloaded all dtml, css, images, and knowledge type sets',
action='index_html')
security.declareProtected(perm_manage, 'reload_all_dtml')
def reload_all_dtml(self, REQUEST=None):
"""Reload _all_ dtml files."""
from common import tree_reload_dtml
reload_dtml(self, self.dtml_files)
self.setDefaultPermissions()
if REQUEST:
return self.message_dialog(
self, REQUEST,
title='Reloaded',
message='dtml files reloaded',
action='index_html')
# security.declareProtected(perm_view, 'get_version')
security.declarePublic('get_version')
def get_version(self):
""" return IVA version """
if not hasattr(self, 'IVA_VERSION'):
return "IVA"
else:
return self.IVA_VERSION
# FIXME: What should we do if self.webtop_quota_amount is invalid?
security.declareProtected(perm_view, 'get_quota')
def get_quota(self):
"""Return quota limit in bytes (-1 if no quota in use)."""
if not hasattr(self, 'webtop_quota'):
return -1
if not hasattr(self, 'webtop_quota_amount'):
return -1
if not self.webtop_quota:
return -1 # no quota
s = self.webtop_quota_amount.strip()
if s[-1].lower() == 'k':
return int(s[:-1]) * 1024
elif s[-1].lower() == 'm':
return int(s[:-1]) * 1024 * 1024
else:
return int(s)
#XXX: security check!
# security.declareProtected(perm_view, 'get_languages')
def get_languages(self):
""" return list of languages available """
self.lang_list = ['et','en','fi','ru']
return self.lang_list
def get_default_language(self):
"Vaikimisi keel"
if not hasattr(self, 'default_language'):
return "en"
return self.default_language
def show_controls_for_developers(self, REQUEST):
"""Return boolean depending on whether we are in debug mode
or not!"""
return not not self.show_developer_controls
# This is used by message_dialog.dtml.
def message_dialog_handler(self, action, REQUEST):
"""Redirects to the given URL, preserving the
state information in the url."""
REQUEST.RESPONSE.redirect(action)
security.declareProtected(perm_view, 'redirect_to_webtop')
def redirect_to_webtop(self, REQUEST):
"""Redirect to webtop."""
uname = str(REQUEST.AUTHENTICATED_USER)
if (not hasattr(self.fle_users.aq_self, uname)):
result = self.fle_users.add_user_fle(uname, ('Member',))
self.kontrolli_kursuse_kaust(self, REQUEST)
getattr(self.fle_users, uname).kysiKirjadeKataloog()
user = self.fle_users.get_user_info(uname)
user.kontrolliKasutajaKodutood(REQUEST)
if user.get_first_name()=='' or user.get_last_name()=='':
return REQUEST.RESPONSE.redirect(self.fle_root().absolute_url()+'/fle_users/' + uname + '/webtop/edit_user_form')
if hasattr(user, 'perm_must_change'):
if user.perm_must_change == 1:
return REQUEST.RESPONSE.redirect(self.fle_root().absolute_url()+'/fle_users/' + uname + '/webtop/edit_user_form')
else:
return REQUEST.RESPONSE.redirect(self.fle_root().absolute_url()+'/organizer_index')
else:
return REQUEST.RESPONSE.redirect(self.fle_root().absolute_url()+'/organizer_index')
security.declareProtected(perm_manage, 'manage_workspace')
def manage_workspace(self,REQUEST):
"""This makes sure that ZCatalog doesn't override manage_workspace
and make it point to index_html, when we actually want manage_main"""
REQUEST.RESPONSE.redirect('manage_main')
def logout(self,REQUEST):
"""This is the logout instruction page."""
return self.message_dialog2(
self, REQUEST,
title= 'Logout',
message="To log out, either close your browser or press the Logout button below. When your browser asks for a username and password, just press Cancel. This will clear your login information from your browser's cache",
extra_value_name = '',
extra_values = (),
option1_value = 'Cancel',
option1_name = 'cancel',
option2_value = 'Logout',
option2_name = 'logout',
handler = 'clear_password')
def clear_password(
self,
cancel=None,
logout=None,
REQUEST=None):
"""This will clear the password cache."""
if logout:
REQUEST.RESPONSE.setStatus(401)
REQUEST.RESPONSE.setHeader("WWW-Authenticate", 'basic realm="Zope"')
return self.message_dialog(
self, REQUEST,
title='Logout',
message='You have been logged out.',
action = 'index_html')
else:
return self.redirect_to_webtop(REQUEST)
# def syndmusteKogum(self):
# # user events. 7day events + overtime events
# return "kalasai"
def has_PIL(self):
"""Has the system PIL (Python Image Library) installed?"""
return PIL_imported
def fix_pictures(self):
""" fix user pictures """
kasutajad = self.get_users()
for kasutaja in kasutajad:
pilt = kasutaja.get_photo()
kasutaja.set_photo(pilt)
return "Done"
def upgrade(self):
""" creates a role """
self._addRole('Items')
return "done"
security.declareProtected(perm_manage, 'wikiOperation')
def wikiOperation(self,REQUEST,alg,lopp,omanik):
from ImportExportIMS import Importer
abi = Importer('admin',self.fle_root())
if hasattr(alg, 'WikiStart'):
kausta_nimi = "WikiStart"
elif hasattr(alg, 'WikiAvaLeht'):
kausta_nimi = "WikiAvaLeht"
if hasattr(lopp, kausta_nimi):
lopp._delObject(getattr(lopp,kausta_nimi).__name__)
fold_obj = lopp.lisa_kaust(kausta_nimi)
fold_obj.set_author(str(REQUEST.AUTHENTICATED_USER))
fold_obj.wiki_kaust = 1
abi.set_omanik(fold_obj,omanik)
for obj in alg.objectValues('ZWiki Page'):
kopi = alg.manage_copyObjects(obj.__name__)
tulem = fold_obj.manage_pasteObjects(kopi)
element = getattr(fold_obj, obj.__name__)
abi.set_omanik(element, omanik)
return
def getId(self):
""" Return object id. Hack XXX """
return self.id
security.declarePublic('register_form_handler')
def register_form_handler(self, REQUEST,
regB='', cancelB='', # buttons
username='', fname='', lname='', email='', preflang='en',optmess='', numbercheck=0):
""" registers user """
if regB and self.get_allow_autoregister():
ok = 1
inv_val = ''
if username and fname and lname and email:
ok = 1
if not '@' in email and not '.' in email:
ok = 0
inv_val+= ' email'
else:
#XXX check email!?
pass
if not fname:
ok = 0
if inv_val: inv_val+=','
inv_val+=' first name'
if not lname:
ok = 0
if inv_val: inv_val+=','
inv_val+=' last name'
if numbercheck != REQUEST.SESSION.get('securenr'):
ok = 0
if inv_val: inv_val+=','
inv_val+= ' number'
if not username:
ok = 0
if inv_val: inv_val+=','
inv_val+=' username'
else:
if self.fle_users.is_valid_uname(username):
ok = 0
if inv_val: inv_val+=','
inv_val+=' username'
# XXX: maybe we don't want that!
# XXX: also check in fle_users folder for user record
# XXX: check for lowlevel acl_users?
if not ok:
return self.register_form(username=username, fname=fname, lname=lname, email=email, optmess=optmess,mess='invalid values: '+inv_val)
#do queueing
self._queue_user(username=username, fname=fname, lname=lname, email=email, preflang=preflang,optmess=optmess)
#XXX: subject of email. Translation!
message = translate(self,"registrant_waiting", target=preflang)
if self.saadaEmail(email,'useraccount request', """
Content-Type:text/plain; charset=utf-8
"""
+message):
return translate(self,"You have been registered, check e-mail",target=self.giveLanguage(REQUEST))
else:
return translate(self,"You have been registered but some problems occured when sending email.",target=self.giveLanguage(REQUEST))
elif cancelB:
return REQUEST.RESPONSE.redirect('index_html')
raise "IVA Error", "unknown button in register_form_handler"
def lostPassword(self,REQUEST, send=0,knimi='', give_email=0):
if give_email:
if not knimi: return 0
try:
kasutaja = self.fle_users.get_user_info(knimi)
except:
return 0
if kasutaja.get_email() != '':
return 1
else:
return 0
return 0 # should never reach here
if not hasattr(self.aq_self,'MailHost'):
return ""
if send:
try:
kasutaja = self.fle_users.get_user_info(knimi)
except:
return 0
if kasutaja.get_email() == '':
return 0
sisu = '\nContent-Type:text/plain; charset=utf-8\n\n\n'
sisu += "\n"+translate(self,'Message from IVA server',target=self.giveLanguage(REQUEST))
sisu += "\n"+translate(self,'IVA server aadress:',target=self.giveLanguage(REQUEST))+" "+self.fle_root().absolute_url()
sisu += "\n"+translate(self,'Username:',target=self.giveLanguage(REQUEST))+" "+knimi
sisu += "\n"+translate(self,'Password:',target=self.giveLanguage(REQUEST))+" "
try:
sisu += kasutaja.getPassword()
except:
sisu += translate(self,"Error fetching password",target=self.giveLanguage(REQUEST))
self.saadaEmail(kasutaja.get_email(),'Lost password',sisu, kasutaja.get_email())
return "Recover password"
security.declarePublic('randomImage')
def randomImage(self):
""" chooses 3/4 images to place on frontpage """
imgs = self.images.frontpage.objectValues()
from random import shuffle
shuffle(imgs)
if self.get_allow_autoregister(): count=3
else: count = 4
return imgs[0:count]
security.declareProtected(perm_manage,'manage_iva_setup_pictures')
def manage_iva_setup_pictures(self, REQUEST, uploadB='', deleteB='',dele='', newimage=''):
""" upload picture, delete picture """
imgContainer = getattr(self.images, 'frontpage')
if deleteB:
from types import StringType
if type(dele) == StringType: dele = (dele,)
for x in dele:
imgContainer._delObject(x)
if uploadB and newimage:
import random
nid = ""
for x in range(15):
nr = 95
while 900 and smtp_port:
from Products.MailHost import MailHost
mailhost = MailHost.MailHost()
mailhost._init(smtp_host, atoi(smtp_port))
self._setObject('MailHost', mailhost)
else:
if len(smtp_host)>0 and smtp_port:
mailhost = getattr(self, 'MailHost')
mailhost.smtp_host = smtp_host
mailhost.smtp_port = smtp_port
self.MFROM = mailfrom
self.def_passwd = def_passwd
self.def_not_change = def_not_change
self.def_not_aff = def_not_aff
return self.manage_iva_setup(mess='settings saved succesfully!')
return
security.declareProtected(perm_manage, 'unqueue_user')
def unqueue_user(self, uname):
del self._pending_users[uname]
security.declarePrivate('_queue_user')
def _queue_user(self,username='', fname='', lname='', email='', preflang='en',optmess=''):
# _pending_users
if not hasattr(self.aq_self, '_pending_users'):
self._pending_users = PersistentMapping()
while self._pending_users.has_key(username):
username+='x'
self._pending_users[username] = {'fname':fname,'lname':lname,'email':email,'preflang':preflang,'optmess':optmess}
security.declareProtected(perm_manage,'get_pending_users')
def get_pending_users(self):
""" get pending users """
return self._pending_users.keys()
security.declareProtected(perm_manage,'get_pending_details')
def get_pending_details(self, uname):
""" get details of pending user """
return self._pending_users[uname]
security.declarePrivate('make_random_number')
def make_random_number(self, REQUEST):
# generates number and stores in in SESSION
import random
rnr = int(random.random()*10000000)
REQUEST.SESSION.set('securenr',rnr)
return rnr
def get_allow_autoregister(self):
return self.Autoregister
security.declarePublic('testtest')
def generate_picture(self, REQUEST, RESPONSE):
""" test"""
srnr = self.make_random_number(REQUEST)
import PIL
from PIL import Image, ImageDraw
import cStringIO
s = cStringIO.StringIO()
pilt = Image.new('RGB',(100,30),(255,255,255))
pil2 = ImageDraw.Draw(pilt)
tekst = str(srnr)
pil2.text((10,10),tekst,fill=(30,30,128))
pilt.save(s,'jpeg')
s.seek(0)
RESPONSE.setHeader('Content-Type','image/jpeg')
return s.read()
def tolgi(self, sona, REQUEST):
"Tlgib etteantud jupi. Abifunktsioon DTML-ist tlkimisel"
return translate(self, sona, target=self.giveLanguage(REQUEST))
security.declareProtected(perm_manage,'exportIMail')
def exportIMail(self,REQUEST):
""" export mailmessages """
from ImportExportIMS import Kirjutus
from ImportExportIMS import kirjutaYldM
import tempfile, os
name = 'ivamessages.zip'
path = os.path.join(Globals.INSTANCE_HOME,'var')
fname = os.path.join(path,name)
#fname = tempfile.mktemp()
yld = kirjutaYldM()
yld.kirjutaYldmanifest('innermail','Innermail messages',base='',href='messages.xml')
yld.lisaFaili(fname)
k = Kirjutus(self.fle_root(), self.get_id())
k.exportMail(fname)
#os.remove(fname)
return "Done! Zip-file is located at %s" % fname
security.declareProtected(perm_manage,'exportICAL')
def exportICAL(self,REQUEST):
""" export user events """
from ImportExportIMS import Kirjutus
from ImportExportIMS import kirjutaYldM
import tempfile, os
name = 'iva_events.zip'
path = os.path.join(Globals.INSTANCE_HOME,'var')
fname = os.path.join(path,name)
#fname = tempfile.mktemp()
yld = kirjutaYldM()
yld.kirjutaYldmanifest('IVA','IVA user events',base='IVA/',href='imsmanifest.xml')
# yld.kirjutaYldmanifest()
yld.lisaFaili(fname)
k = Kirjutus(self.fle_root(), self.get_id())
k.looKursuseFail(0)
k.kirjutaKasutajaSyndmus(self.fle_users.get_users())
k.pakiKursusFaili(fname)
#os.remove(fname)
return "Done! Zip-file is located at %s" % fname
security.declareProtected(perm_manage,'usercourselistcacheupdate')
def usercourselistcacheupdate(self):
""" update user course list cache """
import time
for x in self.fle_users.get_users():
a = time.time()
x.user_courses(update=1)
e = time.time()
print x.get_uname()," kulus ", e-a
return "Updated"
def addCookieCrumbler(self):
""" xxx """
#XXX: migrate me!
if hasattr(self.aq_self, 'login'):
print "we have cookiecrumbler"
return
cc = CookieCrumbler()
cc.id = 'login'
self._setObject('login', cc)
#XXX: picture location!!!
login_form = """
"""
self.manage_addDTMLMethod('login_form','CookieCruymblers login form',login_form)
getattr(self,'login_form').manage_permission('View',['Authenticated', 'Anonymous',], 1)
cc = getattr(self, 'login')
cc.auth_cookie = '__iva'
cc.name_cookie = '__iva_name'
cc.pw_cookie = '__iva_password'
cc.persist_cookie = '__iva_persistent'
return "ok"
Globals.InitializeClass(FLE)
# FIXME: input_checks (some checks done in FLE.__init__)
def manage_addFLE(
self, _id, title,
fle_manager='', fle_manager_pwd='',
fle_manager_first_name='', fle_manager_last_name='',
acl_users_mode='use_existing', smtp_host='', smtp_port='', import_data=None,
REQUEST=None, lang='en', quota=3000000, mfrom='iva@htk.tpu.ee',def_passwd=0,
def_not_change=0,def_not_aff=0,try_it=0):
"""Create a FLE object. (Product Factory Method)."""
if try_it:
if hasattr(self.aq_self, _id):
return 0
else:
return 1
if hasattr(REQUEST,'def_passwd'):
def_passwd = REQUEST.def_passwd
if hasattr(REQUEST,'def_not_change'):
def_not_change = REQUEST.def_not_change
if hasattr(REQUEST,'def_not_aff'):
def_not_aff = REQUEST.def_not_aff
fle = FLE(
_id, title, fle_manager, fle_manager_pwd,
fle_manager_first_name, fle_manager_last_name,
acl_users_mode, smtp_host, smtp_port, import_data, lang, quota, mfrom,
def_passwd,def_not_change,def_not_aff)
self._setObject(_id, fle)
if REQUEST:
return self.manage_main(self, REQUEST)
manage_addFLEForm = Globals.HTMLFile('ui/IVA_creation_form', globals())
# EOF
iva/GroupFolder.py 0100644 0000764 0000764 00000010726 10131152276 013510 0 ustar vahur vahur # -*- coding: utf-8
# $Id: GroupFolder.py,v 1.4 2003/08/18 07:44:24 berlingo Exp $
#
# 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 GroupFolder, which is the root object for group folders
in Knowledge Building."""
__version__ = "$Revision: 1.4 $"[11:-2]
import Globals
#from Globals import Persistent, HTMLFile
import AccessControl
from common import reload_dtml, add_dtml
#import TraversableWrapper
import WebtopFolder
import WebtopTrash
from WebtopItem import WebtopItem
from TraversableWrapper import TWFolder
from TempObjectManager import TempObjectManager
from common import perm_view, perm_edit, perm_manage, perm_add_lo
# This object is the root of a group folder inside a Course or
# a CourseContext.
#
# A group folder contains a trash folder and any
# WebtopItems the users have created. WebtopItem is a superclass, and
# actually the group folder will contain specific subclass instances, like
# WebtopFolder, WebtopFile, WebtopLink and WebtopMemo.
#
class GroupFolder(
WebtopFolder.WebtopFolder,
):
"""Group folder."""
meta_type = "GroupFolder"
list_of_types=('WebtopFolder', 'WebtopLink', 'WebtopMemo', 'WebtopFile','GroupFolder')
security = AccessControl.ClassSecurityInfo()
def __init__(self,parent,name):
"""Construct the group folder root object."""
WebtopItem.__init__(self,parent,name)
TempObjectManager.__init__(self)
self.id = 'gf' + self.id[2:]
self.__id_counter = long(self.id[2:])
security.declarePrivate('manage_afterAdd')
def manage_afterAdd(self, item, container):
"""Create trash and clipboard and call superclass
initialization code."""
WebtopFolder.WebtopFolder.manage_afterAdd(self, item, container)
security.declarePrivate('generate_id')
def generate_id(self):
"""Return a unique (within this webtop) id.
These ids are used for any and all WebtopItems created
instead of their visible names so we avoid any problems with
visible name conflicts and can use more complex visible names
for items."""
self.__id_counter += 1L
return "gf"+str(self.__id_counter)
security.declareProtected(perm_view, 'get_list_item_name')
def get_list_item_name(self, REQUEST=None):
"""Return the name of Groupfolder."""
return self.get_name()
def get_name(self):
"""Return the name of the course."""
try:
if hasattr(self.parent().aq_base, 'toplevel'):
return self.parent().get_name()
except AttributeError:
pass
return WebtopFolder.WebtopFolder.get_name(self)
## security.declarePrivate('add_folder')
## def add_folder(self,name):
## """Implementation of add_folder_handler without http code."""
## f = GroupFolder(self,name)
## self._setObject(f.id,f)
## return f
security.declarePrivate('get_clipboard')
def get_clipboard(self):
uname=str(self.REQUEST.AUTHENTICATED_USER)
return self.fle_users.get_user_info(uname).webtop.clipboard
security.declareProtected(perm_view, 'get_trash')
def get_trash(self):
"""Return trash (an instance of WebtopTrash)"""
#raise 'foo',str(self.aq_chain)
if hasattr(self.parent().aq_base, 'toplevel'):
return self.get_child('trash')
else:
return self.parent().get_trash()
def kysiSyndmusteKataloog(self):
"Lisatakse kui pole"
if self.absolute_url().find('subgroups')==-1:
return self.aq_parent.kysiSyndmusteKataloog()
import Kalender
if not hasattr(self, 'syndmused'):
self._setObject('syndmused', Kalender.KalendriSyndmusteKataloog())
self.syndmused.id='syndmused'
return self.syndmused
Globals.InitializeClass(GroupFolder)
# EOF
iva/GroupFolderProxy.py 0100644 0000764 0000764 00000015663 10131152276 014557 0 ustar vahur vahur # -*- coding: utf-8
# $Id: GroupFolderProxy.py,v 1.4 2003/08/18 07:44:24 berlingo Exp $
#
# 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 WebTopGroupFolderProxy."""
import Globals
import AccessControl
from common import course_level_roles
from common import reload_dtml, add_dtml
import WebtopFolder
from WebtopItem import WebtopItem
from common import perm_view, perm_edit, perm_manage, perm_add_lo
class GroupFolderProxy(
WebtopFolder.WebtopFolder,
):
"""GroupFolderProxy"""
meta_type = "GroupFolderProxy"
security = AccessControl.ClassSecurityInfo()
def __init__(self, parent, name, course_id):
"""Construct GroupFolderProxy"""
self.__course_id = course_id
WebtopItem.__init__(self, parent, name)
self.set_icon('images/group_folder')
security.declarePrivate('manage_afterAdd')
def manage_afterAdd(self,item,container):
"""..."""
WebtopFolder.WebtopFolder.manage_afterAdd(self, item, container)
for role in course_level_roles:
self._addRole(role)
from common import roles_admin, roles_staff, roles_user
from common import roles_student, roles_tutor, roles_teacher
security.declareProtected(perm_view, 'get_list_item_name')
def get_list_item_name(self, REQUEST=None):
"""Return the name of Groupfolder."""
if REQUEST:
uname = str(REQUEST.AUTHENTICATED_USER)
language = self.fle_users.get_child(uname).get_language()
else:
language = 'en'
d = {}
self.get_lang_given(('webtop',), d, language)
return self.get_name() + ' (' + d['L_shared'] + ')'
security.declareProtected(perm_view, 'get_trash')
def get_trash(self):
"""Return trash (an instance of WebtopTrash)"""
return self.__get_group_folder().get_trash()
security.declarePrivate('get_clipboard')
def get_clipboard(self):
return self.__get_group_folder().get_clipboard()
security.declareProtected(perm_view, 'has_content')
def has_content(self):
"""Any WebtopItems in this folder?"""
return self.__get_group_folder().has_content()
security.declareProtected(perm_view, 'list_contents')
def list_contents(self, criteria=''):
"""Returns a list of all different WebtopItems in this folder."""
return self.__get_group_folder().list_contents()
security.declareProtected(perm_edit, 'add_folder_handler')
def add_folder_handler(
self, REQUEST, my_name,
submit = '', # form buttons
cancel = '', #
):
"""Handles the input from folder add form."""
return self.__get_group_folder().add_folder_handler(
REQUEST, my_name, submit, cancel)
security.declareProtected(perm_edit, 'add_link_handler')
def add_link_handler(
self, REQUEST, my_name, url,
type = '',
submit = '', # form buttons
cancel = '', #
back_link = '', # 'add link to webtop' feature outside webtop
):
"""Handles the input from link add form."""
return self.__get_group_folder().add_link_handler(
REQUEST, my_name, url, type, submit, cancel, back_link)
security.declareProtected(perm_edit, 'add_file_handler')
def add_file_handler(
self, REQUEST, my_name, file=None,
key = '',
submit = '', # form buttons
cancel = '', #
):
"""Handles the input from upload form."""
return self.__get_group_folder().add_file_handler(
REQUEST, my_name, file, key, submit, cancel)
security.declareProtected(perm_edit, 'add_memo_handler')
def add_memo_handler(
self,
REQUEST,
my_name,
contents,
submit='',
cancel=''):
"""Handles the input from memo add form."""
return self.__get_group_folder().add_memo_handler(
REQUEST, my_name, contents, submit, cancel)
security.declareProtected(perm_edit, 'form_handler')
def form_handler(
self,
item_ids=None,
copy='', cut='', paste='', remove='', rename='', # submit buttons
REQUEST=None):
"""Handles the input from folder default form:
item copy/cut/paste, remove and rename operations."""
return self.__get_group_folder().form_handler(
item_ids, copy, cut, paste, remove, rename, REQUEST)
security.declareProtected(perm_edit, 'rename_helper')
def rename_helper(self, expr1, expr2=None):
"""Helper function for DTML method wt_rename.dtml"""
return self.__get_group_folder().rename_helper(expr1, expr2)
security.declareProtected(perm_view, 'is_clipboard_empty')
def is_clipboard_empty(self):
"""Is clipboard empty?"""
return self.__get_group_folder().is_clipboard_empty()
security.declareProtected(perm_edit, 'rename_handler')
def rename_handler(
self, REQUEST,
item_id_list,
new_name_list,
submit = '', # form buttons
cancel = '', #
):
"""Handles rename_form submission."""
return self.__get_group_folder().rename_handler(
REQUEST, item_id_list, new_name_list, submit, cancel)
security.declareProtected(perm_view, 'get_size')
def get_size(self):
"""Return size of the object."""
return self.__get_group_folder().get_size()
security.declarePublic('get_child')
def get_child(self, _id):
"""Override get_child() of TraversableWrapper."""
return self.__get_group_folder().get_child(_id)
def is_proxy_for(self, group_folder):
return self.__get_group_folder() == group_folder
security.declarePublic('get_course_this_belongs_to')
def get_course_this_belongs_to(self):
"""Return the course to which the actual group folder belongs to."""
return self.courses.get_child(self.__course_id)
def __get_group_folder(self):
return self.courses.get_child(self.__course_id).gf
def __bobo_traverse__(self, REQUEST, entry_name=None):
if entry_name[:2] == 'gf' or entry_name == 'trash':
ob = getattr(self.__get_group_folder(), entry_name).aq_base
return ob.__of__(self)
else:
return getattr(self, entry_name)
Globals.InitializeClass(GroupFolderProxy)
#EOF
iva/INSTALL 0100644 0000764 0000764 00000005235 10170463351 011740 0 ustar vahur vahur INSTRUCTIONS TO INSTALL IVA 0.6
===================================
IVA Installation guide
Required software:
Zope http://www.zope.org
PyXML http://pyxml.sourceforge.net/
PlacelessTranslationService http://sourceforge.net/projects/collective/
PIL http://www.pythonware.com/products/pil/ (with jpeg support)
jpeg-6b libraries can be found at ftp://ftp.uu.net/graphics/jpeg/
ZWiki http://www.zwiki.org (Currently, ZWiki 0.36.2 recommended)
CMF http://cmf.zope.org (Very optional)
General installation procedure consists of three steps:
See that your system has installed Python (preferrably ver.2.3) and Zope (preferrably ver. 2.7.3).
Install IVA product on your Zope server.
Install an instance of IVA on your Zope server.
If you have already Zope installed on your system, skip the step 1 (however, need to check the version compatibility as with Python).
Detailed guidelines for installation:
Step 1. Install Zope and all required software
Download Zope from http://www.zope.org/Products
Please see zope installation instructions.
Note that IVA works fine without PIL, PyXML and CMF but then some features may give errors or are disabled.
PIL is used in various places all over IVA, PyXML is only for import-export functionality.
Step 2. Install IVA product
Download the latest IVA tarball at http://www.htk.tpu.ee/iva
Unpack it to a temporary directory - tar xfzv iva-0.6-rc1.tgz
Move created directories to zope products directory (typically /usr/local/zope/lib/python/Products)
Restart Zope: inside the Zope Management Interface, or ZMI (typically http://localhost:8080/manage), click on Restart button under Control Panel.
Step 3. Install an instance of IVA
Log into Zope Management Interface (typically http://localhost:8080/manage) as manager.
Create an instance of IVA by selecting IVA from pull-down menu Select type to add...
Select settings for new IVA instance:
ID: name to your IVA instance
Quota: quota for user webtop in bytes (default 3 000 000)
Lang: default language for all new users
Add users to your IVA system:
Go to Management > Course management > Add users.
Enter the list of usernames and system generates the passwords. If a proposed username already exists on this Zope server, IVA adds a number to it (e.g. john1).
Create a course: go to Management > Course management and create a new course by clicking on the Add course link.
Add users to course: Enter the course environment by selecting the name of the course from pull-down menu on your IVA WebTop area. Then go to IVA Management area and click on User Management link in the left menu. Enroll selected users to the course as teachers (or students). Teachers can later add (more) students by themselves.
iva/ITempObjectManager.py 0100644 0000764 0000764 00000002663 10130153777 014727 0 ustar vahur vahur # -*- coding: utf-8
# $Id: ITempObjectManager.py,v 1.4 2003/08/18 07:44:24 berlingo Exp $
#
# 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 an interface for TempObjectManager."""
__version__ = "$Revision: 1.4 $"[11:-2]
from Interface import Base
class ITempObjectManager(Base):
"""Interface for TempObjectManater"""
def add_tmp_object(self, ob_ref):
"""Store given object as a temp object."""
def get_tmp_object(self, toid):
"""Return reference to given (id) temporary object."""
def remove_tmp_object(self, toid):
"""Remove given (id) temporary object."""
# retval: [toid1, toid2, toid3, ...]
def get_tmp_object_ids(self):
"""Return list of temporary object ids."""
# EOF
iva/IUserInfo.py 0100644 0000764 0000764 00000006532 10130153777 013131 0 ustar vahur vahur # -*- coding: utf-8
# $Id: IUserInfo.py,v 1.4 2003/08/18 07:44:24 berlingo Exp $
#
# 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 an interface for UserInfo."""
__version__ = "$Revision: 1.4 $"[11:-2]
from Interface import Base
class IUserInfo(Base):
"""Interface for UserInfo."""
def set_first_name(self, name):
"""Set the first name of the user."""
def set_last_name(self, name):
"""Set the last name of the user."""
def set_email(self, email):
"""Set the email address of the user."""
def set_language(self, language):
"""Set the users language. (Languages are handled by Language.py)."""
def set_photo(self, photo):
"""Set the user photo."""
def set_group(self, group):
"""Set the users group."""
def set_address(self, address):
"""Set the users address."""
def set_country(self, country):
"""Set the users country."""
def set_homepage(self, homepage):
"""Set the users homepage."""
def set_phone(self, phone):
"""Set the phonenumber of the user."""
def set_gsm(self, gsm):
"""Set the gsm (mobile phone) number of the user."""
def set_quote(self, quote):
"""Set the user quote."""
def set_background(self, background):
"""Set the user background."""
def set_personal_interests(self, p_i):
"""Set the users personal interests."""
def set_professional_interests(self, p_i):
"""Set the users professional interests."""
def get_first_name(self, name):
"""Get the first name of the user."""
def get_last_name(self, name):
"""Get the last name of the user."""
def get_email(self, email):
"""Get the email address of the user."""
def get_language(self, language):
"""Get the users language."""
def get_photo(self, photo):
"""Get the user photo."""
def get_group(self, group):
"""Get the users group."""
def get_address(self, address):
"""Get the users address."""
def get_country(self, country):
"""Get the users country."""
def get_homepage(self, homepage):
"""Get the users homepage."""
def get_phone(self, phone):
"""Get the phonenumber of the user."""
def get_gsm(self, gsm):
"""Get the gsm (mobile phone) number of the user."""
def get_quote(self, quote):
"""Get the user quote."""
def get_background(self, background):
"""Get the user background."""
def get_personal_interests(self, p_i):
"""Get the users personal interests."""
def get_professional_interests(self, p_i):
"""Get the users professional interests."""
# EOF
iva/ImportExport.py 0100644 0000764 0000764 00000154724 10130153777 013751 0 ustar vahur vahur # -*- coding: utf-8
# $Id: ImportExport.py,v 1.4 2003/08/18 07:44:24 berlingo Exp $
#
# 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 classes responsible for importing and exporting the data to and from an FLE installation. Uses XML for data storage."""
import sys, time
import xml.dom.minidom
from xml.dom.minidom import Document
import zipfile
from types import UnicodeType
from common import FakeRequest, FakeUpload
class Counter:
def __init__(self):
self.__counter=0
def get_next_counter(self):
self.__counter+=1
return self.__counter
def get_counter(self):
"""Returns the value of the automatic counter."""
return self.__counter
def set_counter(self,val):
self.__counter=val
class DataTable(Counter):
"""Auxiliary class for storing binary data needed for
XML export."""
def __init__(self):
Counter.__init__(self)
self.__cache={}
self.names = []
def get_size(self):
"""Returns the size of the binary cache (in items)."""
return len(self.__cache)
def storeData(self,data,nimi='data',suffix=''):
import random
"""Stores a new binary data into the storage and
assigns it a unique name. The name is returned."""
#name = 'data'+str(self.get_next_counter())
name = nimi+"_"+str(random.randint(1,9999))+"_"+str(random.randint(1,9999))+suffix
self.names.append(name)
self.__cache[name]=data
return name
def restoreData(self,name,data):
"""Re-stores binary data into the storage. The name
is given as a parameter, but should be of the form
'dataN' where N is an integer (of any length). The
restoration process should make sure that all numbers
from 1 to the highest number are filled."""
self.__cache[name]=data
#num = int(name[4:])
#Vahur
num = int(4)
if self.get_counter()',xmlstring).group(1)
print "Transforming from %s to utf-8..." % encoding
xmlstring = unicode(xmlstring,encoding).encode("utf-8")
self.dom = xml.dom.minidom.parseString(xmlstring)
self.root = self.dom.firstChild
for name in zip.namelist():
#if name[:4]=='data':
if not re.search('imsmanifest.xml',name):
self.binarydata.restoreData(name,zip.read(name))
zip.close()
def exportGlobalTypes(self,globals):
"""Exports globally available knowledge types."""
elem = self.dom.createElement("GlobalKnowledgeTypes")
for set in globals.objectValues('ThinkingTypeSet'):
elem.appendChild(self.exportTypeSet(set))
if hasattr(globals,'tmp_objects'):
for set in globals.tmp_objects.objectValues('ThinkingTypeSet'):
elem.appendChild(self.exportTypeSet(set))
return elem
def importGlobalTypes(self,elem,fle_root):
"""Imports globally available knowledge types."""
for telem in elem.childNodes:
self.importTypeSet(telem,fle_root.typesets)
def exportKB(self,courses):
"""Exports the entire knowledge building.
Parameter should point to the CourseManager."""
kb = self.dom.createElement("KnowledgeBuilding")
for c in courses.get_children('Course'):
kb.appendChild(self.exportCourse(c))
return kb
def importKB(self,elem,fle_root):
"""Import knowledge building.
- elem: The XML element containing the data.
- obj: The Zope object containing CourseManager."""
# All children should be course objects
for child in elem.getElementsByTagName('Course'):
self.importCourse(child,fle_root.courses)
#get_transaction().commit()
def exportCourse(self,course):
"""Exports the given course."""
elem = self.dom.createElement("Course")
name = course.get_name()
make_attr(elem,"Name",name)
make_attr(elem,"Teacher",course.get_teacher())
make_attr(elem,"Organisation",course.get_organisation())
make_attr(elem,"StartDate",str(int(round(course.get_start_date()))))
make_attr(elem,"EndDate",str(int(round(course.get_end_date()))))
if course.get_description():
desc=self.dom.createElement("Descr")
make_text(desc,course.get_description())
elem.appendChild(desc)
if course.get_methods():
meth = self.dom.createElement("Methods")
make_text(meth,course.get_methods())
elem.appendChild(meth)
## for set in course.objectValues('ThinkingTypeSet'):
## elem.appendChild(self.exportTypeSet(set))
for fol in course.get_children('GroupFolder'):
elem.appendChild(self.exportGroupFolder(fol))
for ctx in course.get_children("CourseContext"):
elem.appendChild(self.exportContext(ctx))
return elem
def importCourse(self,elem,courses):
"""Imports a course under the given CourseManager."""
id = courses.add_course_impl(get_attr(elem,'Teacher'))
course = courses.get_child(str(id))
descr = ''
if elem.getElementsByTagName("Descr"):
descr = get_text(elem.getElementsByTagName("Descr")[0])
methods = ''
if elem.getElementsByTagName("Methods"):
methods = get_text(elem.getElementsByTagName("Methods")[0])
course.update(
get_attr(elem,"Name"),
descr,
get_attr(elem,"Organisation"),
methods,
int(get_attr(elem,"StartDate")),
int(get_attr(elem,"EndDate")))
# Set local roles to users
for uelem in elem.ownerDocument.firstChild.getElementsByTagName("User"):
try:
user = course.fle_users.get_user_info(
get_attr(uelem,"Name"))
except:
continue # If the user doesn't exist, we'll just skip
for celem in uelem.getElementsByTagName("ACL")[0].\
getElementsByTagName("CourseRole"):
if get_attr(celem,"CourseName") != \
course.get_name():
continue
roles = []
for relem in celem.childNodes:
roles.append(get_attr(relem,"Name"))
if roles:
course.set_roles(user.get_uname(),tuple(roles))
for fol in elem.childNodes:
if fol.nodeName != 'GroupFolder':
continue
self.importGroupFolder(fol,course.__of__(courses),toplevel=1)
for ctx in elem.childNodes:
if ctx.nodeName != 'Context':
continue
self.importContext(ctx,course.__of__(courses))
def exportContext(self,ctx,startonly=0):
"""Exports the given course context."""
elem = self.dom.createElement("Context")
make_attr(elem,"Name",ctx.get_name())
make_attr(elem,"Author",ctx.get_author())
descr = self.dom.createElement("Descr")
make_text(descr,ctx.get_description())
elem.appendChild(descr)
descr = self.dom.createElement("LongDescr")
make_text(descr,ctx.get_long_description())
elem.appendChild(descr)
elem.appendChild(self.exportTypeSet(ctx.get_thinking_type_set()))
for fol in ctx.get_children('GroupFolder'):
elem.appendChild(self.exportGroupFolder(fol))
for note in ctx.get_children('Note'):
elem.appendChild(self.exportNote(note,startonly))
return elem
def importContext(self,elem,course):
"""Imports a context into a course."""
desc = get_text(elem.getElementsByTagName("Descr")[0])
ldesc = get_text(elem.getElementsByTagName("LongDescr")[0])
from CourseContext import CourseContext
ctx = CourseContext(
course,
get_attr(elem,"Name"),
desc,
ldesc,
None, # tt_set not given
get_attr(elem,"Author"))
course._setObject(ctx.get_id(),ctx)
set = elem.getElementsByTagName('KnowledgeTypeSet')[0]
self.importTypeSet(set,ctx.__of__(course))
ctx._tt_set_id=get_attr(set,'ID')
for nelem in elem.childNodes:
if nelem.nodeName != 'GroupFolder':
continue
self.importGroupFolder(nelem,ctx.__of__(course),toplevel=1)
for nelem in elem.childNodes:
if nelem.nodeName != 'Note':
continue
self.importNote(nelem,ctx.__of__(course))
def exportNote(self,note,startonly):
"""Exports the given note."""
if not hasattr(note,'censored'):
note.censored=0
elem = self.dom.createElement("Note")
make_attr(elem,"KnowledgeTypeRef",note.get_tt_id())
make_attr(elem,"ID",note.get_id())
make_attr(elem,"Date",str(int(round(note.get_creation_time()))))
if hasattr(note,'get_real_subject'):
make_attr(elem,"Subject",note.get_real_subject())
else:
make_attr(elem,"Subject",note.get_subject())
make_attr(elem,"Author",note.get_author())
if hasattr(note,'censored') and note.censored:
make_attr(elem,"CensoredBy",note.censorer)
make_attr(elem,"CensoredTime",str(note.censored))
body = self.dom.createElement("NoteBody")
make_text(body,note.get_body())
elem.appendChild(body)
reader_list = self.dom.createElement("ReaderList")
try:
if not startonly:
for (uname, date_data) in note.get_readers_with_all_dates().items():
reader = self.dom.createElement("Reader")
make_attr(reader,"Name", uname)
try:
for date in date_data['when']:
d = self.dom.createElement("Event")
make_attr(d,"Type","ReadTime")
make_attr(d,"Value",str(date))
reader.appendChild(d)
except TypeError:
# This will come up if the 'when' item isn't a list
d = self.dom.createElement("Event")
make_attr(d,"Type","ReadCount")
make_attr(d,"Value",str(date_data))
reader.appendChild(d)
reader_list.appendChild(reader)
except AttributeError:
# This will rise if Thread.py is an old versio.
# In this case we'll just have to skip the reader information.
pass
elem.appendChild(reader_list)
if note.get_url()!='':
link = self.dom.createElement("Link")
make_attr(link,"Src",note.get_url())
make_attr(link,"Name",note.get_url_name())
elem.appendChild(link)
if note.has_image():
name = self.binarydata.storeData(
note.get_image_data())
link = self.dom.createElement("DataLink")
make_attr(link,"LocalName",name)
make_attr(link,
"ContentType",
note.get_image_content_type())
make_attr(link,"Name",note.get_image_name())
elem.appendChild(link)
if not startonly:
for reply in note.get_children('Note'):
elem.appendChild(self.exportNote(reply,startonly))
return elem
def importNote(self,elem,parent):
"""Imports a note into a context or note."""
s_time=time.time()
url=''
url_name=''
image=None
image_name=''
for lelem in elem.childNodes:
if lelem.nodeName=="Link":
url=get_attr(lelem,"Src")
url_name=get_attr(lelem,"Name")
break
for delem in elem.childNodes:
if delem.nodeName=='DataLink':
image_data=self.binarydata.getData(get_attr(delem,"LocalName"),self.prefix)
image_name=get_attr(delem,"Name")
image_content_type = get_attr(delem,"ContentType")
image = FakeUpload('image',image_data,image_content_type)
break
self.timecounters[0]+=(time.time()-s_time)
s_time=time.time()
# We suppose that each Note has a NoteBody.
body = get_text(elem.getElementsByTagName("NoteBody")[0])
## body=''
## for line in elem.getElementsByTagName("NoteBody")[0].childNodes:
## snippet = to_utf8(line.nodeValue)
## if snippet == '\n':
## body += '\r\n'
## else:
## body += snippet
self.timecounters[1]+=(time.time()-s_time)
s_time=time.time()
note = parent.add_reply(
get_attr(elem,"KnowledgeTypeRef"),
get_attr(elem,"Author"),
get_attr(elem,"Subject"),
body,
url,
url_name,
image,
image_name,
creation_time=float(get_attr(elem,"Date")))
self.timecounters[2]+=(time.time()-s_time)
s_time=time.time()
note.set_temporary(0)
parent._setObject(note.id,note)
note=note.__of__(parent)
self.idmap[get_attr(elem,"ID")]=note
self.timecounters[3]+=(time.time()-s_time)
s_time=time.time()
censored = get_attr(elem,"CensoredTime")
if censored:
note.do_censor(float(str(censored)),
get_attr(elem,"CensoredBy"))
# readers (read/unread status)
for rlelem in elem.childNodes:
if rlelem.nodeName == 'ReaderList':
for relem in rlelem.childNodes:
uname = get_attr(relem,'Name')
dates = []
for delem in relem.childNodes:
if delem.nodeName == 'Event' and \
get_attr(delem,"Type")=="ReadTime":
dates.append(float(get_attr(delem,"Value")))
elif delem.nodeName == 'Event' and \
get_attr(delem,"Type")=="ReadCount":
dates.append(time.time())
note.set_exported_reader(uname, dates)
self.timecounters[4]+=(time.time()-s_time)
s_time=time.time()
#get_transaction().commit()
for nelem in elem.childNodes:
if nelem.nodeName != 'Note':
continue
self.importNote(nelem,note.__of__(parent))
def exportTypeSet(self,set):
"""Exports the given knowledgetypeset."""
elem = self.dom.createElement("KnowledgeTypeSet")
make_attr(elem,"ID", set.get_id())
make_attr(elem,"Name", set.get_name())
if set.is_in_tmp(set):
make_attr(elem,"Status",'Unfinished')
delem = self.dom.createElement("Description")
make_text(delem,set.get_description())
elem.appendChild(delem)
starting = self.dom.createElement("StartingTypes")
for start in set.get_thinking_type_thread_start():
starting.appendChild(self.exportTypeRef(start))
elem.appendChild(starting)
for type in set.get_thinking_types():
felem = self.dom.createElement("FollowupRule")
ffelem = self.dom.createElement("KnowledgeTypeRef")
make_attr(ffelem,"ID-REF",type.get_id())
felem.appendChild(ffelem)
for followup in set.get_possible_follow_ups(type):
ffelem = self.dom.createElement("KnowledgeTypeRef")
make_attr(ffelem,"ID-REF", followup.get_id())
felem.appendChild(ffelem)
elem.appendChild(felem)
for type in set.get_thinking_types():
elem.appendChild(self.exportType(type))
return elem
def importTypeSet(self,elem,parent,force_update=0):
"""Imports a knowledge type set into a ThinkingTypeSetManager
or a course."""
from ThinkingTypeSet import ThinkingTypeSet
from ThinkingType import ThinkingType
my_id = get_attr(elem,"ID")
# If the ID of this set is not of the form "ttsNN", then it's a
# predefined set (installed from the file system).
# We check if the set by the same ID already is created and:
# if the set is of the form "ttsNN", we change its id
# else if force_update is activated, we remove the previous version
# else we skip this import.
if my_id in parent.objectIds('ThinkingTypeSet'):
if my_id[:3]=='tts':
# We must assume now that the parent
# is a ThinkingTypeSetManager. Importing several sets
# into course contexts shouldn't happen.
my_id = parent.get_new_valid_tts_id()
elif force_update:
parent.manage_delObjects(my_id)
else:
return
types = []
for telem in elem.getElementsByTagName("KnowledgeType"):
try:
desc=get_text(telem.getElementsByTagName("Description")[0])
except IndexError:
desc=''
try:
checklist=get_text(telem.getElementsByTagName("Checklist")[0])
except IndexError:
checklist=''
try:
phrase=get_text(telem.getElementsByTagName("StartingPhrase")[0])
except IndexError:
phrase=''
type = {
'id': get_attr(telem,"ID"),
'name': get_attr(telem,"Name"),
'starting_phrase': phrase,
'description': desc,
'colour': get_attr(telem,"Colour"),
'icon': None,
# No image file - we'll store the data directly
'icondata': self.binarydata.getData(get_attr(telem.getElementsByTagName("Icon")[0],"LocalName"),self.prefix),
'checklist': checklist,
}
types.append(type)
starters = []
selem = elem.getElementsByTagName("StartingTypes")[0]
for stelem in selem.childNodes:
starters.append(get_attr(stelem,"ID-REF"))
relations = {}
for felem in elem.getElementsByTagName("FollowupRule"):
orig = None
list = []
for ffelem in felem.childNodes:
if orig:
list.append(get_attr(ffelem,"ID-REF"))
else:
orig=get_attr(ffelem,"ID-REF")
relations[orig]=list
descr = get_text(elem.getElementsByTagName("Description")[0])
tts = ThinkingTypeSet(
my_id,
get_attr(elem,"Name"),
descr,
types, # list of pairs (name,obj)
starters, # list of names
relations) # list of pairs (orig_name,reply_name)
parent._setObject(
my_id,
tts)
if get_attr(elem,"Status")=='Unfinished':
parent.move_to_tmp(tts)
#get_transaction().commit()
def exportTypeRef(self,type):
"""Exports the given knowledgetypeset reference."""
elem = self.dom.createElement("KnowledgeTypeRef")
make_attr(elem,"ID-REF",type.get_id())
return elem
def exportType(self,type):
"""Exports the given knowledgetype."""
elem = self.dom.createElement("KnowledgeType")
make_attr(elem,"ID",type.get_id())
make_attr(elem,"Name",type.get_name())
make_attr(elem,"Colour",type.get_colour())
icon = self.dom.createElement("Icon")
make_attr(icon,
"LocalName",
self.binarydata.storeData(type.get_icon().data))
make_attr(icon,"ContentType",type.get_icon().getContentType())
elem.appendChild(icon)
expl = self.dom.createElement("StartingPhrase")
make_text(expl,type.get_starting_phrase())
elem.appendChild(expl)
instr = self.dom.createElement("Description")
make_text(instr,type.get_description())
elem.appendChild(instr)
cl = self.dom.createElement("Checklist")
make_text(cl,type.get_checklist())
elem.appendChild(cl)
return elem
def exportJamming(self, courses):
"""Exports the entire jamming stuff.
Parameter should point to the CourseManager."""
jamming = self.dom.createElement('Jamming')
try:
#for c in courses.get_children('Course'):
for js in courses.get_child('jamming').get_children('JamSession'):
jamming.appendChild(self.exportJamSession(courses, js))
return jamming
except AttributeError:
# We are exporting old FLE version where Course
# objects don't have Jamming object.
return None
def importJamming(self, elem, course):
"""Import Jamming."""
for js in elem.getElementsByTagName('JamSession'):
self.importJamSession(js, course)
#get_transaction().commit()
def exportJamSession(self, course, jam_session,startonly=0):
"""Export the given jam session (on a given course)."""
elem = self.dom.createElement("JamSession")
make_attr(elem, 'CourseName', course.get_name())
make_attr(elem, 'Name', jam_session.get_name())
make_attr(elem, 'Type', jam_session.get_type())
make_attr(elem, 'Descr', jam_session.get_description())
make_attr(elem, 'ID', jam_session.get_id())
make_attr(elem, 'StartingArtefactIDRef',
jam_session.get_starting_artefact_id())
for ja in jam_session.get_children('JamArtefact'):
if startonly:
if ja.get_id() == jam_session.get_starting_artefact_id():
elem.appendChild(self.exportJamArtefact(ja))
else:
elem.appendChild(self.exportJamArtefact(ja))
return elem
def importJamSession(self, elem, courses):
"""Import a jam session (under jamming (under course)) under
the given CourseManager."""
#course_name = get_attr(elem, 'CourseName')
#for course in courses.get_courses():
# if course.get_name() == course_name:
jamming = courses.get_child('jamming')
# break
starting_artefact_id = get_attr(elem, 'StartingArtefactIDRef')
for ja_elem in elem.childNodes:
# if ja_elem.nodeName == 'Artefact' and \
if ja_elem.nodeName == 'JamArtefact' and \
get_attr(ja_elem, 'ID') == starting_artefact_id:
ja_name = get_attr(ja_elem, 'Name')
for delem in ja_elem.childNodes:
if delem.nodeName == 'DataLink':
ja_data = self.binarydata.getData(
get_attr(delem, 'LocalName'),self.prefix)
ja_content_type = get_attr(delem, 'ContentType')
break
break
# Create a jam session with starting artefact.
jam_session = jamming.form_handler(
get_attr(elem, 'Name'),
get_attr(elem, 'Type'),
get_attr(elem, 'Descr'),
ja_name,
FakeUpload('some name', ja_data, ja_content_type),
submit=1,
)
self.idmap[get_attr(elem, 'ID')] = jam_session
# Add annotations to the starting artefact.
starting_artefact = jam_session.get_children('JamArtefact')[0]
self.idmap[get_attr(ja_elem, 'ID')] = starting_artefact
for e in ja_elem.childNodes:
if e.nodeName == 'Annotations':
i = 0
for a in e.childNodes:
if a.nodeName == 'Annotation':
starting_artefact.add_annotation(
get_attr(a, 'Author'),
float(get_attr(a, 'Date')),
get_text(a.getElementsByTagName('Text')[0]))
censored = get_attr(a, 'Censored')
if censored:
starting_artefact.do_censor_annotations((i,), float(censored), get_attr(a, 'Censorer'))
i += 1
break
# readers (read/unread status of the starting artefact)
for rlelem in ja_elem.childNodes:
if rlelem.nodeName == 'ReaderList':
for relem in rlelem.childNodes:
uname = get_attr(relem,'Name')
dates = []
for delem in relem.childNodes:
if delem.nodeName == 'Event' and \
get_attr(delem,"Type")=="ReadTime":
dates.append(float(get_attr(delem,"Value")))
elif delem.nodeName == 'Event' and \
get_attr(delem,"Type")=="ReadCount":
dates.append(time.time())
starting_artefact.set_exported_reader(uname, dates)
# Import the rest of the jam artefacts in this jam session
for ja_elem in elem.childNodes:
if ja_elem.nodeName == 'JamArtefact' and \
get_attr(ja_elem, 'ID') != starting_artefact_id:
self.importJamArtefact(ja_elem, jam_session)
# set parent ids
for ja_elem in elem.childNodes:
id_ = get_attr(ja_elem, 'ID')
if ja_elem.nodeName == 'JamArtefact' and \
id_ != starting_artefact_id:
parent_ids = []
for pelem in ja_elem.childNodes:
if pelem.nodeName == 'Parents':
for prelem in pelem.childNodes:
if prelem.nodeName == 'ParentRef':
parent_ids.append(get_attr(prelem, 'ID-REF'))
break
real_parent_ids = []
for pid in parent_ids:
real_parent_ids.append(self.idmap[pid].get_id())
self.idmap[id_].set_parent_ids(real_parent_ids)
jam_session.update_drawing()
def exportJamArtefact(self, jam_artefact):
"""Export the given JamArtefact."""
elem = self.dom.createElement('JamArtefact')
make_attr(elem, 'Name', jam_artefact.get_real_name())
make_attr(elem, 'Author', str(jam_artefact.get_author()))
make_attr(elem, 'ID', jam_artefact.get_id())
annotations = self.dom.createElement('Annotations')
for tple \
in jam_artefact.get_real_annotations():
try:
(uname, a_time, a_text, censored, censorer) = tple
except ValueError:
# This comes up with versions 1.1betaX
(uname, a_time, a_text) = tple
censored=0
censorer=''
a_elem = self.dom.createElement('Annotation')
make_attr(a_elem, 'Author', uname)
make_attr(a_elem, 'Date', repr(a_time))
text = self.dom.createElement('Text')
make_text(text, a_text)
a_elem.appendChild(text)
make_attr(a_elem, 'Censored', repr(censored))
make_attr(a_elem, 'Censorer', censorer)
annotations.appendChild(a_elem)
elem.appendChild(annotations)
parents = self.dom.createElement('Parents')
for p_id in jam_artefact.get_parent_ids():
p_elem = self.dom.createElement('ParentRef')
make_attr(p_elem, 'ID-REF', p_id)
parents.appendChild(p_elem)
elem.appendChild(parents)
name = self.binarydata.storeData(jam_artefact.get_real_data())
link = self.dom.createElement('DataLink')
make_attr(link, 'LocalName', name)
make_attr(link, 'ContentType', jam_artefact.get_content_type())
elem.appendChild(link)
reader_list = self.dom.createElement("ReaderList")
for (uname, date_data) in \
jam_artefact.get_readers_with_all_dates().items():
reader = self.dom.createElement("Reader")
make_attr(reader,"Name", uname)
try:
for date in date_data['when']:
d = self.dom.createElement("Event")
make_attr(d,"Type","ReadTime")
make_attr(d,"Value",repr(date))
reader.appendChild(d)
except TypeError:
# This will come up if the 'when' item isn't a list
d = self.dom.createElement("Event")
make_attr(d,"Type","ReadCount")
make_attr(d,"Value",repr(date_data))
reader.appendChild(d)
reader_list.appendChild(reader)
elem.appendChild(reader_list)
return elem
def importJamArtefact(self, ja_elem, jam_session):
"""Import a jam artefact under given jam session."""
for delem in ja_elem.childNodes:
if delem.nodeName == 'DataLink':
ja_data = self.binarydata.getData(
get_attr(delem, 'LocalName'),self.prefix)
ja_content_type = get_attr(delem, 'ContentType')
break
artefact = jam_session.add_artefact(get_attr(ja_elem, 'Name'),
ja_data,
ja_content_type,
'temp value')
self.idmap[get_attr(ja_elem, 'ID')] = artefact
for e in ja_elem.childNodes:
if e.nodeName == 'Annotations':
i = 0
for a in e.childNodes:
if a.nodeName == 'Annotation':
artefact.add_annotation(
get_attr(a, 'Author'),
float(get_attr(a, 'Date')),
get_text(a.getElementsByTagName('Text')[0]))
censored = get_attr(a, 'Censored')
if censored:
artefact.do_censor_annotations((i,), float(censored), get_attr(a, 'Censorer'))
i += 1
break
# readers (read/unread status)
for rlelem in ja_elem.childNodes:
if rlelem.nodeName == 'ReaderList':
for relem in rlelem.childNodes:
uname = get_attr(relem,'Name')
dates = []
for delem in relem.childNodes:
if delem.nodeName == 'Event' and \
get_attr(delem,"Type")=="ReadTime":
dates.append(float(get_attr(delem,"Value")))
elif delem.nodeName == 'Event' and \
get_attr(delem,"Type")=="ReadCount":
dates.append(time.time())
artefact.set_exported_reader(uname, dates)
def exportUsers(self,users):
"""Exports FLE users. Parameter should point to the
UserManager."""
elem = self.dom.createElement("Users")
for user in users.objectValues('UserInfo'):
elem.appendChild(self.exportUser(user))
return elem
def exportUserList(self,userlist,do_webtop=0,do_passwd=0):
"""Export a given set of FLE users. Parameter should be
a list of UserInfo objects. By default doesn't export
the webtop or the user's password."""
elem = self.dom.createElement("Users")
for user in userlist:
elem.appendChild(self.exportUser(user,do_webtop,do_passwd))
#get_transaction().commit()
return elem
def importUsers(self,elem,fle_root):
"""Import all users into the given FLE root."""
for user in elem.childNodes:
self.importUser(user,fle_root.fle_users,do_user=1,do_webtop=0)
#get_transaction().commit()
def importUsersWebtops(self,elem,fle_root):
"""Import all users into the given FLE root."""
for user in elem.childNodes:
self.importUser(user,fle_root.fle_users,do_user=0,do_webtop=1)
def exportUserACL(self,fle_user,do_passwd=1):
"""Export a user's Zope ACL information.
User parameter is an FLE UserInfo instance."""
elem = self.dom.createElement("ACL")
#user = fle_user.acl_users.getUser(fle_user.get_uname())
if do_passwd:
try:
passwd = fle_user.getPassword()
except:
passwd = fle_user.getFrozenPassword()
make_attr(elem,"Password",passwd)
try:
domains = fle_user.getDomains()
except:
domains = fle_user.getFrozenDomains()
for dom in domains:
delem = self.dom.createElement("Domain")
dmake_attr(elem,"Name",dom)
elem.appendChild(delem)
if fle_user.is_frozen():
roles = fle_user.getFrozenRoles()
else:
roles = fle_user.getRoles()
for role in roles:
# Skip role 'Authenticated' since that is added
# to a user's roles supefluously and does not need
# to be saved.
if role == 'Authenticated':
continue
relem = self.dom.createElement("Role")
make_attr(relem,"Name",role)
elem.appendChild(relem)
for course in fle_user.courses.objectValues('Course'):
roles = fle_user.getRolesInObject(course)
relem = self.dom.createElement("CourseRole")
make_attr(relem,"CourseName",course.get_name())
for role in roles:
relem2 = self.dom.createElement("Role")
make_attr(relem2,"Name",role)
relem.appendChild(relem2)
elem.appendChild(relem)
return elem
def retrieveUserACL(self,elem):
"""Retrieves a user's ACL information.
Returns password, domains and roles."""
# If the Password attribute doesn't exist, will return
# an empty string (at least xml.dom.minidom does), which
# is ok.
password = get_attr(elem,"Password")
domains = []
for delem in elem.getElementsByTagName("Domain"):
domains.append(get_attr(delem,"Name"))
roles = []
for delem in elem.childNodes:
if delem.nodeName != 'Role':
continue
roles.append(get_attr(delem,"Name"))
return (password, domains, roles)
def exportUser(self,user,do_webtop=1,do_passwd=1):
"""Exports the given user."""
elem = self.dom.createElement("User")
elem.appendChild(self.exportUserACL(user,do_passwd))
make_attr(elem,"Name",user.get_uname())
make_attr(elem,"FirstName",user.get_first_name())
make_attr(elem,"LastName",user.get_last_name())
make_attr(elem,"Organisation",user.get_organization())
make_attr(elem,"Lang",user.get_language())
make_attr(elem,"Email",user.get_email())
make_attr(elem,"Group",user.get_group())
make_attr(elem,"Address1",user.get_address1())
make_attr(elem,"Address2",user.get_address2())
make_attr(elem,"City",user.get_city())
make_attr(elem,"Country",user.get_country())
make_attr(elem,"Homepage",user.get_homepage())
make_attr(elem,"Phone",user.get_phone())
make_attr(elem,"Mobile",user.get_gsm())
make_attr(elem,"WebtopBgImagePath", user.get_webtop_bg_image_path())
if user.is_frozen():
make_attr(elem,"Frozen","1")
if user.get_webtop_bg_image_path()[:len('images')] != 'images':
bg_image = self.dom.createElement("WebtopBackgroundImage")
make_attr(bg_image,
"LocalName",
self.binarydata.storeData(
getattr(user.own_styles,
user.get_webtop_bg_name()).data))
make_attr(bg_image,
"ContentType",
getattr(user.own_styles,
user.get_webtop_bg_name()).getContentType())
elem.appendChild(bg_image)
if user.get_photo() and len(user.get_photo())>0:
photo = self.dom.createElement("Photo")
make_attr(photo,
"LocalName",
self.binarydata.storeData(user.get_photo()))
if user.get_photo_type():
make_attr(photo,
"ContentType",user.get_photo_type())
elem.appendChild(photo)
if len(user.get_quote())>0:
quote = self.dom.createElement("Quote")
make_text(quote,user.get_quote())
elem.appendChild(quote)
if len(user.get_background())>0:
back = self.dom.createElement("Background")
make_text(back,user.get_background())
elem.appendChild(back)
if len(user.get_personal_interests())>0:
personal = self.dom.createElement("Personal")
make_text(personal,user.get_personal_interests())
elem.appendChild(personal)
if len(user.get_professional_interests())>0:
pro = self.dom.createElement("Professional")
make_text(pro,user.get_professional_interests())
elem.appendChild(pro)
if do_webtop:
elem.appendChild(self.exportWebtop(user.webtop))
return elem
def importUser(self,elem,fle_users,do_user,do_webtop):
"""Import a user into the UserManager.
If the user already exists, we'll just skip user creation."""
uname = get_attr(elem,"Name")
if not do_user:
try:
user = fle_users.get_child(uname)
except AttributeError:
return
else:
try:
fle_users.get_user_info(uname)
except:
pass
else:
print "Skipping import of pre-existing user "+uname
return
(password, domains, roles) = \
self.retrieveUserACL(elem.getElementsByTagName("ACL")[0])
# If the user has no roles and no password, we'll just skip.
if not password and not roles:
return
try:
user = fle_users.add_user(
uname,
password,
roles,
domains)
except:
# Error adding user - just skip
return
if not user:
# OK, user adding failed more nicely. Skip again
return
photo=None
try:
photo_data = self.binarydata.getData(
get_attr(elem.getElementsByTagName("Photo")[0],"LocalName"),self.prefix)
photo_content = get_attr(elem.getElementsByTagName("Photo")[0],"ContentType")
photo = FakeUpload('image',photo_data,photo_content)
except IndexError:
pass
try:
web_bg_image_data = self.binarydata.getData(
get_attr(elem.getElementsByTagName("WebtopBackgroundImage")[0],"LocalName"),self.prefix)
except IndexError:
web_bg_image_data = ''
try:
quote=get_text(elem.getElementsByTagName("Quote")[0])
except IndexError:
quote=''
try:
background=get_text(elem.getElementsByTagName("Background")[0])
except IndexError:
background=''
try:
personal=get_text(elem.getElementsByTagName("Personal")[0])
except IndexError:
personal=''
try:
professional=get_text(elem.getElementsByTagName("Professional")[0])
except IndexError:
professional=''
user.edit_info(
first_name = get_attr(elem,"FirstName"),
last_name = get_attr(elem,"LastName"),
email = get_attr(elem,"Email"),
organization = get_attr(elem,"Organisation"),
language = get_attr(elem,"Lang"),
photo_upload = photo,
# photo_url = '',
group = get_attr(elem,"Group"),
address1 = get_attr(elem,"Address1"),
address2 = get_attr(elem,"Address2"),
city = get_attr(elem,"City"),
country = get_attr(elem,"Country"),
homepage = get_attr(elem,"Homepage"),
phone = get_attr(elem,"Phone"),
gsm = get_attr(elem,"Mobile"),
quote = quote,
background = background,
personal_interests = personal,
professional_interests = professional,
)
if web_bg_image_data:
user.set_webtop_bg_from_image_data(web_bg_image_data)
else:
image_name = get_attr(elem,"WebtopBgImagePath")[len('images/'):]
if image_name:
user.set_webtop_bg_from_default_image(image_name)
if get_attr(elem,"Frozen"):
fle_users.freeze_user(user.get_uname())
if do_webtop:
wtelems = elem.getElementsByTagName("Webtop")
if len(wtelems)>0:
webtop=user.__of__(fle_users).webtop
self.importWebtop(wtelems[0],webtop)
def exportWebtop(self,webtop):
"""Export a user's webtop."""
elem = self.dom.createElement("Webtop")
self.exportWebtopFolderContents(webtop,elem)
return elem
def importWebtop(self,elem,webtop):
"""Import a user's webtop."""
self.importWebtopFolderContents(elem,webtop)
def exportWebtopItemAttrs(self,item,elem):
"""Export attributes common to all webtop items
into a predefined XML element."""
#make_attr(elem,"Name",item.get_name())
make_attr(elem,"identifier",item.get_id())
make_attr(elem,"identifierref",item.aq_parent.get_id())
itemname = self.dom.createElement('title')
itemname.appendChild(self.dom.createTextNode(item.get_name()))
elem.appendChild(itemname)
#make_attr(elem,"Date",str(int(item.get_timestamp())))
#make_attr(elem,"Owner",str(item.get_author_name()))
def importWebtopItemAttrs(self,elem,item):
"""Import attributes common to all WebtopItems."""
item.set_timestamp(int(get_attr(elem,"Date")))
owner = get_attr(elem,"Owner")
if owner:
item.set_author(owner)
## elif hasattr(item,'get_uname'):
## item.set_author(item.get_uname()) # Acquired from UserInfo
def exportWebtopFolderStrukt(self, folder):
""" kaustade/stuktuuri exportija kaustas"""
elem = self.dom.createElement("item")
self.exportWebtopItemAttrs(folder,elem)
self.exportWebtopFolderStructure(folder,elem)
return elem
def exportWebtopFolder(self,folder):
"""Export a folder from a user's webtop."""
""" resource, Vahur """
elem = self.dom.createElement("resource")
elem.appendChild(self.dom.createTextNode(folder.aq_parent.get_id()))
self.exportWebtopItemAttrs(folder,elem)
self.exportWebtopFolderContents(folder,elem)
return elem
def exportGroupFolder(self,folder):
"""Export a group folder."""
elem = self.dom.createElement("GroupFolder")
self.exportWebtopItemAttrs(folder,elem)
self.exportWebtopFolderContents(folder,elem)
make_attr(elem,"ID",folder.get_id())
return elem
def importWebtopFolder(self,elem,parent):
"""Imports a webtop folder into the specified parent folder."""
name = get_attr(elem,"Name")
folder = parent.add_folder(name)
self.importWebtopItemAttrs(elem,folder)
self.importWebtopFolderContents(elem,folder)
return folder
def importGroupFolder(self,elem,parent,toplevel=0):
folder = self.importWebtopFolder(elem,parent)
if toplevel:
self.idmap[get_attr(elem,'ID')]=folder
def exportWebtopFolderStructure(self, folder, elem):
"expordi struktuur/kaustad"
for fol in folder.objectValues('WebtopFolder'):
elem.appendChild(self.exportWebtopFolderStrukt(fol))
return elem
def exportWebtopFolderContents(self,folder,elem):
"""Export a folder's contents from a webtop, into
a predefined XML element. This method is called from
both exportWebtop and exportWebtopFolder."""
for fol in folder.objectValues('WebtopFolder'):
elem.appendChild(self.exportWebtopFolder(fol))
for file in folder.objectValues('WebtopFile'):
elem.appendChild(self.exportWebtopFile(file))
for link in folder.objectValues('WebtopLink'):
elem.appendChild(self.exportWebtopLink(link))
for memo in folder.objectValues('WebtopMemo'):
elem.appendChild(self.exportWebtopMemo(memo))
for fol in folder.objectValues('GroupFolder'):
elem.appendChild(self.exportGroupFolder(fol))
return elem
def exportWebtopFolderitemid(self,folder,elem):
""" ekspordi riiul ilma folderiteta"""
for file in folder.objectValues('WebtopFile'):
elem.appendChild(self.exportWebtopFile(file))
for link in folder.objectValues('WebtopLink'):
elem.appendChild(self.exportWebtopLink(link))
for memo in folder.objectValues('WebtopMemo'):
elem.appendChild(self.exportWebtopMemo(memo))
for fol in folder.objectValues('WebtopFolder'):
self.exportWebtopFolderitemid(fol, elem)
return elem
def importWebtopFolderContents(self,elem,folder):
"""Import a webtop folder's contents."""
for celem in elem.childNodes:
if celem.nodeName == 'WebtopFolder':
self.importWebtopFolder(celem,folder)
elif celem.nodeName == 'WebtopFile':
self.importWebtopFile(celem,folder)
elif celem.nodeName == 'Link':
self.importWebtopLink(celem,folder)
elif celem.nodeName == 'WebtopMemo':
self.importWebtopMemo(celem,folder)
elif celem.nodeName == 'GroupFolder':
self.importGroupFolder(celem,folder)
def exportWebtopFile(self,file):
"""Export a file from a user's webtop."""
elem = self.dom.createElement("resource")
#self.exportWebtopItemAttrs(file,elem)
make_attr(elem, "identifier",file.aq_parent.get_id())
make_attr(elem, "type","file")
fnimi = self.binarydata.storeData(file.data)
make_attr(elem,
"href",
fnimi)
elem2 = self.dom.createElement("file")
make_attr(elem2, "href",fnimi)
elem.appendChild(elem2)
elem3 = self.dom.createElement("imsmd:title")
elem3.appendChild(self.dom.createTextNode(file.get_name()))
elem2.appendChild(elem3)
#make_attr(elem,"ContentType",file.getContentType())
return elem
def importWebtopFile(self,elem,folder):
"""Imports a webtop file into the given folder."""
data = self.binarydata.getData(get_attr(elem,"LocalName"),self.prefix)
name = get_attr(elem,"Name")
file = folder.add_file(
name,
FakeUpload(name,data,get_attr(elem,"ContentType")))
self.importWebtopItemAttrs(elem,file)
def exportWebtopLink(self,link):
"""Export a link from a user's webtop."""
elem = self.dom.createElement("resource")
make_attr(elem, "identifier",link.aq_parent.get_id())
make_attr(elem, "type","URL")
make_attr(elem, "href",link.get_url())
elem2 = self.dom.createElement("file")
make_attr(elem2, "href",link.get_url())
elem.appendChild(elem2)
elem3 = self.dom.createElement("imsmd:title")
elem3.appendChild(self.dom.createTextNode(link.get_name()))
elem2.appendChild(elem3)
return elem
#self.exportWebtopItemAttrs(link,elem)
# try:
# if link.is_internal_link():
# make_attr(elem,"IDRef",link.get_obj_ref().get_id())
# return elem
# except TypeError:
# We get this if is_internal_link requires parameters.
# Exporting from older versions may cause this.
# We'll just handle those links as external.
# pass
# except AttributeError:
# This means a link is broken (doesn't point to an
# existing object). Let's just skip export.
# pass
# make_attr(elem,"Src",link.get_url())
def importWebtopLink(self,elem,folder):
"""Imports a webtop link into the given folder."""
name = get_attr(elem,"Name")
src = get_attr(elem,"Src")
objref = get_attr(elem,"IDRef")
if objref:
try:
obj = self.idmap[objref]
link = folder.add_link(name, obj, 1)
except KeyError:
# We get a keyerror if the id is not found.
print "WebtopLink %s with target id %s doesn't exist!" % (name,objref)
return
else:
link = folder.add_link(name, src)
self.importWebtopItemAttrs(elem,link)
def exportWebtopMemo(self,memo):
"""Export a memo from a user's webtop."""
elem = self.dom.createElement("resource")
make_attr(elem, "identifier", memo.aq_parent.get_id())
make_attr(elem, "type", "memo")
#self.exportWebtopItemAttrs(memo,elem)
tit = self.dom.createElement("imsmd:title")
make_text(tit,memo.get_name())
elem.appendChild(tit)
celem = self.dom.createElement("imsmd:description")
make_text(celem,memo.get_body())
elem.appendChild(celem)
return elem
def importWebtopMemo(self,elem,folder):
"""Imports a webtop memo into the given folder."""
name = get_attr(elem,"Name")
contents=get_text(elem.getElementsByTagName("Contents")[0])
memo = folder.add_memo(name, contents)
self.importWebtopItemAttrs(elem,memo)
#EOF
iva/ImportExportEML.py 0100644 0000764 0000764 00000033107 10130153777 014276 0 ustar vahur vahur # -*- coding: utf-8
# $Id: ImportExportEML.py,v 1.4 2003/08/18 07:44:24 berlingo Exp $
#
# 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 classes responsible for importing and exporting the data to and from an FLE installation. Uses XML formatted EML documents for storage."""
import sys
import xml.dom.minidom
from xml.dom.minidom import Document
import zipfile
import time
from types import FloatType
from ImportExport import Counter, DataTable, to_utf8
def date2str(date):
if not type(date)==type(()):
date = time.gmtime(date)
return time.strftime('%Y/%m/%d',date)
def str2date(str):
return time.mktime(time.strptime(str,'%Y/%m/%d'))
def to_id(id):
id=str(id)
if id[0]>='0' and id[0]<='9':
id='id'+id
return id.replace('_','-')
class Exporter:
"""Class that handles the exporting (but not yet importing) of data
to EML and also holds the XMLized content."""
# If the parameter 'file' is specified, it is assumed to be
# an uploaded zip file containing exported data and it is
# loaded into memory. Otherwise an empty Exporter is created.
def __init__(self,file=None):
"""Creates a new Exporter."""
# Add a binary data hash table
self.binarydata = DataTable()
self.idmap = {}
if file:
self.loadZip(file)
else:
# Document: unlink, writexml(writer), toxml()
self.dom = Document()
type=xml.dom.minidom.DocumentType('"Unit-of-study PUBLIC "-//OUNL//DTD EML/XML binding 1.0/1.0//EN" "eml10.dtd"')
self.dom.doctype=type
self.root = self.dom.createElement("unit-of-study")
self.root.setAttribute("encoding","utf-8")
self.dom.appendChild(self.root)
def createZip(self,file):
"""Dumps the currently exported data
(XML document and binary files) into a zip file.
- file: name of the file to create"""
zip = zipfile.ZipFile(file,"w",zipfile.ZIP_DEFLATED)
zip.writestr(zipfile.ZipInfo("fle_eml.xml"),self.dom.toxml())
for name in self.binarydata.getNames():
zip.writestr(
zipfile.ZipInfo(name),
str(self.binarydata.getData(name)))
zip.close()
def loadZip(self,file):
"""Loads a zipped FLE content file.
- file: the file name to load."""
zip = zipfile.ZipFile(file,"r",zipfile.ZIP_DEFLATED)
xmlstring = unicode(
zip.read("imsmanifest.xml"), 'iso-8859-1').encode("utf-8")
self.dom = xml.dom.minidom.parseString(xmlstring)
self.root = self.dom.firstChild
for name in zip.namelist():
if name[:4]=='data':
self.binarydata.restoreData(name,zip.read(name))
zip.close()
def exportCourse(self,course):
"""Exports the given course into an EML unit of study."""
newElem = self.dom.createElement
newText = self.dom.createTextNode
elem = newElem("metadata")
elem2 = newElem("title")
elem2.appendChild(newText(course.get_name()))
elem.appendChild(elem2)
elem2 = newElem("creator")
elem2.appendChild(newText(course.get_teacher()))
elem.appendChild(elem2)
elem2 = newElem("description")
elem3 = newElem("p")
elem3.appendChild(newText(course.get_description()))
elem2.appendChild(elem3)
elem.appendChild(elem2)
elem2 = newElem("copyright")
elem3 = newElem("copyright-year")
elem3.appendChild(newText(date2str(course.get_end_date())[:4]))
elem2.appendChild(elem3)
elem3 = newElem("copyright-owner")
elem3.appendChild(newText(course.get_organisation()))
elem2.appendChild(elem3)
elem.appendChild(elem2)
elem2 = newElem("extra-meta")
elem3 = newElem("creation-date")
elem3.appendChild(newText(date2str(course.get_start_date())))
elem2.appendChild(elem3)
elem3 = newElem("date-last-change")
elem3.appendChild(newText(date2str(course.get_end_date())))
elem2.appendChild(elem3)
elem3 = newElem("meta")
elem3.setAttribute("base","FLE3")
elem3.setAttribute("description","metatype")
elem4 = newElem("unstructured-source")
elem4.appendChild(newText("Course"))
elem3.appendChild(elem4)
elem2.appendChild(elem3)
elem.appendChild(elem2)
self.root.appendChild(elem)
elem = newElem("roles")
elem2 = newElem("learner")
elem2.setAttribute("id","learner")
## elem3 = newElem("role")
## elem3.setAttribute("name","student")
## elem2.appendChild(elem3)
## elem3 = newElem("role")
## elem3.setAttribute("name","tutor")
## elem2.appendChild(elem3)
## elem3 = newElem("role")
## elem3.setAttribute("type","Facilitator")
## elem3.setAttribute("name","teacher")
## elem2.appendChild(elem3)
elem.appendChild(elem2)
elem2 = newElem("staff")
elem2.setAttribute("id","staff")
## elem3 = newElem("role")
## elem3.setAttribute("name","student")
## elem2.appendChild(elem3)
## elem3 = newElem("role")
## elem3.setAttribute("name","tutor")
## elem2.appendChild(elem3)
## elem3 = newElem("role")
## elem3.setAttribute("type","Facilitator")
## elem3.setAttribute("name","Teacher")
## elem2.appendChild(elem3)
elem.appendChild(elem2)
self.root.appendChild(elem)
elem = newElem("content")
elem2 = newElem("activity")
elem2.setAttribute("reusability","reusable")
elem2.setAttribute("id","act0")
elem3 = newElem("activity-description")
elem4 = newElem("what")
elem5 = newElem("p")
elem5.appendChild(newText("Reflection on already completed knowledge building."))
elem4.appendChild(elem5)
elem3.appendChild(elem4)
elem4 = newElem("completed")
elem4.appendChild(newElem("unrestricted"))
elem3.appendChild(elem4)
elem2.appendChild(elem3)
elem.appendChild(elem2)
for ctx in course.get_children("CourseContext"):
elem2 = elem.appendChild(self.exportContext(ctx))
elem.appendChild(elem2)
elem.appendChild(elem2)
self.root.appendChild(elem)
elem = newElem("method")
elem2 = newElem("play")
elem3 = newElem("comment")
elem3.appendChild(newText("The original methods for building this knowledge were as follows:\n"+course.get_methods()))
elem2.appendChild(elem3)
elem3 = newElem("role-ref")
elem3.setAttribute("id-ref","learner")
elem2.appendChild(elem3)
elem3 = newElem("activity-ref")
elem3.setAttribute("id-ref","act0")
elem2.appendChild(elem3)
elem.appendChild(elem2)
self.root.appendChild(elem)
return elem
def exportContext(self,ctx):
"""Exports the given course context."""
newElem = self.dom.createElement
newText = self.dom.createTextNode
elem = newElem("environment")
elem.setAttribute("id",to_id(ctx.get_id()))
elem2 = newElem("metadata")
elem3 = newElem("title")
elem3.appendChild(newText(ctx.get_name()))
elem2.appendChild(elem3)
elem3 = newElem("creator")
elem3.appendChild(newText(ctx.get_author()))
elem2.appendChild(elem3)
elem3 = newElem("description")
elem4 = newElem("p")
elem4.appendChild(newText(ctx.get_description()+"\n\n"+ctx.get_long_description()))
elem3.appendChild(elem4)
elem2.appendChild(elem3)
elem3 = newElem("extra-meta")
elem4 = newElem("meta")
elem4.setAttribute("base","FLE3")
elem4.setAttribute("description","metatype")
elem5 = newElem("unstructured-source")
elem5.appendChild(newText("CourseContext"))
elem4.appendChild(elem5)
elem3.appendChild(elem4)
elem2.appendChild(elem3)
elem.appendChild(elem2)
elem.appendChild(self.exportTTS(ctx.get_thinking_type_set()))
frag = self.dom.createDocumentFragment()
for note in ctx.get_children('Note'):
self.exportNote(frag,note)
elem.appendChild(frag)
return elem
def exportTTS(self,set):
"""Exports the given knowledgetypeset."""
newElem = self.dom.createElement
newText = self.dom.createTextNode
elem = newElem("knowledge-object")
elem2 = newElem("metadata")
elem3 = newElem("title")
elem3.appendChild(newText(set.get_name()))
elem2.appendChild(elem3)
elem3 = newElem("description")
elem4 = newElem("p")
elem4.appendChild(newText(set.get_description()))
elem3.appendChild(elem4)
elem2.appendChild(elem3)
elem3 = newElem("extra-meta")
elem4 = newElem("meta")
elem4.setAttribute("base","FLE3")
elem4.setAttribute("description","metatype")
elem5 = newElem("unstructured-source")
elem5.appendChild(newText("ThinkingTypeSet"))
elem4.appendChild(elem5)
elem3.appendChild(elem4)
elem2.appendChild(elem3)
elem.appendChild(elem2)
elem2 = newElem("source")
for type in set.get_thinking_types():
elem3 = newElem("section")
elem3.setAttribute("id",to_id(set.parent().get_id()+'-'+type.get_id()))
elem4 = self.exportTT(type)
elem3.appendChild(elem4)
elem2.appendChild(elem3)
elem.appendChild(elem2)
return elem
def exportTT(self,type):
"""Exports the given knowledgetype."""
newElem = self.dom.createElement
newText = self.dom.createTextNode
elem = newElem("source")
elem2 = newElem("figure")
elem3 = newElem("figure-source")
elem3.setAttribute(
"entity",
self.binarydata.storeData(type.get_icon().data))
elem2.appendChild(elem3)
elem.appendChild(elem2)
elem2 = newElem("p")
elem2.appendChild(newText(type.get_name()))
elem.appendChild(elem2)
elem2 = newElem("p")
elem2.appendChild(newText(type.get_description()))
elem.appendChild(elem2)
return elem
def exportNote(self,frag,note):
"""Exports the given note."""
newElem = self.dom.createElement
newText = self.dom.createTextNode
elem = newElem("knowledge-object")
elem.setAttribute("id",to_id(note.get_id()))
elem2 = newElem("metadata")
elem3 = newElem("title")
elem3.appendChild(newText(note.get_real_subject()))
elem2.appendChild(elem3)
elem3 = newElem("creator")
elem3.appendChild(newText(note.get_author()))
elem2.appendChild(elem3)
elem3 = newElem("extra-meta")
elem4 = newElem("creation-date")
elem4.appendChild(newText(date2str(note.get_creation_time())))
elem3.appendChild(elem4)
elem4 = newElem("meta")
elem4.setAttribute("base","FLE3")
elem4.setAttribute("description","metatype")
elem5 = newElem("unstructured-source")
elem5.appendChild(newText("Note"))
elem4.appendChild(elem5)
elem3.appendChild(elem4)
elem4 = newElem("meta")
elem4.setAttribute("base","FLE3")
elem4.setAttribute("description","parent")
elem5 = newElem("unstructured-source")
elem5.appendChild(newText(note.parent().get_id()))
elem4.appendChild(elem5)
elem3.appendChild(elem4)
elem4 = newElem("meta")
elem4.setAttribute("base","FLE3")
elem4.setAttribute("description","type")
elem5 = newElem("unstructured-source")
elem5.appendChild(newText(note.get_tt_id()))
elem4.appendChild(elem5)
elem3.appendChild(elem4)
elem2.appendChild(elem3)
elem.appendChild(elem2)
elem2 = newElem("source")
elem3 = newElem("p")
elem3.appendChild(newText(note.get_body()))
elem2.appendChild(elem3)
if note.get_url()!='':
elem3 = newElem("internet-source")
elem3.setAttribute("url",note.get_url())
elem3.setAttribute("link-name",note.get_url_name())
elem2.appendChild(elem3)
if note.has_image():
name = self.binarydata.storeData(
note.get_image_data())
elem3 = newElem("figure")
elem4 = newElem("figure-source")
elem4.setAttribute("entity",name)
elem3.appendChild(elem4)
elem4 = newElem("figure-text")
elem5 = newElem("p")
elem5.appendChild(newText(note.get_image_name()))
elem4.appendChild(elem5)
elem3.appendChild(elem4)
elem2.appendChild(elem3)
elem.appendChild(elem2)
frag.appendChild(elem)
for reply in note.get_children('Note'):
self.exportNote(frag,reply)
#EOF
iva/ImportExportIMS.py 0100644 0000764 0000764 00000424222 10172721725 014313 0 ustar vahur vahur # -*- coding: utf-8
import zipfile
import xml.dom.minidom
import xml.sax
from xml.dom.minidom import Document
import string
from xml.sax import saxutils
from xml.dom.ext.reader import Sax2
from ImportExport import Counter, DataTable, to_utf8, Exporter, Dump
from common import FakeRequest, FakeUpload
from xml.dom import implementation
from xml.dom import EMPTY_NAMESPACE, XML_NAMESPACE
from xml.dom.ext import PrettyPrint
from Products.ZWiki.ZWikiPage import ZWikiPage
from types import UnicodeType
from input_checks import strip_non_xml
import OFS.Image
import types
import re, time
class User_export:
def __init__(self):
self.binarydata = DataTable()
self.sisegrupid = []
doctype = implementation.createDocumentType("enterprise", "http://www.htk.tpu.ee/%7Evahur/ims_epv1p1.dtd", "http://www.htk.tpu.ee/%7Evahur/ims_epv1p1.dtd")
self.user = implementation.createDocument(EMPTY_NAMESPACE, "enterprise", doctype)
self.userelem = self.user.documentElement
prop = self.user.createElement('properties')
self.userelem.appendChild(prop)
source = self.user.createElement('datasource')
source_data = self.user.createTextNode('IVA')
source.appendChild(source_data)
prop.appendChild(source)
datetime = self.user.createElement('datetime')
datetime_data = self.user.createTextNode('kuupaev')
datetime.appendChild(datetime_data)
prop.appendChild(datetime)
def kirjutaKasutaja(self,kasutaja,kursus=''):
person = self.user.createElement('person')
self.userelem.appendChild(person)
sourcedid = self.user.createElement('sourcedid')
person.appendChild(sourcedid)
source = self.user.createElement('source')
source_data = self.user.createTextNode('IVA')
source.appendChild(source_data)
sourcedid.appendChild(source)
id = self.user.createElement('id')
id_data = self.user.createTextNode(kasutaja.get_uname())
id.appendChild(id_data)
sourcedid.appendChild(id)
userid = self.user.createElement('userid')
try:
userid.setAttribute('password',kasutaja.getPassword())
except:
userid.setAttribute('password','nipitiri')
userid_name = self.user.createTextNode(kasutaja.get_uname())
userid.appendChild(userid_name)
person.appendChild(userid)
name = self.user.createElement('name')
person.appendChild(name)
fn = self.user.createElement('fn')
fn_data = self.user.createTextNode(kasutaja.get_first_name()+' '+kasutaja.get_last_name())
fn.appendChild(fn_data)
name.appendChild(fn)
n = self.user.createElement('n')
name.appendChild(n)
family = self.user.createElement('family')
family_data = self.user.createTextNode(kasutaja.get_last_name())
family.appendChild(family_data)
n.appendChild(family)
given = self.user.createElement('given')
given_data = self.user.createTextNode(kasutaja.get_first_name())
given.appendChild(given_data)
n.appendChild(given)
partname = self.user.createElement('partname')
partname.setAttribute('partnametype','First')
partname.setAttribute('lang',kasutaja.get_language())
partname_data = self.user.createTextNode(kasutaja.get_first_name())
partname.appendChild(partname_data)
n.appendChild(partname)
demogr = self.user.createElement('demographics')
email = self.user.createElement('email')
email_data = self.user.createTextNode(kasutaja.get_email())
email.appendChild(email_data)
person.appendChild(email)
url = self.user.createElement('url')
url_data = self.user.createTextNode(kasutaja.get_homepage())
url.appendChild(url_data)
person.appendChild(url)
tel_t = self.user.createElement('tel')
tel_t.setAttribute('teltype','Voice')
tel_t_data = self.user.createTextNode(kasutaja.get_phone())
tel_t.appendChild(tel_t_data)
person.appendChild(tel_t)
tel_gsm = self.user.createElement('tel')
tel_gsm.setAttribute('teltype','Mobile')
tel_gsm_data = self.user.createTextNode(kasutaja.get_gsm())
tel_gsm.appendChild(tel_gsm_data)
person.appendChild(tel_gsm)
adr = self.user.createElement('adr')
person.appendChild(adr)
extadd = self.user.createElement('extadd')
extadd_data = self.user.createTextNode(kasutaja.get_address2())
extadd.appendChild(extadd_data)
adr.appendChild(extadd)
street = self.user.createElement('street')
street_data = self.user.createTextNode(kasutaja.get_address1())
street.appendChild(street_data)
adr.appendChild(street)
locality = self.user.createElement('locality')
locality_data = self.user.createTextNode(kasutaja.get_city())
locality.appendChild(locality_data)
adr.appendChild(locality)
country = self.user.createElement('country')
country_data = self.user.createTextNode(kasutaja.get_country())
country.appendChild(country_data)
adr.appendChild(country)
try:
if kasutaja.get_photo():
photo = self.user.createElement('photo')
photo.setAttribute('imgtype',kasutaja.get_photo_type())
extref = self.user.createElement('extref')
photo_name = self.binarydata.storeData(kasutaja.get_photo(),'user')
extref_data = self.user.createTextNode(photo_name)
extref.appendChild(extref_data)
photo.appendChild(extref)
person.appendChild(photo)
except:
pass
systemrole = self.user.createElement('systemrole')
kas_admin = kasutaja.getRoles()
if 'Manager' in kas_admin:
systemrole.setAttribute('systemroletype','SysAdmin')
else:
systemrole.setAttribute('systemroletype','User')
person.appendChild(systemrole)
try:
instrole = self.user.createElement('institutionrole')
instrole.setAttribute('primaryrole','No')
instrole.setAttribute('institutionroletype','Learner')
for abc in kursus.get_local_roles():
if abc[0]==kasutaja.get_uname() and 'Teacher' in abc[1]:
instrole.setAttribute('institutionroletype','Instructor')
person.appendChild(instrole)
except:
pass
extension = self.user.createElement('extension')
person.appendChild(extension)
org = self.user.createElement('org')
extension.appendChild(org)
orgname = self.user.createElement('orgname')
orgname_data = self.user.createTextNode(kasutaja.get_organization())
orgname.appendChild(orgname_data)
org.appendChild(orgname)
comment = self.user.createElement('comments')
comment_data = self.user.createTextNode(kasutaja.get_background())
comment.appendChild(comment_data)
extension.appendChild(comment)
desc = self.user.createElement('description')
extension.appendChild(desc)
short = self.user.createElement('short')
short_data = self.user.createTextNode(kasutaja.get_personal_interests())
short.appendChild(short_data)
desc.appendChild(short)
long = self.user.createElement('long')
long_data = self.user.createTextNode(kasutaja.get_professional_interests())
long.appendChild(long_data)
desc.appendChild(long)
label = self.user.createElement('label')
label_data = self.user.createTextNode(kasutaja.get_quote())
label.appendChild(label_data)
extension.appendChild(label)
return "valmis"
def pakiFaili(self,kursusega,failinimi="userexport.zip"):
"Pakitakse kasutajad faili"
if kursusega=="/":
kursusega = ''
if zipfile.is_zipfile(failinimi):
zip = zipfile.ZipFile(failinimi,"a",zipfile.ZIP_DEFLATED)
else:
zip = zipfile.ZipFile(failinimi,"w",zipfile.ZIP_DEFLATED)
dump = Dump()
PrettyPrint(self.user,stream=dump)
zip.writestr(zipfile.ZipInfo(kursusega+"users.xml"),dump.getdata())
for name in self.binarydata.names:
zip.writestr(
zipfile.ZipInfo(kursusega+name),
str(self.binarydata.getData(name)))
zip.close()
def kirjutaKursusGrupina(self,kursus):
# Kirjutab grupi mis omab kursuse funktsiooni. Kik kes selles grupis on
# student vi teacher
krupp = self.user.createElement('group')
krupp_s = self.user.createElement('sourcedid')
krupp_source = self.user.createElement('source')
krupp_source_data = self.user.createTextNode('IVA')
krupp_source.appendChild(krupp_source_data)
krupp_s.appendChild(krupp_source)
krupp_id = self.user.createElement('id')
krupp_id_data = self.user.createTextNode(kursus.get_name())
krupp_id.appendChild(krupp_id_data)
krupp_s.appendChild(krupp_id)
krupp.appendChild(krupp_s)
krupp_type = self.user.createElement('grouptype')
type_value = self.user.createElement('typevalue')
type_value.setAttribute('level','1')
krupp_type.appendChild(type_value)
krupp.appendChild(krupp_type)
description = self.user.createElement('description')
desc_short = self.user.createElement('short')
desc_short_data = self.user.createTextNode(kursus.kysiTekst())
desc_short.appendChild(desc_short_data)
description.appendChild(desc_short)
desc_long = self.user.createElement('long')
desc_long_data = self.user.createTextNode(kursus.get_methods())
desc_long.appendChild(desc_long_data)
description.appendChild(desc_long)
desc_full = self.user.createElement('full')
desc_full_data = self.user.createTextNode(kursus.get_description())
desc_full.appendChild(desc_long_data)
description.appendChild(desc_full)
krupp.appendChild(description)
org = self.user.createElement('org')
orgname = self.user.createElement('orgname')
orgname_data = self.user.createTextNode(kursus.get_name())
orgname.appendChild(orgname_data)
org.appendChild(orgname)
orgunit = self.user.createElement('orgunit')
orgunit_data = self.user.createTextNode(kursus.get_organisation())
orgunit.appendChild(orgunit_data)
org.appendChild(orgunit)
krupp.appendChild(org)
enrollcontrol = self.user.createElement('enrollcontrol')
enroll_accept = self.user.createElement('enrollaccept')
enroll_allowed = self.user.createElement('enrollallowed')
try:
if str(kursus.kysiStaatus()) == str('0') or int(kursus.kysiStaatus())>1:
enroll_accept_data = self.user.createTextNode('0')
else:
enroll_accept_data = self.user.createTextNode('1')
except:
enroll_accept_data = self.user.createTextNode('0')
enroll_allowed_data = self.user.createTextNode('1')
enroll_accept.appendChild(enroll_accept_data)
enroll_allowed.appendChild(enroll_allowed_data)
enrollcontrol.appendChild(enroll_accept)
enrollcontrol.appendChild(enroll_allowed)
krupp.appendChild(enrollcontrol)
self.userelem.appendChild(krupp)
def kirjutaSisegrupid(self,kursus,sisegrupp):
krupp = self.user.createElement('group')
sourcedid = self.user.createElement('sourcedid')
source = self.user.createElement('source')
source_data = self.user.createTextNode('IVA')
source.appendChild(source_data)
sourcedid.appendChild(source)
id = self.user.createElement('id')
# id_data = self.user.createTextNode(str(kursus.get_id())+":"+str(sisegrupp.id))
id_data = self.user.createTextNode(str(sisegrupp.id))
id.appendChild(id_data)
sourcedid.appendChild(id)
krupp.appendChild(sourcedid)
description = self.user.createElement('description')
short = self.user.createElement('short')
short_data = self.user.createTextNode(sisegrupp.title)
short.appendChild(short_data)
description.appendChild(short)
krupp.appendChild(description)
#relationship
relationship = self.user.createElement('relationship')
relationship.setAttribute('relation','2')
sourcedid = self.user.createElement('sourcedid')
source = self.user.createElement('source')
source_data = self.user.createTextNode('IVA')
source.appendChild(source_data)
sourcedid.appendChild(source)
id = self.user.createElement('id')
id_data = self.user.createTextNode(kursus.get_name())
id.appendChild(id_data)
sourcedid.appendChild(id)
relationship.appendChild(sourcedid)
label = self.user.createElement('label')
label_data = self.user.createTextNode('Course sub-group')
label.appendChild(label_data)
relationship.appendChild(label)
krupp.appendChild(relationship)
self.userelem.appendChild(krupp)
return
def kirjutaMembership(self,kogum,tyyp='kursus'):
# write tag
if tyyp == 'kursus':
sortsu_id = kogum.get_name()
kasutajad = kogum.get_all_users()
comment_data = self.user.createTextNode('KURSUS')
else:
sortsu_id = kogum.id
kasutajad = kogum.kasutajad_sisegrupis(sortsu_id,objektina=1)
comment_data = self.user.createTextNode('SISEGRUPP')
membership = self.user.createElement('membership')
comment = self.user.createElement('comments')
comment.appendChild(comment_data)
membership.appendChild(comment)
sourcedid = self.user.createElement('sourcedid')
source = self.user.createElement('source')
source_data = self.user.createTextNode('IVA')
source.appendChild(source_data)
sourcedid.appendChild(source)
id = self.user.createElement('id')
id_data = self.user.createTextNode(str(sortsu_id))
id.appendChild(id_data)
sourcedid.appendChild(id)
membership.appendChild(sourcedid)
for juuser in kasutajad:
member = self.user.createElement('member')
sourcedid = self.user.createElement('sourcedid')
source = self.user.createElement('source')
source_data = self.user.createTextNode('IVA')
source.appendChild(source_data)
sourcedid.appendChild(source)
id = self.user.createElement('id')
id_data = self.user.createTextNode(juuser.get_uname())
id.appendChild(id_data)
sourcedid.appendChild(id)
member.appendChild(sourcedid)
idtype = self.user.createElement('idtype')
idtype_data = self.user.createTextNode('1')
idtype.appendChild(idtype_data)
member.appendChild(idtype)
role = self.user.createElement('role')
role.setAttribute('roletype','Learner')
for abc in kogum.get_local_roles():
if abc[0]==juuser.get_uname() and 'Teacher' in abc[1]:
role.setAttribute('roletype','Instructor')
status = self.user.createElement('status')
status_data = self.user.createTextNode('1')
status.appendChild(status_data)
role.appendChild(status)
if tyyp == 'kursus':
self.kirjutaHinded(role,kogum,juuser)
member.appendChild(role)
membership.appendChild(member)
# self.userelem.appendChild(membership)
self.sisegrupid.append(membership)
return
def kirjutaHinded(self,base_elem,kogum,kasutaja):
# kirjutab kasutaja hinded
#XXX: teacher comment, total points comment, total grade & comment, are not exported!
uname = kasutaja.get_uname()
for abc in kogum.kodutood.listAssignments():
punktid = -1
komm = ""
punktid = abc.getGrades(uname, 'points')
komm = abc.getGrades(uname, 'comment')
abc.getGrades(uname, 'teacherComment')
# if abc.tyyp == 0:
# if hasattr(kc, 'testivastused'):
# try:
# vk = getattr(kc.testivastused, abc.testiID)
# komm = vk.objectValues()[0].annaKoguKommentaar()
# except:
# pass
self.kirjutaInter(base_elem, abc, punktid, komm)
koondHinne = kogum.kodutood.getOverallDetails(uname, 'TotPoints')
koondKomm = kogum.kodutood.getOverallDetails(uname, 'overallComment')
self.kirjutaInter(base_elem, 'abc', koondHinne, koondKomm,'finalresult')
return
def kirjutaInter(self,base_elem, too, punktid, komm, mida='interimresult'):
if punktid == -1:
punktid = 0
interim = self.user.createElement(mida)
if mida == 'interimresult':
interim.setAttribute('resulttype',too.id)
mode = self.user.createElement('mode')
if mida == 'interimresult':
mode_data = self.user.createTextNode('Letter Grade')
else:
mode_data = self.user.createTextNode('protsent')
mode.appendChild(mode_data)
interim.appendChild(mode)
values = self.user.createElement('values')
values.setAttribute('valuetype','1')
val_min = self.user.createElement('min')
val_min_data = self.user.createTextNode('0')
val_min.appendChild(val_min_data)
values.appendChild(val_min)
val_max = self.user.createElement('max')
try:
pp = str(too.getPoints())
except:
pp = '9999'
val_max_data = self.user.createTextNode(pp)
val_max.appendChild(val_max_data)
values.appendChild(val_max)
interim.appendChild(values)
result = self.user.createElement('result')
result_data = self.user.createTextNode(str(punktid))
result.appendChild(result_data)
interim.appendChild(result)
comments = self.user.createElement('comments')
comments_data = self.user.createTextNode(str(komm))
comments.appendChild(comments_data)
interim.appendChild(comments)
base_elem.appendChild(interim)
return
def lisaMembership(self):
for abc in self.sisegrupid:
self.userelem.appendChild(abc)
return
class Importer:
def __init__(self, uname,ivajuur,prefix='', kursus='',binaryd='',testonly=0,userwikionly=0,kasuta_jooksvat=0):
"""Creates impoter"""
self.idmap = {}
self.uname = uname
self.prefix = prefix
self.iva = ivajuur
self.kasuta_jooksvat = kasuta_jooksvat
if kursus:
self.kursus = kursus
else:
self.kursus = ''
if binaryd:
self.binarydata = binaryd
else:
self.binarydata = DataTable()
self.timecounters=[0,0,0,0,0,0,0,0,0,0]
self.processed = []
self.testonly = testonly
self.userwikionly = userwikionly
def importTestAnswers(self,elem,tid,map):
from YlTest import TestiVastused
for r in elem.getElementsByTagName('response'):
owner = self.get_attr(r,'owner')
# get userobject. Vastuse omanik
try:
wt = getattr(self.iva.fle_users, owner).webtop
wtc = getattr(wt, 'c'+self.kursus.get_id())
except:
continue
if not hasattr(wtc.aq_self, 'testivastused'):
wtc.manage_addProduct['OFSP'].manage_addFolder('testivastused')
wtc.testivastused.id='testivastused'
tv = getattr(wtc, 'testivastused')
if not hasattr(tv, tid):
tv.manage_addProduct['OFSP'].manage_addFolder(tid)
tvx = getattr(tv, tid)
tvx.id = tid
else:
tvx = getattr(tv,tid)
#kiakse lbi erinevad testilahenduse variandid
for ver in r.getElementsByTagName('version'):
# lahendusvariandi id
id = self.get_attr(ver,'id')
if not hasattr(tvx.aq_self, id):
t = TestiVastused()
t.testinimi = id
t.id = id
tvx._setObject(id,t)
verk = getattr(tvx, id)
comment = self.get_attr(ver,'comment') #anna kogu kommentaar
try:
verk.seaKoguKommentaar(comment)
except AttributeError:
#XXX:weird
pass
for yl in ver.getElementsByTagName('yl'):
#testi lesande (objekti) id
id = self.get_attr(yl,'id')
comment = self.get_attr(yl,'comment')
score = self.get_attr(yl,'score')
tupe = self.get_attr(yl,'type')
answer = self.get_text(yl)
if answer == 'None': answer = None
if tupe == 'List': answer = eval(answer)
if not score: score = None
if hasattr(verk,id):
#XXX: I don't know if this is reasonable
continue
try:
verk._setObject(id, map[id].koopia())
except KeyError:
continue
ylobj = getattr(verk,id)
ylobj.pakutudAndmed = answer
ylobj.opetajaPunktid = score
ylobj.seaOpetajaKommentaar(comment)
def importQT(self, elem, course, uname):
import YlTyybid
from YlAlus import YlAlus
from YlTyybid import ValikYlesanne, TekstivastusegaYlesanne, OigeTekstivastusegaYlesanne, MitmikvalikYlesanne, YksikvalikYlesanne, ArvuvahemikuliseVastusegaYlesanne, ProtsentYlesanne, VastavusYlesanne
from YlTest import YlTest, LahendusLoad, LahendusLuba, TestiVastused
id_map = {}
comment = self.get_text(elem.getElementsByTagName("qticomment")[0])
t_tyybid = ('ValikYlesanne','MitmikvalikYlesanne','YksikvalikYlesanne','OigeTekstivastusegaYlesanne','TekstivastusegaYlesanne','ArvuvahemikuliseVastusegaYlesanne','VastavusYlesanne')
for abc in elem.getElementsByTagName("section"):
# get id and title
sekt_title = self.get_attr(abc,'title')
id = self.get_attr(abc, 'ident')
if not hasattr(course.testid,'nr'):
course.testid.nr=0
# add test. XXX: move this to top and start adding metadata
course.testid.nr = course.testid.nr+1
qt=YlTest()
qt.pealkiri = sekt_title
# qt.id = "test"+str(course.testid.nr)
# course.testid._setObject(qt.id, qt)
qt.id = id
if hasattr(course.testid, qt.id):
qt.id = "test"+str(course.testid.nr)
# harvest data
answers = self.get_attr(abc, 'answers')
if not answers:
answers=0
qt.seaVastusteNahtavus(answers)
open = self.get_attr(abc, 'open')
if not open:
open=0
qt.avatudTaitmiseks = int(open)
randomize = self.get_attr(abc, 'randomize')
qt.seaKysimusteJuhuslikJarjekord(randomize)
type = self.get_attr(abc, 'type')
if not type:
type=0
qt.tyyp = int(type)
try:
md = abc.getElementsByTagName('metadata')[0]
desc = self.get_text(md.getElementsByTagName('description')[0])
qt.kirjeldus = desc
# permission options!
#timelimit and repeats
tstart = float(self.get_attr(md.getElementsByTagName('timelimit')[0],'start'))
tend = float(self.get_attr(md.getElementsByTagName('timelimit')[0],'end'))
repeat = self.get_attr(md.getElementsByTagName('timelimit')[0],'repeat')
qt.koigiLuba.algusAeg = tstart
qt.koigiLuba.loppAeg = tend
qt.koigiLuba.kordadeArv = int(repeat)
from YlTest import LahendusLuba
#groups
for gr in md.getElementsByTagName('person'):
try:
name = self.get_attr(gr,'name')
except:
continue
dm = LahendusLuba()
#if name == 'DuMmY67891': continue
tstart = float(self.get_attr(gr,'start'))
tend = float(self.get_attr(gr,'end'))
repeat = self.get_attr(gr,'repeat')
dm.id = name
dm.algusAeg = tstart
dm.loppAeg = tend
dm.kordadeArv = int(repeat)
qt.isikuLoad._setObject(dm.id,dm)
#persion
for pr in md.getElementsByTagName('group'):
try:
name = self.get_attr(pr,'name')
except:
continue
dm = LahendusLuba()
#if name == 'DuMmY67891': continue
tstart = float(self.get_attr(pr,'start'))
tend = float(self.get_attr(pr,'end'))
repeat = self.get_attr(pr,'repeat')
dm.id = name
dm.algusAeg = tstart
dm.loppAeg = tend
dm.kordadeArv = int(repeat)
qt.grupiLoad._setObject(dm.id,dm)
#limited solving time!?
#finally, add object
except IndexError:
pass
course.testid._setObject(qt.id, qt)
test_map = {}
for bcd in abc.getElementsByTagName("item"):
try:
qt_tyyp = self.get_attr(bcd,'title')
except IndexError:
qt_tyyp = ''
try:
qt_id = self.get_attr(bcd,'ident')
except IndexError:
qt_id = ''
try:
qt_story = self.get_text(bcd.getElementsByTagName("qticomment")[0])
except IndexError:
qt_story = ''
pelem = bcd.getElementsByTagName("presentation")[0]
try:
qt_quiz = self.get_text(pelem.getElementsByTagName("mattext")[0])
except IndexError:
qt_quiz = ''
try:
photo_data = self.binarydata.getData(
self.get_attr(pelem.getElementsByTagName("matimage")[0],'uri'),self.prefix)
except IndexError:
photo_data = None
try:
qt_link = self.get_text(pelem.getElementsByTagName("matemtext")[0])
qt_linkd = self.get_attr(pelem.getElementsByTagName("matemtext")[0],'uri')
except IndexError:
qt_link = ''
qt_linkd = ''
try:
r_grp = pelem.getElementsByTagName("response_grp")[0]
r_grp1 = 1
except IndexError:
r_grp1 = 0
try:
r_lid = pelem.getElementsByTagName("response_lid")[0]
r_lid1 = 1
except IndexError:
r_lid1 = 0
try:
r_xy = pelem.getElementsByTagName("response_xy")[0]
r_xy1 = 1
except IndexError:
r_xy1 = 0
try:
r_str = pelem.getElementsByTagName("response_str")[0]
r_str1 = 1
except IndexError:
r_str1 = 0
try:
r_num = pelem.getElementsByTagName("response_num")[0]
r_num1 = 1
except IndexError:
r_num1 = 0
if r_lid1:
try:
r_render = pelem.getElementsByTagName("render_choice")[0]
rend = 1
except:
rend = 0
if rend and qt_tyyp not in t_tyybid:
qt_tyyp = 'MitmikvalikYlesanne'
if r_str1:
r_fib1 = 0
try:
r_fib = pelem.getElementsByTagName("render_fib")[0]
r_fib1 = 1
except:
r_fib1 = 0
if r_fib1:
if qt_tyyp not in t_tyybid:
try:
xx = bcd.getElementsByTagName("varequal")[0]
tmp = 1
except:
tmp = 0
if tmp:
qt_tyyp = 'OigeTekstivastusegaYlesanne'
else:
qt_tyyp = 'TekstivastusegaYlesanne'
if qt_tyyp == 'ValikYlesanne':
vastus = self.get_text(bcd.getElementsByTagName("varequal")[0])
if vastus == 'T':
vastus =1
else:
vastus =0
punkte = self.get_text(bcd.getElementsByTagName("setvar")[0])
qt_test = ValikYlesanne(qt_quiz)
yl = qt.lisaYlesanne(qt_test)
qt_test.seaKirjeldavTekst('',qt_story)
qt_test.normPunktid=float(punkte)
qt_test.viiteURL = qt_linkd
qt_test.viiteTekst = qt_link
qt_test.vastus = vastus
qt_test.pilt = photo_data
# pistame testi hoidlasse
pass
if qt_tyyp == 'MitmikvalikYlesanne':
punkte = self.get_text(bcd.getElementsByTagName("setvar")[0])
qt_test = MitmikvalikYlesanne(qt_quiz)
yl = qt.lisaYlesanne(qt_test)
qt_test.seaKirjeldavTekst('',qt_story)
qt_test.normPunktid=float(punkte)
qt_test.viiteURL = qt_linkd
qt_test.viiteTekst = qt_link
qt_test.pilt = photo_data
oiged = []
v_text = []
v_id = []
s_text = []
s_id = []
for xbc in bcd.getElementsByTagName("varequal"):
oiged.append(self.get_text(xbc))
for vastused in bcd.getElementsByTagName("response_label"):
v_id.append(self.get_attr(vastused,'ident'))
v_text.append(self.get_text(vastused.getElementsByTagName("mattext")[0]))
for seletused in bcd.getElementsByTagName("itemfeedback"):
s_id.append(self.get_attr(seletused, 'ident'))
s_text.append(self.get_text(seletused.getElementsByTagName("mattext")[0]))
v_sisse = []
s_sisse = []
o_sisse = []
j = 0
for vmass in v_id:
i = 0
for smass in s_id:
if vmass == smass:
v_sisse.append(v_text[j])
s_sisse.append(s_text[i])
i = i + 1
try:
if str(vmass) in oiged:
o_sisse.append(int(j))
except:
pass
j = j + 1
qt_test.valikud = v_sisse
qt_test.selgitused = s_sisse
qt_test.oigedValikud = o_sisse
pass
if qt_tyyp == 'YksikvalikYlesanne':
vastus = self.get_text(bcd.getElementsByTagName("varequal")[0])
punkte = self.get_text(bcd.getElementsByTagName("setvar")[0])
qt_test = YksikvalikYlesanne(qt_quiz)
yl = qt.lisaYlesanne(qt_test)
qt_test.seaKirjeldavTekst('',qt_story)
qt_test.normPunktid=float(punkte)
qt_test.viiteURL = qt_linkd
qt_test.viiteTekst = qt_link
qt_test.pilt = photo_data
v_text = []
v_id = []
s_text = []
s_id = []
for vastused in pelem.getElementsByTagName("response_label"):
v_id.append(self.get_attr(vastused,'ident'))
v_text.append(self.get_text(vastused.getElementsByTagName("mattext")[0]))
for seletused in bcd.getElementsByTagName("itemfeedback"):
s_id.append(self.get_attr(seletused, 'ident'))
s_text.append(self.get_text(seletused.getElementsByTagName("mattext")[0]))
v_sisse = []
s_sisse = []
s_id.reverse()
s_text.reverse()
j = 0
for vmass in v_id:
i = 0
for smass in s_id:
if vmass == smass:
v_sisse.append(v_text[j])
s_sisse.append(s_text[i])
i = i + 1
if vmass == str(vastus):
qt_test.oigeValik = j
j = j + 1
qt_test.valikud = v_sisse
qt_test.selgitused = s_sisse
pass
if qt_tyyp == 'OigeTekstivastusegaYlesanne':
try:
punkte = self.get_text(bcd.getElementsByTagName("setvar")[0])
except:
punkte = 0
qt_test = OigeTekstivastusegaYlesanne(qt_quiz)
yl = qt.lisaYlesanne(qt_test)
qt_test.seaKirjeldavTekst('',qt_story)
qt_test.normPunktid=float(punkte)
qt_test.viiteURL = qt_linkd
qt_test.viiteTekst = qt_link
qt_test.pilt = photo_data
oiged = []
for xbc in bcd.getElementsByTagName("varequal"):
oiged.append(self.get_text(xbc))
qt_test.variandid = oiged
pass
if qt_tyyp == 'TekstivastusegaYlesanne':
try:
punkte = self.get_text(bcd.getElementsByTagName("setvar")[0])
except:
punkte = 0
qt_test = TekstivastusegaYlesanne(qt_quiz)
yl = qt.lisaYlesanne(qt_test)
qt_test.seaKirjeldavTekst('',qt_story)
qt_test.normPunktid=float(punkte)
qt_test.viiteURL = qt_linkd
qt_test.viiteTekst = qt_link
qt_test.pilt = photo_data
pass
if qt_tyyp == 'ArvuvahemikuliseVastusegaYlesanne':
punkte = self.get_text(bcd.getElementsByTagName("setvar")[0])
qt_test = ArvuvahemikuliseVastusegaYlesanne(qt_quiz)
yl = qt.lisaYlesanne(qt_test)
qt_test.seaKirjeldavTekst('',qt_story)
qt_test.normPunktid=float(punkte)
qt_test.viiteURL = qt_linkd
qt_test.viiteTekst = qt_link
qt_test.pilt = photo_data
arv_tyyp = bcd.getElementsByTagName("outcomes")[0]
q_arv_tyyp = self.get_text(arv_tyyp.getElementsByTagName("qticomment")[0])
q_alam = self.get_text(bcd.getElementsByTagName("vargte")[0])
q_oige = self.get_text(bcd.getElementsByTagName("varequal")[0])
q_ylem = self.get_text(bcd.getElementsByTagName("varlte")[0])
qt_test.alamPiir = float(q_alam)
qt_test.ylemPiir = float(q_ylem)
qt_test.oigeVastus = float(q_oige)
try:
qt_test.arvutusTyyp = int(q_arv_tyyp)
except:
pass
pass
if qt_tyyp == 'VastavusYlesanne':
import random
punkte = self.get_text(bcd.getElementsByTagName("setvar")[0])
qt_test = VastavusYlesanne(qt_quiz)
yl = qt.lisaYlesanne(qt_test)
qt_test.seaKirjeldavTekst('',qt_story)
qt_test.normPunktid=float(punkte)
qt_test.viiteURL = qt_linkd
qt_test.viiteTekst = qt_link
qt_test.pilt = photo_data
v_id = []
v_text = []
for xbc in bcd.getElementsByTagName("response_label"):
v_id.append(self.get_attr(xbc,'ident'))
v_text.append(self.get_text(xbc.getElementsByTagName("mattext")[0]))
s_vastused = []
s_kysimused = []
for xbc in bcd.getElementsByTagName("varsubset"):
paar = string.split(self.get_text(xbc),",")
koht_v = v_id.index(paar[0])
koht_p = v_id.index(paar[1])
s_kysimused.append(v_text[koht_v])
s_vastused.append(v_text[koht_p])
s_jarjestus = []
for i in range(len(s_kysimused)):
s_jarjestus.append(i)
random.shuffle(s_jarjestus)
qt_test.kysimused = s_kysimused
qt_test.vastused = s_vastused
qt_test.jarjestus = s_jarjestus
pass
try:
test_map[qt_id] = qt_test
except UnboundLocalError:
#XXX:some test is missing!
pass
self.importTestAnswers(abc,id,test_map)
return
def importMailMessages(self,element):
# import inner-mail messages
um = self.iva.fle_users
for cat in element.getElementsByTagName('catalog'):
owner = self.get_attr(cat,'owner')
try:
ui = getattr(um, owner)
except:
# print "kasutajat %s ei leitnud, jtan vahele" % owner
continue
box = ui.kysiKirjadeKataloog()
for mess in cat.getElementsByTagName('message'):
read = int(self.get_attr(mess,'read'))
owncopy = self.get_attr(mess,'owncopy')
title = self.get_text(mess.getElementsByTagName('title')[0])
body = self.get_text(mess.getElementsByTagName('body')[0])
sender = self.get_text(mess.getElementsByTagName('sender')[0])
receiver = self.get_text(mess.getElementsByTagName('receiver')[0])
date = self.get_text(mess.getElementsByTagName('date')[0])
mail = box.lisaKiri(None,title,body,sender,receiver,99999)
mail.loomisaeg = float(date)
if owncopy: mail.omakopi = 1
if read:
mail.loetud = 1
else:
mail.loetud = 0
def importKodutood(self,element):
# impordime kodutd
kt_koht = getattr(self.kursus,'kodutood')
grupid = []
for assign in element.getElementsByTagName('Assignment'):
try:
orgID = self.get_attr(assign,'originalID')
except:
orgID = ''
tyyp = int(self.get_text(assign.getElementsByTagName('type')[0]))
pkiri = str(self.get_text(assign.getElementsByTagName('title')[0]))
kirjeldus = str(self.get_text(assign.getElementsByTagName('description')[0]))
punkt = float(self.get_text(assign.getElementsByTagName('points')[0]))
try:
res = str(self.get_text(assign.getElementsByTagName('resource')[0]))
except:
res = ''
loppaeg = self.get_text(assign.getElementsByTagName('end')[0])
try:
testiID = str(self.get_text(assign.getElementsByTagName('test')[0]))
except:
testiID = None
try:
for gr in assign.getElementsByTagName('group'):
gnimi = self.get_text(gr)
grupid.append(gnimi)
except:
grupid = None
if res:
sisu = res.split('/')
res = '/courses/'+str(self.kursus.id)+"/"+sisu[3]+"/"+sisu[4]
too = kt_koht.lisaKodutoo('request',tyyp,orgID)
too.pealkiri = pkiri
too.kirjeldus = kirjeldus
too.normPunkte = punkt
too.juhend = res
if loppaeg != 'None':
too.loppaeg = float(loppaeg)
# New parameter
too.lockingFolder = 0
if testiID != None:
too.testiID = testiID
if grupid != None:
too.grupid = grupid
return
def handleGrades(self,isik,uid):
for x in isik.getElementsByTagName('interimresult'):
workid = self.get_attr(x, 'resulttype')
try:
points = float(self.get_text(x.getElementsByTagName('result')[0]))
except:
points = ''
try:
s_com = self.get_text(x.getElementsByTagName('comments')[0])
except:
s_com = ''
try:
t_com = self.get_text(x.getElementsByTagName('tcomment')[0])
except:
t_com = ''
if points:
self.kursus.kodutood.setUserPoints(workid,uid,'points',points)
self.kursus.kodutood.setUserPoints(workid,uid,'comment',s_com)
self.kursus.kodutood.setUserPoints(workid,uid,'teacherComment',t_com)
f = isik.getElementsByTagName('finalresult')[0]
try:
grade = self.get_text(f.getElementsByTagName('result')[0])
if grade:
self.kursus.kodutood.setUserOverall(uid,'grade',grade)
except:
pass
try:
comment = self.get_text(f.getElementsByTagName('comments')[0]) #overall comment
self.kursus.kodutood.setUserOverall(uid,'overallComment',comment)
except:
pass
try:
t_com = self.get_text(f.getElementsByTagName('tcomment')[0])
self.kursus.kodutood.setUserOverall(uid,'gradeCom',t_com)
except:
pass
try:
modpoints = float(self.get_text(f.getElementsByTagName('modpoints')[0]))
if modpoints:
self.kursus.kodutood.setUserOverall(uid,'TotPoints',modpoints)
except:
pass
try:
modcomment = self.get_text(f.getElementsByTagName('modcomment')[0])
self.kursus.kodutood.setUserOverall(uid,'TotPointsCom',modcomment)
except:
pass
def lisaIsik(self,isik,tyyp,grupinimi=''):
uid = self.get_text(isik.getElementsByTagName('id')[0])
print uid
roll = self.get_attr(isik.getElementsByTagName('role')[0],'roletype')
if tyyp == 'kursus':
try:
self.kursus.add_student(uid)
#handle grades here! interimresult, finalresult
self.handleGrades(isik,uid)
if roll == 'Instructor':
self.kursus.set_roles(uid,('Teacher',))
#else:
#XXX:we already set Student in add_student
#self.kursus.set_roles(uid,('Student',))
except:
pass
else:
self.kursus.lisa_sisegruppi(grupinimi,uid)
return
def restoreMembership(self,failisisu):
sisegr = self.kursus.subgroups.objectValues()
sisegrupid = []
for grupid in sisegr:
sisegrupid.append(grupid.get_name())
for group in failisisu.getElementsByTagName('group'):
id = self.get_text(group.getElementsByTagName('id')[0])
try:
typevalue = self.get_attr(group.getElementsByTagName('typevalue')[0],'level')
except:
typevalue = ''
if str(typevalue) == '1':
try:
orgname = self.get_text(group.getElementsByTagName('orgname')[0])
except:
orgname = 'orgnameorgnameorgname'
# if self.kursus:
# if str(orgname) == str(self.kursus.get_name()):
# pass
for ship in failisisu.getElementsByTagName('membership'):
try:
komm = self.get_text(ship.getElementsByTagName('comments')[0])
except:
komm = ''
ship_id = self.get_text(ship.getElementsByTagName('id')[0])
# k_nimi = self.kursus.get_name()+' *'
# if ship_id+' *' == str(self.kursus.get_name()) == id+' *' and str(komm) == 'KURSUS':
if ship_id == str(self.kursus.get_name()) == id and str(komm) == 'KURSUS':
for isik in ship.getElementsByTagName('member'):
self.lisaIsik(isik,'kursus')
else:
id = self.get_text(group.getElementsByTagName('id')[0])
if not id in sisegrupid:
try:
sgr = self.kursus.lisa_grupp(id)
sgr.kysiSyndmusteKataloog()
except:
pass
for ship in failisisu.getElementsByTagName('membership'):
try:
komm = self.get_text(ship.getElementsByTagName('comments')[0])
except:
komm = ''
if str(komm) == 'SISEGRUPP':
ship_id = self.get_text(ship.getElementsByTagName('id')[0])
if ship_id == id:
for isik in ship.getElementsByTagName('member'):
self.lisaIsik(isik,'sisegrupp',id)
return
def importUsers(self,element):
um = getattr(self.iva, 'fle_users')
tulem = ""
us_alg = time.time()
for person in element.getElementsByTagName('person'):
roles = []
userid = self.get_text(person.getElementsByTagName('userid')[0])
# if userid=='admin':
# continue
password = self.get_attr(person.getElementsByTagName('userid')[0],'password')
try:
family = self.get_text(person.getElementsByTagName('family')[0])
except:
family = ''
try:
given = self.get_text(person.getElementsByTagName('given')[0])
except:
given = ''
try:
email = self.get_text(person.getElementsByTagName('email')[0])
except:
email = ''
try:
url = self.get_text(person.getElementsByTagName('url')[0])
except:
url = ''
try:
for telephones in person.getElementsByTagName('tel'):
if self.get_attr(telephones,'teltype') == 'Voice':
voice = self.get_text(telephones)
else:
mobile = self.get_text(telephones)
except:
voice = ''
mobile = ''
try:
addr2 = self.get_text(person.getElementsByTagName('extadd')[0])
except:
addr2 = ''
try:
street = self.get_text(person.getElementsByTagName('street')[0])
except:
street = ''
try:
locality = self.get_text(person.getElementsByTagName('locality')[0])
except:
locality = ''
try:
country = self.get_text(person.getElementsByTagName('country')[0])
except:
country = ''
try:
photo_tag = person.getElementsByTagName('photo')[0]
photo_type = self.get_attr(photo_tag,'imgtype')
photo_location = self.get_text(photo_tag.getElementsByTagName('extref')[0])
photo = self.binarydata.getData(photo_location, self.prefix)
except:
photo = None
try:
s_r = person.getElementsByTagName('systemrole')[0]
systemrole = self.get_attr(s_r,'systemroletype')
if systemrole == 'SysAdmin':
roles.append('Manager')
except:
systemrole = ''
try:
i_r = self.get_text(person.getElementsByTagName('institutionrole')[0])
inst_role = self.get_attr(i_r,'institutionroletype')
except:
instrole = ''
try:
eriala = self.get_text(person.getElementsByTagName('orgname')[0])
except:
eriala = ''
try:
comm = self.get_text(person.getElementsByTagName('comments')[0])
except:
comm = ''
try:
huvid = self.get_text(person.getElementsByTagName('short')[0])
except:
huvid = ''
try:
amet_huvid = self.get_text(person.getElementsByTagName('long')[0])
except:
amet_huvid = ''
try:
label = self.get_text(person.getElementsByTagName('label')[0])
except:
label = ''
if um.kasKasutajaOlemas(userid) and hasattr(um, userid):
tulem = "kasutaja "+userid+" olemas"
continue
if not um.kasKasutajaOlemas(userid):
um.acl_users._doAddUser(userid,password,[],())
if not hasattr(um, userid):
kasutaja = um.add_user_fle(userid,('Member',))
else:
kasutaja = getattr(um.aq_self, userid)
kasutaja.kysiSyndmusteKataloog()
kasutaja.edit_info(given,family,email,eriala,'keel',photo,'','',street,addr2,
locality,country,url,voice,mobile,label,comm,huvid,amet_huvid)
if photo != None:
kasutaja.set_photo(photo,photo_type)
us_lopp = time.time()
print "Users:",us_lopp-us_alg
return
def test(self,elem, folder, uname, indeks,loop=0):
for bcd in elem.childNodes:
if bcd.nodeType == 1 and bcd.nodeName == 'resource':
pid = self.get_attr(bcd,"identifier")
if indeks[self.eemalda(pid)] == self.eemalda(folder.id):
tyyp = self.get_attr(bcd,'type')
name = self.get_text(bcd.getElementsByTagName("title")[0])
if tyyp == 'file':
data_name = self.get_attr(bcd.getElementsByTagName("file")[0],'href')
data = self.binarydata.getData(data_name,self.prefix)
file = folder.add_file(name,
FakeUpload(name,data,'application/msword'))
if tyyp == 'memo':
sisu = self.get_text(bcd.getElementsByTagName("description")[0])
memo = folder.add_memo(name,sisu)
if tyyp == 'URL':
sisu = self.get_attr(bcd,'href')
link = folder.add_link(name, sisu)
if loop==0:
folder = getattr(folder,folder.id)
self.importItems(elem,folder,uname,indeks)
return folder
def importItems(self, elem, course, uname, indeks,loop=0):
if loop:
self.test(elem,course,uname,indeks,loop=1)
for abc in course.objectValues():
if abc.meta_type == 'WebtopFolder':
folder = getattr(course,abc.id)
self.test(elem,folder,uname, indeks)
return "kala"
def get_text(self,elem):
res=u''
for line in elem.childNodes:
res += line.nodeValue
return to_utf8(res)
def get_attr(self,elem,name):
return to_utf8(elem.getAttribute(name))
def eemalda(self,pid):
try:
number = int(re.sub('[a-zA-Z]','',pid))
except ValueError:
number = 0
return number
def importOrg(self,elem,course):
for abc in elem.getElementsByTagName("organization"):
if self.get_text(abc.getElementsByTagName("title")[0]) == "Raamaturiiul":
nelem = abc
abc = nelem.getElementsByTagName("item")[0]
return abc
def createCourse(self,elem,courses,teacher):
""" creates an empty course, other functions fill this with data
course will be named imported_+exported course name """
vigu = 0
try:
title = elem.getElementsByTagName("imsmd:title")[0]
title_c = self.get_text(title.getElementsByTagName("imsmd:langstring")[0])
except:
vigu = vigu +1
try:
c_organisation = self.get_text(elem.getElementsByTagName("ivamd:organisation")[0])
except:
c_organisation = ""
vigu = vigu+1
try:
c_method = self.get_text(elem.getElementsByTagName("ivamd:methods")[0])
except:
c_method = ""
vigu = vigu+1
try:
c_quote = self.get_text(elem.getElementsByTagName("ivamd:quote")[0])
except:
c_quote = ""
vigu = vigu+1
try:
c_status = int(self.get_text(elem.getElementsByTagName("ivamd:status")[0]))
except:
c_status = 0
vigu = vigu+1
try:
c_picture_name = self.get_attr(elem.getElementsByTagName("ivamd:picture")[0],"href")
c_picture = self.binarydata.getData(c_picture_name,self.prefix)
except:
c_picture = None
vigu = vigu+1
try:
desk = elem.getElementsByTagName("imsmd:description")[0]
desk_c = self.get_text(desk.getElementsByTagName("imsmd:langstring")[0])
# title_c = "imported_"+title_c
except:
desk = ''
vigu = vigu+1
if vigu < 3:
# don't change the below line in haste
# title_c += " *"
id = courses.add_course_impl(teacher)
course = courses.get_child(str(id))
course.remove_person(teacher)
course.update(title_c,desk_c,c_organisation,c_method,0,0,c_quote,c_picture,c_status)
#course.kontrolliRyhmaLaud()
course.add_folder('CourseFolder')
course.kysiSyndmusteKataloog()
return course
else:
pass
#print "vigu:", vigu
#print "vigu tekkis liialt palju, jtan kursuse tegemise katki"
return 0
def lisaSyndmus(self,resource,tiitel):
from Kalender import KalendriSyndmus, KalendriSyndmusteKataloog
import time
for fail in resource.getElementsByTagName('file'):
href = self.get_attr(fail,'href')
syndmused = self.binarydata.getData(str(self.prefix+href))
synd = syndmused.split('\r\n')
synd_p = []
for abc in synd:
try:
if abc[0] == ' ':
eelmine = synd_p.pop()
synd_p.append(eelmine + " "+abc)
else:
synd_p.append(abc)
except:
pass
final = []
for abc in synd_p:
uu = abc.split(':',1)
final.append(uu)
v_cal = 0
v_event = 0
v_loend = 0
for syndmus in final:
if syndmus[0] == 'BEGIN' and syndmus[1] == 'VCALENDAR':
v_cal = 1
if not v_cal:
continue
if syndmus[0] == 'BEGIN' and syndmus[1] == 'VEVENT':
v_event = 1
if not v_event: # no point to collect data
continue # if we don't have event
if syndmus[0] == 'DTSTART' or syndmus[0] == 'DTEND':
temp = syndmus[1]
aeg = []
aeg.append(int(temp[0:4]))
aeg.append(int(temp[4:6]))
aeg.append(int(temp[6:8]))
aeg.append(int(temp[9:11]))
aeg.append(int(temp[11:13]))
aeg.append(int(temp[13:15]))
aeg.append(int(0))
aeg.append(int(0))
aeg.append(int(0))
if syndmus[0] == 'DTSTART':
v_loend = v_loend +1
dtstart = time.mktime(aeg)
if syndmus[0] == 'DTEND':
v_loend = v_loend +1
dtend = time.mktime(aeg)
if syndmus[0] == 'N':
v_loend = v_loend +1
n = syndmus[1]
if syndmus[0] == 'DESCRIPTION':
v_loend = v_loend +1
desc = syndmus[1]
if syndmus[0] == 'SUMMARY':
v_loend = v_loend +1
summary = syndmus[1]
if syndmus[0] == 'STATUS':
v_loend = v_loend +1
status = int(syndmus[1])
if syndmus[0] == 'CUTYPE':
v_loend = v_loend +1
cutype = syndmus[1]
if syndmus[0] == 'URL':
v_loend = v_loend +1
url = syndmus[1]
if syndmus[0] == 'X-PROPERTY;VALUE=NAME':
v_loend = v_loend +1
name = syndmus[1]
if syndmus[0] == 'RESOURCES':
v_loend = v_loend +1
res = syndmus[1]
if syndmus[0] == 'END' and syndmus[1] == 'VCALENDAR':
break
if not v_cal:
continue
if syndmus[0] == 'END' and syndmus[1] == 'VEVENT':
if v_loend > 5:
# try make an event
koht = None
if cutype == 'INDIVIDUAL':
try:
temp = getattr(self.iva.fle_users, n)
koht = getattr(temp, 'syndmused')
except:
pass
if cutype == 'GROUP':
try:
temp = getattr(self.iva.courses, str(self.kursus.get_id()))
except AttributeError:
print "XXXX: we couldn't find a course we should have made!"
continue
if n == 'kursus':
# koht = getattr(temp, 'syndmused')
koht = temp.kysiSyndmusteKataloog()
else:
try:
temp2 = getattr(temp.subgroups, n)
koht = temp2.kysiSyndmusteKataloog()
except:
loodud = self.kursus.lisa_grupp(n)
koht = loodud.kysiSyndmusteKataloog()
if not koht:
break # no place to event
syndmus = koht.lisaSyndmusKohe(name, summary, desc, dtstart, dtend, url, res, status)
self.set_omanik(syndmus, self.owner)
v_event = 0
v_loend = 0
if not v_event:
continue
return
def ImportUserEvents(self,resource,tiitel):
for org in resource.getElementsByTagName('organization'):
id = self.get_attr(org,'identifier')
temp = id.split('_')
juuser = temp[1]
self.owner = juuser
for item in org.getElementsByTagName('item'):
idref = self.get_attr(item,'identifierref')
tiitel = self.get_text(item.getElementsByTagName('title')[0])
self.otsiTarget(idref,resource,tiitel)
self.owner = self.uname
return
def add_file_metadata(self,object,element):
""" file metadata extraction and handling here only """
try:
md = element.getElementsByTagName('metadata')[0]
creationtime = float(self.get_attr(md,'creationtime'))
object.set_timestamp(creationtime)
except:
pass
for an in element.getElementsByTagName('annotation'):
type = self.get_attr(an, 'parameters')
if type != 'comment':
continue
person = self.get_text(an.getElementsByTagName('person')[0])
date = float(self.get_text(an.getElementsByTagName('date')[0]))
desc = self.get_text(an.getElementsByTagName('description')[0])
status = int(self.get_text(an.getElementsByTagName('status')[0]))
value = self.get_text(an.getElementsByTagName('value')[0])
object.postComment(None,'add',desc,value,status,person,date)
try:
p = element.getElementsByTagName('permission')[0]
except:
return
status = int(self.get_text(p.getElementsByTagName('status')[0])) #permission status actually
object.setObjPermission(status)
position = int(self.get_text(p.getElementsByTagName('position')[0]))
object.weight = position
tl = p.getElementsByTagName('timelimits')[0]
tend = float(self.get_attr(tl, 'end'))
tstart = float(self.get_attr(tl, 'start'))
object.setTimeLimits(tstart,tend)
tfunc = int(self.get_text(tl))
object.setTimeFunc(tfunc)
docstatus = int(self.get_text(p.getElementsByTagName('docstatus')[0]))
object.setStatus(docstatus)
commentable = int(self.get_text(p.getElementsByTagName('commentable')[0]))
object.setCommentable(commentable)
comment_view = int(self.get_attr(p.getElementsByTagName('commentable')[0],'view'))
object.setCommentsVisible(comment_view)
rateable = int(self.get_text(p.getElementsByTagName('rateable')[0]))
object.setRateable(rateable)
rate_view = int(self.get_attr(p.getElementsByTagName('rateable')[0],'view'))
object.setRatingVisible(rate_view)
return
def add_folder_metadata(self,object,element):
""" folder metadata extraction here ONLY! """
try:
pres = self.get_attr(element,'presentation')
if pres == '1':
object.seaEsitluskaust(int(pres))
except AttributeError:
pass
try:
md = element.getElementsByTagName('metadata')[0]
#XXX: We don't have any metadata. Happened when exported just a wiki
except IndexError:
return
try:
creationtime = float(self.get_attr(md,'creationtime'))
object.set_timestamp(creationtime)
except:
pass
for an in element.getElementsByTagName('annotation'):
type = self.get_attr(an, 'parameters')
if type != 'visit':
continue
person = self.get_text(an.getElementsByTagName('person')[0])
date = float(self.get_text(an.getElementsByTagName('date')[0]))
object.kylastus(None,person,date)
try:
p = element.getElementsByTagName('permission')[0]
except:
return
status = int(self.get_text(p.getElementsByTagName('status')[0])) #permission status actually
object.setObjPermission(status)
position = int(self.get_text(p.getElementsByTagName('position')[0]))
object.weight = position
tl = p.getElementsByTagName('timelimits')[0]
tend = float(self.get_attr(tl, 'end'))
tstart = float(self.get_attr(tl, 'start'))
object.setTimeLimits(tstart,tend)
tfunc = int(self.get_text(tl))
object.setTimeFunc(tfunc)
return
def handleMetadata(self,element):
try:
format = self.get_text(element.getElementsByTagName('imsmd:format')[0])
except:
format = 'application/msword'
return format
def set_omanik(self,obj,omanik):
try:
obj.manage_setLocalRoles(omanik, ('Owner',))
acl = self.iva.fle_users.leiaKasutajaKataloog(omanik)
acl_user = acl.aq_inner.getUser(omanik)
obj.changeOwnership(self.iva.acl_users.getUser(omanik).__of__(self.iva.acl_users))
except:
return 0
return 1
def handleResource(self,resource,asukoht,resour,tiitel=''):
tyyp = self.get_attr(resource,'type')
for element in resource.childNodes:
# otsi ja leia failid, memod jms
if element.nodeName == 'dependency':
idref = self.get_attr(element, 'identifierref')
self.otsiTarget(idref,resour,'MISC STUFF',asukoht)
if element.nodeName != 'file':
#vib vajada fixi.
continue
else:
tekst = ''
orgID = ''
try:
href = self.get_attr(element,'href')
except:
pass
try:
tekst = self.get_text(element.getElementsByTagName('imsmd:title')[0])
except:
pass
try:
if not tekst:
tekst = self.get_text(element.getElementsByTagName('title')[0])
except:
pass
try:
orgID = self.get_attr(element.getElementsByTagName('imsmd:title')[0],'originalID')
except:
pass
try:
orgID = self.get_attr(element.getElementsByTagName('title')[0],'originalID')
except:
pass
try:
orgOwner = self.get_attr(element.getElementsByTagName('imsmd:title')[0],'originalOwner')
except:
pass
try:
orgOwner = self.get_attr(element.getElementsByTagName('title')[0],'originalOwner')
except:
pass
if tyyp == 'file' or tyyp == 'webcontent':
fail_alg = time.time()
# FIXFIXFIX: faili formatt
try:
format = self.handleMetadata(element.getElementsByTagName('metadata')[0])
except:
format = 'application/msword'
href = self.get_attr(element,'href')
data_alg = time.time()
data = self.binarydata.getData(str(self.prefix+href))
data_lopp = time.time()
print "Faili lugemine",data_lopp-data_alg
# FIX: file type
number = 1
if not tekst:
tekst = tiitel
number = 0
lisa_alg = time.time()
try:
fail = asukoht.add_file(tekst,FakeUpload(tekst,data,format),number)
except:
fail = asukoht.add_file(tekst,FakeUpload(tekst,data,format),0)
lisa_lopp = time.time()
print "lisa fail:",lisa_lopp-lisa_alg
result = self.set_omanik(fail,orgOwner)
if not result:
self.set_omanik(fail,self.owner)
self.add_file_metadata(fail,element)
fail_lopp = time.time()
print "Fail:",fail_lopp-fail_alg
if tyyp == 'memo':
data = self.binarydata.getData(str(self.prefix+href))
memo = asukoht.add_memo(tekst,data)
# memo.set_author(self.owner)
memo.manage_delLocalRoles((self.uname,))
result = self.set_omanik(memo,orgOwner)
if not result:
self.set_omanik(memo,self.owner)
self.add_file_metadata(memo,element)
if tyyp == 'URL':
link = asukoht.add_link(tekst,href)
# link.set_author(self.owner)
link.manage_delLocalRoles((self.uname,))
result = self.set_omanik(link,orgOwner)
if not result:
self.set_omanik(link,self.owner)
self.add_file_metadata(link,element)
#XXX:wikipages and owners
if tyyp == 'wikipage':
if hasattr(asukoht.aq_inner.aq_self, tiitel):
# wikipage = getattr(asukoht, tiitel)
asukoht._delObject(tiitel)
data = self.binarydata.getData(str(self.prefix+href))
# wikipage = ZWikiPage(source_string=data, __name__=tiitel)
wikipage = ZWikiPage(source_string=data, __name__=tiitel)
parent = [self.wikiparent]
wikipage.parents = parent
#XXX: we d'nt catalog wikis.
# wikipage.index_object()
asukoht._setObject(tiitel,wikipage)
# wikipage += 'lammas tuli klla!!'
if tyyp == 'wikiimage' or tyyp == 'wikifile':
if hasattr(asukoht.aq_inner.aq_self, tiitel):
asukoht._delObject(tiitel)
data = self.binarydata.getData(str(self.prefix+href))
if tyyp == 'wikiimage':
asukoht._setObject(tiitel, OFS.Image.Image(tiitel,tiitel,''))
else:
asukoht._setObject(tiitel, OFS.Image.File(tiitel,tiitel,''))
asukoht._getOb(tiitel).manage_upload(data)
return
def createFolder(self,asukoht,nimi,orgID='',orgOwner=''):
#XXX: we should try to handle real object id here somehow!
# loo kaust
# try:
# print asukoht.absolute_url()
# print nimi
if 1==1:
kaust = asukoht.add_folder(nimi,orgID)
if orgOwner:
self.set_omanik(kaust, orgOwner)
else:
self.set_omanik(kaust, self.owner)
# except:
return kaust
def otsiItemid(self,item,tiitel,asukoht,resour,start=0):
# resources tagi ka siia tooma
try:
params = self.get_attr(item,'parameters')
except:
params = ''
tit = self.get_text(item.getElementsByTagName('title')[0])
try:
orgID = self.get_attr(item.getElementsByTagName('title')[0],'originalID')
except:
orgID = ''
try:
orgOwner = self.get_attr(item.getElementsByTagName('title')[0],'originalOwner')
except:
orgOwner = ''
if not start:
if not self.testonly:
uusfolder = self.createFolder(asukoht,tit,orgID,orgOwner)
self.add_folder_metadata(uusfolder,item)
# asukoht = getattr(asukoht,tit)
idref = self.get_attr(item,'identifierref')
try:
self.otsiTarget(idref,resour,'MISC STUFF',getattr(asukoht,uusfolder.id),params)
except:
self.otsiTarget(idref,resour,'MISC STUFF',asukoht,params)
for bcd in item.childNodes:
if bcd.nodeType == 1 and bcd.nodeName == 'item':
#otsi itemi tiitel
#otsi identifierref
try:
temp = getattr(asukoht,uusfolder.id)
except:
temp = asukoht
self.otsiItemid(bcd,tiitel,temp,resour)
return
def otsiWikid(self,item,tiitel,asukoht,resour,start=0,vanem=''):
tit = self.get_text(item.getElementsByTagName('title')[0])
self.wikiparent = ''
idref = self.get_attr(item,'identifierref')
start = 0
if not start:
self.wikiparent = vanem
self.otsiTarget(idref,resour,tit,asukoht)
for bcd in item.childNodes:
if bcd.nodeType == 1 and bcd.nodeName == 'item':
temp = tit
self.otsiWikid(bcd,tiitel,asukoht,resour,vanem=temp)
return
def leiaLahendus(self,target,tiitel,asukoht='',resour='',params=''):
try:
xmlbase = self.get_attr(target,'xml:base')
except:
xmlbase = ''
type = self.get_attr(target,'type')
href = self.get_attr(target,'href')
if params == 'wikifolder' and not self.testonly:
wiki_resour = target.getElementsByTagName('resources')[0]
# for wiki_items in target.getElementsByTagName('item'):
#XXX: we try and except since something happened here what should not happen
try:
wiki_items = target.getElementsByTagName('item')[0]
except IndexError:
return
self.otsiWikid(wiki_items,tiitel,asukoht,wiki_resour,start=1)
return
if re.search('webcontent',type) and not self.testonly: # lheb raamaturiiulile
# temp = getattr(self.iva.courses, self.kursus.get_id())
# asukoht = getattr(temp, 'gf')
self.handleResource(target,asukoht,resour,tiitel)
if re.search('file',type) or re.search('memo',type) or re.search('URL',type) or re.search('wiki',type):
if not self.testonly:
print "testonly: ",self.testonly
self.handleResource(target,asukoht,resour,tiitel)
if re.search('Calenda',type) and not self.testonly:
self.lisaSyndmus(target,tiitel)
if re.search('imscp',type):
if not self.kursus:
self.kursus = self.coursemanager
abc = Importer(self.uname,self.iva,xmlbase,self.kursus,self.binarydata,userwikionly=self.userwikionly,kasuta_jooksvat=self.kasuta_jooksvat,testonly=self.testonly)
failisisu = abc.loadFile(self.prefix+xmlbase+href)
abc.processFile(self.kursus,failisisu)
self.processed.append(target)
if re.search('imsqti',type):
abc = Importer(self.uname,self.iva,self.prefix+xmlbase,self.kursus,self.binarydata,userwikionly=self.userwikionly,kasuta_jooksvat=self.kasuta_jooksvat,testonly=self.testonly)
failisisu = abc.loadFile(self.prefix+xmlbase+href)
abc.processFile(self.kursus,failisisu)
self.processed.append(target)
if re.search('meediapaja',type) or re.search('teadmuspaja',type) or params == 'Assignments' and not self.testonly:
abc = Importer(self.uname,self.iva,self.prefix+xmlbase,self.kursus,self.binarydata,userwikionly=self.userwikionly,kasuta_jooksvat=self.kasuta_jooksvat,testonly=self.testonly)
failisisu = abc.loadFile(self.prefix+xmlbase+href)
abc.processFile(self.kursus,failisisu)
self.processed.append(target)
if re.search('SYNDMUSED',tiitel) and not self.testonly:
self.ImportUserEvents(target,tiitel)
if params == 'RAAMATURIIUL' and not self.testonly:
r_res = target.getElementsByTagName('resources')[0]
for r_org in target.getElementsByTagName('organization'):
self.otsiTOC(r_org, r_res)
if params == 'RYHMALAUAD' and not self.testonly:
tmpasukoht = self.riiuliasukoht
self.riiuliasukoht = getattr(self.kursus,'subgroups')
r_res = target.getElementsByTagName('resources')[0]
for r_org in target.getElementsByTagName('organization'):
self.otsiTOC(r_org, r_res,subgroup=1)
self.riiuliasukoht = tmpasukoht
if params == 'SISEGRUPP' and not self.testonly:
tmpasukoht = self.riiuliasukoht
self.riiuliasukoht = getattr(self.kursus,'subgroups')
s_res = target.getElementsByTagName('resources')[0]
for s_org in target.getElementsByTagName('organization'):
s_nimi = self.get_attr(s_org,'identifier').split(':')[1]
s_nimi=re.sub('[^a-zA-Z0-9]', '_', s_nimi)
if s_nimi[0] == "_": s_nimi="x"+s_nimi
if s_nimi[-2:] == "__": s_nimi += "x"
if not hasattr(self.riiuliasukoht.aq_inner.aq_self, s_nimi):
print "teen gruppi!",s_nimi
self.kursus.lisa_grupp(s_nimi)
#XXX:subgroup name mapping!
try:
self.riiuliasukoht = getattr(self.riiuliasukoht.aq_inner.aq_self, s_nimi)
except AttributeError:
self.riiuliasukoht = self.kursus.lisa_grupp(s_nimi)
self.otsiTOC(s_org,s_res)
self.riiuliasukoht = tmpasukoht
if params == 'KASUTAJATE WEBTOPID' or params == 'KASUTAJATE SAHTLID' and not self.testonly:
tmpasukoht = self.riiuliasukoht
u_res = target.getElementsByTagName('resources')[0]
for u_org in target.getElementsByTagName('organization'):
u_ident = self.get_attr(u_org,'identifier').split('_')[1]
self.owner = u_ident
#XXX: we didn't export admin in previous versions and we're in
# trouble now ;(
if not hasattr(self.kursus.fle_users, u_ident):
continue
if params == 'KASUTAJATE SAHTLID':
tmp = getattr(self.kursus.fle_users, u_ident).webtop
else:
tmp = getattr(self.kursus.fle_users, u_ident).webtop
if not hasattr(tmp, 'c'+str(self.kursus.id)):
cf = tmp.lisa_kursuse_kaust_ilma_requestita(self.owner,str('c'+str(self.kursus.id)))
self.set_omanik(cf,self.owner)
self.riiuliasukoht = getattr(tmp, 'c'+str(self.kursus.id))
self.otsiTOC(u_org, u_res)
self.owner = self.uname
self.riiuliasukoht = tmpasukoht
return
def otsiTarget(self,identifier,ressursid,tiitel,asukoht='',params=''):
for target in ressursid.getElementsByTagName("resource"):
id = self.get_attr(target,'identifier')
if id == identifier and not self.vaataKasTehtud(target):
self.leiaLahendus(target,tiitel,asukoht,ressursid,params)
self.processed.append(target)
return
if id == identifier and self.vaataKasTehtud(target):
#print "---------------- leidsime sobiva kuid see oli juba tehtud :( jama!!!! target1"
pass
for target in self.root.getElementsByTagName("manifest"):
id = self.get_attr(target,'identifier')
if id == identifier and not self.vaataKasTehtud(target):
self.leiaLahendus(target,tiitel,asukoht,ressursid,params=params)
self.processed.append(target)
return
if id == identifier and self.vaataKasTehtud(target):
#print "---------------- leidsime sobiva kuid see oli juba tehtud :( jama!!!! target2"
pass
for target in self.root.getElementsByTagName("organization"):
id = self.get_attr(target,'identifier')
if id == identifier and not self.vaataKasTehtud(target):
self.leiaLahendus(target,tiitel,asukoht,ressursid,params=params)
self.processed.append(target)
return
if id == identifier and self.vaataKasTehtud(target):
pass
#print "---------------- leidsime sobiva kuid see oli juba tehtud :( jama!!!!otsiTarget3"
#print "identifieri " + identifier + " pole vimalik leida"
return
def otsiTOC(self,element,ressursid,subgroup=0):
#XXX:keyword subgroup should go away, it's needed to import iva ver 0.4.2 subgroup portfolios
for target in element.childNodes:
if not target.nodeName == 'item':
continue
identifier = self.get_attr(target,'identifier')
try:
identifierref = self.get_attr(target,'identifierref')
except:
identifierref = ''
try:
params = self.get_attr(target,'parameters')
except:
params = ''
tiitel = self.get_text(target.getElementsByTagName('title')[0])
try:
orgID = self.get_attr(target.getElementsByTagName('title')[0],'originalID')
except:
orgID = ''
try:
orgOwner = self.get_attr(target.getElementsByTagName('title')[0],'originalOwner')
except:
orgOwner = ''
if self.vaataKasTehtud(target):
continue
else:
self.processed.append(target)
if identifierref:
if params == 'wikifolder':
tmp = self.riiuliasukoht
self.riiuliasukoht = self.riiuliasukoht.add_wiki(tiitel)
self.add_folder_metadata(self.riiuliasukoht,target)
if orgOwner:
self.set_omanik(self.riiuliasukoht, orgOwner)
else:
self.set_omanik(self.riiuliasukoht, self.owner)
self.otsiTarget(identifierref, ressursid, tiitel,asukoht=self.riiuliasukoht,params=params)
if params == 'wikifolder':
self.riiuliasukoht = tmp
else:
#XXX:That's freaky stuff.
if not subgroup:
if not self.testonly:
self.riiuliasukoht = self.createFolder(self.riiuliasukoht, tiitel,orgID,orgOwner)
self.add_folder_metadata(self.riiuliasukoht,target)
else:
m = self.riiuliasukoht.objectValues()
korras = 0
for x in m:
if x.get_id() == tiitel:
self.riiuliasukoht = getattr(self.riiuliasukoht, x.get_id())
korras = 1
break
if not korras:
self.riiuliasukoht = self.kursus.lisa_grupp(tiitel)
#self.riiuliasukoht = getattr(self.riiuliasukoht, kaust)
self.otsiTOC(target, ressursid)
if not self.testonly:
self.riiuliasukoht = self.riiuliasukoht.aq_parent
return
def processZip2(self):
""" ... """
kaustad = []
abc = self.root.getElementsByTagName("organizations")[0]
for i in abc.getElementsByTagName("organization"):
kaustad.append(self.get_attr(i,'xml:base'))
return kaustad
def vaataKasTehtud(self,element):
for abc in self.processed:
if element.isSameNode(abc):
return 1
return 0
def otsiKasKasutajaid(self,element):
try:
res_xmlbase = self.get_attr(element,'xml:base')
except:
res_xmlbase = ''
for res in element.getElementsByTagName('resource'):
if re.search('imsent',self.get_attr(res,'type')) and not self.vaataKasTehtud(res):
try:
xmlbase = self.get_attr(res,'xml:base')
except:
xmlbase = ''
try:
href = self.get_attr(res.getElementsByTagName('file')[0],'href')
except:
return
abc = Importer(self.uname,self.iva,self.prefix+xmlbase,self.kursus,self.binarydata,userwikionly=self.userwikionly,kasuta_jooksvat=self.kasuta_jooksvat,testonly=self.testonly)
failisisu = abc.loadFile(self.prefix+xmlbase+href)
abc.processFile(self.kursus,failisisu)
# self.importUsers(res)
self.processed.append(res)
if not failisisu:
failisisu = ''
return failisisu
for res in self.root.getElementsByTagName('resource'):
if re.search('imsent',self.get_attr(res,'type')) and not self.vaataKasTehtud(res):
# self.importUsers(res)
# self.processed.append(res)
abc = Importer(self.uname,self.iva,self.prefix+xmlbase,self.kursus,self.binarydata,userwikionly=self.userwikionly,kasuta_jooksvat=self.kasuta_jooksvat,testonly=self.testonly)
failisisu = abc.loadFile(self.prefix+xmlbase+href)
abc.processFile(self.kursus,failisisu)
self.processed.append(res)
return failisisu
return
def otsiAlgandmed(self,elem):
try:
metadata = elem.getElementsByTagName("metadata")[0]
except:
pass
#raise 'IVA Error','Missing toplevel-manifest metadata element'
try:
resources = elem.getElementsByTagName("resources")[0]
except:
pass
#raise 'IVA Error','Missing toplevel-manifest resources element'
try:
organizations = elem.getElementsByTagName("organizations")[0]
except:
raise 'IVA Error','Missing toplevel-manifest organizations element'
return metadata, organizations, resources
def processFile(self,coursemanager,element):
""" process zip and find anything usable. """
proc_alg = time.time()
self.owner = self.uname
self.coursemanager = coursemanager
i = 0
kas_kursus = 0
#for organizations in self.root.getElementsByTagName("organizations"):
#self.kursus = self.createCourse(self.root.getElementsByTagName('metadata')[0],coursemanager,uname)
st_elem = element.firstChild
self.root = element.firstChild
# return
success = self.kontrolliEsimeneElement(st_elem,coursemanager)
if success:
return
# Siit edasi eeldame, et tegemist on CP-ga
ok = 0
j = 0
try:
st_elem = element.getElementsByTagName("manifest")[0]
except IndexError:
print "XXX:for now, we totally failed reading file."
return
self.root = st_elem
metadata,orgnz, resources = self.otsiAlgandmed(st_elem)
if not self.userwikionly and not self.testonly and not self.kasuta_jooksvat:
kas_kursus = self.createCourse(metadata,coursemanager,self.uname)
if kas_kursus:
self.kursus = kas_kursus
self.riiuliasukoht = getattr(self.kursus, 'gf')
else:
self.riiuliasukoht = ''
#print "sellest failist ei saanud kursust teha\nProovin kasutada jooksvat kursust"
if self.userwikionly:
self.riiuliasukoht = self.userwikionly
if self.kasuta_jooksvat:
self.riiuliasukoht = getattr(self.kursus, 'gf')
failisisu = self.otsiKasKasutajaid(resources)
for org in orgnz.childNodes:
if org.nodeName == 'organization':
self.otsiTOC(org,resources)
# kursus ja sisegrupid peaksid olema nd loodud. paigutan kasutajad.
if failisisu and not self.userwikionly and not self.testonly and not self.kasuta_jooksvat:
self.restoreMembership(failisisu)
proc_lopp = time.time()
print "Process Zip:",proc_lopp-proc_alg
def loadZip(self,file):
zip = zipfile.ZipFile(file,"r",zipfile.ZIP_DEFLATED)
for name in zip.namelist():
# if not re.search('imsmanifest.xml',name):
self.binarydata.restoreData(name,zip.read(name))
zip.close()
def loadFile(self,nimi):
xmlstring = self.binarydata.getData(nimi)
print "loen faili: ",nimi
try:
fish = xml.dom.minidom.parseString(xmlstring)
except UnicodeError, ExpatError:
print "XML data is not utf-8 encoded! Detecting encoding..."
encoding = re.search('encoding="([-a-zA-Z0-9]*)">',xmlstring).group(1)
print "Transforming from %s to utf-8..." % encoding
xmlstring = unicode(xmlstring,encoding).encode("utf-8")
fish = xml.dom.minidom.parseString(xmlstring)
return fish
def kontrolliEsimeneElement(self,element,courses):
if self.testonly and element.nodeName!='questestinterop':
try:
element = element.getElementsByTagName("questestinterop")[0]
except:
pass
if element.nodeName =='MailMessages':
if self.userwikionly or self.testonly:
return "kala"
self.importMailMessages(element)
return "MM"
if element.nodeName == 'questestinterop':
if self.userwikionly:
return "kala"
#Jump to qti import
self.importQT(element,self.kursus,self.uname)
return "QT"
if element.nodeName == 'enterprise':
if self.userwikionly or self.testonly:
return "kala"
#FIX: 1st element is DocumentType
abc = element.nextSibling
if not self.kasuta_jooksvat:
self.importUsers(abc)
else:
print "users not imported"
#Jump to user import
return "EP"
if element.nodeName == 'Assignments':
if self.userwikionly or self.testonly:
return "kala"
self.importKodutood(element)
return "Ass"
if element.nodeName == 'Jamming':
if self.userwikionly or self.testonly:
return "kala"
print " import Jamming"
kala = Exporter(self.iva,prefix=self.prefix)
kala.binarydata = self.binarydata
kala.importJamming(element,self.kursus)
return "MP"
if element.nodeName == 'KnowledgeBuilding':
if self.userwikionly or self.testonly:
return "kala"
print " import KnowledgeBuilding"
kala = Exporter(self.iva,prefix=self.prefix)
kala.binarydata = self.binarydata
for ctx in element.childNodes:
kala.importContext(ctx,self.kursus)
return "TP"
return 0
class kirjutaYldM:
def __init__(self):
self.mainmani = Document()
self.root_element = self.mainmani.createElement("manifest")
self.root_element.setAttribute('identifier','IVA')
self.root_element.setAttribute('version','1')
self.root_element.setAttribute('xmlns','http://www.imsproject.org/xsd/ims_cp_rootv1p1')
self.root_element.setAttribute('xmlns:imsmd','http://www.imsproject.org/xsd/ims_md_rootv1p1.xsd')
self.root_element.setAttribute('xmlns:xsi','http://www.w3.org/2000/10/XMLSchema-instance')
self.root_element.setAttribute('xsi:schemaLocation','http://www.imsproject.org/xsd/ims_cp_rootv1p1 http://www.imsproject.org/xsd/ims_cp_rootv1p1.xsd http://www.imsproject.org/xsd/ims_md_rootv1p1 http://www.imsproject.org/xsd/ims_md_rootv1p1.xsd')
self.mainmani.appendChild(self.root_element)
md=self.mainmani.createElement("metadata")
self.root_element.appendChild(md)
mds=self.mainmani.createElement('schema')
md.appendChild(mds)
text = self.mainmani.createTextNode('IMS Content')
mds.appendChild(text)
mdv=self.mainmani.createElement('schemaversion')
md.appendChild(mdv)
mdv.appendChild(self.mainmani.createTextNode('1.1'))
rek = self.mainmani.createElement('imsmd:record')
md.appendChild(rek)
gen = self.mainmani.createElement('imsmd:general')
rek.appendChild(gen)
tit = self.mainmani.createElement('imsmd:title')
gen.appendChild(tit)
lang = self.mainmani.createElement('imsmd:langstring')
lang.setAttribute('xml:lang','en-US')
lang.appendChild(self.mainmani.createTextNode('Data exported from IVA. See http://www.htk.tpu.ee/iva'))
tit.appendChild(lang)
self.organizations = self.mainmani.createElement("organizations")
self.root_element.appendChild(self.organizations)
self.organization = self.mainmani.createElement("organization")
self.organization.setAttribute('identifier','courses')
self.organizations.appendChild(self.organization)
self.ress = self.mainmani.createElement("resources")
self.root_element.appendChild(self.ress)
def kirjutaYldmanifest(self, kursusenr=0, kirjeldus='kirjeldus',tyyp='imscp_xmlv1p1p3',base='course/',href='imsmanifest.xml'):
m = self.mainmani.createElement("item")
m.setAttribute('identifier','item_'+str(kursusenr))
m.setAttribute('identifierref','resource_'+str(kursusenr))
# m.setAttribute('identifier','course'+str(kursusenr))
self.organization.appendChild(m)
title = self.mainmani.createElement("title")
title.appendChild(self.mainmani.createTextNode(kirjeldus))
m.appendChild(title)
item = self.mainmani.createElement("resource")
item.setAttribute('identifier','resource_'+str(kursusenr))
item.setAttribute('type',tyyp)
if base != "":
item.setAttribute('xml:base',base)
item.setAttribute('href',href)
item_title = self.mainmani.createElement('file')
item_title.setAttribute('href',href)
item.appendChild(item_title)
self.ress.appendChild(item)
return m
def lisaFaili(self, failinimi="ivaarhiiv.zip"):
"Lisatakse yldmanifest zip'i"
if zipfile.is_zipfile(failinimi):
zip = zipfile.ZipFile(failinimi,"a",zipfile.ZIP_DEFLATED)
else:
zip = zipfile.ZipFile(failinimi,"w",zipfile.ZIP_DEFLATED)
dump = Dump()
self.mainmani.writexml(dump)
zip.writestr(zipfile.ZipInfo("imsmanifest.xml"),dump.getdata())
zip.close()
class Kirjutus:
import string
def __init__(self, ivajuur, kursusenr):
""" Uue eksportkirjutaja loomine. Parameetrina eksporditava iva juurobjekt """
self.generateID() # just in case
self.iva = ivajuur
if kursusenr != None and kursusenr != 0:
self.kursus = getattr(ivajuur.courses, str(kursusenr))
self.kursusenr = kursusenr
else:
self.kursusenr = 0
self.kursus = None
return
def looKursuseFail(self,metadata=1):
# kursuse faili loomine
# must be called before other functions
self.binarydata = DataTable()
self.idmap = {}
self.dom=Document()
self.loendur=Counter()
# valmistame ette dokumendi
self.root=self.dom.createElement("manifest")
self.dom.appendChild(self.root)
self.root.setAttribute('identifier','IVA')
self.root.setAttribute('version','1')
self.root.setAttribute('xmlns','http://www.imsproject.org/xsd/ims_cp_rootv1p1')
self.root.setAttribute('xmlns:imsmd','http://www.imsproject.org/xsd/ims_md_rootv1p1.xsd')
self.root.setAttribute('xmlns:xsi','http://www.w3.org/2000/10/XMLSchema-instance')
self.root.setAttribute('xmlns:ivamd','http://www.htk.tpu.ee/%7Evahur/ivaplus.xsd')
self.root.setAttribute('xsi:schemaLocation','http://www.imsproject.org/xsd/ims_cp_rootv1p1 http://www.imsproject.org/xsd/ims_cp_rootv1p1.xsd http://www.imsproject.org/xsd/ims_md_rootv1p1 http://www.imsproject.org/xsd/ims_md_rootv1p1.xsd http://www.htk.tpu.ee/%7Evahur/ivaplus http://www.htk.tpu.ee/%7Evahur/ivaplus.xsd')
if metadata:
metadata = self.dom.createElement("metadata")
schema = self.dom.createElement("schema")
schema_data = self.dom.createTextNode("IMS Content")
schema.appendChild(schema_data)
schema_ver = self.dom.createElement("schemaversion")
schema_ver_data = self.dom.createTextNode("1.1")
schema_ver.appendChild(schema_ver_data)
metadata.appendChild(schema)
metadata.appendChild(schema_ver)
md_methods = self.dom.createElement('ivamd:methods')
md_methods_data = self.dom.createTextNode(self.kursus.get_methods())
md_methods.appendChild(md_methods_data)
metadata.appendChild(md_methods)
md_organisation = self.dom.createElement('ivamd:organisation')
md_organisation_data = self.dom.createTextNode(self.kursus.get_organisation())
md_organisation.appendChild(md_organisation_data)
metadata.appendChild(md_organisation)
md_quote = self.dom.createElement('ivamd:quote')
md_quote_data = self.dom.createTextNode(self.kursus.kysiTekst())
md_quote.appendChild(md_quote_data)
metadata.appendChild(md_quote)
if self.kursus.kysiLogo():
md_picture = self.dom.createElement('ivamd:picture')
name = self.binarydata.storeData(self.kursus.kysiLogo())
md_picture.setAttribute('href',name)
metadata.appendChild(md_picture)
md_status = self.dom.createElement('ivamd:status')
try:
md_status_data = self.dom.createTextNode(str(self.kursus.staatus))
except:
md_status_data = self.dom.createTextNode(str(0))
md_status.appendChild(md_status_data)
metadata.appendChild(md_status)
record = self.dom.createElement('imsmd:record')
general = self.dom.createElement('imsmd:general')
record.appendChild(general)
title = self.dom.createElement('imsmd:title')
general.appendChild(title)
lang = self.dom.createElement('imsmd:langstring')
lang.setAttribute('xml:lang','en-US')
lang_data = self.dom.createTextNode(self.kursus.get_name())
lang.appendChild(lang_data)
title.appendChild(lang)
descr = self.dom.createElement('imsmd:description')
descrlang = self.dom.createElement('imsmd:langstring')
descrlang.setAttribute('xml:lang','en-US')
descrlang_data = self.dom.createTextNode(self.kursus.get_description())
descrlang.appendChild(descrlang_data)
descr.appendChild(descrlang)
general.appendChild(descr)
metadata.appendChild(record)
self.root.appendChild(metadata)
self.organizations = self.dom.createElement('organizations')
self.organization = self.dom.createElement('organization')
self.organization.setAttribute('identifier','IVA_CONTENT'+str(self.idnumber))
self.organizations.appendChild(self.organization)
self.resources = self.dom.createElement('resources')
self.root.appendChild(self.organizations)
self.root.appendChild(self.resources)
def generateID(self):
# generates idnumber. used as identifer and identifierref
# used as 'ITEM'+str(self.idnumber) and 'TARGET'+str(self.idnumber)
import random
self.idnumber = str(random.randint(1,9999))+"_"+str(random.randint(1,9999))
return self.idnumber
def lisaMetadata(self,vanem,objekt,technical='',annotations=''):
metadata = self.dom.createElement('metadata')
try:
metadata.setAttribute('creationtime',str(objekt.get_timestamp()))
except AttributeError:
pass
if technical:
technical = self.dom.createElement('imsmd:technical')
format = self.dom.createElement('imsmd:format')
try:
format_data = self.dom.createTextNode(str(objekt.content_type))
except:
format_data = self.dom.createTextNode('text/plain')
format.appendChild(format_data)
technical.appendChild(format)
perm = self.dom.createElement('permission')
technical.appendChild(perm)
status = self.dom.createElement('status')
status.appendChild(self.dom.createTextNode(str(objekt.getObjPermission())))
perm.appendChild(status)
order = self.dom.createElement('position')
order.appendChild(self.dom.createTextNode(str(objekt.weight)))
perm.appendChild(order)
docStatus = self.dom.createElement('docstatus')
docStatus.appendChild(self.dom.createTextNode(str(objekt.getDocStatus())))
perm.appendChild(docStatus)
#userRating!?
uca = self.dom.createElement('commentable')
uca.setAttribute('view',str(objekt.isCommentsVisible()))
uca.appendChild(self.dom.createTextNode(str(objekt.isCommentable())))
perm.appendChild(uca)
ura = self.dom.createElement('rateable')
ura.setAttribute('view',str(objekt.isRatingVisible()))
ura.appendChild(self.dom.createTextNode(str(objekt.isRateable())))
perm.appendChild(ura)
time = self.dom.createElement('timelimits')
time.setAttribute('start',str(objekt.getStartTime()))
time.setAttribute('end',str(objekt.getEndTime()))
time.appendChild(self.dom.createTextNode(str(objekt.getTimeFunc())))
perm.appendChild(time)
for up in objekt.listLocalUserRoles('Items'):
granted = self.dom.createElement('granted')
granted.appendChild(self.dom.createTextNode(str(up)))
perm.appendChild(granted)
metadata.appendChild(technical)
if annotations:
for x in objekt.getComments():
an = self.dom.createElement('annotation')
an.setAttribute('parameters','comment')
metadata.appendChild(an)
person = self.dom.createElement('person')
person.appendChild(self.dom.createTextNode(str(x[0])))
an.appendChild(person)
date = self.dom.createElement('date')
date.appendChild(self.dom.createTextNode(str(x[2])))
an.appendChild(date)
desc = self.dom.createElement('description')
desc.appendChild(self.dom.createTextNode(str(x[4])))
an.appendChild(desc)
#XXX:not compilant
stat = self.dom.createElement('status')
stat.appendChild(self.dom.createTextNode(str(x[1])))
an.appendChild(stat)
value = self.dom.createElement('value')
value.appendChild(self.dom.createTextNode(str(x[3])))
an.appendChild(value)
vanem.appendChild(metadata)
return metadata
def kirjutaItem(self,vanem,isvisible='',parameters='',tiitel='',no_ref=0,originalID='',originalOwner='',realObject=None):
# writes an item tag and appends to vanem
item = self.dom.createElement('item')
item.setAttribute('identifier','ITEM'+str(self.idnumber))
if realObject is not None and realObject.kasEsitluskaust():
item.setAttribute('presentation',str(realObject.kasEsitluskaust()))
if not no_ref:
item.setAttribute('identifierref','TARGET'+str(self.idnumber))
if realObject:
md = self.dom.createElement('metadata')
try:
md.setAttribute('creationtime',str(realObject.get_timestamp()))
except AttributeError:
pass
item.appendChild(md)
if hasattr(realObject.aq_self, 'kylastused'):
for x in realObject.aq_self.kylastused.keys():
an = self.dom.createElement('annotation')
an.setAttribute('parameters','visit')
md.appendChild(an)
ps = self.dom.createElement('person')
ps.appendChild(self.dom.createTextNode(str(x)))
an.appendChild(ps)
dt = self.dom.createElement('date')
dt.appendChild(self.dom.createTextNode(str(realObject.aq_self.kylastused[x])))
an.appendChild(dt)
perm = self.dom.createElement('permission')
md.appendChild(perm)
status = self.dom.createElement('status')
status.appendChild(self.dom.createTextNode(str(realObject.getObjPermission())))
perm.appendChild(status)
order = self.dom.createElement('position')
order.appendChild(self.dom.createTextNode(str(realObject.weight)))
perm.appendChild(order)
time = self.dom.createElement('timelimits')
time.setAttribute('start',str(realObject.getStartTime()))
time.setAttribute('end',str(realObject.getEndTime()))
time.appendChild(self.dom.createTextNode(str(realObject.getTimeFunc())))
perm.appendChild(time)
for up in realObject.listLocalUserRoles('Items'):
granted = self.dom.createElement('granted')
granted.appendChild(self.dom.createTextNode(str(up)))
perm.appendChild(granted)
if isvisible != '':
item.setAttribute('isvisible',isvisible)
if parameters != '':
item.setAttribute('parameters',parameters)
if tiitel != '':
self.kirjutaTitle(item,tiitel,originalID=originalID,originalOwner=originalOwner)
vanem.appendChild(item)
return item
def kirjutaResource(self,vanem,tyyp='webcontent',fail='', href='',base=''):
# writes resource tag and appends to vanem
resource = self.dom.createElement('resource')
resource.setAttribute('identifier','TARGET'+str(self.idnumber))
resource.setAttribute('type',tyyp)
if base != '':
resource.setAttribute('xml:base',base)
if href != '':
resource.setAttribute('href',str(href))
if fail != '':
self.kirjutaFile(resource,fail)
vanem.appendChild(resource)
return resource
def kirjutaTitle(self,vanem,tiitel,namespace='',originalID='',originalOwner=''):
title = self.dom.createElement(namespace+'title')
if originalID:
#XXX: THIS IS NOT IMS VALID!
title.setAttribute('originalID',originalID)
if originalOwner:
#XXX: THIS IS NOT IMS VALID!
title.setAttribute('originalOwner',originalOwner)
title_data = self.dom.createTextNode(tiitel)
title.appendChild(title_data)
vanem.appendChild(title)
return title
def kirjutaFile(self,vanem,fail):
fail_elem = self.dom.createElement('file')
fail_elem.setAttribute('href',fail)
vanem.appendChild(fail_elem)
return fail_elem
def kirjutaDependency(self,vanem,targetid):
dep = self.dom.createElement('dependency')
dep.setAttribute('identifierref','TARGET'+str(targetid))
vanem.appendChild(dep)
return dep
def kirjutaManifest(self,base=''):
# creates sub-manifest, returns 3 elements: metadata, organizations and resources
manifest = self.dom.createElement('manifest')
manifest.setAttribute('identifier','TARGET'+str(self.idnumber))
if base != '':
manifest.setAttribute('xml:base',base)
metadata = self.dom.createElement('metadata')
manifest.appendChild(metadata)
organizations = self.dom.createElement('organizations')
manifest.appendChild(organizations)
resources = self.dom.createElement('resources')
manifest.appendChild(resources)
self.root.appendChild(manifest)
return metadata,organizations,resources
def otsiWebtopItemid(self,folder,itemid,resource,start=0):
targetid = self.generateID()
prms = ''
if folder.kasWikiKaust():
prms = 'wikifolder'
if not start:
item = self.kirjutaItem(itemid,parameters=prms,no_ref=1,realObject=folder)
self.kirjutaTitle(item,folder.get_name(),originalID=folder.getId(),originalOwner=folder.getOwnerTuple()[1])
else:
item = itemid
for obj in folder.list_contents(criteria='weight'):
print obj.absolute_url()
targetid = self.generateID()
if obj.meta_type != 'WebtopFolder':
ii = self.kirjutaItem(item)
self.kirjutaTitle(ii, obj.get_name(),originalID=obj.getId(),originalOwner=obj.getOwnerTuple()[1])
if obj.meta_type == 'WebtopFile':
res = self.kirjutaResource(resource,tyyp='file')
fnimi = self.binarydata.storeData(obj.data,'file')
fail = self.kirjutaFile(res,fnimi)
metadata = self.lisaMetadata(fail,obj, technical=1,annotations=1)
self.kirjutaTitle(metadata,obj.get_name(),'imsmd:',originalID=obj.getId(),originalOwner=obj.getOwnerTuple()[1])
if obj.meta_type == 'WebtopLink':
res = self.kirjutaResource(resource,tyyp='URL')
fail = self.kirjutaFile(res,obj.get_url())
metadata = self.lisaMetadata(fail,obj,technical=1,annotations=1)
self.kirjutaTitle(fail,obj.get_name(),'imsmd:',originalID=obj.getId(),originalOwner=obj.getOwnerTuple()[1])
if obj.meta_type == 'WebtopMemo':
res = self.kirjutaResource(resource,tyyp='memo')
mnimi = self.binarydata.storeData(obj.get_body(),'memo')
file = self.kirjutaFile(res,mnimi)
metadata = self.lisaMetadata(file,obj,technical=1,annotations=1)
self.kirjutaTitle(file,obj.get_name(),'imsmd:',originalID=obj.getId(),originalOwner=obj.getOwnerTuple()[1])
if obj.meta_type == 'WebtopFolder':
targetid = self.generateID()
if obj.kasWikiKaust():
self.kirjutaWiki(obj, 'ident',obj.aq_inner.get_name(),obj.wikiKaustEsimeneLeht(),item)
else:
self.otsiWebtopItemid(obj,item,resource)
# for fol in folder.objectValues('WebtopFolder'):
#if fol.kasWikiKaust():
# XXX wiki kirjutamine!?
# self.kirjutaWiki(fol, 'ident', fol.get_name(),fol.wikiKaustEsimeneLeht(),item)
#else:
# self.otsiWebtopItemid(fol,item,resource)
return
def kirjutaWebtop(self,point,misc='ident',tiitel='SISEGRUPP'):
# exports webtop style components
self.generateID()
self.kirjutaItem(self.organization,tiitel=tiitel, parameters=tiitel)
e_metadata,e_organizations,e_resources = self.kirjutaManifest()
organization = self.dom.createElement('organization')
# organization.setAttribute('identifier',misc+str(self.idnumber))
organization.setAttribute('identifier',misc)
e_organizations.appendChild(organization)
self.otsiWebtopItemid(point,organization,e_resources,start=1)
return
def kirjutaKasutajaWebtop(self,kasutajad):
self.generateID()
self.kirjutaItem(self.organization,tiitel='KASUTAJATE WEBTOPID',parameters='KASUTAJATE WEBTOPID')
w_metadata,w_organizations,w_resources = self.kirjutaManifest()
# self.generateID()
# self.kirjutaItem(self.organization,tiitel='KASUTAJATE SAHTLID',parameters='KASUTAJATE SAHTLID')
# s_metadata,s_organizations,s_resources = self.kirjutaManifest()
for user in kasutajad:
uname = user.get_uname()
try:
pp = getattr(self.iva.fle_users, uname)
point = getattr(pp.webtop, 'c'+self.kursusenr)
webtop_ation = self.dom.createElement('organization')
webtop_ation.setAttribute('identifier','user_'+str(uname)+'_webtop')
w_organizations.appendChild(webtop_ation)
self.otsiWebtopItemid(point,webtop_ation,w_resources,start=1)
except:
pass
# try:
# point = getattr(pp.sahtel, 'c'+self.kursusenr)
# sahtel_ation = self.dom.createElement('organization')
# sahtel_ation.setAttribute('identifier','user_'+str(uname)+'_sahtel')
# s_organizations.appendChild(sahtel_ation)
# self.otsiWebtopItemid(point,sahtel_ation,s_resources,start=1)
# except:
# pass
return
def pakiKursusFaili(self,failinimi,path='ABCDE'):
import string
if path == 'ABCDE':
path = str(self.kursusenr)
if path != '':
path += '/'
if zipfile.is_zipfile(failinimi):
zip = zipfile.ZipFile(failinimi,"a",zipfile.ZIP_DEFLATED)
else:
zip = zipfile.ZipFile(failinimi,"w",zipfile.ZIP_DEFLATED)
dump = Dump()
self.dom.writexml(dump)
zip.writestr(zipfile.ZipInfo(path+"imsmanifest.xml"),dump.getdata())
for name in self.binarydata.names:
zip.writestr(
zipfile.ZipInfo(path+name),
str(self.binarydata.getData(name)))
zip.close()
def otsiWikiLapsed(self,point,resources,organization,start='WikiStart',sygavus=99999):
#puudub koht muutjate jaoks
for wiki in self.wikid:
wiki_vanemad = wiki[1]
if start in wiki_vanemad:
self.generateID()
wikileht = getattr(point, wiki[0])
item = self.kirjutaItem(organization,parameters='ZWiki',tiitel=wikileht.name())
wname = self.binarydata.storeData(wikileht,'wiki')
self.kirjutaResource(resources,'wikipage',wname)
if not self.wikilevel == sygavus:
self.wikilevel = self.wikilevel+1
self.otsiWikiLapsed(point, resources, item, wikileht.name(),sygavus)
self.wikilevel = self.wikilevel-1
for wiki in self.wiki_pildid:
self.generateID()
wiki_pilt = getattr(point, wiki)
if wiki_pilt.meta_type == 'Image':
tyyp = 'wikiimage'
if wiki_pilt.meta_type == 'File':
tyyp = 'wikifile'
item = self.kirjutaItem(organization, parameters='ZWiki',tiitel=wiki_pilt.id())
wname = self.binarydata.storeData(wiki_pilt.data,tyyp)
res = self.kirjutaResource(resources,tyyp=tyyp)
fail = self.kirjutaFile(res,wname)
metadata = self.lisaMetadata(fail,wiki_pilt, technical=1)
#print wiki_pilt.getContentType()
self.wiki_pildid = []
return
def indekseeriWikid(self,point):
self.wikid = []
self.wiki_pildid = []
temp = []
#for wiki in point.objectValues('ZWiki Page'):
for wiki in point.objectValues():
if wiki.meta_type == 'ZWiki Page':
try:
temp.append(wiki.name())
temp.append(wiki.parents)
self.wikid.append(temp)
temp = []
except:
pass
if wiki.meta_type == 'Image' or wiki.meta_type == 'File':
self.wiki_pildid.append(wiki.id())
#print wiki.__name__+" "+wiki.meta_type
return
def kirjutaWiki(self,point,misc='ident',tiitel='ZWIKI',start='WikiStart',toc='',palju=''):
self.generateID()
if toc:
self.kirjutaItem(toc,parameters='wikifolder',tiitel=tiitel,originalID=point.getId(),originalOwner=point.getOwnerTuple()[1],realObject=point)
else:
self.kirjutaItem(self.organization,tiitel=tiitel,parameters='wikifolder')
w_metadata,w_organizations,w_resources = self.kirjutaManifest()
organization = self.dom.createElement('organization')
organization.setAttribute('identifier',misc+str(self.idnumber))
w_organizations.appendChild(organization)
#kirjutame esieme wiki-lehe
self.generateID()
try:
item = self.kirjutaItem(organization,parameters='ZWiki',tiitel=getattr(point,start).name())
except:
start = 'WikiAvaLeht'
item = self.kirjutaItem(organization,parameters='ZWiki',tiitel=getattr(point,'WikiAvaLeht').name())
wnimi = self.binarydata.storeData(getattr(point, start),'wiki')
self.kirjutaResource(w_resources,'wikipage', wnimi)
self.indekseeriWikid(point)
self.wikilevel = 1
if palju:
self.otsiWikiLapsed(point,w_resources,item,start,palju)
else:
self.otsiWikiLapsed(point,w_resources,item,start)
return
def kirjutaKasutajaWiki(self,kasutajad,start='WikiStart'):
self.generateID()
self.kirjutaItem(self.organization,tiitel='KASUTAJA WIKI')
w_metadata,w_organizations,w_resources = self.kirjutaManifest()
self.generateID()
for kasutaja in kasutajad:
uname = kasutaja.get_uname()
try:
pp = getattr(self.iva.fle_users, uname)
point = getattr(pp.webtop, 'c'+self.kursusenr)
wiki_organization = self.dom.createElement('organization')
wiki_organization.setAttribute('identifier','user_'+str(uname)+'_wiki')
self.generateID()
try:
item = self.kirjutaItem(wiki_organization,tiitel=getattr(point,start).name())
except:
start = 'WikiAvaLeht'
try:
item = self.kirjutaItem(wiki_organization,tiitel=getattr(point,start).name())
except:
continue
w_organizations.appendChild(wiki_organization)
wnimi = self.binarydata.storeData(getattr(point, start),'wiki')
self.kirjutaResource(w_resources,'wikipage', wnimi)
self.indekseeriWikid(point)
self.otsiWikiLapsed(point,w_resources,item,start)
except:
pass
return
def vCalTime(self, aeg):
import time
vaeg = time.localtime(aeg)
v_aeg = ""
v_aeg += str(vaeg[0])
if len(str(vaeg[1])) == 1:
v_aeg += "0" +str(vaeg[1])
else:
v_aeg += str(vaeg[1])
if len(str(vaeg[2])) == 1:
v_aeg += "0" +str(vaeg[2])
else:
v_aeg += str(vaeg[2])
v_aeg += "T"
if len(str(vaeg[3])) == 1:
v_aeg += "0"+str(vaeg[3])
else:
v_aeg += str(vaeg[3])
if len(str(vaeg[4])) == 1:
v_aeg += "0"+str(vaeg[4])
else:
v_aeg += str(vaeg[4])
if len(str(vaeg[5])) == 1:
v_aeg += "0"+str(vaeg[5])
else:
v_aeg += str(vaeg[5])
return v_aeg
def format(self,sisend):
temp = re.sub('\r\n',' ',sisend)
pikkus = len(temp)
tulem = ""
if pikkus>60:
abc = ""
for taht in temp:
abc += taht
if len(abc)>59:
tulem += abc
tulem += "\r\n"
tulem += " "
abc = ""
tulem += abc
#tulem += "\r\n"
else:
tulem = temp
return tulem
def kirjutaEvent(self,point,omanik='mina',kat='kursus'):
tulem = ""
for syndmus in point.objectValues():
tulem += "BEGIN:VEVENT\r\n"
tulem += "DTSTART:"+self.vCalTime(syndmus.algus)+"\r\n"
tulem += "DTEND:"+self.vCalTime(syndmus.lopp)+"\r\n"
tulem += "N:"+omanik+"\r\n"
tulem += "DESCRIPTION:"+self.format(syndmus.pikk)+"\r\n"
tulem += "SUMMARY:"+self.format(syndmus.lyhi)+"\r\n"
tulem += "STATUS:"+str(syndmus.olek)+"\r\n"
tulem += "CUTYPE:"+kat+"\r\n"
tulem += "URL:"+syndmus.viide+"\r\n"
tulem += "X-PROPERTY;VALUE=NAME:"+self.format(syndmus.nimi)+"\r\n"
# tulem += "X-COMPONENT;VALUE=NAME:"+self.format(oma)+"\r\n"
tulem += "RESOURCES:"+self.format(syndmus.siseviide)+"\r\n"
tulem += "END:VEVENT\r\n"
return tulem
def has_events(self,point):
for syndmus in point.objectValues():
return 1
return 0
def kirjutavCal(self,point,omanik,kat,organiz='', resour=''):
if organiz == '':
organiz = self.organization
if resour == '':
resour = self.resources
if self.has_events(point):
vCal = "BEGIN:VCALENDAR\r\n"
vCal += "METHOD:PUBLISH\r\n"
vCal += "VERSION:2.0\r\n"
vCal += "PRODID:IVA\r\n"
vCal += self.kirjutaEvent(point,omanik,kat)
vCal += "END:VCALENDAR\r\n"
nimi = self.binarydata.storeData(vCal,'vcal','.ics')
self.generateID()
self.kirjutaItem(organiz,tiitel='iCalendar - '+omanik+' - syndmused',parameters='iCalendar - '+omanik+' - syndmused')
# self.kirjutaItem(self.organization,tiitel='iCalendar - '+omanik+' syndmused')
self.kirjutaResource(resour,'iCalendar',nimi)
# self.kirjutaResource(self.resources,'iCalendar',nimi)
return
def kirjutaKasutajaSyndmus(self,kasutajad):
self.generateID()
self.kirjutaItem(self.organization, tiitel="KASUTAJATE SYNDMUSED",parameters="KASUTAJATE SYNDMUSED")
s_metadata,s_organizations,s_resources = self.kirjutaManifest()
for user in kasutajad:
try:
uname = user.get_uname()
point = getattr(self.iva.fle_users, uname)
if self.has_events(point.syndmused):
syndmus_organization = self.dom.createElement('organization')
syndmus_organization.setAttribute('identifier','user_'+str(uname)+'_events')
s_organizations.appendChild(syndmus_organization)
self.kirjutavCal(point.syndmused, uname, 'INDIVIDUAL',syndmus_organization,s_resources)
except:
pass
return
def exportMail(self,failinimi,palju=''):
mmdoc = Document()
mm = mmdoc.createElement('MailMessages')
mmdoc.appendChild(mm)
users = []
if not palju:
users = self.iva.fle_users.get_users()
else:
users = eval(palju)
for x in users:
if not hasattr(x, 'kirjad'):
continue
point = getattr(x, 'kirjad')
cat = mmdoc.createElement('catalog')
cat.setAttribute('owner', x.get_uname())
mm.appendChild(cat)
for kiri in point.objectValues():
mess = mmdoc.createElement('message')
mess.setAttribute('read',str(kiri.kasLoetud()))
if kiri.kasOmaKoopia():
mess.setAttribute('owncopy','1')
cat.appendChild(mess)
title = mmdoc.createElement('title')
tekst = kiri.kysiPealkiri()
tekst = re.sub(']]>',']] >',tekst)
# decode and then encode
try:
tekst = tekst.decode('utf-8')
except UnicodeDecodeError:
tekst = tekst.decode('iso-8859-15')
tekst = tekst.encode('utf-8')
title.appendChild(mmdoc.createCDATASection(strip_non_xml(tekst)))
mess.appendChild(title)
body = mmdoc.createElement('body')
tekst = kiri.kysiSisu()
tekst = re.sub(']]>',']] >',tekst)
try:
tekst = tekst.decode('utf-8')
except UnicodeDecodeError:
tekst = tekst.decode('iso-8859-13')
tekst = tekst.encode('utf-8')
body.appendChild(mmdoc.createCDATASection(strip_non_xml(tekst)))
mess.appendChild(body)
sender = mmdoc.createElement('sender')
sender.appendChild(mmdoc.createTextNode(str(kiri.kysiSaatja())))
mess.appendChild(sender)
receiver = mmdoc.createElement('receiver')
receiver.appendChild(mmdoc.createTextNode(str(kiri.saaja)))
mess.appendChild(receiver)
date = mmdoc.createElement('date')
date.appendChild(mmdoc.createTextNode(str(kiri.kysiAeg())))
mess.appendChild(date)
if zipfile.is_zipfile(failinimi):
zip = zipfile.ZipFile(failinimi,"a",zipfile.ZIP_DEFLATED)
else:
zip = zipfile.ZipFile(failinimi,"w",zipfile.ZIP_DEFLATED)
# mmdoc.dump = Dump()
# mmdoc.writexml(mmdoc.dump)
# zip.writestr(zipfile.ZipInfo("messages.xml"),mmdoc.dump.getdata())
zip.writestr(zipfile.ZipInfo("messages.xml"),mmdoc.toprettyxml())
zip.close()
return
def exportKodutood(self, point,failinimi,path):
# expordime kodutd
kt_doc = Document()
kt = kt_doc.createElement('Assignments')
kt_doc.appendChild(kt)
kt.setAttribute('identifier','IVA')
kt.setAttribute('version','1')
for kodu in point.listAssignments():
too = kt_doc.createElement('Assignment')
too.setAttribute('originalID',kodu.get_id())
kt.appendChild(too)
tyyp = kt_doc.createElement('type')
tyyp_data = kt_doc.createTextNode(str(kodu.tyyp))
tyyp.appendChild(tyyp_data)
too.appendChild(tyyp)
pkiri = kt_doc.createElement('title')
pkiri_data = kt_doc.createTextNode(str(kodu.getTitle()))
pkiri.appendChild(pkiri_data)
too.appendChild(pkiri)
kirjeldus = kt_doc.createElement('description')
kirjeldus_data = kt_doc.createTextNode(str(kodu.kirjeldus))
kirjeldus.appendChild(kirjeldus_data)
too.appendChild(kirjeldus)
punkt = kt_doc.createElement('points')
punkt_data = kt_doc.createTextNode(str(kodu.getPoints()))
punkt.appendChild(punkt_data)
too.appendChild(punkt)
try:
resour = kt_doc.createElement('resource')
resour_data = kt_doc.createTextNode(str(kodu.juhend))
resour.appendChild(resour_data)
too.appendChild(resour)
except:
pass
try:
aeg = kt_doc.createElement('end')
aeg_data = kt_doc.createTextNode(str(kodu.loppaeg))
aeg.appendChild(aeg_data)
too.appendChild(aeg)
except:
pass
try:
grupp = kt_doc.createElement('groups')
for abc in kodu.getGroups():
gr = kt_doc.createElement('group')
grupp_data = kt_doc.createTextNode(str(abc))
gr.appendChild(grupp_data)
grupp.appendChild(gr)
too.appendChild(grupp)
except:
pass
try:
test = kt_doc.createElement('test')
test_data = kt_doc.createTextNode(str(kodu.testiID))
test.appendChild(test_data)
too.appendChild(test)
except:
pass
self.generateID()
self.kirjutaItem(self.organization,tiitel='Assignments',parameters='Assignments')
self.kirjutaResource(self.resources,'assignments','assignments.xml','assignments.xml')
if zipfile.is_zipfile(failinimi):
zip = zipfile.ZipFile(failinimi,"a",zipfile.ZIP_DEFLATED)
else:
zip = zipfile.ZipFile(failinimi,"w",zipfile.ZIP_DEFLATED)
kt_doc.dump = Dump()
kt_doc.writexml(kt_doc.dump)
zip.writestr(zipfile.ZipInfo(path+"assignments.xml"),kt_doc.dump.getdata())
zip.close()
return
def exportPajad(self,failinimi,path,startonly=0):
self.generateID()
TP = Document()
MP = Document()
kala = Exporter(self.iva)
tp_elem = TP.createElement('KnowledgeBuilding')
for ctx in self.kursus.get_children("CourseContext"):
tp_elem.appendChild(kala.exportContext(ctx,startonly))
TP.appendChild(tp_elem)
mp_elem = MP.createElement('Jamming')
try:
#for c in courses.get_children('Course'):
for js in self.kursus.get_child('jamming').get_children('JamSession'):
mp_elem.appendChild(kala.exportJamSession(self.kursus, js,startonly))
except:
pass
MP.appendChild(mp_elem)
self.kirjutaItem(self.organization,tiitel='TEADMUSPAJA',parameters='TEADMUSPAJA')
self.kirjutaResource(self.resources,'teadmuspaja','teadmuspaja.xml','teadmuspaja.xml')
self.generateID()
self.kirjutaItem(self.organization,tiitel='MEEDIAPAJA',parameters='MEEDIAPAJA')
self.kirjutaResource(self.resources,'meediapaja','meediapaja.xml','meediapaja.xml')
if zipfile.is_zipfile(failinimi):
zip = zipfile.ZipFile(failinimi,"a",zipfile.ZIP_DEFLATED)
else:
zip = zipfile.ZipFile(failinimi,"w",zipfile.ZIP_DEFLATED)
TP.dump = Dump()
MP.dump = Dump()
TP.writexml(TP.dump)
MP.writexml(MP.dump)
zip.writestr(zipfile.ZipInfo(path+"teadmuspaja.xml"),TP.dump.getdata())
zip.writestr(zipfile.ZipInfo(path+"meediapaja.xml"),MP.dump.getdata())
for name in kala.binarydata.names:
zip.writestr(
zipfile.ZipInfo(path+name),
str(kala.binarydata.getData(name)))
zip.close()
return
def exportQTI(self,failinimi,path,teacherExporting=0):
# function for going all necessary to export tests
self.generateID()
self.kirjutaItem(self.organization,tiitel='QTI',parameters='QTI')
self.kirjutaResource(self.resources,'imsqti_xmlv1p1','qti.xml','qti.xml')
element = self.looTestiFail()
self.kirjutaTestid(element,teacherExporting=teacherExporting)
self.kirjutaTestidZipi(failinimi,path)
def looTestiFail(self):
self.generateID()
self.qti = Document()
self.qtibin = DataTable()
self.qtiroot = self.qti.createElement("questestinterop")
self.qtiroot.setAttribute('xmlns','http://www.imsglobal.org/xsd/ims_qtiasiv1p2')
self.qtiroot.setAttribute('xmlns:xsi','http://www.w3.org/2000/10/XMLSchema-instance')
self.qtiroot.setAttribute('xsi:schemaLocation','http://www.imsglobal.org/xsd/ims_qtiasiv1p2 http://www.imsglobal.org/xsd/ims_qtiasiv1p2.xsd')
self.qti.appendChild(self.qtiroot)
return self.qtiroot
def kirjutaTestidZipi(self,failinimi,path=''):
if zipfile.is_zipfile(failinimi):
zip = zipfile.ZipFile(failinimi,"a",zipfile.ZIP_DEFLATED)
else:
zip = zipfile.ZipFile(failinimi,"w",zipfile.ZIP_DEFLATED)
self.qti.dump = Dump()
self.qti.writexml(self.qti.dump)
zip.writestr(zipfile.ZipInfo(path+"qti.xml"),self.qti.dump.getdata())
for name in self.qtibin.names:
zip.writestr(
zipfile.ZipInfo(path+name),
str(self.qtibin.getData(name)))
zip.close()
return
def testiPilt(self,vanem, varamu):
if varamu.pilt is not None:
mat_pilt = self.qti.createElement('matimage')
name = self.qtibin.storeData(varamu.pilt,'qti')
mat_pilt.setAttribute('uri',name)
vanem.appendChild(mat_pilt)
return vanem
def testiViide(self,vanem, varamu):
if varamu.viiteURL != '':
matem = self.qti.createElement('matemtext')
matem.setAttribute('uri',varamu.viiteURL)
matem.appendChild(self.qti.createTextNode(varamu.viiteTekst))
vanem.appendChild(matem)
return vanem
def testiKirjeldavTekst(self,vanem,varamu):
if varamu.kirjeldavTekst != '':
komm = self.qti.createElement('qticomment')
komm.appendChild(self.qti.createTextNode(varamu.kirjeldavTekst))
vanem.appendChild(komm)
return vanem
def testiItem(self,vanem,varamu):
elem = self.qti.createElement('item')
elem.setAttribute('ident',varamu.get_id())
elem.setAttribute('title',varamu.meta_type)
vanem.appendChild(elem)
return elem
def exportUserResponses(self,vanem,hoidla,users=''):
if not users:
users = self.kursus.get_all_users()
else:
users = eval(users)
for x in users:
try:
tmpx = getattr(self.iva.fle_users, x.get_uname()).webtop
tmpy = getattr(tmpx, 'c'+self.kursus.get_id()).testivastused
z = getattr(tmpy, hoidla.get_id())
except AttributeError:
continue
elem = self.qti.createElement('response')
elem.setAttribute('owner',x.get_uname())
for i in z.aq_self.objectValues():
ver = self.qti.createElement('version')
ver.setAttribute('id',str(i.get_id()))
try:
ver.setAttribute('comment',str(i.annaKoguKommentaar()))
except AttributeError:
pass
elem.appendChild(ver)
for j in i.objectValues():
yl = self.qti.createElement('yl')
yl.setAttribute('id',j.get_id())
try:
if j.annaOpetajaPunktid() is not None:
yl.setAttribute('score',str(j.annaOpetajaPunktid()))
except AttributeError:
pass
try:
yl.setAttribute('comment',str(j.annaOpetajaKommentaar()))
except AttributeError:
pass
try:
if type(j.pakutud())==types.ListType:
yl.setAttribute('type','List')
yl.appendChild(self.qti.createTextNode(str(j.pakutud())))
except AttributeError:
pass
ver.appendChild(yl)
vanem.appendChild(elem)
return
def kirjutaTestid(self,vanem,testinimi='',users='',teacherExporting=0):
if testinimi != '':
ainult_yks_test = 1
else:
ainult_yks_test = 0
qticomment = self.qti.createElement("qticomment")
qticomment_data = self.qti.createTextNode('Here is a set of questions and tests from IVA')
qticomment.appendChild(qticomment_data)
vanem.appendChild(qticomment)
# export all tests and questions within course
for hoidla in self.kursus.testid.objectValues():
if hoidla.get_id() == testinimi or not ainult_yks_test:
sektion = self.qti.createElement('section')
sektion.setAttribute('title',str(hoidla.pealkiri))
sektion.setAttribute('ident',str(hoidla.get_id()))
sektion.setAttribute('type',str(hoidla.kysiTyyp()))
sektion.setAttribute('randomize',str(hoidla.kasKysimusteJuhuslikJarjekord()))
sektion.setAttribute('answers',str(hoidla.kysiVastusteNahtavus()))
sektion.setAttribute('open',str(hoidla.avatudTaitmiseks))
md = self.qti.createElement('metadata')
sektion.appendChild(md)
tl = self.qti.createElement('timelimit')
tl.setAttribute('repeat',str(hoidla.koigiLuba.kordadeArv))
tl.setAttribute('start',str(hoidla.koigiLuba.algusAeg))
tl.setAttribute('end',str(hoidla.koigiLuba.loppAeg))
md.appendChild(tl)
grs = self.qti.createElement('groups')
md.appendChild(grs)
for x in hoidla.grupiLoad.objectValues():
gr = self.qti.createElement('group')
gr.setAttribute('repeat',str(x.kordadeArv))
gr.setAttribute('start',str(x.algusAeg))
gr.setAttribute('end',str(x.loppAeg))
gr.setAttribute('name',str(x.id))
grs.appendChild(gr)
prs = self.qti.createElement('persons')
md.appendChild(prs)
for x in hoidla.isikuLoad.objectValues():
pr = self.qti.createElement('person')
pr.setAttribute('repeat',str(x.kordadeArv))
pr.setAttribute('start',str(x.algusAeg))
pr.setAttribute('end',str(x.loppAeg))
pr.setAttribute('name',str(x.id))
prs.appendChild(pr)
desc = self.qti.createElement('description')
desc.appendChild(self.qti.createTextNode(str(hoidla.annaKirjeldus())))
md.appendChild(desc)
uresp = self.qti.createElement('userresponses')
sektion.appendChild(uresp)
if not teacherExporting:
self.exportUserResponses(uresp,hoidla,users)
#print hoidla.get_id()
for yled in hoidla.objectValues():
#print "->>"+yled.get_id()
#print yled.get_id()+" - "+ yled.meta_type
tyyp = yled.meta_type
if tyyp=='ValikYlesanne':
elem = self.testiItem(sektion,yled)
self.testiKirjeldavTekst(elem,yled)
present = self.qti.createElement('presentation')
elem.appendChild(present)
flo = self.qti.createElement('flow')
present.appendChild(flo)
mat = self.qti.createElement('material')
flo.appendChild(mat)
mattext = self.qti.createElement('mattext')
mattext.appendChild(self.qti.createTextNode(yled.kysimus))
mat.appendChild(mattext)
self.testiViide(mat,yled)
self.testiPilt(mat,yled)
resp_lid = self.qti.createElement('response_lid')
resp_lid.setAttribute('ident',yled.get_id())
resp_lid.setAttribute('rcardinality',"Single")
flo.appendChild(resp_lid)
render = self.qti.createElement('render_choice')
resp_lid.appendChild(render)
flow_l = self.qti.createElement('flow_label')
render.appendChild(flow_l)
resp_lab = self.qti.createElement('response_label')
resp_lab.setAttribute('ident','T')
flow_l.appendChild(resp_lab)
mat2 = self.qti.createElement('material')
resp_lab.appendChild(mat2)
mattext2 = self.qti.createElement('mattext')
mattext2.appendChild(self.qti.createTextNode('True'))
mat2.appendChild(mattext2)
resp_lab = self.qti.createElement('response_label')
resp_lab.setAttribute('ident','F')
flow_l.appendChild(resp_lab)
mat2 = self.qti.createElement('material')
resp_lab.appendChild(mat2)
mattext2 = self.qti.createElement('mattext')
mattext2.appendChild(self.qti.createTextNode('False'))
mat2.appendChild(mattext2)
resproc = self.qti.createElement('resprocessing')
elem.appendChild(resproc)
out = self.qti.createElement('outcomes')
resproc.appendChild(out)
muut = self.qti.createElement('decvar')
muut.setAttribute('vartype','Integer')
muut.setAttribute('maxvalue',str(yled.normPunktid))
out.appendChild(muut)
kond = self.qti.createElement('respcondition')
kond.setAttribute('title','Correct')
resproc.appendChild(kond)
kond_var = self.qti.createElement('conditionvar')
kond.appendChild(kond_var)
varequal = self.qti.createElement('varequal')
varequal.setAttribute('respident',yled.get_id())
if yled.vastus:
varequal.appendChild(self.qti.createTextNode('T'))
else:
varequal.appendChild(self.qti.createTextNode('F'))
kond_var.appendChild(varequal)
setvar = self.qti.createElement('setvar')
setvar.setAttribute('action','Add')
setvar.appendChild(self.qti.createTextNode(str(yled.normPunktid)))
kond.appendChild(setvar)
pass
if tyyp=='OigeTekstivastusegaYlesanne':
elem = self.testiItem(sektion,yled)
self.testiKirjeldavTekst(elem,yled)
present = self.qti.createElement('presentation')
elem.appendChild(present)
flo = self.qti.createElement('flow')
present.appendChild(flo)
mat = self.qti.createElement('material')
flo.appendChild(mat)
mattext = self.qti.createElement('mattext')
mattext.appendChild(self.qti.createTextNode(yled.kysimus))
mat.appendChild(mattext)
self.testiViide(mat,yled)
self.testiPilt(mat,yled)
resp_lid = self.qti.createElement('response_str')
resp_lid.setAttribute('ident',yled.get_id())
resp_lid.setAttribute('rcardinality',"Single")
flo.appendChild(resp_lid)
render = self.qti.createElement('render_fib')
render.setAttribute('fibtype','String')
render.setAttribute('encoding','UTF_8')
resp_lid.appendChild(render)
resp_lab = self.qti.createElement('response_label')
resp_lab.setAttribute('ident','A')
render.appendChild(resp_lab)
resproc = self.qti.createElement('resprocessing')
elem.appendChild(resproc)
out = self.qti.createElement('outcomes')
resproc.appendChild(out)
muut = self.qti.createElement('decvar')
muut.setAttribute('vartype','Integer')
muut.setAttribute('maxvalue',str(yled.normPunktid))
out.appendChild(muut)
kond = self.qti.createElement('respcondition')
kond.setAttribute('title','Correct')
resproc.appendChild(kond)
kond_var = self.qti.createElement('conditionvar')
kond.appendChild(kond_var)
for abc in yled.variandid:
varequal = self.qti.createElement('varequal')
varequal.setAttribute('respident',yled.get_id())
varequal.appendChild(self.qti.createTextNode(str(abc)))
kond_var.appendChild(varequal)
setvar = self.qti.createElement('setvar')
setvar.setAttribute('action','Add')
setvar.appendChild(self.qti.createTextNode(str(yled.normPunktid)))
kond.appendChild(setvar)
pass
if tyyp=='YksikvalikYlesanne':
elem = self.testiItem(sektion,yled)
self.testiKirjeldavTekst(elem,yled)
present = self.qti.createElement('presentation')
elem.appendChild(present)
flo = self.qti.createElement('flow')
present.appendChild(flo)
mat = self.qti.createElement('material')
flo.appendChild(mat)
mattext = self.qti.createElement('mattext')
mattext.appendChild(self.qti.createTextNode(yled.kysimus))
mat.appendChild(mattext)
self.testiViide(mat,yled)
self.testiPilt(mat,yled)
resp_lid = self.qti.createElement('response_lid')
resp_lid.setAttribute('ident',yled.get_id())
resp_lid.setAttribute('rcardinality',"Single")
flo.appendChild(resp_lid)
render = self.qti.createElement('render_choice')
render.setAttribute('shuffle','Yes')
resp_lid.appendChild(render)
i=0
for abc in yled.valikud:
resp_lab = self.qti.createElement('response_label')
resp_lab.setAttribute('ident',str(i))
render.appendChild(resp_lab)
flow_mat = self.qti.createElement('flow_mat')
resp_lab.appendChild(flow_mat)
mat2 = self.qti.createElement('material')
flow_mat.appendChild(mat2)
mattext2 = self.qti.createElement('mattext')
mattext2.appendChild(self.qti.createTextNode(abc))
mat2.appendChild(mattext2)
i=i+1
resproc = self.qti.createElement('resprocessing')
elem.appendChild(resproc)
out = self.qti.createElement('outcomes')
resproc.appendChild(out)
muut = self.qti.createElement('decvar')
muut.setAttribute('vartype','Integer')
muut.setAttribute('maxvalue',str(yled.normPunktid))
out.appendChild(muut)
kond = self.qti.createElement('respcondition')
kond.setAttribute('title','Correct')
resproc.appendChild(kond)
kond_var = self.qti.createElement('conditionvar')
kond.appendChild(kond_var)
varequal = self.qti.createElement('varequal')
varequal.setAttribute('respident',yled.get_id())
varequal.appendChild(self.qti.createTextNode(str(yled.oigeValik)))
kond_var.appendChild(varequal)
setvar = self.qti.createElement('setvar')
setvar.setAttribute('action','Add')
setvar.appendChild(self.qti.createTextNode(str(yled.normPunktid)))
kond.appendChild(setvar)
i=0
if not hasattr(yled,'selgitused'):
selgitused = []
for abc in yled.selgitused:
itemfeed = self.qti.createElement('itemfeedback')
itemfeed.setAttribute('ident',str(i))
elem.appendChild(itemfeed)
flow_m = self.qti.createElement('flow_mat')
itemfeed.appendChild(flow_m)
mat = self.qti.createElement('material')
flow_m.appendChild(mat)
mattext = self.qti.createElement('mattext')
mattext.appendChild(self.qti.createTextNode(abc))
mat.appendChild(mattext)
i=i+1
pass
if tyyp=='TekstivastusegaYlesanne':
elem = self.testiItem(sektion,yled)
self.testiKirjeldavTekst(elem,yled)
present = self.qti.createElement('presentation')
elem.appendChild(present)
flo = self.qti.createElement('flow')
present.appendChild(flo)
mat = self.qti.createElement('material')
flo.appendChild(mat)
mattext = self.qti.createElement('mattext')
mattext.appendChild(self.qti.createTextNode(yled.kysimus))
mat.appendChild(mattext)
self.testiViide(mat,yled)
self.testiPilt(mat,yled)
resp_lid = self.qti.createElement('response_str')
resp_lid.setAttribute('ident',yled.get_id())
resp_lid.setAttribute('rcardinality',"Ordered")
flo.appendChild(resp_lid)
render = self.qti.createElement('render_fib')
render.setAttribute('fibtype','String')
render.setAttribute('enconding','UTF_8')
render.setAttribute('prompt','Box')
resp_lid.appendChild(render)
resp_lab = self.qti.createElement('response_label')
resp_lab.setAttribute('ident','A')
render.appendChild(resp_lab)
pass
if tyyp=='MitmikvalikYlesanne':
elem = self.testiItem(sektion,yled)
self.testiKirjeldavTekst(elem,yled)
present = self.qti.createElement('presentation')
elem.appendChild(present)
flo = self.qti.createElement('flow')
present.appendChild(flo)
mat = self.qti.createElement('material')
flo.appendChild(mat)
mattext = self.qti.createElement('mattext')
mattext.appendChild(self.qti.createTextNode(yled.kysimus))
mat.appendChild(mattext)
self.testiViide(mat,yled)
self.testiPilt(mat,yled)
resp_lid = self.qti.createElement('response_lid')
resp_lid.setAttribute('ident',yled.get_id())
resp_lid.setAttribute('rcardinality',"Multiple")
flo.appendChild(resp_lid)
render = self.qti.createElement('render_choice')
render.setAttribute('shuffle','Yes')
resp_lid.appendChild(render)
i=0
for abc in yled.valikud:
resp_lab = self.qti.createElement('response_label')
resp_lab.setAttribute('ident',str(i))
render.appendChild(resp_lab)
flow_mat = self.qti.createElement('flow_mat')
resp_lab.appendChild(flow_mat)
mat2 = self.qti.createElement('material')
flow_mat.appendChild(mat2)
mattext2 = self.qti.createElement('mattext')
mattext2.appendChild(self.qti.createTextNode(abc))
mat2.appendChild(mattext2)
i=i+1
resproc = self.qti.createElement('resprocessing')
elem.appendChild(resproc)
out = self.qti.createElement('outcomes')
resproc.appendChild(out)
muut = self.qti.createElement('decvar')
muut.setAttribute('vartype','Integer')
muut.setAttribute('maxvalue',str(yled.normPunktid))
out.appendChild(muut)
kond = self.qti.createElement('respcondition')
kond.setAttribute('title','Correct')
resproc.appendChild(kond)
kond_var = self.qti.createElement('conditionvar')
kond.appendChild(kond_var)
for abc in yled.oigedValikud:
varequal = self.qti.createElement('varequal')
varequal.setAttribute('respident',yled.get_id())
varequal.appendChild(self.qti.createTextNode(str(abc)))
kond_var.appendChild(varequal)
setvar = self.qti.createElement('setvar')
setvar.setAttribute('action','Add')
setvar.appendChild(self.qti.createTextNode(str(yled.normPunktid)))
kond.appendChild(setvar)
i=0
for abc in yled.selgitused:
itemfeed = self.qti.createElement('itemfeedback')
itemfeed.setAttribute('ident',str(i))
elem.appendChild(itemfeed)
flow_m = self.qti.createElement('flow_mat')
itemfeed.appendChild(flow_m)
mat = self.qti.createElement('material')
flow_m.appendChild(mat)
mattext = self.qti.createElement('mattext')
mattext.appendChild(self.qti.createTextNode(abc))
mat.appendChild(mattext)
i=i+1
pass
if tyyp=='ArvuvahemikuliseVastusegaYlesanne':
elem = self.testiItem(sektion,yled)
self.testiKirjeldavTekst(elem,yled)
present = self.qti.createElement('presentation')
elem.appendChild(present)
flo = self.qti.createElement('flow')
present.appendChild(flo)
mat = self.qti.createElement('material')
flo.appendChild(mat)
mattext = self.qti.createElement('mattext')
mattext.appendChild(self.qti.createTextNode(yled.kysimus))
mat.appendChild(mattext)
self.testiViide(mat,yled)
self.testiPilt(mat,yled)
resp_lid = self.qti.createElement('response_num')
resp_lid.setAttribute('ident',yled.get_id())
resp_lid.setAttribute('rcardinality',"Single")
resp_lid.setAttribute('numtype','Decimal')
flo.appendChild(resp_lid)
render = self.qti.createElement('render_fib')
render.setAttribute('fibtype','Decimal')
render.setAttribute('prompt','Box')
resp_lid.appendChild(render)
resp_lab = self.qti.createElement('response_label')
resp_lab.setAttribute('ident','A')
render.appendChild(resp_lab)
resproc = self.qti.createElement('resprocessing')
elem.appendChild(resproc)
out = self.qti.createElement('outcomes')
resproc.appendChild(out)
komm = self.qti.createElement('qticomment')
komm.appendChild(self.qti.createTextNode(str(yled.arvutusTyyp)))
out.appendChild(komm)
muut = self.qti.createElement('decvar')
muut.setAttribute('vartype','Integer')
muut.setAttribute('maxvalue',str(yled.normPunktid))
out.appendChild(muut)
kond = self.qti.createElement('respcondition')
kond.setAttribute('title','Correct')
resproc.appendChild(kond)
kond_var = self.qti.createElement('conditionvar')
kond.appendChild(kond_var)
varless = self.qti.createElement('vargte')
varless.setAttribute('respident',yled.get_id())
varless.appendChild(self.qti.createTextNode(str(yled.alamPiir)))
kond_var.appendChild(varless)
varequal = self.qti.createElement('varequal')
varequal.setAttribute('respident',yled.get_id())
varequal.appendChild(self.qti.createTextNode(str(yled.oigeVastus)))
kond_var.appendChild(varequal)
varover = self.qti.createElement('varlte')
varover.setAttribute('respident',yled.get_id())
varover.appendChild(self.qti.createTextNode(str(yled.ylemPiir)))
kond_var.appendChild(varover)
setvar = self.qti.createElement('setvar')
setvar.setAttribute('action','Add')
setvar.appendChild(self.qti.createTextNode(str(yled.normPunktid)))
kond.appendChild(setvar)
pass
if tyyp=='ProtsentYlesanne':
elem = self.testiItem(sektion,yled)
self.testiKirjeldavTekst(elem,yled)
present = self.qti.createElement('presentation')
elem.appendChild(present)
flo = self.qti.createElement('flow')
present.appendChild(flo)
mat = self.qti.createElement('material')
flo.appendChild(mat)
mattext = self.qti.createElement('mattext')
mattext.appendChild(self.qti.createTextNode(yled.kysimus))
mat.appendChild(mattext)
self.testiViide(mat,yled)
self.testiPilt(mat,yled)
points = self.qti.createElement('points')
points_data = self.qti.createTextNode(str(yled.normPunktid))
points.appendChild(points_data)
elem.appendChild(points)
searching = self.qti.createElement('searching')
searching.appendChild(self.qti.createTextNode(str(yled.kysitav)))
elem.appendChild(searching)
solvent = self.qti.createElement('solvent') #lahus
min = self.qti.createElement('min')
min.appendChild(self.qti.createTextNode(str(yled.lahustiAlamPiir)))
max = self.qti.createElement('max')
max.appendChild(self.qti.createTextNode(str(yled.lahustiYlemPiir)))
names = self.qti.createElement('names')
names.appendChild(self.qti.createTextNode(str(yled.lahustiTekst)))
stype = self.qti.createElement('type')
stype.appendChild(self.qti.createTextNode(str(yled.lahustiYhik)))
solvent.appendChild(min)
solvent.appendChild(max)
solvent.appendChild(names)
solvent.appendChild(stype)
elem.appendChild(solvent)
soluble = self.qti.createElement('soluble') #aine
min = self.qti.createElement('min')
min.appendChild(self.qti.createTextNode(str(yled.aineAlamPiir)))
max = self.qti.createElement('max')
max.appendChild(self.qti.createTextNode(str(yled.aineYlemPiir)))
names = self.qti.createElement('names')
names.appendChild(self.qti.createTextNode(str(yled.aineTekst)))
stype = self.qti.createElement('type')
stype.appendChild(self.qti.createTextNode(str(yled.aineYhik)))
soluble.appendChild(min)
soluble.appendChild(max)
soluble.appendChild(names)
soluble.appendChild(stype)
elem.appendChild(soluble)
accuracy = self.qti.createElement('accuracy')
accuracy.appendChild(self.qti.createTextNode(str(yled.vastuseTapsusProtsent)))
elem.appendChild(accuracy)
scoring = self.qti.createElement('scoring')
scoring.appendChild(self.qti.createTextNode(str(yled.arvutusTyyp)))
elem.appendChild(scoring)
if tyyp=='VastavusYlesanne':
elem = self.testiItem(sektion,yled)
self.testiKirjeldavTekst(elem,yled)
present = self.qti.createElement('presentation')
elem.appendChild(present)
flo = self.qti.createElement('flow')
present.appendChild(flo)
mat = self.qti.createElement('material')
flo.appendChild(mat)
mattext = self.qti.createElement('mattext')
mattext.appendChild(self.qti.createTextNode(yled.kysimus))
mat.appendChild(mattext)
self.testiViide(mat,yled)
self.testiPilt(mat,yled)
resp_grp = self.qti.createElement('response_grp')
resp_grp.setAttribute('ident',yled.get_id())
resp_grp.setAttribute('rcardinality',"Multiple")
flo.appendChild(resp_grp)
render = self.qti.createElement('render_choice')
render.setAttribute('shuffle','Yes')
resp_grp.appendChild(render)
i=0
krupp = ''
for abc in yled.vastused:
resp_lab = self.qti.createElement('response_label')
ident = 'p'+str(i)
if krupp != '':
krupp = krupp+','
krupp = krupp + ident
resp_lab.setAttribute('ident',ident)
resp_lab.setAttribute('rshuffle','Yes')
resp_lab.setAttribute('rrange','Exact')
render.appendChild(resp_lab)
rmat = self.qti.createElement('material')
resp_lab.appendChild(rmat)
rmattext = self.qti.createElement('mattext')
rmattext.setAttribute('texttype','text/plain')
rmattext.appendChild(self.qti.createTextNode(abc))
rmat.appendChild(rmattext)
i=i+1
i=0
for abc in yled.kysimused:
resp_lab = self.qti.createElement('response_label')
resp_lab.setAttribute('ident','v'+str(i))
resp_lab.setAttribute('match_max','1')
resp_lab.setAttribute('match_group',krupp)
resp_lab.setAttribute('rshuffle','Yes')
resp_lab.setAttribute('rrange','Exact')
render.appendChild(resp_lab)
rmat = self.qti.createElement('material')
resp_lab.appendChild(rmat)
rmattext = self.qti.createElement('mattext')
rmattext.setAttribute('texttype','text/plain')
rmattext.appendChild(self.qti.createTextNode(abc))
rmat.appendChild(rmattext)
i=i+1
resproc = self.qti.createElement('resprocessing')
elem.appendChild(resproc)
out = self.qti.createElement('outcomes')
resproc.appendChild(out)
muut = self.qti.createElement('decvar')
muut.setAttribute('vartype','Integer')
muut.setAttribute('maxvalue',str(yled.normPunktid))
out.appendChild(muut)
kond = self.qti.createElement('respcondition')
kond.setAttribute('title','Correct')
resproc.appendChild(kond)
kond_var = self.qti.createElement('conditionvar')
kond.appendChild(kond_var)
jah = self.qti.createElement('and')
kond_var.appendChild(jah)
i=0
for abc in yled.vastused:
varsub = self.qti.createElement('varsubset')
varsub.setAttribute('respident',yled.get_id())
varsub.setAttribute('setmatch','Exact')
varsub.appendChild(self.qti.createTextNode('v'+str(i)+','+'p'+str(i)))
jah.appendChild(varsub)
i=i+1
setvar = self.qti.createElement('setvar')
setvar.setAttribute('action','Add')
setvar.appendChild(self.qti.createTextNode(str(yled.normPunktid)))
kond.appendChild(setvar)
pass
vanem.appendChild(sektion)
return
iva/JamArtefact.py 0100644 0000764 0000764 00000041236 10140215616 013437 0 ustar vahur vahur # -*- coding: utf-8
# $Id: JamArtefact.py,v 1.4 2003/08/18 07:44:24 berlingo Exp $
# 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
__version__ = '$Revision: 1.4 $'[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, translate
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()
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
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_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 REQUEST.RESPONSE.redirect('jam_artefact_index_html')
# 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)
prefix = translate(self,'Censored',target=self.giveLanguage(REQUEST))
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:
stamp = time.strftime(translate(self,'short_date_format',target=self.giveLanguage(REQUEST)),
time.localtime(censored))
prefix = 'censored %s %s' % (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 + \
'' + render(what,
legal_tags=normal_entry_tags,
do_horizontal_space=1)
else:
what = render(what,
legal_tags=normal_entry_tags,
do_horizontal_space=1)
anns.append((who, when, what, censored, censorer))
return anns
security.declarePrivate('get_real_annotations')
def get_real_annotations(self):
"""Return list of annotation tuples."""
return self.__annotations
security.declarePrivate('add_annotation')
def add_annotation(self, uname, annotation_time, annotation_text):
"""Add annotation to JamArtefact."""
# annotation censorship
censored = 0
censorer = ''
# uname and annotation_time can be used as a key attribute
self.__annotations.append((uname, annotation_time, annotation_text,
censored, censorer))
self._p_changed = 1
security.declarePrivate('do_censor_annotations')
def do_censor_annotations(self, annotation_indexes, time, user):
"""Censor annotation."""
for i in [int(x) for x in annotation_indexes]:
t = self.__annotations[i]
self.__annotations[i] = (t[0], t[1], t[2], time, user)
self._p_changed = 1
security.declarePrivate('do_uncensor_annotations')
def do_uncensor_annotations(self, annotation_indexes):
"""Uncensor annotation."""
for i in [int(x) for x in annotation_indexes]:
t = self.__annotations[i]
self.__annotations[i] = (t[0], t[1], t[2], 0, '')
self._p_changed = 1
security.declareProtected(perm_add_lo, 'add_annotation_form_handler')
def add_annotation_form_handler(
self,
REQUEST,
annotation_text,
submit = '', # form buttons
cancel = '', #
):
"""Add annotation form handler."""
user = str(REQUEST.AUTHENTICATED_USER)
if self.__censored and not self.may_censor_jam_artefact(user):
raise 'FLE Error', "I don't want to anything."
if submit:
time_now = time.time()
# FIXME: report that annotation_text doesn't work
if annotation_text:
self.add_annotation(user, time_now, annotation_text)
self.lisaSyndmus(REQUEST, 'lisatudMeediaAnnotatsioone')
self.tootoaMuutus('meediapaja')
elif cancel:
pass
else:
raise 'FLE Error', 'Unknown button.' # Should never happen.
REQUEST.RESPONSE.redirect('index_html')
security.declareProtected(perm_view, 'get_parent_ids')
def get_parent_ids(self):
"""Return a list of parent ids."""
if type(self.__parent_ids) == StringType:
return (self.__parent_ids,)
else:
return self.__parent_ids
security.declarePrivate('set_parent_ids')
def set_parent_ids(self, parent_ids):
"""Set parent ids."""
self.__parent_ids = parent_ids
security.declareProtected(perm_view, 'may_censor_jam_artefact')
def may_censor_jam_artefact(self, person):
"""Return boolean depending on whether user may or may not
censor jam artefacts."""
from AccessControl.PermissionRole import rolesForPermissionOn
return intersect_bool(
get_roles(self, person),
rolesForPermissionOn(perm_edit, self))
security.declareProtected(perm_edit, 'censor_jam_artefact_handler')
def censor_jam_artefact_handler(
self, REQUEST,
censor=None, # buttons in jam artefact page
uncensor=None, #
censor_annotations=None, #
uncensor_annotations=None, #
verify=None, # buttons in verify page
verify_annotations=None, #
cancel=None, #
annotation_indexes=(),
):
"""Handles jam_artefact censorship."""
if type(annotation_indexes) == StringType:
annotation_indexes = (annotation_indexes,)
if verify:
import time
self.do_censor(time.time(),str(REQUEST.AUTHENTICATED_USER))
if REQUEST:
return self.message_dialog(
self, REQUEST,
title='Message is censored',
message='Message is censored',
action='index_html')
if verify_annotations:
import time
self.do_censor_annotations(annotation_indexes,
time.time(),
str(REQUEST.AUTHENTICATED_USER))
if REQUEST:
return self.message_dialog(
self, REQUEST,
title='Annotation is censored',
message='Annotation is censored',
action='index_html')
elif cancel:
if REQUEST:
REQUEST.RESPONSE.redirect('index_html')
elif uncensor:
self.do_uncensor()
if REQUEST:
REQUEST.RESPONSE.redirect('index_html')
elif uncensor_annotations:
self.do_uncensor_annotations(annotation_indexes)
if REQUEST:
REQUEST.RESPONSE.redirect('index_html')
elif censor:
if REQUEST:
return self.message_dialog2(
self, REQUEST,
title='Warning',
message='Are you sure you want to censor this artefact? Your name and this date will be stored and displayed along with the censorship notice to everyone viewing this artefact.',
handler='censor_jam_artefact_handler',
extra_value_name='jam_artefact',
extra_values=(str(self.get_id()),),
option1_value = 'cancel',
option1_name = 'cancel',
option2_value = 'ok',
option2_name = 'verify')
elif censor_annotations:
if REQUEST:
return self.message_dialog2(
self, REQUEST,
title="Warning",
message="Are you sure you want to censor the annotations you selected? Your name and this date will be stored and displayed along with the censorship notice to everyone viewing annotations.",
handler='censor_jam_artefact_handler',
extra_value_name='annotation_indexes',
extra_values=annotation_indexes,
option1_value = 'Cancel',
option1_name = 'cancel',
option2_value = 'Ok',
option2_name = 'verify_annotations')
else:
raise 'FLE Error', 'Unknown button'
def do_censor(self, time, user):
self.__censored = time
self.__censorer = user
def do_uncensor(self):
self.__censored = 0
del self.__censorer
security.declareProtected(perm_view, 'is_censored')
def is_censored(self):
"""Return whether this jam artefact is censored."""
return not not self.__censored
security.declareProtected(perm_view, 'get_censor_time')
def get_censor_time(self, REQUEST):
"""Return time when the artefact was censored."""
return time.strftime(translate(self,'short_date_format',target=self.giveLanguage(REQUEST)),
time.localtime(self.__censored))
security.declareProtected(perm_view, 'get_censorer')
def get_censorer(self):
"""Return person who censored the artefact."""
return self.__censorer
Globals.default__class_init__(JamArtefact)
# EOF
iva/JamSession.py 0100644 0000764 0000764 00000024030 10137425152 013326 0 ustar vahur vahur # -*- coding: utf-8
# $Id: JamSession.py,v 1.4 2003/08/18 07:44:24 berlingo Exp $
# 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: 1.4 $'[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 reload_dtml, add_dtml, 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 """
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.lisaSyndmus(REQUEST, 'lisatudMeediaFaile')
self.tootoaMuutus('meediapaja')
self.add_artefact(artefact_name, data, content_type, parent_ids,
REQUEST)
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
iva/JamSessionGraph.py 0100644 0000764 0000764 00000033621 10146724607 014325 0 ustar vahur vahur # -*- coding: utf-8
# $Id: JamSessionGraph.py,v 1.4 2003/08/18 07:44:24 berlingo Exp $
# 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 classes LayeredGraph and JamSessionGraph."""
__version__ = '$Revision: 1.4 $'[11:-2]
try:
from PIL import Image, ImageDraw
except ImportError:
pass
import cStringIO
import Globals
from AccessControl import ClassSecurityInfo
from JamSession import JamSession
from common import perm_view, perm_edit, perm_manage, perm_add_lo
# The sole purpose of this class is to help JamSessionGraph.
# The code does not probably make too much sense unless you know something
# about graph drawing. The information used to implement this class comes
# from the book "Graph Drawing: Algorithms for the Visualization of Graphs"
class LayeredGraph:
"""This class helps to draw DAG as a layered graph."""
def __init__(self, V, E):
destination_nodes = []
for (u,v) in E:
destination_nodes.append(v)
self.__nodes = {}
for node in V:
self.__nodes[node] = {}
for node in V:
if node not in destination_nodes:
self.__start_node = node
break
self.__edges = E
self.__to_layered_graph()
self.__to_proper()
self.__reduce_crossings()
def get_representation(self):
G = {}
G['nodes'] = self.__nodes
G['edges'] = self.__edges
G['layers'] = self.__layers
return G
def __to_layered_graph(self):
nodes = self.__nodes
edges = self.__edges
# At this point every node is real, i.e. there are not dummy nodes.
done = []
todo = []
for node_name in nodes.keys():
nodes[node_name]['real'] = 1
if node_name == self.__start_node:
nodes[node_name]['layer'] = 0
done.append(node_name)
else:
nodes[node_name]['layer'] = -1
todo.append(node_name)
# Assign nodes to layers.
while len(todo) > 0:
for (u,v) in edges:
if (u not in done) or (v not in todo):
continue
# Node u is assigned to some layer.
# Node v does not has layer yet.
# We can assign a layer to v, if for all (x,v) in
# edges, node x already has an assigned layer...
ok = 1
u_nodes = []
for (a,b) in edges:
if b is not v: continue
if a not in done:
ok = 0
break
else:
u_nodes.append(a)
# ... no, that is not the case.
if not ok:
continue
# Yes, we can assign a layer to v.
layer = max([nodes[n]['layer'] for n in u_nodes])
nodes[v]['layer'] = layer + 1
done.append(v)
todo.remove(v)
def __to_proper(self):
nodes = self.__nodes
edges = self.__edges
# Make dummy nodes
i = 0
to_remove = []
for (u,v) in edges:
difference = nodes[v]['layer'] - nodes[u]['layer']
# All egdes that span several layers are replaced with
# dummy layers and short edges, e.g:
#
# layer 0 N N
# |\ |\
# layer 1 N | N D
# | | ==> | |
# layer 2 N | N D
# | |
# layer 3 N N
#
# N = node, D = dummy node
if difference > 1:
to_remove.append((u,v)) # remove the original edge later
layer = nodes[u]['layer'] + 1
a = u
while difference > 1:
b = 'dummy' + str(i)
# make edge
edges.append((a,b))
# make dummy node
dummy_node = {'layer': layer, 'real': 0}
nodes[b] = dummy_node
# update for next loop
a = b; i += 1; difference -= 1; layer +=1
edges.append((b,v)) # the edge from the last dummy node
# Actual removing
for (u,v) in to_remove:
edges.remove((u,v))
# Order of nodes on each layer. (Cross reduction phase
# will re-order nodes on each layer...)
layers = []
for i in range(0, max([nodes[node_name]['layer'] for \
node_name in nodes.keys()]) + 1):
layers.append([])
for node_name in nodes.keys():
l = nodes[node_name]['layer']
layers[l].append(node_name)
self.__layers = layers
def __n_crossings(self):
n = 0
for i in range(1, len(self.__layers)):
n += self.__crossing_number(i-1, i)
return n
def __crossing_number(self, layer_1_index, layer_2_index):
if layer_1_index > layer_2_index:
layer_1_index, layer_2_index = layer_2_index, layer_1_index
layer_1 = self.__layers[layer_1_index]
layer_2 = self.__layers[layer_2_index]
number = 0
for u in range(0, len(layer_2)):
for v in range(u+1, len(layer_2)):
u_pos = []
v_pos = []
for (a,b) in self.__edges:
if (a not in layer_1) or (b not in layer_2): continue
if b == layer_2[u]:
u_pos.append(layer_1.index(a))
elif b == layer_2[v]:
v_pos.append(layer_1.index(a))
for i in v_pos:
for j in u_pos:
if j > i: number += 1
return number
# Median method (not perfect, odd and even degree stuff is
# not implemented.)
def __two_layer_crossing_reduce(self,
fixed_layer_index,
changing_layer_index):
nodes = self.__nodes
layers = self.__layers
fixed_layer = layers[fixed_layer_index]
changing_layer = layers[changing_layer_index]
pos = []
for node_name in changing_layer:
neighbour_pos = []
for neighbour in nodes[node_name]['neighbours']:
if nodes[neighbour]['layer'] != fixed_layer_index: continue
neighbour_pos.append(fixed_layer.index(neighbour))
if len(neighbour_pos) > 0:
pos.append(neighbour_pos[len(neighbour_pos)/2])
else:
pos.append(0)
for j in range(0, len(pos)):
min_val = pow(2,30)
index = 0
for k in range(0, len(pos)):
if pos[k] >= 0 and pos[k] < min_val:
min_val = pos[k]
index = k
pos[index] = -len(pos) + j
for j in range(0,len(pos)):
pos[j] += len(pos)
new_layer = []
for j in range(len(changing_layer)):
new_layer.append(changing_layer[pos[j]])
layers[changing_layer_index] = new_layer
def __reduce_crossings(self):
nodes = self.__nodes
edges = self.__edges
# Add explicit neigbourhood information to each node
for node_name in nodes.keys():
nodes[node_name]['neighbours'] = []
for (u,v) in edges:
u_neighbours = nodes[u]['neighbours']
v_neighbours = nodes[v]['neighbours']
if v not in u_neighbours:
u_neighbours.append(v)
if u not in v_neighbours:
v_neighbours.append(u)
# Crossing reduction
r = range(1, len(self.__layers))
n_a = 0 # number of crossing after top to bottom sweep
n_b = 0 # number of crossing after bottom to top sweep
n_loops = 0
tested = []
min_val = pow(2,30)
while n_loops < 10 and ((n_a, n_b) not in tested or n_b > min_val):
n_loops += 1
tested.append((n_a, n_b))
# sweep from top to bottom...
for i in r: self.__two_layer_crossing_reduce(i-1, i)
n_a = self.__n_crossings()
r.reverse()
# ... and back from bottom to top.
for i in r: self.__two_layer_crossing_reduce(i, i-1)
n_b = self.__n_crossings()
r.reverse()
if n_b < min_val:
min_val = n_b
class JamSessionGraph(JamSession):
"""JamSessionGraph"""
meta_type = 'JamSession'
security= ClassSecurityInfo()
security.declareObjectPublic()
security.declareProtected(perm_view, 'get_type')
def get_type(self):
"""Return type of the JamSession."""
return 'graph'
security.declareProtected(perm_view, 'get_printable_type')
def get_printable_type(self):
"""Return printable (localized) type of the JamSession."""
return "Diverge and converge"
security.declarePrivate('update_drawing')
def update_drawing(self):
G = self.build_graph().get_representation()
# Assign horizontal positions for nodes ( real and dummy ones)
# FIXME: This code just puts nodes next to each other starting
# FIXME: from left.
columns = []
max_width = 0
for layer in G['layers']:
width = 0
cols = 0
for node_name in layer:
node = G['nodes'][node_name]
if node['real'] == 1:
node['position'] = width + 30 + 60
width += 5 * 30
else:
node['position'] = width + 15
width += 30
if width > max_width: max_width = width
columns.append(width / 30)
# How much we have to pad each (layer) row of the table?
for i in range(0, len(G['layers'])):
columns[i] = max_width/30 - columns[i]
G['width'] = max_width
G['columns'] = columns
G['n_nodes'] = n_nodes = len(
filter(lambda key, G=G: \
G['nodes'][key]['real'] == 1, G['nodes'].keys()))
# Delete old images.
self.manage_delObjects(self.objectIds('Image'))
# Draw new ones.
for i in range(1, len(G['layers'])):
im = Image.new('L', (max_width, 40), 255)
draw = ImageDraw.Draw(im)
for node_name in G['layers'][i]:
# If one node has several parent nodes, we want that
# incoming edges are separated:
#
# BAD! GOOD!
#
# \ | / \ | /
# \|/ \ | /
# **node** **node**
#
# Therefore, we put edges to the dictionary so that
# we can handle one node at a time.
to_draw = {}
for (u,v) in G['edges']:
if v == node_name:
if to_draw.has_key(v):
to_draw[v].append(u)
else:
to_draw[v]=[u]
# Loop over nodes
for v in to_draw.keys():
# Sort edges (u,v) by x-coordinate of u node...
data = []
for u in to_draw[v]:
data.append( (u, v, G['nodes'][u]['position']) )
data.sort(lambda x,y: ((x[2] <= y[2]) and [-1] or [1])[0])
# .. and then draw them from left to right
delta_delta = min(10, 100 / len(data))
delta = ((len(data)-1) / 2) * -delta_delta
for (u,v, dummy) in data:
draw.line([(G['nodes'][u]['position'], 0),
(G['nodes'][v]['position']+delta, 30),
(G['nodes'][v]['position']+delta, 40)],
fill=0)
# Draw arrow?
if G['nodes'][v]['real'] == 1:
draw.line([(G['nodes'][v]['position']+delta, 39),
(G['nodes'][v]['position']+delta-4,35)],
fill=0)
draw.line([(G['nodes'][v]['position']+delta, 39),
(G['nodes'][v]['position']+delta+4,35)],
fill=0)
delta += delta_delta
del draw
s = cStringIO.StringIO()
im.save(s, 'GIF')
s.seek(0)
content = s.read()
name = 'layer_' + str(i) + '_' + str(n_nodes)
self.manage_addImage(name, content, '')
self.drawing = G
security.declarePrivate('build_graph')
def build_graph(self):
V = []
E = []
for ja in self.get_children('JamArtefact'):
v = ja.get_id()
V.append(v)
for u in ja.get_parent_ids():
E.append((u,v))
return LayeredGraph(V, E)
Globals.default__class_init__(JamSessionGraph)
iva/JamSessionLinear.py 0100644 0000764 0000764 00000004154 10146724607 014475 0 ustar vahur vahur # -*- coding: utf-8
# $Id: JamSessionLinear.py,v 1.4 2003/08/18 07:44:24 berlingo Exp $
# 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
__version__ = '$Revision: 1.4 $'[11:-2]
import Globals
from AccessControl import ClassSecurityInfo
from JamSessionLinearOrTree import table
from JamSessionLinearOrTree import JamSessionLinearOrTree
from JamSession import JamSession
from common import perm_view, perm_edit, perm_manage, perm_add_lo
class JamSessionLinear(
JamSession,
JamSessionLinearOrTree,
):
"""JamSessionLinear"""
meta_type = 'JamSession'
security= ClassSecurityInfo()
security.declareObjectPublic()
security.declareProtected(perm_view, 'get_type')
def get_type(self):
"""Return type of the JamSession."""
return 'linear'
security.declareProtected(perm_view, 'get_printable_type')
def get_printable_type(self):
"""Return printable (localized) type of the JamSession."""
return "Mutate on previous"
security.declarePrivate(perm_view, 'update_drawing')
def update_drawing(self):
tree = self.build_tree(self.get_children('JamArtefact')[0])
t = table(('empty',None))
self.table_render_tree(tree, t, 1, 0)
for y in range(t.get_height()-2):
if t.get(0, y)[0] == '_selection':
t.set(0, y, ('empty', None))
self.drawing = t.get_repr()
Globals.default__class_init__(JamSessionLinear)
iva/JamSessionLinearOrTree.py 0100644 0000764 0000764 00000010420 10130153777 015604 0 ustar vahur vahur # -*- coding: utf-8
# $Id: JamSessionLinearOrTree.py,v 1.4 2003/08/18 07:44:24 berlingo Exp $
# 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
__version__ = '$Revision: 1.4 $'[11:-2]
import Globals
"""Simple two dimensional table."""
class table:
def __init__(self, empty_val):
self._t = []
self._w = 0
self._h = 0
self._empty_val = empty_val
def get_repr(self):
return self._t
def get_width(self):
return self._w
def get_height(self):
return self._h
def set(self, x, y, data):
if y >= self._h:
for i in range(y - self._h + 1):
self._t.append([self._empty_val] * self._w)
self._h = y + 1
if x >= self._w:
for i in range(self._h):
for j in range(x - self._w + 1):
self._t[i].append(self._empty_val)
self._w = x + 1
self._t[y][x] = data
def get(self, x, y):
return self._t[y][x]
def debug_print(self):
for row in self._t:
for data in row:
print data,
print
class JamSessionLinearOrTree:
"""JamSessionLinearOrTree"""
def build_tree(self, root_artefact):
return {'artefact_id': root_artefact.get_id(),
'children': [self.build_tree(x) for x in \
root_artefact.get_children_artefacts()]
}
# Render tree depth first, from left to right.
# The letters in 'ns', 'nes', 'esw', 'ew', 'sw' correspond
# to north, east, south, and west.
def table_render_tree(self, tree, table, x, y):
"""Render table into table"""
# Render this node...
table.set(x-1, y, ('_selection', tree['artefact_id']))
table.set(x, y, ('artefact', tree['artefact_id']))
ret_dim_info = [x]
# .. and then all of its children, from left to right.
if len(tree['children']) > 0:
table.set(x, y+1, ('ns', None)) # may be modified later
# leftmost child
dim_info = \
self.table_render_tree(tree['children'][0], table, x, y+2)
for d in dim_info:
ret_dim_info.append(d)
# the rest of children
for node in tree['children'][1:]:
# Figure out horizontal position for this node.
m = x
for i in range(self.left_depth(node)):
try: m = max(m, dim_info[i])
except IndexError: break # current branch deeper
# Draw stuff between left sibling (of this node) and this node.
sx = ret_dim_info[1]
if sx == x:
table.set(sx, y+1, ('nes', None))
else:
table.set(sx, y+1, ('esw', None))
for i in range(sx+1, m+2):
table.set(i, y+1, ('ew', None))
table.set(m+2, y+1, ('sw', None))
# Draw recursively this node.
dim_info = self.table_render_tree(node, table, m+2, y+2)
# Update red_dim_info.
for i in range(len(dim_info)):
try:
ret_dim_info[i+1] = max(ret_dim_info[i+1], dim_info[i])
except IndexError:
ret_dim_info.append(dim_info[i])
return ret_dim_info
def left_depth(self, node):
if len(node['children']) > 0:
return self.left_depth(node['children'][0]) + 1
else:
return 1
Globals.default__class_init__(JamSessionLinearOrTree)
iva/JamSessionTree.py 0100644 0000764 0000764 00000003735 10146724607 014166 0 ustar vahur vahur # -*- coding: utf-8
# $Id: JamSessionTree.py,v 1.4 2003/08/18 07:44:24 berlingo Exp $
# 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
__version__ = '$Revision: 1.4 $'[11:-2]
import Globals
from AccessControl import ClassSecurityInfo
from JamSessionLinearOrTree import table
from JamSessionLinearOrTree import JamSessionLinearOrTree
from JamSession import JamSession
from common import perm_view, perm_edit, perm_manage, perm_add_lo
class JamSessionTree(
JamSession,
JamSessionLinearOrTree,
):
"""JamSessionTree"""
meta_type = 'JamSession'
security= ClassSecurityInfo()
security.declareObjectPublic()
security.declareProtected(perm_view, 'get_type')
def get_type(self):
"""Return type of the JamSession."""
return 'tree'
security.declareProtected(perm_view, 'get_printable_type')
def get_printable_type(self):
"""Return printable (localized) type of the JamSession."""
return "Explore possibilities"
security.declarePrivate(perm_view, 'update_drawing')
def update_drawing(self):
tree = self.build_tree(self.get_children('JamArtefact')[0])
t = table(('empty',None))
self.table_render_tree(tree, t, 1, 0)
self.drawing = t.get_repr()
Globals.default__class_init__(JamSessionTree)
iva/Jamming.py 0100644 0000764 0000764 00000020605 10140433157 012637 0 ustar vahur vahur # -*- coding: utf-8
# $Id: Jamming.py,v 1.5 2003/08/18 07:44:24 berlingo Exp $
#
# 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 Jamming, which has a number of JamSessions."""
__version__ = '$Revision: 1.5 $'[11:-2]
import time
import OFS, Globals
from Globals import Persistent
from AccessControl import ClassSecurityInfo
from Cruft import Cruft
from JamSessionLinear import JamSessionLinear
from JamSessionTree import JamSessionTree
from JamSessionGraph import JamSessionGraph
from TraversableWrapper import Traversable
from common import add_dtml, reload_dtml, intersect_bool, make_action, translate
from common import perm_view, perm_edit, perm_manage, perm_add_lo
from input_checks import is_valid_title
"""A container for JamSessions. The only reason we really need this
class is for implementing Jamming tab by using own fle_html_header here."""
class Jamming(
Traversable,
Cruft, # for find_URL_of_fle_root()
Persistent,
OFS.Folder.Folder,
):
"""Jamming, contained within Course, represents jamming for
one course."""
meta_type = 'Jamming'
security = ClassSecurityInfo()
security.declareObjectPublic()
def __init__(self, id_):
"""Constructor of the Jamming."""
self.id = id_
self.title = 'Jamming, container for JamSessions'
# This is for group folder path listings - show path up to jamming.
self.toplevel = 1
security.declareProtected(perm_view, 'index_html')
def index_html(self,REQUEST):
""" index html """
return REQUEST.RESPONSE.redirect('jamming_index_html')
security.declareProtected(perm_view, 'get_bg_colour_name')
def get_bg_colour_name(self):
"""..."""
return 'bl'
def get_name(self):
"""Get course name."""
return "jamming"
security.declareProtected(perm_view, 'get_n_jam_sessions')
def get_n_jam_sessions(self):
"""Return number of JamSessions in (the jamming of) this course."""
return len(self.get_children('JamSession'))
security.declareProtected(perm_view, 'get_n_artefacts')
def get_n_artefacts(self):
"""Return total number of JamArtefact in this jamming."""
n = 0
for js in self.get_children('JamSession'):
n += js.get_n_artefacts()
return n
security.declareProtected(perm_view, 'get_n_unread_artefacts')
def get_n_unread_artefacts(self, REQUEST):
"""Return total number of unread JamArtefact in this jamming."""
n = 0
for js in self.get_children('JamSession'):
n += js.get_n_unread_artefacts(REQUEST)
return n
security.declareProtected(perm_edit, 'delete_jam_session_handler')
def delete_jam_sessions_handler(
self,
REQUEST,
jam_session_id_list):
"""Form handler for deleting JamSessions."""
return self.message_dialog2(
self, REQUEST,
title = 'Confirmation',
message = translate(self, 'Are you sure you want to delete the following jam sessions:', target=self.giveLanguage(REQUEST)) + ' ' + \
', '.join([self.get_child(js_id).get_name() for \
js_id in jam_session_id_list]),
handler = 'delete_jam_sessions_confirmation_form_handler',
extra_value_name = 'jam_session_id_list',
extra_values = jam_session_id_list,
option1_value = 'Cancel',
option1_name = 'cancel',
option2_value = 'Ok',
option2_name = 'delete'
)
security.declareProtected(perm_edit,
'delete_jam_sessions_confirmation__handler')
def delete_jam_sessions_confirmation_form_handler(
self,
REQUEST,
jam_session_id_list,
cancel='', # submit buttons
delete='',
):
"""Delete jam sessions."""
if delete:
for js_id in jam_session_id_list:
self._delObject(js_id)
elif cancel:
pass
else:
raise 'FLE Error', 'Unknown button'
REQUEST.RESPONSE.redirect('index_html')
security.declareProtected(perm_add_lo, 'form_handler')
def form_handler(
self,
my_name = '',
type = None, # 'linear', 'tree', or 'graph'
description = None,
artefact_name = None,
artefact_upload = None,
annotation = '',
submit = '', # submit buttons
cancel = '', #
REQUEST = None,
):
"""Form handler for creating new JamSession."""
if submit:
if type == 'graph' and not self.has_PIL():
# Users are not able to select graph type from UI if PIL is
# not installed so this never happens unless input is hacked.
raise 'FLE Error', 'PIL not installed'
error_fields = []
my_name = my_name.strip()
if not is_valid_title(my_name):
error_fields.append(translate(self,'Title of jam session:',target=self.giveLanguage(REQUEST)))
if not description:
error_fields.append(translate(self,'Description of jam session:',target=self.giveLanguage(REQUEST)))
if type not in ('linear', 'tree', 'graph'):
error_fields.append(translate(self,'Type of jam session:',target=self.giveLanguage(REQUEST)))
if not artefact_upload or len(artefact_upload.filename)==0:
error_fields.append(translate(self,'Upload the starting artefact:',target=self.giveLanguage(REQUEST)))
if not is_valid_title(artefact_name):
error_fields.append(translate(self,'Name of the starting artefact:',target=self.giveLanguage(REQUEST)))
import re
tmp = error_fields
error_fields = []
for x in tmp:
error_fields.append(re.sub(':','',x))
if len(error_fields) > 0:
msg = translate(self,'Invalid fields',target=self.giveLanguage(REQUEST)) + ": '" + \
"' , '".join(error_fields) + "'"
return self.message_dialog_error(
self, REQUEST,
title= 'Invalid input',
message=msg,
action=apply(
make_action,
['jam_add_session_form'] +
[(x, eval(x)) for x in
('my_name', 'description', 'type', 'artefact_name',
'annotation')]))
data = artefact_upload.read()
try:
content_type = artefact_upload.headers['content-type']
except KeyError:
content_type = ''
id_ = 'js' + self.parent().parent().generate_id()
jam_session_class = {'linear': JamSessionLinear,
'tree': JamSessionTree,
'graph': JamSessionGraph}[type]
self._setObject(id_, jam_session_class(
id_,
my_name,
description,
artefact_name, # starting artefact
data, #
content_type, #
))
if REQUEST:
self.lisaSyndmus(REQUEST, 'lisatudMeedia')
self.tootoaMuutus('meediapaja')
ja = self._getOb(id_).get_children('JamArtefact')[0]
uname = repr(REQUEST.AUTHENTICATED_USER)
ja.update_reader(uname)
if annotation:
ja.add_annotation(uname, time.time(), annotation)
elif cancel:
pass
else:
raise 'FLE Error', 'Unknown button' # Should never happen.
if REQUEST:
REQUEST.RESPONSE.redirect('index_html')
else: # import code
return self.get_child(id_)
Globals.default__class_init__(Jamming)
# EOF
iva/Kalender.py 0100644 0000764 0000764 00000034405 10146427717 013020 0 ustar vahur vahur # -*- coding: utf-8
# 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
import AccessControl
import OFS, Globals
from OFS import SimpleItem
import types
import time
from TraversableWrapper import Traversable
from Globals import Persistent
from AccessControl import ClassSecurityInfo
from Cruft import Cruft
from common import add_dtml, translate
class KalendriSyndmus(
OFS.SimpleItem.Item,
Persistent,
AccessControl.Role.RoleManager,
Traversable,
Cruft
):
""" Teade kalendris """
meta_type = 'Event'
security = ClassSecurityInfo()
security.declareObjectPublic()
def __init__(self, nimi, lyhi='', pikk='', algus=-1, lopp=-1, viide="", siseviide="", olek=0,blokerid=[]):
"Alustus"
if algus == -1:
algus = time.time()
if lopp == -1:
lopp = time.time()
self.nimi=nimi
self.lyhi=lyhi
self.pikk=pikk
self.algus=algus
self.lopp=lopp
self.viide=viide
self.siseviide=siseviide
self.blokerid = []
self.olek=olek #0-ajatu sündmus 1-lõpetamata töö 2-lõpetatud töö
self.icon_tag=None
def kysiNimi(self):
"Teate nimi"
return self.nimi
def getIconTag(self):
if not hasattr(self,'icon_tag'):
self.icon_tag = None
if self.icon_tag is not None:
result = ""
else:
result = ""
return result
def setIconTag(self,path):
self.icon_tag = path
self.icon_tag = self.icon_tag
return self.icon_tag
def kysiLyhi(self):
"Lühikirjeldus"
return self.lyhi
def kysiPikk(self):
"Pikk kirjeldus"
return self.pikk
security.declarePublic('kysiAlgus')
def kysiAlgus(self):
"Syndmuse algusaeg"
return self.algus
def kysiLopp(self):
"Syndmuse lõppaeg"
return self.lopp
def aegTekstina(self, REQUEST, aeg, timestamp=''):
"tekstiesitus"
if aeg==-1: return "*"
if not timestamp:
timestamp = translate(self,'timestamp_format',target=self.giveLanguage(REQUEST))
else:
timestamp = REQUEST[timestamp]
return time.strftime(timestamp, time.localtime(aeg))
def tekstAjana(self, REQUEST, ajatekst):
"Tagasi ajaformaati"
return mktime(time.strptime(translate(self,'timestamp_format',target=self.giveLanguage(REQUEST))), ajatekst)
def kysiViide(self):
"Välisviide"
return self.viide
def kysiSiseviide(self):
"Siseviide"
return self.siseviide
def kysiSiseviiteURL(self):
"Siseviide"
return self.fle_root().absolute_url()+self.siseviide
def siseviiteNimi(self):
"Nagu funktsiooni nime ütleb"
import re
if self.siseviide=="": return ""
m=self.siseviide.split("/")
o=self.fle_root()
try:
for x in m:
if len(x)>0:
o=getattr(o, re.sub('%20',' ',x))
except:
return ""
return o.get_name()
#return getattr(self.fle_root(), self.siseviide)
#return str(self.get_object_of_url(self.siseviide, self.fle_root()))
def kysiSiseviiteLink(self):
"Koos"
return ""+self.siseviiteNimi()+""
def kysiOlek(self):
"Sündmuse olek"
if hasattr(self, 'olek'): return self.olek
return 0
def getPersonalStatus(self,REQUEST):
""" """
if hasattr(self, 'status_'+str(REQUEST.AUTHENTICATED_USER)):
return getattr(self,'status_'+str(REQUEST.AUTHENTICATED_USER))
else:
return 0
return 0
def olekuTekst(self, REQUEST, nr=-1):
"Olek tekstina"
if nr==-1: nr=self.kysiOlek()
if nr==0: return ""
if nr==1: return "incomplete"
if nr==2: return "complete"
def olekuLahter(self, REQUEST):
"Olekut illustreeriv lahter"
if self.kysiOlek()==0:
return "
"
if self.kysiOlek()==1: #pooleli
if time.time()>self.lopp: #Hilinenud
return "
"
else: return "
"
return "
"
def olekuVarv(self, REQUEST):
"Olekut illustreeriv lahter"
if self.getPersonalStatus(REQUEST):
stat = self.getPersonalStatus(REQUEST)
else:
stat = self.kysiOlek()
if stat==0:
return "\"black\""
if stat==1: #pooleli
if time.time()>self.lopp: #Hilinenud
return "\"red\""
else: return "\"blue\""
return "\"green\""
def tabeliRida(self, REQUEST):
"Osa tabelist"
tulemus="
"+\
self._tabeliReaSisu(REQUEST)+"
\n"
return tulemus
def muutmisTabeliRida(self, REQUEST,select=0,omanik=0,timestamp=''):
"Osa tabelist"
tulemus="
"
kast="
"
kast += "
"
if omanik:
if self.kysiOmanik().getUserName()==REQUEST.AUTHENTICATED_USER.getUserName() and self.asukohaNimi()==None:
tulemus+=kast
else:
tulemus+="
\n"
return tulemus
def _tabeliReaSisu(self, REQUEST, timestamp=''):
"Abitükk teistele"
# FIXFIX: stupid url checking...
asukoht = REQUEST.URL0.split("/")
if not asukoht[-1] == "syndmusteMuutmisVorm" and not asukoht[-1] == "kalendriPaevaSyndmusteLoetelu":
tulemus = "
"
# self.aegTekstina(REQUEST, self.kysiAlgus())+\
# if self.kysiOmanik().getUserName()==REQUEST.AUTHENTICATED_USER.getUserName():
# tulemus=tulemus+self.kysiLyhi()
# else:
# tulemus=tulemus+self.kysiLyhi()+" " #võõras sündmus
# tulemus=tulemus+""
return tulemus
def asukohaNimi(self):
"Kursuse nimi, kus sündmus asub, muu sündmuse puhul None"
aadress=self.absolute_url()
algus=aadress.find('courses')
if algus>=0:
nr=aadress[algus:].split("/")[1]
t=getattr(self.fle_root().courses, nr).get_name()
m=aadress[algus:].split("/")
for i in range(len(m)):
if m[i]=="subgroups" and i+1\n"+self.vaatamisSisu(REQUEST)
tulemus=tulemus+self.fle_html_footer(self, REQUEST)
return tulemus
def userStatus(self,REQUEST,submitt='',olek='',userLocation=''):
""" User changes event status for himself """
if not submitt:
return
if not olek:
return
keyword = 'status_'+str(REQUEST.AUTHENTICATED_USER)
try:
setattr(self, keyword,int(olek))
except:
return "something happened"
return REQUEST.RESPONSE.redirect(self.absolute_url()+'?userLocation='+userLocation)
def muutmisLeht(self, REQUEST,userLocation=''):
"Sündmuse muutus"
import YlTest
from YlTest import LahendusLuba
abi=LahendusLuba() #vaid ajamenüü tarbeks
self.algus=abi.ajaPyydmisLeht(REQUEST, "algus")
self.lopp=abi.ajaPyydmisLeht(REQUEST, "lopp")
if self.lopp=algusmp and aegmp"
for syndmus in loetelu:
tulemus=tulemus+syndmus.tabeliRida(REQUEST)
tulemus=tulemus+""+self.fle_html_footer(self,REQUEST)
return tulemus
def index_html(self, REQUEST):
"tabel"
return self.event_list()
def syndmusteMuutmisLeht(self, REQUEST, kustutus=(),backlink='',userLocation="Organizer"):
"Sündmuste kustutamine"
if type(kustutus)==types.StringType:
kustutus=(kustutus,)
eurl = self.absolute_url()
for x in kustutus:
self._delObject(x.split('/')[-1])
#REQUEST.RESPONSE.redirect('syndmusteMuutmisVorm')
if backlink:
return REQUEST.RESPONSE.redirect(backlink)
return REQUEST.RESPONSE.redirect(REQUEST.HTTP_REFERER)
# return self.event_list()
def addEvent(self, REQUEST,userLocation='Organizer'):
"Uus sündmus"
nr='event'+str(self.kysiUusNr())
k=KalendriSyndmus(nr)
if hasattr(REQUEST, 'etime'):
timesta = time.localtime(time.time())
t_algus = []
t_algus.append(int(REQUEST.etime[:4]))
t_algus.append(int(REQUEST.etime[4:6]))
t_algus.append(int(REQUEST.etime[6:]))
for x in timesta[3:]:
t_algus.append(x)
k.algus = time.mktime(t_algus)
k.lopp = k.algus
k.id=nr
self._setObject(nr, k)
# REQUEST.RESPONSE.redirect(nr+"/muutmisVorm")
return REQUEST.RESPONSE.redirect(nr+'/changeEvent?userLocation='+userLocation)
def lisaSyndmusKohe(self, nimi, lyhi, pikk, start, end, url, res, status):
nr = str(self.kysiUusNr())
k = KalendriSyndmus(nimi, lyhi, pikk, start, end, url, res, status)
k.id = nr
self._setObject(nr, k)
return k
def syndmusteKogum(self,REQUEST=None, mida='', sort='', previous='', etime='', private=''):
# for use in event_list ZPT
return self.objectValues()
iva/Kirjakast.py 0100644 0000764 0000764 00000021731 10166766406 013217 0 ustar vahur vahur # -*- coding: utf-8
# 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
from common import translate
import AccessControl
import OFS, Globals
from OFS import SimpleItem
import types
import time
from TraversableWrapper import Traversable
from Globals import Persistent
from AccessControl import ClassSecurityInfo
from Cruft import Cruft
class Kiri(
OFS.SimpleItem.Item,
Persistent,
AccessControl.Role.RoleManager,
Traversable,
Cruft,
):
"Message in inbox"
def __init__(self, pealkiri, sisu, saatja, saaja, remote_id):
"Kirja loomine"
self.pealkiri=pealkiri
self.sisu=sisu
self.saatja=saatja
self.loomisaeg=time.time()
self.loetud=0
self.saaja = saaja
self.remote_id = remote_id
def kysiPealkiri(self):
"Pealkirja kysimine"
if self.pealkiri == "":
self.pealkiri = "(untitled)"
return self.pealkiri
def kysiSisu(self,sup=''):
"Sisu kysimine"
import re
if sup == 1: sup = '\n'
if sup:
return re.sub(' ',sup,self.sisu)
else:
return self.sisu
def kysiSaatja(self):
return self.saatja
def kasOmaKoopia(self):
if hasattr(self, 'omakopi'):
return self.omakopi
return 0
def kysiSaatja_nimega(self):
"Saatja kysimine"
try:
saatja = getattr(self.fle_root().fle_users, self.saatja)
# return saatja.firstAndLast()
if saatja.get_first_name()!="" and saatja.get_last_name()!="":
vastus = saatja.get_first_name()
vastus += " "
vastus += saatja.get_last_name()
else:
vastus = saatja.get_uname()
return vastus
except:
return self.saatja
def kysiAeg(self):
"Aja kysimine"
# FIX:
# return self.aeg
return self.loomisaeg
def kysiAegTekstina(self, REQUEST):
"Saatmisaeg"
return self.aegTekstina(REQUEST, self.loomisaeg)
def aegTekstina(self, REQUEST, aeg):
"tekstiesitus"
if aeg==-1: return "*"
return time.strftime(translate(self,'timestamp_format',target=self.giveLanguage(REQUEST)), time.localtime(aeg))
def kasLoetud(self):
"Kas loetud"
return self.loetud
def setRemoteRead(self,REQUEST):
""" set mail read in senders mailbox """
k = self.fle_root().fle_users
try:
kasutaja = getattr(k, self.saatja).kysiKirjadeKataloog()
except AttributeError:
return 0
# tulemus += "
"+self.remote_id+"
"
# mis siis kui kasutaja 7 korda kirja avab? :)
try:
saatja_kopi = getattr(kasutaja, self.remote_id)
setattr(saatja_kopi, str(REQUEST.AUTHENTICATED_USER)+"_hasread" ,1)
except:
pass
return 1
def index_html(self, REQUEST,userLocation=''):
"Valjastus"
self.loetud=1
REQUEST.set('userLocation',userLocation)
return self.mail_index()
class Kirjakast(
OFS.Folder.Folder,
OFS.SimpleItem.Item,
Persistent,
AccessControl.Role.RoleManager,
Traversable,
Cruft
):
kirjaNr=0
uusiKirju=0
def index_html(self, REQUEST,userLocation=''):
""" index_html """
REQUEST.set('userLocation',userLocation)
return REQUEST.RESPONSE.redirect(self.absolute_url()+'/mailbox_index')
return self.fle_root().mailbox_index(self, REQUEST)
def listMessages(self,REQUEST):
""" list messsage objects
location == 1 == outbox else inbox
"""
if hasattr(REQUEST, 'mblocation'):
mblocation = REQUEST.mblocation
else:
mblocation = 0
if mblocation == 0:
self.uusiKirju = 0
messages = []
for mess in self.objectValues():
if mblocation and hasattr(mess, 'omakopi'):
messages.append(mess)
if not mblocation and not hasattr(mess, 'omakopi'):
messages.append(mess)
return messages
def kirjakastiMuutus(self, REQUEST, kiri=(),userLocation='Organizer'):
"Esiotsa vaid kustutamine"
REQUEST.set('userLocation',userLocation)
if type(kiri)==types.StringType:
kiri=(kiri,)
for x in kiri:
self._delObject(x)
return self.mailbox_index()
REQUEST.RESPONSE.redirect('mailbox_index')
def lisaKiri(self, REQUEST=None, pealkiri='', sisu='', saatja='', saaja='', remote_id=''):
"Kirja lisamine kasti"
import re
self.uusiKirju=1
k=Kiri(pealkiri, re.sub('\n', ' ', sisu), saatja, saaja, remote_id)
self.kirjaNr=self.kirjaNr+1
kirjanimi="kiri"+str(self.kirjaNr)
k.id=kirjanimi
self._setObject(kirjanimi, k)
if REQUEST:
return k.id
else:
return k
def kasUusiKirju(self, REQUEST):
"jah/ei"
return self.uusiKirju
def kirjaSaatmiseLeht(self, REQUEST, kellele, pealkiri, sisu, lisa='', s_kellele='',userLocation='Organizer'):
"Saatmine, kellele on inimeste komadega eraldatud loetelu"
REQUEST.set('userLocation',userLocation)
kiri_saadetud=[]
if REQUEST.SESSION.has_key('kellele'):
REQUEST.SESSION.delete('kellele')
if lisa:
if kellele:
kellele += ", "
kellele += s_kellele
REQUEST.set('kellele', kellele)
# REQUEST.RESPONSE.redirect('createMail?request='+REQUEST)
# REQUEST.RESPONSE.redirect('createMail?kellele='+kellele+'&pealkiri='+pealkiri+'&sisu='+sisu)
return self.createMail()
if not kellele:
REQUEST.set('emptyto','1')
# REQUEST.RESPONSE.redirect('kirjaKoostamiseVorm?kellele='+kellele+'&pealkiri='+pealkiri+'&sisu='+sisu+'&error=1')
return self.createMail()
# tulemus=self.hdr(self, REQUEST)
saaja = kellele
omakopi_id = self.omakoopia(REQUEST, kellele,saaja,pealkiri,sisu)
kellele=kellele.split(',')
for i in range(len(kellele)):
kellele[i]=kellele[i].strip()
# tulemus=tulemus+"
\n
"
result = []
for kasutaja in kellele:
# tulemus=tulemus+kasutaja
tulemus = []
tulemus.append(kasutaja)
if kasutaja not in kiri_saadetud:
kass = self.saadaKiri(REQUEST, kasutaja, saaja, pealkiri, sisu, omakopi_id)
kiri_saadetud.append(kasutaja)
else:
tulemus.append('No double postings')
continue
if kass[0] != 0:
tulemus.append('Internal mail message was sent succesfully')
else:
tulemus.append('Internal mail message failed')
if kass[1] == 0:
tulemus.append('E-mail failed')
if kass[1] != 3 and kass[1] !=0:
tulemus.append('E-mail was sent succesfully')
result.append(tulemus)
# tulemus += "
\n"
# tulemus=tulemus+self.fle_html_footer(self, REQUEST)
return self.mailStatus(result=result)
def saadaKiri(self, REQUEST, kellele, saaja, pealkiri, sisu, remote_id,fleroot=''):
"Kellele on yks inimene"
if fleroot:
k = fleroot
else:
k=self.fle_root().fle_users
if not hasattr(k, kellele): return 0,0
kasutaja = k.get_user_info(kellele)
saatja = k.get_user_info(str(REQUEST.AUTHENTICATED_USER))
try:
if saatja.get_first_name()!='' and saatja.get_last_name()!='':
lisa_saatja = saatja.get_first_name()+" "+saatja.get_last_name()
else:
lisa_saatja = saatja.get_uname()
if kasutaja.email_kirjad == 1 and kasutaja.get_email():
raport = self.saadaEmail(kasutaja.get_email().strip(),pealkiri,sisu+"\n\n\n"+\
lisa_saatja,saatja.get_email().strip())
except:
pass
kirja_id = getattr(k, kellele).kysiKirjadeKataloog().lisaKiri(REQUEST, pealkiri, sisu, str(REQUEST.AUTHENTICATED_USER), saaja, remote_id)
try:
if raport == 999:
pass
except:
raport = 3
return kirja_id,raport
def omakoopia(self, REQUEST, kellele,saaja, pealkiri,sisu):
# k=self.fle_root().fle_users
# outbox = getattr(k, str(REQUEST.AUTHENTICATED_USER)).kysiKirjadeKataloog()
# sisu = "Kiri saadetud: "+kellele+"
"+sisu
kirja_id = self.lisaKiri(REQUEST, pealkiri, sisu, str(REQUEST.AUTHENTICATED_USER), saaja, '9999')
uuskiri = getattr(self,kirja_id)
uuskiri.omakopi = 1
return kirja_id
iva/Kodutoo.py 0100644 0000764 0000764 00000053771 10166520533 012716 0 ustar vahur vahur # -*- coding: utf-8
# 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
import AccessControl
import OFS, Globals
from OFS import SimpleItem
import types
import time
import re
from TraversableWrapper import Traversable
from Globals import Persistent, PersistentMapping
from AccessControl import ClassSecurityInfo
from AccessControl import allow_module, allow_class, allow_type
from Cruft import Cruft
from common import add_dtml, translate, perm_edit, perm_view
class Kodutoo(
OFS.SimpleItem.Item,
Persistent,
AccessControl.Role.RoleManager,
Traversable,
Cruft
):
meta_type = 'Assignment'
security = ClassSecurityInfo()
""" Assignment object """
def __init__(self, REQUEST, tyyp, kirjeldus="",
normPunkte=0,kalendriID=None):
""" init """
self.tyyp=int(tyyp)
self.kirjeldus=kirjeldus
self.pealkiri = ""
#self.loppaeg=None #Esituspiiri pole määratud. no deadline
# now we always have deadline
self.loppaeg = time.time()
self.normPunkte=normPunkte
self.kalendriID=None #kalendrisyndmuse id. event id.
self.hwID = None #assignment id. for peer review only.
self.testiID = None #quiz id. for quiz type assignment only.
self.reviewMapping = PersistentMapping()
self.lockingFolder = None
def manage_afterAdd(self, item, container):
container.grades[self.id] = {}
def lockFolder(self):
""" lock folder """
#XXX:hasattr remove
if not hasattr(self, 'lockingFolder'):
self.lockingFolder = 0
return self.lockingFolder
def getAssignmentID(self):
if not hasattr(self, 'hwID'):
return ""
return self.hwID
def setAssignmentID(self,hwID):
self.hwID = hwID
def get_id(self):
return self.id
def getDeadline(self, REQUEST):
return time.strftime(translate(self,'timestamp_format',target=self.giveLanguage(REQUEST)), time.localtime(self.loppaeg))
def getGrades(self,user,detail=''):
""" doc string """
gradesObj = getattr(self, 'grades')
if not gradesObj.has_key(self.get_id()):
gradesObj[self.get_id()] = {}
grades = gradesObj[self.get_id()]
if not grades.has_key(user):
value = float(0)
self.setUserPoints(self.get_id(), user, detail, value)
if not gradesObj['Overall'].has_key(user):
gradesObj['Overall'][user] = {}
return grades[user][detail]
def getRawType(self):
""" return assignment type as integer """
return self.tyyp
def getType(self, REQUEST):
""" get assignment type word """
return self.getTypes(REQUEST)[self.tyyp]
def getPoints(self):
""" get assignment value in points """
return self.normPunkte
def quizID(self):
try:
return self.testiID
except AttributeError:
return None
def getTitle(self, REQUEST=None):
"Antakse kui on"
if len(self.pealkiri.strip())==0:
return "(untitled)"
return self.pealkiri
def getGroups(self):
""" gets groupwork groups"""
if not hasattr(self, 'grupid'):
self.grupid = []
return self.grupid
def kodutooMaterjal(self,bs, tulem='',level=1):
i=1
aste=""
if not hasattr(self, 'juhend'):
self.juhend = ""
while i!=level:
aste += "--"
i=i+1
for obj in bs.list_contents(criteria='weight'):
s=obj.absolute_url()[len(self.fle_root().absolute_url()):]
tulem += "\n"
if obj.meta_type == 'WebtopFolder' and not obj.kasWikiKaust():
tulem = self.kodutooMaterjal(obj,tulem,level+1)
return tulem
def getReviewers(self,uname):
""" return a list who's work users must review """
if not hasattr(self, 'reviewMapping'):
self.reviewMapping = PersistentMapping()
try:
return self.reviewMapping[uname]
except KeyError:
return []
def maxReviewers(self):
max = -1
for x in self.reviewMapping.keys():
if len(self.reviewMapping[x])>max:
max = len(self.reviewMapping[x])
return max
def countReviewer(self,uname):
count = 0
for x in self.reviewMapping.keys():
if uname in self.reviewMapping[x]:
count = count +1
return count
def getLinkToAssignment(self, uname, c_id, asID):
""" return url to user's webtop. Needed only for Peer review. tyyp==4 """
if asID is None: return ""
try:
path = getattr(self.fle_root().fle_users, uname).webtop
path = getattr(path, 'c'+c_id).esitlused
path = getattr(path, asID)
except AttributeError:
return ""
url = path.absolute_url()+'/'
return url
security.declareProtected(perm_edit, 'automaticMatching')
def automaticMatching(self, REQUEST, courseid, randomize, number, number2):
""" automatically divide users """
course = getattr(self.fle_root().courses, courseid)
users = course.get_all_users()
from random import choice
for x in users:
self.reviewMapping[x.get_uname()] = []
for i in range(0,number):
nameObj = choice(users)
ring = 1
stopp = 0
while (x.get_uname() == nameObj.get_uname() or self.countReviewer(nameObj.get_uname())>number2-1) and stopp==0:
print x.get_uname(),' - ',nameObj.get_uname(),' - ',self.countReviewer(nameObj.get_uname())
nameObj = choice(users)
ring = ring + 1
if ring>50:
print "ring juba liiga suur!"
stopp = 1
if not stopp:
self.addPeerReviewMatching(0,x.get_uname(),nameObj.get_uname(),r_add=1)
else:
#XXX: try finding available person
for j in users:
if self.countReviewer(j.get_uname())"+ translate(self,'Deadline updated: ',target=self.giveLanguage(REQUEST))
if self.loppaeg !=None:
s_pikk += time.strftime(translate(self,'timestamp_format',target=self.giveLanguage(REQUEST)), time.localtime(self.loppaeg))
else:
s_pikk += translate(self, 'No deadline',target=self.giveLanguage(REQUEST))
s_end = self.loppaeg
if eelmine_punktid != self.normPunkte:
s_pikk += " "+translate(self,'Points changed:',target=self.giveLanguage(REQUEST))+" "+str(self.normPunkte)
syndmused._delObject(too_syndmus.id)
wiga = 0
except:
pass
if wiga:
s_end = time.time()
if hasattr(REQUEST, 'kasLoppaeg'):
s_end = abi.ajaPyydmisLeht(REQUEST, 'loppaeg')
s_pikk = translate(self,'New task added', target=self.giveLanguage(REQUEST))+" "+self.pealkiri+"("+kt_tyyp+") "+self.kirjeldus+" "
s_pikk += translate(self,'Points:',target=self.giveLanguage(REQUEST))+" "+str(self.normPunkte)
if self.tyyp != 0 and self.tyyp != 3:
s_pikk += " "+translate(self,'Deadline:',target=self.giveLanguage(REQUEST))
s_pikk += time.strftime(translate(self,'timestamp_format',target=self.giveLanguage(REQUEST)), time.localtime(s_end))
try:
s_algus = s_end
except:
s_algus = time.time()
s_end = time.time()
too_syndmus = syndmused.lisaSyndmusKohe(s_nimi,s_lyhi,s_pikk,s_algus,s_end,'',self.juhend,s_status)
too_syndmus.setIconTag('images/kodune')
if self.tyyp == 2:
uusID.append(too_syndmus.id)
else:
uusID = too_syndmus.id
#self.kalendriID = too_syndmus.id
self.kalendriID = uusID
REQUEST.RESPONSE.redirect('../manage_assignments')
def assignmentGrading_handler(self, REQUEST, save, user, points, comment):
""" assignmentGrading form handler. Saves user grade """
try:
points = float(points)
except:
return self.message_dialog(message='Invalid value for points. Must be numerical!')
if self.tyyp!=2:
self.setUserPoints(self.get_id(), user, 'points', points)
self.setUserPoints(self.get_id(), user, 'comment', comment)
if self.tyyp==2:
for x in self.kasutajad_sisegrupis(user):
self.setUserPoints(self.get_id(), x, 'points', points)
self.setUserPoints(self.get_id(), x, 'comment', comment)
return REQUEST.RESPONSE.redirect(self.absolute_url()+'/manage_gradeAssignment')
class KodutoodeKataloog(
OFS.Folder.Folder,
OFS.SimpleItem.Item,
Persistent,
AccessControl.Role.RoleManager,
Traversable,
Cruft
):
""" Assignments folder """
meta_type = "Assignments folder"
security = ClassSecurityInfo()
security.declareObjectPublic()
# XXX:Migration needed for Persistent mapping
def __init__(self):
""" self.grades mapping example:
grades = {
'too1':{
'Vahur':{
'points':'55.3',
'comment':'comment box',
'teacherComment':'teacher comment box'
}
}
'Overall':{
'Vahur':{
'TotPoints':'90.1',
'TotPointsComment':'Total points comment',
'grade':'F',
'gradeCom':'Total grade comment',
'OverallComment':'Overall comment'
}
}
}
"""
self.grades = PersistentMapping()
self.grades['Overall'] = {}
self.grades = self.grades
self.hindeTahised=["A", "B", "C", "D", "E", "F"]
self.hindePiirid=[90, 80, 70, 60, 50]
self.tooNr=0
def getTypes(self, REQUEST):
"Assignment types"
t = [translate(self, 'Quiz',target=self.giveLanguage(REQUEST)), translate(self, 'Product',target=self.giveLanguage(REQUEST)), translate(self, 'Groupwork',target=self.giveLanguage(REQUEST)), translate(self,'Presentation',target=self.giveLanguage(REQUEST)), translate(self,'Peer review',target=self.giveLanguage(REQUEST))]
return t
def kysiCSV(self, REQUEST):
""" return users grades in a csv file """
REQUEST.RESPONSE.setHeader('Content-disposition','attachment; filename=grades.csv')
users = self.get_all_users()
t = "name;"
for x in self.listAssignments():
t += x.getTitle()+';'
t += "total;grade;\n"
for x in users:
t+= self.firstAndLast(x.get_uname())+";"
for too in self.listAssignments():
t+=str(too.getGrades(x.get_uname(),'points'))+";"
t+= str(self.getOverallDetails(x.get_uname(),'TotPoints'))+';';
t+= str(self.getOverallDetails(x.get_uname(),'grade'))+";\n"
return t
def getOverallDetails(self, user, detail=''):
""" return things """
gradesObj = getattr(self, 'grades')
try:
return gradesObj['Overall'][user][detail]
except KeyError:
return
def index_html(self,REQUEST):
""" redirect to manage_assignments """
return REQUEST.RESPONSE.redirect('manage_assignments')
def lisaKodutoo(self, REQUEST, tyyp,preferred_id=''):
"Luuakse vastava tüübiga kodutöö ja väljastatakse selle eksemplar"
self.tooNr=self.tooNr+1
id='too'+str(self.tooNr)
while hasattr(self,id):
self.tooNr = self.tooNr+1
id = 'too'+str(self.tooNr)
too=Kodutoo(REQUEST, tyyp)
if preferred_id:
too.id = preferred_id
else:
too.id=id
self._setObject(too.id, too)
return too
def addAssignment_handler(self, REQUEST):
"Andmete salvestus"
too=self.lisaKodutoo(REQUEST, REQUEST.tyyp)
if too.tyyp==2:
too.grupid = []
REQUEST.RESPONSE.redirect(self.absolute_url()+'/'+too.id+'/manage_changeAssignment')
def manageAssignFormHandler(self, REQUEST, kustuta='', salvesta='', tooID=()):
"Toiming vastavalt nupule"
if kustuta:
if type(tooID)==types.StringType:
tooID=(tooID,)
for x in tooID:
self._delObject(x)
if salvesta:
self.hindeTahised=[]
self.hindePiirid=[]
kokku=len(REQUEST.hindePiir)
veel=1
i=0
while veel and i0) and (self.hindePiirid[i]<=self.hindePiirid[i-1]):
# veel=0
except:
veel=0
i=i+1
#self.aq_parent.kontrolliHinneteKaustad(REQUEST)
REQUEST.RESPONSE.redirect('manage_assignments')
def normpunktideSumma(self, REQUEST=None):
"Kataloogis olevate tööde normpunktide summa"
summa=0
for x in self.objectValues():
summa+=x.normPunkte
return summa
def punktideleVastavHinne(self, REQUEST, punkte):
"Arvutatakse tähis punktide järgi"
if not hasattr(self, 'hindePiirid'): return translate(self, 'No scale',target=self.giveLanguage(REQUEST))
if len(self.hindePiirid)==0: return translate(self, 'No grades', target=self.giveLanguage(REQUEST))
if self.normpunktideSumma(REQUEST)<=0:
return ""
try:
protsent=float(punkte)*100/self.normpunktideSumma(REQUEST)
except:
return ""
i=0
while i= self.hindePiirid[i]:
return self.hindeTahised[i]
i+=1
if i