# -*- coding: utf-8 # $Id: Management.py 140 2008-02-27 06:23:37Z vahur $ # # 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 Globals from Globals import Persistent from Products.PageTemplates.PageTemplateFile import PageTemplateFile import AccessControl import Acquisition from OFS.SimpleItem import SimpleItem from zope.interface import implements, Interface from zope.component import getUtility, queryMultiAdapter from interfaces import IManagement, IFLE, ICourseManager, IStatistics, IUserManager, IWebtopItem from common import perm_manage, perm_access, perm_edit, perm_view import StringIO, sys, time from DateTime.DateTime import DateTime from Products.ZCatalog.Catalog import CatalogError class Management(SimpleItem, Persistent, Acquisition.Implicit): """ management """ id = 'Management' meta_type = 'Management' implements(IManagement) security = AccessControl.ClassSecurityInfo() security.declareProtected(perm_manage, 'management_tab') management_tab = PageTemplateFile('ui/management_tab', globals()) management_tab._owner = None manage_options=( {'label' : 'Management', 'action' : 'management_tab'}, ) security.declareProtected(perm_manage, 'migrateTo13_step2') def migrateTo13_step2(self): """ stuff to do when upgrading to IVA 1.3 """ fle = getUtility(IFLE, context=self) fle.Statistics._makeSQLMethods() from common import IVA_VERSION fle.IVA_VERSION = IVA_VERSION return "done" security.declareProtected(perm_manage, 'migrateTo13_step4') def migrateTo13_step4(self): """ stuff to do when upgrading to IVA 1.3 """ fle = getUtility(IFLE, context=self) import MySQLdb import cPickle import os, Globals conf = self.getSQLSettings() table_prefix = conf.get('table_prefix') db = conf.get('database', None) host = conf.get('hostname', None) user = conf.get('username', None) passwd = conf.get('password', None) data_dir = os.path.join(Globals.INSTANCE_HOME,'var','iva_stat') path = '_'.join(fle.getPhysicalPath()[1:]).lower()+'_' if not db or not host: return "Invalid MySQL connection settings. Please revise your MySQL settings." db_conn = MySQLdb.connect(host=host, user=user, passwd=passwd, db=db) cursor = db_conn.cursor() #uc_stat -> iva_course_user #f = open('ivas_htkiva_iva_uc_stat.dat', 'r') fname = os.path.join(data_dir, path+'uc_stat.dat') f = open(fname, 'r') uc_stat = cPickle.load(f) f.close() for uname in uc_stat.keys(): for course in uc_stat[uname].keys(): vals = uc_stat[uname][course] lastAccess = str(time.strftime('%Y-%m-%d %H:%M', time.localtime(float(vals['lastAccess'])))) try: visit_kb = str(time.strftime('%Y-%m-%d %H:%M', time.localtime(float(vals['visit_knowledgebuilding'])))) except KeyError: visit_kb = 0 try: visit_jm = str(time.strftime('%Y-%m-%d %H:%M', time.localtime(float(vals['visit_jamming'])))) except KeyError: visit_jm = 0 cursor.execute("""insert into %s_course_user values ('%s', '%s', %s, '%s', %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, '%s', '%s') """ % (table_prefix, uname, str(course), vals['openPages'], lastAccess, vals['notesRead'], vals['postedNotes'], vals['postedArtefacts'], vals['postedArtefactAnnos'], vals['uploadedFiles'], vals['createdWikis'], vals['memosAdded'], vals['foldersOpened'], vals['testsSolved'], vals['numTimesEntered'], vals['linksAdded'], visit_kb, visit_jm, ) ) # c_stat -> iva_course_updates fname = os.path.join(data_dir, path+'c_stat.dat') f = open(fname, 'r') #f = open('ivas_htkiva_iva_c_stat.dat', 'r') c_stat = cPickle.load(f) f.close() for course in c_stat.keys(): vals = c_stat[course] try: mod_bs = str(time.strftime('%Y-%m-%d %H:%M', time.localtime(float(vals['modBookshelf'])))) except KeyError: mod_bs = '0000-00-00 00:00:00' try: mod_kb = str(time.strftime('%Y-%m-%d %H:%M', time.localtime(float(vals['modKnowledge'])))) except KeyError: mod_kb = '0000-00-00 00:00:00' try: mod_jm = str(time.strftime('%Y-%m-%d %H:%M', time.localtime(float(vals['modJamming'])))) except KeyError: mod_jm = '0000-00-00 00:00:00' cursor.execute("""insert into %s_course_updates values ('%s', 0,0,0,0,0) on duplicate key update course_id=course_id """ % (table_prefix, str(course))) q = """update %s_course_updates set modified_jamming='%s' where course_id=%s""" % ( table_prefix, mod_jm, str(course) ) cursor.execute(q) q = """update %s_course_updates set modified_knowledgebuilding='%s' where course_id=%s""" % ( table_prefix, mod_kb, str(course) ) cursor.execute(q) q = """update %s_course_updates set modified_bookshelf='%s' where course_id=%s""" % ( table_prefix, mod_bs, str(course) ) cursor.execute(q) # ug_stat -> iva_users fname = os.path.join(data_dir, path+'ug_stat.dat') f = open(fname, 'r') #f = open('ivas_htkiva_iva_ug_stat.dat', 'r') c_stat = cPickle.load(f) f.close() for uname in c_stat.keys(): try: tim = c_stat[uname]['lastAccessGlobal'] except: tim = '0000-00-00 00:00:00' lastAccess = str(time.strftime('%Y-%m-%d %H:%M', time.localtime(float(tim)))) p_open = c_stat[uname]['pagesOpenTotal'] cursor.execute("""insert into %s_users values ('%s', %s, '%s') on duplicate key update uname=uname""" % (table_prefix, uname, p_open, lastAccess)) # o_stat -> obj_history fname = os.path.join(data_dir, path+'o_stat.dat') f = open(fname, 'r') #f = open('ivas_htkiva_iva_o_stat.dat', 'r') o_stat = cPickle.load(f) f.close() for url in o_stat.keys(): for uname in o_stat[url].keys(): times = o_stat[url][uname]['times'] for t in o_stat[url][uname]['times']: acc_time = str(time.strftime('%Y-%m-%d %H:%M', time.localtime(float(t)))) cursor.execute("""insert into %s_obj_history (url, uname, count, time) values ( '%s', '%s', 1, '%s')""" % (table_prefix, url, uname, acc_time)) return "done" security.declareProtected(perm_manage, 'migrateTo13_step5') def migrateTo13_step5(self): """ set correct ZWiki editing permissions so that subgroup members can collaboratively work on one wiki """ cm = getUtility(ICourseManager, context=self) cm._setupZWikipermissions() return "done" security.declareProtected(perm_manage, 'migrateTo13_step1') def migrateTo13_step1(self): """ stuff to do when upgrading to IVA 1.3 Give 'Change permissions' permission to Owner atleast on Blog folder. add fulltext index to blogs zcatalog and catalog_webtop_items """ um = getUtility(IUserManager, context=self) cm = getUtility(ICourseManager, context=self) fle = getUtility(IFLE, context=self) for u in um.objectValues('UserInfo'): b = u.Blog b.manage_permission('Change permissions', ('Owner',), 1) for c in cm.objectValues('Course'): b = c.Blog b.manage_permission('Change permissions', ('Teacher','IVAAdmin'), 1) from OFS.ObjectManager import BadRequestException bz = fle.blogs_zcatalog class largs: def __init__(self, **kw): self.__dict__.update(kw) try: bz.manage_addProduct['ZCTextIndex'].manage_addLexicon('lexicon', elements=[ largs(group= 'Case Normalizer' , name= 'Case Normalizer' ), largs(group= 'Stop Words', name= " Don't remove stop words" ), largs(group= 'Word Splitter' , name= "IVA Unicode Whitespace splitter" ), ] ) except BadRequestException: #id already in use pass class attrs: doc_attr = 'getTitle, getContent, getIntro' lexicon_id = 'lexicon' index_type = 'Cosine Measure' try: bz.addIndex('fulltext', 'ZCTextIndex', attrs()) bz.manage_reindexIndex(('fulltext',)) except CatalogError: pass try: bz.addColumn('absolute_url') except CatalogError: pass try: bz.addColumn('get_author') except CatalogError: pass try: bz.addColumn('get_timestamp') except CatalogError: pass wtz = fle.catalog_webtop_items try: wtz.manage_addProduct['ZCTextIndex'].manage_addLexicon('lexicon', elements=[ largs(group= 'Case Normalizer' , name= 'Case Normalizer' ), largs(group= 'Stop Words', name= " Don't remove stop words" ), largs(group= 'Word Splitter' , name= "IVA Unicode Whitespace splitter" ), ] ) except BadRequestException: #id already in use pass wtz_extra = attrs() wtz_extra.doc_attr = 'get_name' try: wtz.addIndex('fulltext', 'ZCTextIndex', wtz_extra) #wtz.manage_reindexIndex(('fulltext',)) except CatalogError: pass try: wtz.addIndex('meta_type', 'KeywordIndex') except CatalogError: pass try: wtz.addIndex('getRelativeContentURL', 'PathIndex') except CatalogError: pass try: wtz.addColumn('absolute_url') except CatalogError: pass try: wtz.addColumn('getRelativeContentURL') except CatalogError: pass bz.refreshCatalog(clear=1) wtz.refreshCatalog(clear=1) from common import IVA_VERSION fle.IVA_VERSION = IVA_VERSION return "permissions changed, indexes added" def migrateTo14_step1(self): """ register components""" from interfaces import IFLE from Products.Five.component import enableSite enableSite(self.fle_root()) self.registerUtilities() return "Step 1 completed." def registerUtilities(self): """ register utilities """ fle = self.fle_root() sm = self.getSiteManager() sm.registerUtility(fle.Statistics, IStatistics) sm.registerUtility(fle, IFLE) sm.registerUtility(fle.fle_users, IUserManager) sm.registerUtility(fle.courses, ICourseManager) security.declareProtected(perm_manage, 'migrateTo14_step4') def migrateTo14_step2(self): """ migrate to version 1.4. Step 2 """ s = getUtility(IStatistics, context=self) dbpref = self.getSQLSettings().get('table_prefix') s._makeSQLMethods(prefix=dbpref) return "Step 2 completed." def migrateTo14_step3(self): """ migrate to version 1.4. Step 3 """ um = getUtility(IUserManager, context=self) for ui in um.objectValues('UserInfo'): wt = getattr(ui, 'webtop') try: wt._delObject('trash') except AttributeError: pass return "Step 3 completed." security.declareProtected(perm_manage, 'migrateTo14_step1') def migrateTo14_step4(self): """ migrate to version 1.4. Step 4 """ um = getUtility(IUserManager, context=self) cm = getUtility(ICourseManager, context=self) fle = getUtility(IFLE, context=self) from Products.ZCatalog.Catalog import CatalogError from Products.ZCTextIndex.ZCTextIndex import manage_addLexicon class largs: def __init__(self, **kw): self.__dict__.update(kw) class attrs: doc_attr = 'getTitle, getContent, getIntro' lexicon_id = 'lexicon' index_type = 'Cosine Measure' # catalog_webtop_items catalog = fle.catalog_webtop_items # del lexicon and fulltext index try: catalog._delObject('lexicon') except AttributeError: pass try: catalog.delIndex('fulltext') except CatalogError: pass try: catalog.delIndex('getRelativeContentURL') except CatalogError: pass # add lexicon and fulltext index manage_addLexicon(catalog, 'lexicon', elements=[ largs(group= 'Case Normalizer' , name= 'Case Normalizer' ), largs(group= 'Stop Words', name= " Don't remove stop words" ), largs(group= 'Word Splitter' , name= "IVA Unicode Whitespace splitter" ), ] ) params = attrs() params.doc_attr = 'get_name' try: catalog.addIndex('fulltext', 'ZCTextIndex', params) except CatalogError: pass try: catalog.addIndex('allowedRolesAndUsers', 'KeywordIndex') except CatalogError: pass try: catalog.addIndex('getObjPermission', 'FieldIndex') except CatalogError: pass try: catalog.addIndex('getWeight', 'FieldIndex') except CatalogError: pass try: catalog.addIndex('get_size', 'FieldIndex') except CatalogError: pass try: catalog.addIndex('get_timestamp', 'FieldIndex') except CatalogError: pass try: catalog.addIndex('path', 'IVAPathIndexNG') except CatalogError: pass class DRattrs: since_field='getStartTimeIndex' until_field='getEndTimeIndex' try: catalog.addIndex('visible', 'DateRangeIndex', DRattrs()) except CatalogError: pass # webtop_catalog metadata try: catalog.addColumn('getWeight') except CatalogError: pass try: catalog.addColumn('get_icon_path') except CatalogError: pass try: catalog.addColumn('get_id') except CatalogError: pass try: catalog.addColumn('get_size') except CatalogError: pass try: catalog.addColumn('kasWikiKaust') except CatalogError: pass try: catalog.addColumn('lastModification') except CatalogError: pass try: catalog.addColumn('meta_type') except CatalogError: pass try: catalog.addColumn('getTitle') except CatalogError: pass try: catalog.addColumn('get_timestamp') except CatalogError: pass # delete get_name # add get_name as fieldindex try: catalog.delIndex('get_name') except CatalogError: pass try: catalog.addIndex('get_name', 'FieldIndex') except CatalogError: pass # courses zcatalog catalog = cm.courses_zcatalog try: catalog.delIndex('get_all_users_id') except CatalogError: pass try: catalog.addIndex('get_all_users_id', 'KeywordIndex') except CatalogError: pass try: catalog.addIndex('isLocked', 'FieldIndex') except CatalogError: pass try: catalog.addColumn('isLocked') except CatalogError: pass try: catalog.addColumn('getSubgroupList') except CatalogError: pass try: catalog.addColumn('get_all_users_id') except CatalogError: pass # userinfo zcatalog umz = um.userinfo_zcatalog try: umz.addColumn('get_photo_tag') except CatalogError: pass # extra.indexed_attrs: get_uname try: umz.addIndex('userid', 'FieldIndex', extra = largs(indexed_attrs = 'get_uname')) except CatalogError: pass try: umz.addIndex('has_photo', 'FieldIndex') except CatalogError: pass # blogs catalog catalog = fle.blogs_zcatalog catalog._delObject('lexicon') try: catalog.delIndex('fulltext') except CatalogError: pass manage_addLexicon(catalog, 'lexicon', elements=[ largs(group= 'Case Normalizer' , name= 'Case Normalizer' ), largs(group= 'Stop Words', name= " Don't remove stop words" ), largs(group= 'Word Splitter' , name= "IVA Unicode Whitespace splitter" ), ] ) try: catalog.addIndex('fulltext', 'ZCTextIndex', attrs()) except CatalogError: pass catalog.manage_reindexIndex(ids=['fulltext',]) # events zcatalog catalog = fle.catalog_events try: catalog.addColumn('meta_type') except CatalogError: pass try: catalog.delIndex('path') except CatalogError: pass try: catalog.addIndex('path', 'IVAPathIndexNG') except CatalogError: pass catalog.manage_reindexIndex(ids=['path',]) from common import IVA_VERSION fle.IVA_VERSION = IVA_VERSION return "Step 4 completed." security.declareProtected(perm_manage, 'migrateTo14_step5_1') def migrateTo14_step5_1(self): """ migrate to version 1.4. Step 5 """ um = getUtility(IUserManager, context=self) cm = getUtility(ICourseManager, context=self) fle = getUtility(IFLE, context=self) cat = getattr(fle, 'catalog_webtop_items') cat.manage_catalogClear() catalog = cm.courses_zcatalog #catalog.manage_reindexIndex(ids=['get_all_users_id']) catalog.refreshCatalog(clear=1) # refresh userinfo_catalog umz = um.userinfo_zcatalog umz.refreshCatalog(clear=1) return "Step 5.1 completed." security.declareProtected(perm_manage, 'migrateTo14_step5_2') def migrateTo14_step5_2(self): """ migrate to version 1.4. Step 5 """ cm = getUtility(ICourseManager, context=self) print "TODO: courses:", len(cm.objectValues('Course')) #import transaction count = 1 for c in cm.objectValues('Course'): print count, c self._step5_walk(c) #if count in range(0, 1000, 150): # print "commit" # transaction.commit() count = count + 1 return "Step 5.2 completed." security.declareProtected(perm_manage, 'migrateTo14_step5_3') def migrateTo14_step5_3(self): """ migrate to version 1.4. Step 5 """ print "TODO: users:", len(self.fle_users.objectValues('UserInfo')) um = getUtility(IUserManager, context=self) #import transaction count = 1 for c in um.objectValues('UserInfo'): print count, c self._step5_walk(c.webtop) #if count in range(0, 8000, 1000): # print "commit" # transaction.commit() count = count + 1 return "Step 5.3 completed." security.declareProtected(perm_manage, 'migrateTo14_step6') def migrateTo14_step6(self): """ fix CourseContext permissions """ cm = getUtility(ICourseManager, context=self) for c in cm.objectValues('Course'): for cc in c.objectValues('CourseContext'): cc.manage_permission('View', tuple(), 1) return "Step 6 done" security.declareProtected(perm_manage, 'migrateTo14_step7') def migrateTo14_step7(self): """ fix permissions """ um = getUtility(IUserManager, context=self) for f in um.objectValues('UserInfo'): w = f.webtop self._step7_walk(w) return "Step 7 done" security.declareProtected(perm_manage, 'migrateTo14_step8') def migrateTo14_step8(self): """ fix subgroup permissions """ cm = getUtility(ICourseManager, context=self) for c in cm.objectValues('Course'): sg = c.subgroups self._step7_walk(sg) return "Step 8 done" def _step7_walk(self, obj): for x in obj.objectValues(): x.manage_permission('View', tuple(), 1) self._step7_walk(x) def _step5_walk(self, obj): """ step 5 walker """ for x in obj.objectValues(): if IWebtopItem.providedBy(x): try: #print "INDEXING:", x.absolute_url() x.index_object() except TypeError: print "TypeError" self._step5_walk(x) security.declareProtected(perm_manage, 'migratePersonalEvents') def migratePersonalEvents(self): """ from 0.7 to 0.8 disables creation of personal event method will go through all user's personal 'syndmused' folder and remove 'Add FLE LO' permission from everybody 'Add FLE LO' permission will be given to 'User' and 'Owner' on 'subgroups' folder. """ um = getUtility(IUserManager, context=self) cm = getUtility(ICourseManager, context=self) a = cm.courses_zcatalog.addColumn('getLogoThumbnailURL') for c in cm.get_courses(): g = c.getObject() subgroup = getattr(g.aq_inner, 'subgroups', None) if subgroup is None: continue subgroup.manage_permission('Add FLE LO', ('Owner', 'User'), 1) for u in um.get_users(): s = getattr(u.aq_inner, 'syndmused', None) if s is None: continue s.manage_permission('Add FLE LO', (), 0) return "Removed 'Add FLE LO' permission from users. Added 'Add FLE LO' permission on subgroups. Added thumbnail url metadata to course_zcatalog." security.declareProtected(perm_manage, 'migrateTo072') def migrateTo072(self): """ migrates IVA to version 0.7.2 """ um = getUtility(IUserManager, context=self) umz = um.userinfo_zcatalog umz.delIndex('get_organization') umz.addIndex('get_organization', 'FieldIndex') return "done" # FLE.py-st security.declareProtected(perm_manage, 'addIndexes') def addIndexes(self): """ add missing ZCatalog indexes XXX: there is no link to this yet """ cm = getUtility(ICourseManager, context=self) cmz = getattr(cm, 'courses_zcatalog') cmz.addIndex('getUniqId', 'FieldIndex') cmz.refreshCatalog(clear=1) return "Done" security.declarePrivate('indexBlogs') def indexBlogs(self, a, b): """ asd """ fle = getUtility(IFLE, context=self) cat = getattr(fle, 'blogs_zcatalog') a.default_catalog = 'blogs_zcatalog' cat.catalog_object(a) return a security.declareProtected(perm_manage, 'migrateBlogs') def migrateBlogs(self, REQUEST, RESPONSE): """ migrate blogs - attach a catalog, index etc XXX: there is no link to this yet 1. create zcatalog 'blogs_zcatalog' 2. create add default_catalog to all entries 3. catalog blogs. """ fle = getUtility(IFLE, context=self) fle.add_blogs_zcatalog() cat = getattr(fle, 'blogs_zcatalog') path = '/'.join(self.getPhysicalPath()) cat.ZopeFindAndApply(fle, search_sub=1, obj_expr='isEntry()==1', apply_func=self.indexBlogs, apply_path=path) return "Done" security.declarePrivate('addWebtopItem') def addWebtopItem(self, a, b): """ asd """ fle = getUtility(IFLE, context=self) cat = getattr(fle, 'catalog_webtop_items') cat.catalog_object(a) return a security.declareProtected(perm_manage, 'catalogWebtopItems') def catalogWebtopItems(self): """ catalog all webtops """ fle = getUtility(IFLE, context=self) try: cat = getattr(fle, 'catalog_webtop_items') cat.delIndex('get_content') except: pass cat = getattr(fle, 'catalog_webtop_items') path = '/'.join(fle.getPhysicalPath()) cat.ZopeFindAndApply(self, search_sub=1, obj_expr="default_catalog=='catalog_webtop_items' and meta_type in ['WebtopFile', 'WebtopFolder', 'WebtopItem', 'WebtopLink', 'WebtopMemo', 'WebtopProxyFile', 'Webtop', 'SubgroupManager', 'Subgroup', 'Portfolio', 'AssignmentProxy', 'GroupFolder']", apply_func=self.addWebtopItem, apply_path=path) return "Done" security.declareProtected(perm_manage, 'addCaches') def addCaches(self): """ migrate to version 1.0 """ fle = getUtility(IFLE, context=self) um = getUtility(IUserManager, context=self) self.images._delObject('HTTPCache') AcceleratedHTTPCacheManager.manage_addAcceleratedHTTPCacheManager(fle, 'HTTPCache') http_cache = getattr(fle, 'HTTPCache') http_cache.manage_editProps('', {'anonymous_only':0, 'interval':3600, 'notify_urls':''}) # add uniq id to users for x in um.get_users(): suffix = '_'+str(int(time.time())) uniq_id = um.generateId(prefix='user',suffix=suffix, rand_ceiling=99999999999) x.setUniqId(uniq_id) cat = getattr(self, 'catalog_webtop_items') cat.delIndex('get_content') return "Done" security.declareProtected(perm_manage, 'createQTImages') def createQTImages(self): """ create qtImages inside 'testid' folder """ # XXX: write me # 1. find all courses. # 2. get testid folder # 3. qti = QTImages() # 4. self._setObject(qti.id, qti) cm = getUtility(ICourseManager, context=self) from QTImages import QTImages for x in cm.objectValues('Course'): testid = getattr(x, 'testid') qti = QTImages() testid._setObject(qti.id, qti) self.migrateQTImages() return "Done" security.declareProtected(perm_manage, 'createTrackers') def createTrackers(self): """ create trackers - new in IVA 1.0 """ cm = getUtility(ICourseManager, context=self) for x in cm.objectValues('Course'): x.createTracker() return "Done" security.declareProtected(perm_manage, 'migrateQTImages') def migrateQTImages(self): """ migrate QT images """ cm = getUtility(ICourseManager, context=self) import re for x in cm('Course'): qtiimages = x.testid.qtimages j = 0 for q in x.testid.getQuizzes(): for z in q.ylesanded(): j = j + 1 if hasattr(z, 'pildid'): i = 0 for p in z.pildid: newid = 'Image'+str(j)+str(i) try: qtiimages.manage_addImage(newid, p, newid) except: qtiimages._delObject(newid) qtiimages.manage_addImage(newid, p, newid) subst = str(z.id+'/kysiPilt?pildinr='+str(i)) txt = z.kirjeldavTekst #txt = re.sub(subst, 'qtimages/'+newid, z.kirjeldavTekst.decode('utf-8')) txt = re.sub(z.id, 'qtimages', txt) txt = re.sub('kysiPilt', newid, txt) txt = re.sub('\?pildinr='+str(i), '', txt) z.kirjeldavTekst = txt i = i + 1 del z.pildid return "Done" security.declareProtected(perm_manage, 'migrateTo10') def migrateTo10(self): """ migrate IVA to version 1.0 """ self.delete_pt() self.createQTImages() self.addCaches() self.migrateBlogs() self.addIndexes() self.setupSkins() self.createTrackers() self.catalogWebtopItems() security.declareProtected(perm_manage, 'migrateScheduler') def migrateScheduler(self): """ add yourself to scheduler """ cp = self.Control_Panel try: cp._delObject('timerservice') except AttributeError: pass return "Done" security.declareProtected(perm_manage, 'migrateTo15_step0') def migrateTo15_step0(self, REQUEST, out=None): """ migrate to version 1.5 * replace cmfcore site manager with Five.sitemanager """ if out is None: out = sys.stdout print >> out, "migration step 0" fle = self.fle_root() components_view = queryMultiAdapter((fle, REQUEST), Interface, 'components.html') try: components_view.unmakeSite() except ValueError: pass components_view.makeSite() self.registerUtilities() from common import IVA_VERSION fle.IVA_VERSION = IVA_VERSION + "-S0" security.declareProtected(perm_manage, 'migrateTo15_step1') def migrateTo15_step1(self, REQUEST, out=None): """ migrate to version 1.5 * delete unused objects. * delete local role Member, there is no use of it * replace standard userfolder with PAS, if needed. Or just add one """ if out is None: out = sys.stdout sm = self.getSiteManager() fle = getUtility(IFLE, context=self) fle = sm.getUtility(IFLE) # delete cookiecrumbler. using pas now try: fle._delObject('login') except AttributeError: pass try: fle._delObject('login_form') except AttributeError: pass # delete mailhost, we're using zope.sendmail now # unregister utility? # sm.registerUtility(obj.MailHost, IMailHost) try: fle._delObject('MailHost') except AttributeError: pass print >> out, "Deleted login, login_form, MailHost" # add PluggableAuthService #fle._delObject('acl_users') if not hasattr(fle.aq_base, 'acl_users'): fle._setupPAS() print >> out, "Creating acl_users folder" else: # replace userfolder with PAS, if required from Products.PluggableAuthService.Extensions.upgrade import _replaceUserFolder, replace_acl_users print >> out, "Replacing standard acl_user folder with PAS user folder " #eplace_acl_users(fle) _replaceUserFolder(fle) fle._setupPAS() pass from common import IVA_VERSION fle.IVA_VERSION = IVA_VERSION + "-S1" return "ok" security.declareProtected(perm_manage, 'migrateTo15_step2') def migrateTo15_step2(self, REQUEST, out=None): """ migrate to version 1.5 step 2 """ if out is None: out = sys.stdout cm = getUtility(ICourseManager, context=self) cm._delRoles(('Student', 'Teacher', 'Member', 'Staff')) fle = getUtility(IFLE, context=self) fle._addRole('Student') fle._addRole('Teacher') lroles = fle.get_local_roles() for uname, roles in lroles: #print uname, roles if len(roles) == 1 and roles[0] == 'Member': fle.manage_delLocalRoles((uname,)) continue if not 'Member' in roles: continue newroles = tuple() for r in roles: if r == 'Member': continue newroles += (r,) fle.manage_setLocalRoles(uname, newroles) from common import IVA_VERSION fle.IVA_VERSION = IVA_VERSION + "-S2" print >> out, "migration step 2 completed - local roles deleted" return "ok" security.declareProtected(perm_manage, 'migrateTo15_step3') def migrateTo15_step3(self, REQUEST, out=None): """ migrate to version 1.5 step 3 * create two groups per course * delete local roles from /courses/cnr (Teacher, Student) * give group 0_teachers role Teacher * give group 0 role Student """ if out is None: out = sys.stdout cm = getUtility(ICourseManager, context=self) print >> out, "migration step 3: creating %s groups..." % str(len(cm.objectIds('Course'))) for c in cm.objectValues('Course'): try: self.acl_users.groups.manage_addGroup(str(c.getId()), '', '') except KeyError: pass try: self.acl_users.groups.manage_addGroup(str(c.getId())+'_teachers', '', '') except KeyError: pass lroles = c.get_local_roles() for l in lroles: grname = str(c.getId()) if 'Teacher' in l[1]: grname += '_teachers' elif 'Student' in l[1]: pass # groupname is correct, go ahead else: continue # don't want to delete Owner and stuff # add to group self.acl_users.groups.manage_addPrincipalsToGroup(grname, (l[0],)) # delete local roles c.manage_delLocalRoles((l[0],)) grname = str(c.getId()) c.manage_setLocalRoles(grname, ('Student',)) c.manage_setLocalRoles(grname+'_teachers', ('Teacher',)) from common import IVA_VERSION fle = getUtility(IFLE, context=self) fle.IVA_VERSION = IVA_VERSION + "-S3" return "ok" security.declareProtected(perm_manage, 'migrateTo15_step4') def migrateTo15_step4(self, REQUEST, out=None): """ migrate to version 1.5 step 4 * delete folder /fle_users/username/own_styles * go through all UserInfo/webtop/c objects * give group 0_teachers role Teacher * give group 0 role Student """ if out is None: out = sys.stdout fle = getUtility(IFLE, context=self) fle.manage_permission(perm_access, ('Authenticated', 'IVAAdmin', 'Manager', 'Owner'), 0) fle.manage_permission('Zwiki: Rate pages', ('',), 0) fle.manage_permission('Zwiki: Edit pages', ('Owner', 'Teacher', 'IVAAdmin', 'Manager'), 0) fle.manage_permission('Zwiki: Add pages', ('Owner', 'Teacher', 'IVAAdmin', 'Manager'), 0) um = getUtility(IUserManager, context=self) um.manage_permission(perm_access, ('',), 1) # acquire um.manage_permission(perm_view, ('',), 1) # acquire c = 0 print >> out, "migration step 4: cleaning %s users..." % str(len(um.objectValues('UserInfo'))) for u in um.objectValues('UserInfo'): try: u._delObject('own_styles') except AttributeError: pass u.manage_permission(perm_edit, ('',), 1) u.manage_permission(perm_view, ('',), 1) u.manage_permission('Manage FLE', ('',), 1) c += 1 if c in range(0,10000, 500): print >> out, "done: "+str(c) w = u.get_webtop() for cwt in w.objectValues('WebtopFolder'): # c1, c2 etc cwt.manage_permission(perm_access, ('Manager', 'IVAAdmin', 'Owner', 'Student', 'Teacher'), 0) cwt.manage_permission(perm_view, ('Manager', 'IVAAdmin', 'Owner', 'Student', 'Teacher'), 0) try: port = cwt.portfolio port.setObjPermission(0) #port.manage_permission(perm_view, ('Manager', 'IVAAdmin', 'Owner', 'Teacher', 'Student'), 0) for assg in port.objectValues(): assg.setObjPermission(4) except AttributeError: pass cnr = cwt.getId()[1:] okok_s = self.acl_users.groups.listAssignedPrincipals(cnr) okok_t = self.acl_users.groups.listAssignedPrincipals(cnr+'_teachers') #print "parts::", okok_s, okok_t not_in_groups = True for k in okok_s+okok_t: if u.get_uname() in k: #print "OK, user %s in group %s" % (u.get_uname(), cnr) not_in_groups = False if not_in_groups: print >> out, "User %s doesn't belong to right groups... has webtop but not a member of a course! %s" % (u.get_uname(), cwt.get_id()) cwt.manage_setLocalRoles(cnr, ('Student',)) cwt.manage_setLocalRoles(cnr+'_teachers', ('Teacher',)) fle = getUtility(IFLE, context=self) from common import IVA_VERSION fle.IVA_VERSION = IVA_VERSION + "-S4" return "ok" security.declareProtected(perm_manage, 'migrateTo15_step5') def migrateTo15_step5(self, REQUEST, out=None): """ migrate to version 1.5 step 6 """ if out is None: out = sys.stdout fle = self.aq_parent cm = fle.courses um = fle.fle_users print >> out, "migration step 5: fixing CourseContext permissions" for c in cm.objectValues('Course'): for cc in c.objectValues('CourseContext'): print >>out, "Fixing CourseContext permissions @ %s " % cc.absolute_url() for tts in cc.objectValues('ThinkingTypeSet'): tts.manage_permission('View', ('Manager','IVAAdmin','Staff','User', 'Student', 'Teacher'), 0) for tt in tts.objectValues('ThinkingType'): tt.manage_permission('View', ('Manager','IVAAdmin','Staff','User', 'Student', 'Teacher'), 0) print >> out, "migration step 5: modifing assignments permission" for x in cm.objectValues('Course'): k = x.kodutood assignments = [] for t in k.objectValues('Assignment'): if t.getRawType() == 4: if t.getAssignmentID() is not None: assignments.append([getattr(k, t.getAssignmentID()), t]) if len(assignments) == 0: continue for uname in x.get_all_users_id(): u = getattr(um, uname, None) if u is None: continue wt = u.webtop try: cwt = getattr(wt, 'c'+str(x.get_id())) port = cwt.portfolio except AttributeError: continue for prod, rev in assignments: work = getattr(port, prod.get_id(), None) if work is None: continue work.setObjPermission(2) work.itemPropUsers(None, savePropUser=1, unames=rev.getMyReviewers(uname)) print >> out, "step 5: replacing permissions: %s" % work.absolute_url() self._migrateTo15_recurser(work, rev.getMyReviewers(uname)) print >> out, "migration step 5: scanning %s portfolios" % len(um.objectValues('UserInfo')) c = 0 for ui in um.objectValues('UserInfo'): c += 1 if c in range(0,10000, 500): print >> out, "done: "+str(c) wt = ui.get_webtop() for w in wt.objectValues('WebtopFolder'): # c1, c2, etc try: port = w.portfolio except AttributeError: # no portfolio here continue port.setObjPermission(0) from common import IVA_VERSION fle.IVA_VERSION = IVA_VERSION + "-S5" return "ok" def _migrateTo15_recurser(self, obj, llist): for o in obj.objectValues(): o.setObjPermission(2) o.itemPropUsers(None, savePropUser=1, unames=llist) if len(o.objectValues()) > 0: self._migrateTo15_recurser(o, llist) security.declareProtected(perm_manage, 'migrateTo15_step6') def migrateTo15_step6(self, REQUEST, out=None): """ migrate to version 1.5 step 6 """ if out is None: out = sys.stdout fle = self.aq_parent print >> out, "recreating sql methods" s = fle.Statistics dbpref = fle.getSQLSettings().get('table_prefix') s._makeSQLMethods(prefix=dbpref) print >> out, "migration step 6: fixing indexes. Reindexing catalog_webtop_items. Depending on size of IVA, this can take a long time!" #fle = getUtility(IFLE, context=self) # need aquisition cw = fle.catalog_webtop_items try: cw.delIndex('allowedRolesAndUsers') except CatalogError: pass try: cw.addColumn('getObjPermission') except CatalogError: pass cw.refreshCatalog(clear=1, pghandler=DynOutHandler(out)) print >> out, "refreshing courses zcatalog" cc = fle.courses.courses_zcatalog.refreshCatalog(clear=1, pghandler=DynOutHandler(out, steps=50)) from common import IVA_VERSION fle.IVA_VERSION = IVA_VERSION return "ok" security.declareProtected(perm_manage, 'deleteUnusedWebtops') def deleteUnusedWebtops(self, REQUEST=None, out=None): """ delete unused webtops """ if out is None: out = sys.stdout print >> out, "Deleting..." #um = getUtility(IUserManager, context=self) um = self.fle_users for u in um.objectValues('UserInfo'): w = u.get_webtop() to_del = [] for cwt in w.objectValues('WebtopFolder'): # c1, c2 etc cnr = cwt.getId()[1:] okok_s = self.acl_users.groups.listAssignedPrincipals(cnr) okok_t = self.acl_users.groups.listAssignedPrincipals(cnr+'_teachers') not_in_groups = True for k in okok_s+okok_t: if u.get_uname() in k: not_in_groups = False if not_in_groups: to_del.append(cwt.getId()) for t in to_del: print >> out, "%s/%s" % (w.absolute_url(), t) w._delObject(t) if REQUEST is not None: REQUEST.RESPONSE.setHeader('Content-Type', 'text/plain') try: return out.getvalue() except AttributeError: pass class DynOutHandler: """ Progress handler output to out """ def __init__(self, out, steps=1000): self._out = out self._steps = steps def init(self, ident, max): self._ident = ident self._max = max self._start = time.time() self.fp = self._out self.output('Process started (%d objects to go)' % self._max) def info(self, text): self.output(text) def finish(self): self.output('Process terminated. Duration: %0.2f seconds' % \ (time.time() -self._start)) def report(self, current, *args, **kw): if current > 0: if current % self._steps == 0: seconds_so_far = time.time() - self._start seconds_to_go = seconds_so_far / current * (self._max - current) self.output('%d/%d (%.2f%%) Estimated termination: %s' % \ (current, self._max, (100.0 * current / self._max), DateTime(time.time() + seconds_to_go).strftime('%Y/%m/%d %H:%M:%Sh'))) def output(self, text): print >> self._out, '%s: %s' % (self._ident, text) Globals.InitializeClass(Management)