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

commiting v1 of migration

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • 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