#-*- mode: python; mode: fold -*- # $Id: install.py 152 2005-11-04 17:07:18Z joachim $ from Products.ExternalMethod.ExternalMethod import ExternalMethod from Products.CPSInstaller.CPSInstaller import CPSInstaller from Products.CMFCore.CMFCorePermissions import View, ModifyPortalContent,AccessContentsInformation from Products.WAeUP.WAeUPPermissions import UniversityManage, StudentManage,FacultyManage,\ DepartmentManage,CourseManage try: from Products.CPSSubscriptions.permissions import CanNotifyContent CPSSubscriptions = True except ImportError: CPSSubscriptions = False try: from Products.CPSForum.CPSForumPermissions import ForumManageComments CPSForum = True except ImportError: CPSForum = False from Products.WAeUP.Students import addStudentsFolder SRPP_ID = "demouni" SRPP_TITLE = "Demo University" class WAeUPInstaller(CPSInstaller): """ WAeUP Installer """ product_name = "WAeUP" def install(self,portal): "install" log = [] prlog = log.append def pr(msg, prlog=prlog): prlog('%s
' % msg) product_name = self.product_name pr("Starting %(product_name)s install" % vars() ) # Roles and Permissions ###( # self.verifyRoles(( # A role that can manage the University. 'UniversityManager', # A role that can manage the StudentsRecords. 'StudentManager', # A role that can manage a Faculty. 'FacultyManager', # A role that can manage a department. 'DepartmentManager', # A role that can manage a Course. 'CourseManager', # The Student Role 'Student', )) waeup_perms = { UniversityManage: ('Manager', 'SectionManager','UniversityManager', ), StudentManage: ('Manager', 'SectionManager','UniversityManager', 'StudentManager' ), FacultyManage: ('Manager', 'SectionManager','UniversityManager', 'FacultyManager' ), DepartmentManage: ('Manager', 'SectionManager','UniversityManager', 'DepartmentManager' ), CourseManage: ('Manager', 'SectionManager','UniversityManager', 'CourseManager' ), } self.setupPortalPermissions(waeup_perms) ###) # external methods ###( # ext_methods = ( { 'id': 'waeup_migrate', 'title': 'WAeUP (migrate from an earlier version)', 'script': 'WAeUP.install', 'method': 'migrate', 'protected': 1, }, ) portal_objectIds = portal.objectIds() for meth in ext_methods: method = meth['id'] if method in portal_objectIds: portal._delObject(method) pr('Creating %s External Method' % method) ext_method = ExternalMethod(method, meth['title'], meth['script'], meth['method']) portal._setObject(method, ext_method) if method in portal_objectIds: manage_perms = portal[method].manage_permission if meth['protected']: pr("Protecting %s" % method) manage_perms(View, roles=['Manager'], acquire=0) manage_perms(AccessContentsInformation, roles=['Manager'], acquire=0) else: manage_perms(View, roles=['Manager'], acquire=1) ###) ########################################## # Actions ########################################## waeup_ptypes = "'University','StudentsFolder','Student','Jamb','Faculty','Department','Course'" waeup_ptypes += ",'AccoFolder','Accommodation','StudentPersonal','AcademicsFolder'" waeup_ptypes += ",'StudyLevel','Semester','CourseTicket'" if CPSSubscriptions: ###( ptypes = "('Portal', 'CPSMailAccess Message', 'CPSMailAccess Box', 'CPSMailAccess Folder',"\ + waeup_ptypes + ")" condition = "object.portal_type not in %s" % ptypes action = {'id' : 'notify_content', 'name' : 'action_notify_content', 'action' : 'string:${object_url}/content_notify_email_form', 'condition' : 'python:%s' % condition, 'permission' : (CanNotifyContent,), 'category' : 'object', } self.deleteActions({'portal_subscriptions': ['notify_content',]}) self.verifyAction('portal_subscriptions', **action) if CPSForum: condition = "object.portal_type not in (%s)" % waeup_ptypes action = {'id' : 'activate_comments', 'name': 'action_activate_comments', 'action': 'string:${object/absolute_url}/set_comment_mode?mode=1', 'condition' : 'python:%s' % condition, 'permission': (ForumManageComments,), 'category' : 'object', } self.deleteActions({'portal_subscriptions': ['activate_comments',]}) self.verifyAction('portal_subscriptions', **action) # now portal_discussion self.deleteActions({'portal_discussion': ['comment', 'activate_comments', 'deactivate_comments', 'manage_comments']}) action = {'id' : 'comment', 'name': 'action_comment', 'action': "string:${object/absolute_url}/post_comment", 'condition' : "python:getattr(object.getContent(), 'allow_discussion' , None) and object.hasCommentAction()", 'permission': (View,), 'category' : 'object', } self.verifyAction('portal_discussion', **action) action = {'id' : 'activate_comments', 'name': 'action_activate_comments', 'action': "string:${object/absolute_url}/set_comment_mode?mode=1", 'condition' : "python:getattr(object.getTypeInfo(),'cps_proxy_type','') in ('document', 'folderishdocument') and getattr(object.getContent(), 'allow_discussion' , None) == 1", 'permission': (ForumManageComments,), 'category' : 'object', } self.verifyAction('portal_discussion', **action) action = {'id' : 'deactivate_comments', 'name': 'action_deactivate_comments', 'action': "string:${object/absolute_url}/set_comment_mode?mode=0", 'condition' : "python:getattr(object.getTypeInfo(),'cps_proxy_type','') in ('document', 'folderishdocument') and getattr(object.getContent(), 'allow_discussion' , None) == 1", 'permission': (ForumManageComments,), 'category' : 'object', } self.verifyAction('portal_discussion', **action) action = {'id' : 'manage_comments', 'name': 'action_manage_comments', 'action': "string:${object/absolute_url}/manage_comment", 'condition' : "python:getattr(object.getTypeInfo(),'cps_proxy_type','') in ('document', 'folderishdocument') and getattr(object.getContent(), 'allow_discussion' , None) == 1", 'permission': (ForumManageComments,), 'category' : 'object', } self.verifyAction('portal_discussion', **action) ###) ########################################## # main_tab actions ###( ########################################## path = "/sections/%(SRPP_ID)s" % globals() actions = ( { 'tool' : 'portal_actions', 'id' : 'student_administration', 'name' : 'Students', 'action' : 'string:${portal_url}/students', #'action' : 'string:$portal_url%(path)s/students' % vars(), 'permission': (View, ), 'category' : 'main_tabs', 'visible' : 1, }, { 'tool' : 'portal_actions', 'id' : 'Academics', 'name' : 'Academics', #'action' : 'string:$portal_url%(path)s/academics' % vars(), #'action' : 'string:${portal_url}/sections/unidemo', 'action' : 'string:${portal_url}/academics', 'permission': (View ), 'category' : 'main_tabs', 'visible' : 1, }, { 'tool' : 'portal_actions', 'id' : 'accomodation', 'name' : 'Accommodation', #'action' : 'string:$portal_url%(path)s/accommodation' % vars(), #'action' : 'string:${portal_url}/sections/waeup/accommodation/accommodation_index_html', 'action' : 'string:${portal_url}/accommodation', 'permissions': (View), #'permissions': (ModifyPortalContent,UniversityManage,StudentManage), 'category' : 'main_tabs', 'visible' : 1, }, ## { 'tool' : 'portal_actions', ## 'id' : 'add_jamb', ## 'name' : 'Add Student JAMB', ## 'action' : 'string:${object/absolute_url}/create_jamb', ## 'permission': (), ## 'condition' : 'python: member and here.portal_type in ("StudentsFolder",) and "StudentManager" in member.getGroups()', ## 'category' : 'student', ## 'visible' : 1, ## }, ## { 'tool' : 'portal_actions', ## 'id' : 'add_faculty', ## 'name' : 'Add New Faculty', ## 'action' : 'string:${object/absolute_url}/addFaculty', ## 'permission': (), ## 'condition' : 'python: member and here.portal_type in ("University",) and "StudentManager" in member.getGroups()', ## 'category' : 'student', ## 'visible' : 1, ## }, ## { 'tool' : 'portal_actions', ## 'id' : 'add_department', ## 'name' : 'Add New Department', ## 'action' : 'string:${object/absolute_url}/addDepartment', ## 'permission': (), ## 'condition' : 'python: member and here.portal_type in ("Faculty",) and "StudentManager" in member.getGroups()', ## 'category' : 'student', ## 'visible' : 1, ## }, ## { 'tool' : 'portal_actions', ## 'id' : 'add_course', ## 'name' : 'Add New Course', ## 'action' : 'string:${object/absolute_url}/addCourse', ## 'permission': (), ## 'condition' : 'python: member and here.portal_type in ("Department",) and "StudentManager" in member.getGroups()', ## 'category' : 'student', ## 'visible' : 1, ## }, ## { 'tool' : 'portal_actions', ## 'id' : 'add_personal', ## 'name' : 'Add personal Data', ## 'action' : 'string:${object/absolute_url}/create_personal_form', ## 'permission': (), ## 'condition' : 'python: 0 and member and not here.portal_type in ("Jamb","StudentsFolder") and not "StudentManager" in member.getGroups()', ## 'category' : 'student', ## 'visible' : 1, ## }, ## { 'tool' : 'portal_actions', ## 'id' : 'edit_jamb', ## 'name' : 'Edit Jamb Data', ## 'action' : 'cpsdocument_edit_form', ## 'permission': ( ), ## 'condition' : 'python: member and here.portal_type in ("Student",) and "StudentManager" in member.getGroups()', ## 'category' : 'student', ## 'visible' : 1, ## }, ) self.verifyActions(actions) ########################################## ###) # skins ########################################## pr("Verifying %(product_name)s skinss" % vars()) wskins = { 'waeup_default' : 'Products/WAeUP/skins/waeup_default', 'waeup_faculty' : 'Products/WAeUP/skins/waeup_faculty', 'waeup_student' : 'Products/WAeUP/skins/waeup_student', } self.verifySkins(wskins) self.resetSkinCache() # Themes ###( # # Importing portal themes ## theme_container = getattr(portal, 'portal_themes') ## # the first theme in each category is the default theme. ## themes_list = {'WAeUP': ({'id': 'waeup_plain_theme', ## 'file': 'waeup_plain_theme.zexp', ## }, ## {'id': 'waeup_management_theme', ## 'file': 'waeup_management_theme.zexp', ## }, ## ), ## } ## ## ## theme_ids = theme_container.objectIds() ## theme_container.manage_delObjects(theme_ids) ## target_themes = themes_list[Target] ## for theme in target_themes: ## pr(" Importing %s theme" % theme['id']) ## zexppath = os.path.join(zexpdir, theme['file']) ## try: ## theme_container._importObjectFromFile(zexppath) ## except: ## pr(" Could not import theme %s" % theme['id']) ## ## # set the first theme in the list as the default one. ## theme_container.setDefaultTheme(target_themes[0]['id']) ###) ########################################## # portal types ########################################## dtypes = portal.getWAeUPTypes() self.verifyFlexibleTypes(dtypes) self.allowContentTypes('University', ('Workspace','Section',)) ########################################## # Schemas ########################################## pr("Verifying %(product_name)s schemas" % vars()) self.verifySchemas(portal.getWAeUPSchemas()) ########################################## # widgets ########################################## pr("Verifying %(product_name)s widgets" % vars()) self.verifyWidgets(portal.getWAeUPWidgets()) ########################################## # layouts ########################################## pr("Verifying %(product_name)s layouts" % vars()) self.verifyLayouts(portal.getWAeUPLayouts()) ########################################## # Vocabularies ########################################## pr("Verifying %(product_name)s vocabularies" % vars()) self.verifyVocabularies(portal.getWAeUPVocabularies()) ########################################## # Groups ########################################## self.installCustomWorkflows() self.verifyWorkflowAssociation() pr("End of specific %(product_name)s install" % vars()) #return '\n'.join(log) self.finalize() def verifyPortlets(self, portlets=(), object=None): ###( """Verify the existence of given portet in the object's portlet container. If not found, a portlet is instantiated. Existing portlets are not affected. 'portlets' is a tuple with the dictionaries given by the export tab as entries. The default object is the portal itself. return the list a new portlet ids. """ if object is None: object = self.portal self.log('Verifying portlets on %s' % object.absolute_url(relative=1)) portlet_container = self.getPortletContainer(object, create=1) ttool = self.getTool('portal_types') returned = [] for new_portlet in portlets: existing_portlets = portlet_container.listPortlets() updated = 0 # Check if the portlet needs an update identifier = new_portlet.get('identifier') if identifier: for portlet in existing_portlets: if identifier == portlet.identifier: self.log(" Update of portlet: %s" % portlet) portlet.edit(**new_portlet) portlet_id = portlet.getId() updated = 1 continue slot = new_portlet.get('slot') if slot: for portlet in existing_portlets: if slot == portlet.slot: self.log(" Update of portlet: %s" % portlet) portlet.edit(**new_portlet) portlet_id = portlet.getId() updated = 1 continue if not updated: self.log(" Creation of portlet: %s" % new_portlet) portlet_id = self.portal.portal_cpsportlets.createPortlet( ptype_id=new_portlet['type'], context=object, **new_portlet) if portlet_id not in returned: returned.append(portlet_id) return returned ###) def installCustomWorkflows(self): ###( """Installs custom workflows """ from Products.WAeUP.Workflows.WAeUPWorkflow import \ waeupWorkflowsInstall waeupWorkflowsInstall(self.context) ###) def verifyWorkflowAssociation(self): ###( """Verify workflow association """ ws_chains = { 'Student': 'waeup_workspace_wf', 'Jamb': 'waeup_workspace_wf', } se_chains = { 'University': 'waeup_section_wf', 'AcademicsFolder': 'waeup_section_wf', 'StudentsFolder': 'waeup_student_wf', 'Student': 'waeup_student_wf', 'StudentPersonal': 'waeup_student_wf', 'Jamb': 'waeup_section_wf', 'ScratchCard': 'waeup_section_wf', 'Faculty': 'waeup_section_wf', 'Department': 'waeup_section_wf', 'Course': 'waeup_section_wf', 'StudyLevel': 'waeup_student_wf', 'Semester': 'waeup_student_wf', 'CourseTicket': 'waeup_student_wf', 'AccoFolder': 'waeup_section_wf', 'Accommodation': 'waeup_section_wf', } self.verifyLocalWorkflowChains(self.portal['workspaces'], ws_chains, destructive=1) self.verifyLocalWorkflowChains(self.portal['sections'], se_chains, destructive=1) ###) def install(self): ###( installer = WAeUPInstaller(self) installer.install(self) dirtool = getattr(self,'portal_directories') groups = dirtool.groups for delEntry in ('StudentManager',): if delEntry in groups.listEntryIds(): groups.deleteEntry(delEntry) for newEntry in ('Students',): if newEntry not in groups.listEntryIds(): groups.createEntry({'group': newEntry, 'members': []}) #groups.manage_setLocalGroupRoles(groupid = 'StudentManager',roles=('Manager',)) #groups.manage_setLocalGroupRoles(groupid = 'Students',roles=('Contributor',)) sections = getattr(self,'sections') waeup = getattr(sections,SRPP_ID,None) if not waeup: sections.invokeFactory('University',SRPP_ID) waeup = getattr(sections,SRPP_ID) waeup.getContent().edit(mapping={'Title':SRPP_TITLE}) waeup.folder_localrole_add(member_ids=('group:Students',), member_role='SectionReviewer', ) waeup.invokeFactory('StudentsFolder','students') students = getattr(waeup,'students').getContent() students.edit(mapping={'Title':'Students'}) waeup.folder_localrole_add(member_ids=('group:Students',), member_role='SectionReviewer', ) ## waeup.content_create(type_name='AcademicsFolder',title='academics') ## sections.waeup.folder_localrole_add(member_ids=('group:StudentManager',), ## member_role='SectionManager', ## ) waeup.students.manage_setLocalGroupRoles(groupid = 'Students',roles=('Contributor',)) waeup.invokeFactory('AcademicsFolder','academics', title='Academics') academics = getattr(waeup,'academics').getContent() academics.edit(mapping={'Title':'Academics'}) waeup.invokeFactory('AccoFolder','accommodation', title='Accommodation') accommodation = getattr(waeup,'accommodation').getContent() accommodation.edit(mapping={'Title':'Accommodation'}) if not hasattr(waeup,'academics'): waeup.invokeFactory('AcademicsFolder','academics') academics = getattr(waeup,'academics').getContent() academics.edit(mapping={'Title':'Academics'}) if not hasattr(waeup,'accommodation'): waeup.invokeFactory('AccoFolder','accommodation') accommodation = getattr(waeup,'accommodation').getContent() accommodation.edit(mapping={'Title':'Accommodation'}) waeup.manage_setLocalGroupRoles(groupid = 'role:Anonymous',roles=('SectionReader',)) # portlets ###( # portlets = ( ## {'identifier': 'waeup_main_tabs', ## 'type': 'Custom Portlet', ## 'slot': 'main_tabs', ## 'order': 0, ## 'render_method': 'portlet_main_navigation', ## 'Title': 'main tabs', ## }, {#'identifier': 'waeup_breadcrumbs', 'type': 'Breadcrumbs Portlet', 'slot': 'waeup_breadcrumbs', 'first_item': 0, 'display_site_root': 0, 'Title': 'waeup_breadcrumbs', 'display': 'horizontal_trail', 'display_hidden_folders': 0, 'order': 0, }, {#'identifier': 'waeup_main_tab_actions', 'type': 'Actions Portlet', 'slot': 'main_tabs', 'order': 0, 'categories': ['main_tabs',], 'Title': 'waep_main_tab_actions', }, {#'identifier': 'waeup_object_actions', 'type': 'Actions Portlet', 'slot': 'waeup_object_actions', 'order': 0, 'categories': ['object',], 'Title': 'waep_manager_actions', }, {#'identifier': 'waeup_left_top', 'type': 'Custom Portlet', 'slot': 'left_top', 'order': 0, 'render_method': 'portlet_session_info', 'Title': 'Session Info', }, ) installer.verifyPortletContainer(waeup) installer.verifyPortlets(portlets,waeup) ###) return installer.logResult() ###) def migrate(self): ###( "update data" log = [] prlog = log.append def pr(msg, prlog=prlog): prlog('%s' % msg) sections = getattr(self,'sections') waeup = getattr(sections,SRPP_ID,None) pr( "Start migrate") pr("migrating courses") academics = getattr(waeup,'academics') for fac in [getattr(academics,f.id) for f in academics.contentValues(filter={'portal_type': ('Faculty',)})]: pr("Faculty: %s" % fac.title_or_id()) for dep in [getattr(fac,d.id) for d in fac.contentValues(filter={'portal_type': ('Department',)})]: pr("Department: %s" % dep.title_or_id()) for course in [getattr(dep,c.id) for c in dep.contentValues(filter={'portal_type': ('Course',)})]: pr("Course: %s" % course.title_or_id()) content = course.getContent() heading = getattr(content,'heading',course.id) pr("heading = %(heading)s" % vars()) content.edit(mapping={'Title': heading}) pr("migrating halls") for ac in [getattr(waeup,a.id) for a in waeup.contentValues(filter={'portal_type': ('AccoFolder',)})]: for hall in [getattr(ac,h.id) for h in ac.contentValues(filter={'portal_type': ('Accommodation',)})]: pr("Hall: %s" % hall.title_or_id()) content = hall.getContent() heading = getattr(content,'heading',hall.id) pr("heading = %(heading)s" % vars()) content.edit(mapping={'Title': heading}) return '\n'.join(log) ###)