Changeset 513
- Timestamp:
- 08/04/09 15:42:43 (3 years ago)
- Location:
- enpraxis.educommons/trunk/enpraxis/educommons
- Files:
-
- 2 modified
-
extras/PreMigrate.py (modified) (5 diffs)
-
upgrades/v3_1_1_to_3_2_1.py (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
enpraxis.educommons/trunk/enpraxis/educommons/extras/PreMigrate.py
r506 r513 23 23 from Products.CMFCore.utils import getToolByName 24 24 from StringIO import StringIO 25 from Products. ATContentTypes.migration.walker import CatalogWalker26 from Products. ATContentTypes.migration.migrator import CMFFolderMigrator, CMFItemMigrator25 from Products.contentmigration.basemigrator.walker import CatalogWalker 26 from Products.contentmigration.basemigrator.migrator import CMFFolderMigrator 27 27 from zope.app.annotation.interfaces import IAnnotations, IAttributeAnnotatable 28 from zope.component import getUtility, getMultiAdapter 28 29 from zope.interface import directlyProvidedBy, directlyProvides 29 from Products.CMFPlone import transaction 30 from Products.CMFPlone.PloneTool import transaction 31 from plone.portlets.interfaces import IPortletManager, IPortletAssignmentMapping 30 32 31 33 # base class to migrate objects and retain their license annotations 32 class ObjectMigrator(CMFItemMigrator):33 """Persist annotations to new object"""34 35 def migrate_annotations(self):36 """Persist annotations"""37 if hasattr(self.old, '__annotations__'):38 annotations = self.old.__annotations__39 self.new.__annotations__ = annotations40 41 def migrate_clearcopyright(self):42 """Migrate clear copyright status to annotation """43 if hasattr(self.old, 'clearedCopyright'):44 copyright_status = self.old.getClearedCopyright()45 """ Manually append field to default content type """46 self.new.__annotations__['eduCommons.clearcopyright'] = copyright_status47 48 def migrate_current_workflow(self):49 """Annotate the current workflow state"""50 wft = self.old.portal_url.portal_workflow51 cur_state = wft.getInfoFor(self.old, 'review_state')52 self.new.__annotations__['review_state'] = cur_state53 54 34 class eduCommonsFoldersMigrator(CMFFolderMigrator): 55 35 """Persist annotations to new object""" … … 75 55 76 56 77 78 class ECCourseMigrator(eduCommonsFoldersMigrator): 57 class CourseMigrator(eduCommonsFoldersMigrator): 79 58 """Base class to migrate to Folder """ 80 59 81 60 def migrate_courseproperties(self): 82 """Place course specific fields in an annotation, to be used post-install of 3.0.1 """ 83 if hasattr(self.old, 'Term'): 84 self.new.__annotations__['course.term'] = self.old.Term 85 if hasattr(self.old, 'CourseId'): 86 self.new.__annotations__['course.courseid'] = self.old.CourseId 87 if hasattr(self.old, 'InstructorName'): 88 self.new.__annotations__['course.instructorname'] = self.old.InstructorName 89 if hasattr(self.old, 'instructorAsPrincipalCreator'): 90 self.new.__annotations__['course.instructor_principal'] = self.old.instructorAsPrincipalCreator 91 if hasattr(self.old, 'InstructorEmail'): 92 self.new.__annotations__['course.instructoremail'] = self.old.InstructorEmail 93 if hasattr(self.old, 'displayInstructorEmail'): 94 self.new.__annotations__['course.displayInstructorEmail'] = self.old.displayInstructorEmail 95 61 """Place course specific fields in an annotation, to be used in 3.1.1 to 3.2.1 migration """ 62 if hasattr(self.old, 'term'): 63 self.new.__annotations__['course.term'] = self.old.term 64 if hasattr(self.old, 'courseId'): 65 self.new.__annotations__['course.courseid'] = self.old.courseId 66 if hasattr(self.old, 'structure'): 67 self.new.__annotations__['course.structure'] = self.old.structure 68 if hasattr(self.old, 'level'): 69 self.new.__annotations__['course.level'] = self.old.level 70 if hasattr(self.old, 'instructorName'): 71 self.new.__annotations__['course.instructorname'] = self.old.instructorName 72 if hasattr(self.old, 'instructorAsCreator'): 73 self.new.__annotations__['course.instructor_principal'] = self.old.instructorAsCreator 74 if hasattr(self.old, 'instructorEmail'): 75 self.new.__annotations__['course.instructoremail'] = self.old.instructorEmail 76 if hasattr(self.old, 'displayInstEmail'): 77 self.new.__annotations__['course.displayInstructorEmail'] = self.old.displayInstEmail 78 if hasattr(self.old, 'crosslisting'): 79 self.new.__annotations__['course.crosslisting'] = self.old.crosslisting 96 80 text = self.old.getText() 97 81 self.new.__annotations__['course.text'] = text 98 99 #Remove right_slots portlets 100 self.old.manage_delProperties(['right_slots',]) 101 82 83 def migrate_portlets(self): 84 """ Remove the portlets associated with the course """ 85 rightColumn = getUtility(IPortletManager, name=u'plone.rightcolumn', context=self.new) 86 right = getMultiAdapter((self.new, rightColumn), IPortletAssignmentMapping, context=self.new) 87 del right['OER Recommender'] 88 del right['Course Summary'] 89 del right['Reuse Course'] 102 90 103 91 walkerClass = CatalogWalker 104 src_meta_type = ' ECCourse'105 src_portal_type = ' ECCourse'92 src_meta_type = 'Course' 93 src_portal_type = 'Course' 106 94 dst_meta_type = 'ATFolder' 107 95 dst_portal_type = 'Folder' 108 96 109 class ECDepartmentMigrator(eduCommonsFoldersMigrator):97 class DivisionMigrator(eduCommonsFoldersMigrator): 110 98 """Base class to migrate to Folder """ 111 99 112 100 def migrate_deptproperties(self): 113 """Place course specific fields in an annotation, to be used post-install of 3.0.1"""101 """Place course specific fields in an annotation, to be used in 3.1.1 to 3.2.1 migration """ 114 102 text = self.old.getText() 115 103 self.new.__annotations__['dept.text'] = text … … 117 105 118 106 walkerClass = CatalogWalker 119 src_meta_type = ' ECDepartment'120 src_portal_type = ' ECDepartment'107 src_meta_type = 'Division' 108 src_portal_type = 'Division' 121 109 dst_meta_type = 'ATFolder' 122 110 dst_portal_type = 'Folder' 123 111 124 class ECFolderMigrator(eduCommonsFoldersMigrator): 125 """Base class to migrate to Folder """ 126 127 walkerClass = CatalogWalker 128 src_meta_type = 'ECFolder' 129 src_portal_type = 'ECFolder' 130 dst_meta_type = 'ATFolder' 131 dst_portal_type = 'Folder' 132 133 map = {'getExcludeFromNav' : 'setExcludeFromNav'} 134 135 136 137 # Object migrators 138 class GFolderMigrator(CMFFolderMigrator): 139 """Base class to migrate to Folder """ 140 141 walkerClass = CatalogWalker 142 src_meta_type = 'GFolder' 143 src_portal_type = 'GFolder' 144 dst_meta_type = 'ATFolder' 145 dst_portal_type = 'Folder' 146 147 def migrate_current_workflow(self): 148 """Annotate the current workflow state""" 149 wft = self.old.portal_url.portal_workflow 150 cur_state = wft.getInfoFor(self.old, 'review_state') 151 self.new.__annotations__['review_state'] = cur_state 152 153 map = {'getExcludeFromNav' : 'setExcludeFromNav'} 154 155 156 class ECDocumentMigrator(ObjectMigrator): 157 """Base class to migrate to Document """ 158 159 walkerClass = CatalogWalker 160 src_meta_type = 'ECDocument' 161 src_portal_type = 'ECDocument' 162 dst_meta_type = 'ATDocument' 163 dst_portal_type = 'Document' 164 map = {'getRawText' : 'setText', 165 'getExcludeFromNav' : 'setExcludeFromNav'} 166 167 class GDocumentMigrator(ObjectMigrator): 168 """Base class to migrate to Document """ 169 170 walkerClass = CatalogWalker 171 src_meta_type = 'GDocument' 172 src_portal_type = 'GDocument' 173 dst_meta_type = 'ATDocument' 174 dst_portal_type = 'Document' 175 map = {'getRawText' : 'setText', 176 'Format' : 'setFormat', 177 'getExcludeFromNav' : 'setExcludeFromNav'} 178 179 class ECFileMigrator(ObjectMigrator): 180 """Base class to migrate to File """ 181 182 walkerClass = CatalogWalker 183 src_meta_type = 'ECFile' 184 src_portal_type = 'ECFile' 185 dst_meta_type = 'ATFile' 186 dst_portal_type = 'File' 187 map = {'getFile' : 'setFile', 188 'getExcludeFromNav' : 'setExcludeFromNav'} 189 190 class GFileMigrator(ObjectMigrator): 191 """Base class to migrate to File """ 192 193 walkerClass = CatalogWalker 194 src_meta_type = 'GFile' 195 src_portal_type = 'GFile' 196 dst_meta_type = 'ATFile' 197 dst_portal_type = 'File' 198 map = {'getFile' : 'setFile', 199 'getExcludeFromNav' : 'setExcludeFromNav'} 200 201 class ECImageMigrator(ObjectMigrator): 202 """Base class to migrate to default Image """ 203 204 walkerClass = CatalogWalker 205 src_meta_type = 'ECImage' 206 src_portal_type = 'ECImage' 207 dst_meta_type = 'ATImage' 208 dst_portal_type = 'Image' 209 map = {'getImage' : 'setImage', 210 'getExcludeFromNav' : 'setExcludeFromNav'} 211 212 class GImageMigrator(ObjectMigrator): 213 """Base class to migrate to default Image """ 214 215 walkerClass = CatalogWalker 216 src_meta_type = 'GImage' 217 src_portal_type = 'GImage' 218 dst_meta_type = 'ATImage' 219 dst_portal_type = 'Image' 220 map = {'getImage' : 'setImage', 221 'getExcludeFromNav' : 'setExcludeFromNav'} 222 223 class ECLinkMigrator(ObjectMigrator): 224 """Base class to migrate to default Link""" 225 226 walkerClass = CatalogWalker 227 src_meta_type = 'ECLink' 228 src_portal_type = 'ECLink' 229 dst_meta_type = 'ATLink' 230 dst_portal_type = 'Link' 231 map = {'getRemoteUrl' : 'setRemoteUrl', 232 'getExcludeFromNav' : 'setExcludeFromNav'} 233 234 def pre_migrate_2_3_1_to_3_0_4(self): 112 def pre_migrate_3_1_1_to_3_2_1(self): 235 113 """Run the migration""" 236 114 … … 241 119 portal = portal_url.getPortalObject() 242 120 243 244 121 #create migrateable_properties to migrate old site props 245 site_props = portal.portal_properties.site_properties246 122 portal.portal_properties.addPropertySheet('migrateable_properties', 'Old Site Properties') 247 123 m_props = portal.portal_properties.migrateable_properties 248 124 249 125 m_props.manage_addProperty(id='site_title', type='string', value=portal.title) 250 126 m_props.manage_addProperty(id='description', type='string', value=portal.description) 251 127 m_props.manage_addProperty(id='email_from_address', type='string', value=portal.email_from_address) 252 128 m_props.manage_addProperty(id='email_from_name', type='string', value=portal.email_from_name) 253 m_props.manage_addProperty(id='division_descriptor', type='string', value=site_props.institution_object)254 m_props.manage_addProperty(id='course_descriptor', type='string', value=site_props.institution_sub_object)255 129 256 #create ims_properties to migrate out of tool 257 portal.portal_properties.addPropertySheet('ims_properties', 'IMS Transport Properties') 258 ims_props = portal.portal_properties.ims_properties 259 IMStool = portal.portal_IMSTransportTool 260 for prop in IMStool.propertyMap(): 261 if prop['id'] != 'title': 262 #make an ims_properties entry 263 id = prop['id'] 264 type = prop['type'] 265 value = IMStool.getProperty(id) 266 ims_props.manage_addProperty(id=id, type=type, value=value) 267 268 #create contentlicensing_properties to capture tool props that need to migrate 269 portal.portal_properties.addPropertySheet('contentlicensing_properties', 'Content Licensing Properties') 270 cl_props = portal.portal_properties.contentlicensing_properties 271 CLtool = portal.portal_contentlicensing 272 for prop in CLtool.propertyMap(): 273 if prop['id'] != 'title': 274 id = prop['id'] 275 type = prop['type'] 276 value = CLtool.getProperty(id) 277 if id == 'Jurisdiction': 278 type = 'string' 279 cl_props.manage_addProperty(id=id, type=type, value=value) 280 281 transaction.commit() 282 283 #create annotation for position in course, as one cannot access it properly in the migrators 284 brains = portal.portal_catalog.searchResults(portal_type=['ECFolder', 285 'ECImage', 286 'ECDocument', 287 'ECFile', 288 'ECLink'], 289 path='/') 290 for brain in brains: 291 obj = brain.getObject() 292 #Only annotate those objects set to show in Navigation 293 if obj.getExcludeFromNav() == False: 294 if not hasattr(obj, '__annotations__') and obj.portal_type != 'ECLink': 295 annotations = IAnnotations(obj) 296 annotations['eduCommons.objPositionInCourse'] = '' 297 if obj.portal_type in ['ECFolder', 'ECImage', 'ECDocument', 'ECFile']: 298 pos = obj.getNavPosition() 299 obj.__annotations__['eduCommons.objPositionInCourse'] = pos + 2 300 elif obj.portal_type == 'ECLink': 301 #Links are not annotatable by default, allow each Link to be annotatable 302 directly = directlyProvidedBy(obj) 303 directlyProvides(obj, directly + IAttributeAnnotatable) 304 annotations = IAnnotations(obj) 305 pos = obj.getNavPosition() 306 annotations['eduCommons.objPositionInCourse'] = pos + 2 307 308 transaction.commit() 309 310 migrators = ( 311 GDocumentMigrator, ECDocumentMigrator, 312 GFileMigrator, ECFileMigrator, 313 GImageMigrator, ECImageMigrator, 314 ECLinkMigrator, ECFolderMigrator, 315 ECDepartmentMigrator, ECCourseMigrator, 316 GFolderMigrator,) 130 migrators = ( DivisionMigrator, CourseMigrator) 317 131 318 132 for migrator in migrators: … … 322 136 print >> out, walker.getOutput() 323 137 324 325 138 #Refresh catalog indices 326 139 self.portal_catalog.reindexIndex(self.portal_catalog.indexes(),None) 327 328 #remove display_view from front_page329 fp = getattr(self, 'front-page', None)330 331 if fp:332 fp.manage_delProperties(['layout',])333 print >> out, "Removed layout from front-page"334 335 336 #remove caching policy337 self.caching_policy_manager.removePolicy('ECImageAndECFilePolicy')338 print >> out, "Removed Image and File Caching Policy"339 340 #uninstall FCKEditor341 if self.portal_quickinstaller.isProductInstalled('FCKeditor'):342 self.portal_quickinstaller.uninstallProducts(products=['FCKeditor'])343 print >> out, "Uninstalled FCKEditor"344 if not self.portal_quickinstaller.isProductInstalled('Kupu'):345 self.portal_quickinstaller.installProducts(products=['Kupu'])346 self.portal_properties.site_properties.available_editors = ('None', 'Kupu')347 print >> out, "Installed Kupu"348 349 #Rename default objects350 #Need to add Folder back to addable for Plone Site first....351 pt = self.portal_types352 plone_site = pt.getTypeInfo('Plone Site')353 plone_site.allowed_content_types += ('Folder',)354 355 ap = getattr(self, 'About', None)356 if ap:357 ap.setId('about')358 359 hp = getattr(self, 'Help', None)360 if hp:361 hp.setId('help')362 363 fp = getattr(self, 'Feedback', None)364 if fp:365 fp.setId('feedback')366 140 367 141 print >> out, "Migration finished" -
enpraxis.educommons/trunk/enpraxis/educommons/upgrades/v3_1_1_to_3_2_1.py
r511 r513 21 21 __version__ = '$ Revision 0.0 $'[11:-2] 22 22 23 23 from Products.CMFPlone.utils import _createObjectByType 24 from StringIO import StringIO 24 25 import string 25 26 from zope.component import getUtility, getMultiAdapter 26 27 from Products.CMFCore.utils import getToolByName 27 28 from enpraxis.educommons.browser.packagecourseview import appendObjPosition 29 from enpraxis.educommons import portlet 28 30 from collective.imstransport.utilities.interfaces import IIMSTransportUtility 31 from plone.portlets.interfaces import IPortletManager, IPortletAssignmentMapping 29 32 30 33 def migrate(portal_setup): 31 34 """ Migration from eduCommons 3.1.1 to 3.2.1 """ 32 35 out = StringIO() 36 print >> out, '<h3>Starting Migration</h3>\n' 37 print >> out, '<ul>\n' 38 39 self = portal_setup 40 33 41 portal_url = getToolByName(portal_setup, 'portal_url') 34 portal= portal_url.getPortalObject() 35 36 updateAdmins(portal) 37 updateBaseProperties(portal) 38 updateCourses(portal) 39 40 41 def updateAdmins(portal): 42 portal= portal_url.getPortalObject() 43 44 oldsite = getattr(portal.aq_parent, 'eduCommons') 45 46 deleteDefaultContent(self, portal, out) 47 copyZMIObjects(self, portal, oldsite, out) 48 copyFolders(self, portal, oldsite, out) 49 migrateTheme(self, portal, oldsite, out) 50 migrateProperties(self, portal, oldsite, out) 51 migrateUsers(self, portal, oldsite, out) 52 updateAdmins(self, portal, oldsite, out) 53 updateBaseProperties(self, portal, oldsite, out) 54 #deleteOldSite(self, portal, oldsite, out) 55 56 def deleteDefaultContent(self, portal, out): 57 """ Remove default objects """ 58 portal.manage_delObjects(['about', 'help', 'front-page']) 59 print >> out, '<li>Deleted default content</li>\n' 60 61 def copyZMIObjects(self, portal, oldsite, out): 62 """ Copies old objects to new instace """ 63 portal.MailHost = oldsite.MailHost 64 portal.portal_skins.custom = oldsite.portal_skins.custom 65 66 def copyFolders(self, portal, oldsite, out): 67 """ Copies the top level folders from oldsite to portal """ 68 69 folders = oldsite.portal_catalog.searchResults(Type='Folder', 70 path={'query':'/', 71 'depth':2,}) 72 print >> out, ' <li>Copying Folders</li>\n' 73 print >> out, ' <ul>\n' 74 75 for folder in folders: 76 obj = folder.getObject() 77 if obj.__annotations__.has_key('dept.text'): 78 migrateDivision(self, portal, obj) 79 else: 80 co = oldsite.manage_copyObjects(obj.id) 81 portal.manage_pasteObjects(co) 82 setWorkflow(self, getattr(portal, obj.id), obj) 83 print >> out, ' <li>Copied %s</li>\n' %obj.Title() 84 print >> out, ' </ul>\n' 85 print >> out, ' <li>Copied Content</li>\n' 86 87 # Migrate other top level content 88 89 objs = oldsite.portal_catalog.searchResults(portal_type=['File', 'Image', 'Document'], 90 path={'query':'/', 91 'depth':2,}) 92 obj_ids = [x.id for x in objs] 93 co = oldsite.manage_copyObjects(obj_ids) 94 portal.manage_pasteObjects(co) 95 for x in obj_ids: 96 obj = getattr(oldsite, x) 97 newobj = getattr(portal, x) 98 if x != 'front-page': 99 newobj.setExcludeFromNav(True) 100 if obj.__annotations__.has_key('review_state'): 101 moveWorkflow(self, newobj, obj.__annotations__['review_state']) 102 103 104 105 def migrateTheme(self, portal, oldsite, out): 106 """ Delete default base_properties in portal and migrate oldsite base_properties """ 107 if getattr(oldsite.portal_skins.custom, 'base_properties', None): 108 old_custom = oldsite.portal_skins.custom 109 new_custom = portal.portal_skins.custom 110 new_custom.base_properties = old_custom.base_properties 111 print >> out, ' <li>Migrated theme</li>\n' 112 113 114 def migrateProperties(self, portal, oldsite, out): 115 """ Transfer old properties to new """ 116 #Migrate eduCommons Properties 117 old_ec_props = oldsite.portal_properties.educommons_properties 118 new_ec_props = portal.portal_properties.educommons_properties 119 for prop in old_ec_props.propertyMap(): 120 #Overwrite default new values with default old values 121 if prop['id'] in new_ec_props.propertyIds(): 122 id = prop['id'] 123 key_value = {id : old_ec_props.getProperty(id) } 124 new_ec_props.manage_changeProperties(**key_value) 125 #Add properties if they don't exist in new 126 else: 127 id = prop['id'] 128 type = prop['type'] 129 value = old_ec_props.getProperty(id) 130 new_ec_props.manage_addProperty(id=id, type=type, value=value) 131 132 print >> out, ' <li>Migrated eduCommons Properties</li>\n' 133 134 #Migrate ContentLicensing Propertiese 135 old_cl_props = oldsite.portal_properties.content_licensing_properties 136 new_cl_props = portal.portal_properties.content_licensing_properties 137 for prop in old_cl_props.propertyMap(): 138 #Overwrite default new values with default old values 139 if prop['id'] in new_cl_props.propertyIds(): 140 id = prop['id'] 141 if id != 'Jurisdiction': 142 key_value = {id : old_cl_props.getProperty(id) } 143 new_cl_props.manage_changeProperties(**key_value) 144 else: 145 for value in new_cl_props.jurisdiction_options: 146 if old_cl_props.getProperty(id) in value: 147 new_cl_props.manage_changeProperties(Jurisdiction=value) 148 #Add properties if they don't exist in new 149 else: 150 id = prop['id'] 151 type = prop['type'] 152 value = old_cl_props.getProperty(id) 153 new_cl_props.manage_addProperty(id=id, type=type, value=value) 154 155 print >> out, ' <li>Migrated ContentLicensing Properties</li>\n' 156 157 #Migrate relevant old site properties 158 old_site_props = oldsite.portal_properties.migrateable_properties 159 portal.manage_changeProperties(title=old_site_props.site_title, 160 description=old_site_props.description, 161 email_from_address=old_site_props.email_from_address, 162 email_from_name=old_site_props.email_from_name 163 ) 164 165 print >> out, ' <li>Migrated Site properties</li>\n' 166 167 168 169 def migrateUsers(self, portal, oldsite, out): 170 """ Migrate Users """ 171 old_users = oldsite.acl_users.manage_copyObjects(['local_roles', 172 'mutable_properties', 173 'portal_role_manager', 174 'source_groups', 175 'source_users']) 176 portal.acl_users.manage_delObjects(['local_roles', 177 'mutable_properties', 178 'portal_role_manager', 179 'source_groups', 180 'source_users']) 181 portal.acl_users.manage_pasteObjects(old_users) 182 183 #Activate plugins for each copied object 184 acl_users = portal.acl_users 185 acl_users.local_roles.manage_activateInterfaces(['ILocalRolesPlugin', 186 'IRolesPlugin']) 187 acl_users.mutable_properties.manage_activateInterfaces(['IPropertiesPlugin', 188 'IUserEnumerationPlugin']) 189 acl_users.portal_role_manager.manage_activateInterfaces(['IRoleAssignerPlugin', 190 'IRoleEnumerationPlugin', 191 'IRolesPlugin']) 192 acl_users.source_groups.manage_activateInterfaces(['IGroupEnumerationPlugin', 193 'IGroupIntrospection', 194 'IGroupManagement', 195 'IGroupsPlugin']) 196 acl_users.source_users.manage_activateInterfaces(['IAuthenticationPlugin', 197 'IUserAdderPlugin', 198 'IUserEnumerationPlugin', 199 'IUserIntrospection', 200 'IUserManagement']) 201 202 old_pgd = oldsite.portal_groupdata 203 portal.portal_groupdata = old_pgd 204 205 old_pmd = oldsite.portal_memberdata 206 portal.portal_memberdata = old_pmd 207 208 #Set all users default editor to Kupu 209 users = portal.acl_users.getUsers() 210 for user in users: 211 user.setProperties(wysiwyg_editor = 'Kupu') 212 213 print >> out, ' <li>Migrated Users</li>\n' 214 215 216 def updateAdmins(self, portal, oldsite, out): 42 217 """ Convert users that have administrator role to have manager role """ 43 218 users = portal.acl_users.getUsers() … … 54 229 portal.acl_users.userFolderEditUser(user.getId(), None, roles, user.getDomains()) 55 230 56 def updateBaseProperties( portal):231 def updateBaseProperties(self, portal, oldsite, out): 57 232 """ Update logo.gif to logo.png to """ 58 233 custom = portal.portal_skins.custom.aq_inner.aq_explicit … … 63 238 base_props.manage_changeProperties(logoName='logo.png') 64 239 65 def updateCourses(portal): 66 """ Convert existent zipped course downloads to new Common Cartridge based package """ 67 68 course_brains = portal.portal_catalog(path= {'query':'/'.join(portal.getPhysicalPath())+'/'}, portal_type='Course') 69 70 for course in course_brains: 71 course = course.getObject() 72 73 #repackage Download this Course object for existent courses 74 zip_exists = 0 75 for object in course.listFolderContents(): 76 if 'download this course' == string.lower(object.Title()): 77 #delete object, repackage as FSS based IMS package 78 zip_exists = 1 79 course.manage_delObjects([object.getId()]) 80 81 if zip_exists == 1: 82 file_id = course.id + '.zip' 83 84 ims_util = getUtility(IIMSTransportUtility) 85 data, course = ims_util.exportPackage(course, file_id, packagetype='IMS Common Cartridge') 86 87 course.invokeFactory("FSSFile",id=file_id, title="Download this Course") 88 fileobj = getattr(course,file_id) 89 publishObject(fileobj) 90 fileobj.setTitle("Download This Course") 91 92 fileobj.setFile(data) 93 appendObjPosition(fileobj) 94 95 course.portal_catalog.reindexObject(fileobj) 240 def repackageCourse(self, course): 241 """ Convert existent zipped course downloads to new Common Cartridge based package """ 242 file_id = course.id + '.zip' 243 244 ims_util = getUtility(IIMSTransportUtility) 245 data, course = ims_util.exportPackage(course, file_id, packagetype='IMS Common Cartridge') 246 247 course.invokeFactory("FSSFile",id=file_id, title="Download this Course") 248 fileobj = getattr(course,file_id) 249 publishObject(fileobj) 250 fileobj.setTitle("Download This Course") 251 252 fileobj.setFile(data) 253 fileobj.setExcludeFromNav(True) 254 appendObjPosition(fileobj) 255 256 course.portal_catalog.reindexObject(fileobj) 257 258 def deleteOldSite(self, portal, oldsite, out): 259 """ Remove the old site """ 260 app = self.aq_parent.aq_parent 261 app.manage_delObjects(oldsite.getId()) 262 app.manage_renameObject(portal.getId(), 'eduCommons', REQUEST=None) 263 264 print >> out, '</ul>\n' 265 print >> out, 'Done.\n' 266 return out.getvalue() 96 267 97 268 def publishObject(context): … … 105 276 106 277 107 108 109 278 def migrateDivision(self, portal, dobj): 279 """ Migrate a division from the old site to the new. """ 280 # Create a new division 281 _createObjectByType('Division', 282 portal, 283 id=dobj.getId(), 284 title=dobj.Title(), 285 description=dobj.Description(), 286 subject=dobj.Subject(), 287 contributors=dobj.Contributors(), 288 creators=dobj.Creators(), 289 language=dobj.Language(), 290 rights=dobj.Rights(), 291 creation_date=dobj.CreationDate(), 292 ) 293 # Copy over remaining division attributes 294 div = getattr(portal, dobj.getId()) 295 div.setText(dobj.__annotations__['dept.text']) 296 #div.syndication_information = dobj.syndication_information 297 for x in dobj.__annotations__.keys(): 298 if 'review_state' == x: 299 moveWorkflow(self, div, dobj.__annotations__[x]) 300 if x != 'dept.text': 301 div.__annotations__[x] = dobj.__annotations__[x] 302 303 # Copy Course sub objects 304 oc = [] 305 for oid,obj in dobj.objectItems(): 306 if 'Folder' == obj.Type(): 307 ann = getattr(obj, '__annotations__', None) 308 if ann and ann.has_key('course.text'): 309 migrateCourse(self, div, obj) 310 elif oid != 'syndication_information': 311 oc.append(oid) 312 else: 313 oc.append(oid) 314 315 # Copy all other sub objects 316 co = dobj.manage_copyObjects(oc) 317 div.manage_pasteObjects(co) 318 319 for oid,obj in div.objectItems(): 320 if 'Course' != obj.Type() and 'syndication_information' != oid: 321 moveWorkflow(self, obj, getattr(dobj, oid).__annotations__['review_state']) 322 obj.workflow_history = getattr(dobj, oid).workflow_history 323 324 def migrateCourse(self, div, cobj): 325 """ Migrate a course from the old site to the new. """ 326 327 # Create a new course 328 _createObjectByType('Course', 329 div, 330 id=cobj.getId(), 331 title=cobj.Title(), 332 description=cobj.Description(), 333 subject=cobj.Subject(), 334 contributors=cobj.Contributors(), 335 creators=cobj.Creators(), 336 language=cobj.Language(), 337 rights=cobj.Rights(), 338 creation_date=cobj.CreationDate(), 339 ) 340 341 # Copy over remaining course attributes 342 course = getattr(div, cobj.getId()) 343 course.setText(cobj.__annotations__['course.text']) 344 a2f = {'course.term':'term', 345 'course.courseid':'courseId', 346 'course.instructorname':'instructorName', 347 'course.instructor_principal':'instructorAsCreator', 348 'course.instructoremail':'instructorEmail', 349 'course.displayInstructorEmail':'displayInstEmail', 350 'course.structure':'structure', 351 'course.level':'level', 352 'course.crosslisting':'crosslisting'} 353 354 for x in cobj.__annotations__: 355 if x in a2f: 356 mut = course.getField(a2f[x]).getMutator(course) 357 mut(cobj.__annotations__[x]) 358 elif 'review_state' == x: 359 moveWorkflow(self, course, cobj.__annotations__[x]) 360 else: 361 course.__annotations__[x] = cobj.__annotations__[x] 362 363 #ensure course has 0 position 364 course.__annotations__['eduCommons.objPositionInCourse'] = 0 365 366 #ensure portlets exist on courses 367 rightColumn = getUtility(IPortletManager, name=u'plone.rightcolumn', context=course) 368 right = getMultiAdapter((course, rightColumn), IPortletAssignmentMapping, context=course) 369 370 #This code breaks the course object when the server has no outbound access to the web 371 if u'OER Recommender' not in right: 372 right[u'OER Recommender'] = portlet.oerrecommenderportlet.Assignment() 373 374 if u'Course Summary' not in right: 375 right[u'Course Summary'] = portlet.courseinfoportlet.Assignment() 376 377 if u'Reuse Course' not in right: 378 right[u'Reuse Course'] = portlet.reusecourseportlet.Assignment() 379 380 # Copy Course Objects 381 ids = cobj.objectIds() 382 383 if 'syndication_information' in ids: 384 ids.remove('syndication_information') 385 386 # don't copy course download 387 zip = cobj.getId() + '.zip' 388 if zip in ids: 389 ids.remove(zip) 390 391 co = cobj.manage_copyObjects(ids) 392 393 course.manage_pasteObjects(co) 394 #ensure each object has correct position in course 395 for oid in ids: 396 olditem = getattr(cobj, oid) 397 if olditem.__annotations__.has_key('eduCommons.objPositionInCourse'): 398 pos = olditem.__annotations__['eduCommons.objPositionInCourse'] 399 400 newitem = getattr(course, oid) 401 newitem.__annotations__['eduCommons.objPositionInCourse'] = pos 402 403 setWorkflow(self, course, cobj) 404 #If the course package existed, repackage 405 if zip in cobj.objectIds(): 406 repackageCourse(self, course) 407 408 409 def setWorkflow(self, new, old, omappings={}, retainHistory=True): 410 for oldid,olditem in old.objectItems(): 411 zip = new.id + '.zip' 412 if oldid in omappings: 413 oldid = omappings[oldid] 414 if oldid != zip: 415 newitem = getattr(new.aq_explicit, oldid) 416 try: 417 if olditem.__annotations__.has_key('review_state'): 418 moveWorkflow(self, newitem, olditem.__annotations__['review_state']) 419 if retainHistory: 420 newitem.workflow_history = olditem.workflow_history 421 if 'Folder' == olditem.Type(): 422 setWorkflow(self, newitem, olditem) 423 else: 424 state = olditem.portal_workflow.getInfoFor(olditem, 'review_state') 425 moveWorkflow(self, newitem, state) 426 if retainHistory: 427 newitem.workflow_history = olditem.workflow_history 428 if 'Folder' == olditem.Type(): 429 setWorkflow(self, newitem, olditem) 430 431 except AttributeError: 432 pass 433 434 435 def moveWorkflow(self, newobj, ostate): 436 wt = newobj.portal_workflow 437 nstate = wt.getInfoFor(newobj, 'review_state') 438 result = False 439 if 'Visible' == ostate: 440 ostate = 'Published' 441 if nstate == ostate: 442 result = True 443 elif 'InProgress' == nstate: 444 wt.doActionFor(newobj, 'submit', comment='', include_subfolders=False) 445 result = moveWorkflow(self, newobj, ostate) 446 elif 'QA' == nstate: 447 wt.doActionFor(newobj, 'release', comment='', include_subfolders=False) 448 result = moveWorkflow(self, newobj, ostate) 449 elif 'Released' == nstate: 450 wt.doActionFor(newobj, 'publish', comment='', include_subfolders=False) 451 result = moveWorkflow(self, newobj, ostate) 452 elif 'Published' == nstate: 453 result = True 454 return result 455 456 457
