Changeset 513

Show
Ignore:
Timestamp:
08/04/09 15:42:43 (3 years ago)
Author:
david
Message:

commiting v1 of migration

Location:
enpraxis.educommons/trunk/enpraxis/educommons
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • enpraxis.educommons/trunk/enpraxis/educommons/extras/PreMigrate.py

    r506 r513  
    2323from Products.CMFCore.utils import getToolByName 
    2424from StringIO import StringIO 
    25 from Products.ATContentTypes.migration.walker import CatalogWalker 
    26 from Products.ATContentTypes.migration.migrator import CMFFolderMigrator, CMFItemMigrator 
     25from Products.contentmigration.basemigrator.walker import CatalogWalker  
     26from Products.contentmigration.basemigrator.migrator import CMFFolderMigrator 
    2727from zope.app.annotation.interfaces import IAnnotations, IAttributeAnnotatable 
     28from zope.component import getUtility, getMultiAdapter 
    2829from zope.interface import directlyProvidedBy, directlyProvides 
    29 from Products.CMFPlone import transaction 
     30from Products.CMFPlone.PloneTool import transaction 
     31from plone.portlets.interfaces import IPortletManager, IPortletAssignmentMapping 
    3032 
    3133# 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__ = annotations 
    40  
    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_status 
    47  
    48     def migrate_current_workflow(self): 
    49         """Annotate the current workflow state""" 
    50         wft = self.old.portal_url.portal_workflow 
    51         cur_state = wft.getInfoFor(self.old, 'review_state') 
    52         self.new.__annotations__['review_state'] = cur_state 
    53  
    5434class eduCommonsFoldersMigrator(CMFFolderMigrator): 
    5535    """Persist annotations to new object""" 
     
    7555 
    7656 
    77  
    78 class ECCourseMigrator(eduCommonsFoldersMigrator): 
     57class CourseMigrator(eduCommonsFoldersMigrator): 
    7958    """Base class to migrate to Folder """ 
    8059     
    8160    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             
    9680        text = self.old.getText() 
    9781        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']         
    10290 
    10391    walkerClass = CatalogWalker 
    104     src_meta_type = 'ECCourse' 
    105     src_portal_type = 'ECCourse' 
     92    src_meta_type = 'Course' 
     93    src_portal_type = 'Course' 
    10694    dst_meta_type = 'ATFolder' 
    10795    dst_portal_type = 'Folder' 
    10896 
    109 class ECDepartmentMigrator(eduCommonsFoldersMigrator): 
     97class DivisionMigrator(eduCommonsFoldersMigrator): 
    11098    """Base class to migrate to Folder """ 
    11199 
    112100    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 """ 
    114102        text = self.old.getText() 
    115103        self.new.__annotations__['dept.text'] = text 
     
    117105 
    118106    walkerClass = CatalogWalker 
    119     src_meta_type = 'ECDepartment' 
    120     src_portal_type = 'ECDepartment' 
     107    src_meta_type = 'Division' 
     108    src_portal_type = 'Division' 
    121109    dst_meta_type = 'ATFolder' 
    122110    dst_portal_type = 'Folder' 
    123111 
    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): 
     112def pre_migrate_3_1_1_to_3_2_1(self): 
    235113    """Run the migration""" 
    236114      
     
    241119    portal = portal_url.getPortalObject() 
    242120 
    243  
    244121    #create migrateable_properties to migrate old site props 
    245     site_props = portal.portal_properties.site_properties 
    246122    portal.portal_properties.addPropertySheet('migrateable_properties', 'Old Site Properties') 
    247123    m_props = portal.portal_properties.migrateable_properties 
    248      
     124    
    249125    m_props.manage_addProperty(id='site_title', type='string', value=portal.title) 
    250126    m_props.manage_addProperty(id='description', type='string', value=portal.description) 
    251127    m_props.manage_addProperty(id='email_from_address', type='string', value=portal.email_from_address) 
    252128    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) 
    255129 
    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) 
    317131 
    318132    for migrator in migrators: 
     
    322136        print >> out, walker.getOutput() 
    323137 
    324  
    325138    #Refresh catalog indices 
    326139    self.portal_catalog.reindexIndex(self.portal_catalog.indexes(),None) 
    327  
    328     #remove display_view from front_page 
    329     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 policy 
    337     self.caching_policy_manager.removePolicy('ECImageAndECFilePolicy') 
    338     print >> out, "Removed Image and File Caching Policy" 
    339  
    340     #uninstall FCKEditor 
    341     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 objects 
    350     #Need to add Folder back to addable for Plone Site first.... 
    351     pt = self.portal_types 
    352     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') 
    366140 
    367141    print >> out, "Migration finished" 
  • enpraxis.educommons/trunk/enpraxis/educommons/upgrades/v3_1_1_to_3_2_1.py

    r511 r513  
    2121__version__   = '$ Revision 0.0 $'[11:-2] 
    2222 
    23  
     23from Products.CMFPlone.utils import _createObjectByType 
     24from StringIO import StringIO 
    2425import string 
    2526from zope.component import getUtility, getMultiAdapter 
    2627from Products.CMFCore.utils import getToolByName 
    2728from enpraxis.educommons.browser.packagecourseview import appendObjPosition 
     29from enpraxis.educommons import portlet 
    2830from collective.imstransport.utilities.interfaces import IIMSTransportUtility 
     31from plone.portlets.interfaces import IPortletManager, IPortletAssignmentMapping 
    2932 
    3033def migrate(portal_setup): 
    3134    """ 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     
    3341    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 
     56def 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 
     61def 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     
     66def 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     
     105def 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         
     114def 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         
     169def 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 
     216def updateAdmins(self, portal, oldsite, out): 
    42217    """ Convert users that have administrator role to have manager role """ 
    43218    users = portal.acl_users.getUsers() 
     
    54229            portal.acl_users.userFolderEditUser(user.getId(), None, roles, user.getDomains()) 
    55230         
    56 def updateBaseProperties(portal): 
     231def updateBaseProperties(self, portal, oldsite, out): 
    57232    """ Update logo.gif to logo.png to  """         
    58233    custom = portal.portal_skins.custom.aq_inner.aq_explicit 
     
    63238                base_props.manage_changeProperties(logoName='logo.png') 
    64239                                 
    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) 
     240def 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 
     258def 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()     
    96267 
    97268def publishObject(context): 
     
    105276 
    106277 
    107  
    108  
    109  
     278def 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 
     324def 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 
     409def 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 
     435def 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