Back to index

plone3  3.1.7
betas.py
Go to the documentation of this file.
00001 from zope.component import queryUtility
00002 
00003 from Products.CMFActionIcons.interfaces import IActionIconsTool
00004 from Products.CMFCore.interfaces import IActionProvider
00005 from Products.CMFCore.Expression import Expression
00006 from Products.CMFCore.utils import getToolByName
00007 
00008 from Products.CMFPlone.migrations.migration_util import loadMigrationProfile
00009 from alphas import addContentRulesAction
00010 from alphas import enableZope3Site
00011 from alphas import registerToolsAsUtilities
00012 
00013 from Acquisition import aq_base
00014 
00015 def beta1_beta2(portal):
00016     """ 3.0-beta1 -> 3.0-beta2
00017     """
00018 
00019     out = []
00020 
00021     enableZope3Site(portal, out)
00022     registerToolsAsUtilities(portal, out)
00023 
00024     migrateHistoryTab(portal, out)
00025 
00026     changeOrderOfActionProviders(portal, out)
00027     updateEditActionConditionForLocking(portal, out)
00028     addOnFormUnloadJS(portal, out)
00029 
00030     # Add the action a second time, now to the correct action category
00031     addContentRulesAction(portal, out)
00032 
00033     cleanupOldActions(portal, out)
00034 
00035     cleanDefaultCharset(portal, out)
00036 
00037     loadMigrationProfile(portal, 'profile-Products.CMFPlone.migrations:3.0b1-3.0b2')
00038 
00039     addAutoGroupToPAS(portal, out)
00040 
00041     removeS5Actions(portal, out)
00042 
00043     addCacheForKSSRegistry(portal, out)
00044 
00045     modifyKSSResources(portal, out)
00046 
00047     addContributorToCreationPermissions(portal, out)
00048 
00049     cleanupActionProviders(portal, out)
00050 
00051     hidePropertiesAction(portal, out)
00052 
00053     return out
00054 
00055 
00056 def beta2_beta3(portal):
00057     """ 3.0-beta2 -> 3.0-beta3
00058     """
00059 
00060     out = []
00061 
00062     enableZope3Site(portal, out)
00063     registerToolsAsUtilities(portal, out)
00064 
00065     loadMigrationProfile(portal, 'profile-Products.CMFPlone.migrations:3.0b2-3.0b3')
00066 
00067     removeSharingAction(portal, out)
00068     
00069     addEditorToSecondaryEditorPermissions(portal, out)
00070 
00071     return out
00072 
00073 
00074 def beta3_rc1(portal):
00075     """ 3.0-beta3 -> 3.0-rc1
00076     """
00077 
00078     out = []
00079 
00080     enableZope3Site(portal, out)
00081     registerToolsAsUtilities(portal, out)
00082 
00083     loadMigrationProfile(portal, 'profile-Products.CMFPlone.migrations:3.0b3-3.0b4')
00084 
00085     moveKupuAndCMFPWControlPanel(portal, out)
00086 
00087     updateLanguageControlPanel(portal, out)
00088 
00089     updateTopicTitle(portal, out)
00090 
00091     modifyKSSResourcesForDevelMode(portal, out)
00092 
00093     return out
00094 
00095 
00096 def migrateHistoryTab(portal, out):
00097     portal_actions = getToolByName(portal, 'portal_actions', None)
00098     if portal_actions is not None:
00099         objects = getattr(portal_actions, 'object', None)
00100         if objects is not None:
00101             if 'rss' in objects.objectIds():
00102                 objects.manage_renameObjects(['rss'], ['history'])
00103                 out.append('Migrated history action.')
00104 
00105 
00106 def changeOrderOfActionProviders(portal, out):
00107     portal_actions = getToolByName(portal, 'portal_actions', None)
00108     if portal_actions is not None:
00109         portal_actions.deleteActionProvider('portal_actions')
00110         portal_actions.addActionProvider('portal_actions')
00111         out.append('Changed the order of action providers.')
00112 
00113 def cleanupOldActions(portal, out):
00114     portal_actions = getToolByName(portal, 'portal_actions', None)
00115     if portal_actions is not None:
00116         # Remove some known unused actions from the object_tabs category and
00117         # remove the category completely if no actions are left
00118         object_tabs = getattr(portal_actions, 'object_tabs', None)
00119         if object_tabs is not None:
00120             if 'contentrules' in object_tabs.objectIds():
00121                 object_tabs._delObject('contentrules')
00122             if 'change_ownership' in object_tabs.objectIds():
00123                 object_tabs._delObject('change_ownership')
00124             if len(object_tabs.objectIds()) == 0:
00125                 del object_tabs
00126                 portal_actions._delObject('object_tabs')
00127                 out.append('Removed object_tabs action category.')
00128         object_ = getattr(portal_actions, 'object', None)
00129         if object_ is not None:
00130             if 'reply' in object_.objectIds():
00131                 object_._delObject('reply')
00132         user = getattr(portal_actions, 'user', None)
00133         if user is not None:
00134             if 'logged_in' in user.objectIds():
00135                 user._delObject('logged_in')
00136             if 'myworkspace' in user.objectIds():
00137                 user._delObject('myworkspace')
00138         global_ = getattr(portal_actions, 'global', None)
00139         if global_ is not None:
00140             if 'manage_members' in global_.objectIds():
00141                 global_._delObject('manage_members')
00142             if 'configPortal' in global_.objectIds():
00143                 global_._delObject('configPortal')
00144             if len(global_.objectIds()) == 0:
00145                 del global_
00146                 portal_actions._delObject('global')
00147                 out.append('Removed global action category.')
00148 
00149 def cleanDefaultCharset(portal, out):
00150     charset = portal.getProperty('default_charset', None)
00151     if charset is not None:
00152         if not charset.strip():
00153             portal.manage_delProperties(['default_charset'])
00154             out.append('Removed empty default_charset portal property')
00155 
00156 
00157 def addAutoGroupToPAS(portal, out):
00158     from Products.PlonePAS.Extensions.Install import activatePluginInterfaces
00159     from StringIO import StringIO
00160 
00161     sout=StringIO()
00162 
00163     if not portal.acl_users.objectIds(['Automatic Group Plugin']):
00164         from Products.PlonePAS.plugins.autogroup import manage_addAutoGroup
00165         manage_addAutoGroup(portal.acl_users, 'auto_group',
00166                 'Automatic Group Provider',
00167                 'AuthenticatedUsers', "Logged-in users (Virtual Group)")
00168         activatePluginInterfaces(portal, "auto_group", sout)
00169         out.append("Added automatic group PAS plugin")
00170 
00171 def removeS5Actions(portal, out):
00172     portalTypes = getToolByName(portal, 'portal_types', None)
00173     if portalTypes is not None:
00174         document = portalTypes.restrictedTraverse('Document', None)
00175         if document:
00176             ids = [x.getId() for x in document.listActions()]
00177             if 's5_presentation' in ids:
00178                 index = ids.index('s5_presentation')
00179                 document.deleteActions([index])
00180                 out.append("Removed 's5_presentation' action from actions tool.")
00181 
00182     iconsTool = queryUtility(IActionIconsTool)
00183     if iconsTool is not None:
00184         ids = [x.getActionId() for x in iconsTool.listActionIcons()]
00185         if 's5_presentation' in ids:
00186             iconsTool.removeActionIcon('plone','s5_presentation')
00187             out.append("Removed 's5_presentation' icon from actionicons tool.")
00188 
00189 def addCacheForKSSRegistry(portal, out):
00190     ram_cache_id = 'ResourceRegistryCache'
00191     reg = getToolByName(portal, 'portal_kss', None)
00192     if reg is not None and getattr(aq_base(reg), 'ZCacheable_setManagerId', None) is not None:
00193         reg.ZCacheable_setManagerId(ram_cache_id)
00194         reg.ZCacheable_setEnabled(1)
00195         out.append('Associated portal_kss with %s' % ram_cache_id)
00196 
00197 def modifyKSSResources(portal, out):
00198     # make kukit.js conditonol and not load for anonymous
00199     reg = getToolByName(portal, 'portal_javascripts', None)
00200     if reg is not None:
00201         id = '++resource++kukit-src.js'
00202         entry = aq_base(reg).getResourcesDict().get(id, None)
00203         if entry:
00204             reg.updateScript(id, expression='not:here/@@plone_portal_state/anonymous', compression='safe')
00205             out.append('Updated kss javascript resource %s, to disable kss for anonymous.' % id)
00206     # register the new kss resources
00207     reg = getToolByName(portal, 'portal_kss', None)
00208     if reg is not None:
00209         new_resources = ['at_experimental.kss', 'plone_experimental.kss']
00210         for id in new_resources:
00211             entry = aq_base(reg).getResourcesDict().get(id, None)
00212             if not entry:
00213                 reg.registerKineticStylesheet(id, enabled=0)
00214                 out.append('Added kss resource %s, disabled by default.' % id)
00215 
00216 def modifyKSSResourcesForDevelMode(portal, out):
00217     # separate kukit.js and kukit-src-js based on debug mode
00218     reg = getToolByName(portal, 'portal_javascripts', None)
00219     if reg is not None:
00220         id = '++resource++kukit-src.js'
00221         entry = aq_base(reg).getResourcesDict().get(id, None)
00222         if entry:
00223             pos = aq_base(reg).getResourcePosition(id)
00224             # delete kukit-src.js
00225             aq_base(reg).unregisterResource(id)
00226             # add the new ones
00227             id1 = '++resource++kukit.js'
00228             if aq_base(reg).getResourcesDict().get(id1, None):
00229                 aq_base(reg).unregisterResource(id1)
00230             aq_base(reg).registerScript(id1,
00231                     expression="python: not here.restrictedTraverse('@@plone_portal_state').anonymous() and here.restrictedTraverse('@@kss_devel_mode').isoff()",
00232                     inline=False, enabled=True,
00233                     cookable=True, compression='none', cacheable=True)
00234             id2 = '++resource++kukit-devel.js'
00235             if aq_base(reg).getResourcesDict().get(id2, None):
00236                 aq_base(reg).unregisterResource(id2)
00237             aq_base(reg).registerScript(id2,
00238                     expression="python: not here.restrictedTraverse('@@plone_portal_state').anonymous() and here.restrictedTraverse('@@kss_devel_mode').ison()",
00239                     inline=False, enabled=True,
00240                     cookable=True, compression='none', cacheable=True)
00241             # move them to where the old one has been
00242             aq_base(reg).moveResource(id1, pos)
00243             aq_base(reg).moveResource(id2, pos + 1)
00244             out.append('Updated kss javascript resources, to enable the use of production and development versions.')
00245 
00246 def addContributorToCreationPermissions(portal, out):
00247     
00248     if 'Contributor' not in portal.valid_roles():
00249         portal._addRole('Contributor')
00250     if 'Contributor' not in portal.acl_users.portal_role_manager.listRoleIds():
00251         portal.acl_users.portal_role_manager.addRole('Contributor')
00252     
00253     for p in ['Add portal content', 'Add portal folders', 'ATContentTypes: Add Document',
00254                 'ATContentTypes: Add Event', 'ATContentTypes: Add Favorite',
00255                 'ATContentTypes: Add File', 'ATContentTypes: Add Folder', 
00256                 'ATContentTypes: Add Image', 'ATContentTypes: Add Large Plone Folder',
00257                 'ATContentTypes: Add Link', 'ATContentTypes: Add News Item', ]:
00258         roles = [r['name'] for r in portal.rolesOfPermission(p) if r['selected']]
00259         if 'Contributor' not in roles:
00260             roles.append('Contributor')
00261             portal.manage_permission(p, roles, bool(portal.acquiredRolesAreUsedBy(p)))
00262 
00263 def removeSharingAction(portal, out):
00264     portal_types = getToolByName(portal, 'portal_types', None)
00265     if portal_types is not None:
00266         for fti in portal_types.objectValues():
00267             action_ids = [a.id for a in fti.listActions()]
00268             if 'local_roles' in action_ids:
00269                 fti.deleteActions([action_ids.index('local_roles')])
00270                 
00271     out.append('Removed explicit references to sharing action')
00272     
00273 def addEditorToSecondaryEditorPermissions(portal, out):
00274     
00275     for p in ['Manage properties', 'Modify view template', 'Request review']:
00276         roles = [r['name'] for r in portal.rolesOfPermission(p) if r['selected']]
00277         if 'Editor' not in roles:
00278             roles.append('Editor')
00279             portal.manage_permission(p, roles, bool(portal.acquiredRolesAreUsedBy(p)))
00280 
00281 def updateEditActionConditionForLocking(portal, out):
00282     """
00283     Condition on edit views for Document, Event, File, Folder, Image, 
00284     Large_Plone_Folder, Link, Topic has been added to not display the Edit
00285     tab if an item is locked
00286     """
00287     portal_types = getToolByName(portal, 'portal_types', None)
00288     lockable_types = ['Document', 'Event', 'Favorite', 'File', 'Folder',
00289                       'Image', 'Large Plone Folder', 'Link',
00290                       'News Item', 'Topic']
00291     if portal_types is not None:
00292         for contentType in lockable_types:
00293             fti = portal_types.getTypeInfo(contentType)
00294             if fti:
00295                 for action in fti.listActions():
00296                     if action.getId() == 'edit' and not action.condition:
00297                         action.condition = Expression("not:object/@@plone_lock_info/is_locked_for_current_user|python:True")
00298 
00299 def addOnFormUnloadJS(portal, out):
00300     """
00301     add the form unload JS to the js registry
00302     """
00303     jsreg = getToolByName(portal, 'portal_javascripts', None)
00304     script = 'unlockOnFormUnload.js'
00305     if jsreg is not None:
00306         script_ids = jsreg.getResourceIds()
00307         # Failsafe: first make sure the stylesheet doesn't exist in the list
00308         if script not in script_ids:
00309             jsreg.registerScript(script,
00310                                  enabled = True,
00311                                  cookable = True)
00312             # put it at the bottom of the stack
00313             jsreg.moveResourceToBottom(script)
00314             out.append("Added " + script + " to portal_javascripts")
00315 
00316 def moveKupuAndCMFPWControlPanel(portal, out):
00317     """
00318     Move Kupu control panel to the Plone section and the CMFPW control panel
00319     to the add-on section if it is installed.
00320     """
00321     cp = getToolByName(portal, 'portal_controlpanel', None)
00322     if cp is not None:
00323         kupu = cp.getActionObject('Products/kupu')
00324         if kupu is not None:
00325             kupu.category = 'Plone'
00326         cmfpw = cp.getActionObject('Plone/placefulworkflow')
00327         if cmfpw is not None:
00328             cmfpw.category = 'Products'
00329 
00330 def updateLanguageControlPanel(portal, out):
00331     """Use the new configlet for the language control panel"""
00332     cp = getToolByName(portal, 'portal_controlpanel', None)
00333     if cp is not None:
00334         lang = cp.getActionObject('Plone/PloneLanguageTool')
00335         if lang is not None:
00336             lang.action = Expression('string:${portal_url}/@@language-controlpanel')
00337 
00338 def updateTopicTitle(portal, out):
00339     """Update the title of the topic type."""
00340     tt = getToolByName(portal, 'portal_types', None)
00341     if tt is not None:
00342         topic = tt.get('Topic')
00343         if topic is not None:
00344             topic.title = 'Collection'
00345 
00346 
00347 def cleanupActionProviders(portal, out):
00348     """Remove no longer existing action proiders."""
00349     at = getToolByName(portal, "portal_actions")
00350     for provider in at.listActionProviders():
00351         candidate = getToolByName(portal, provider, None)
00352         if candidate is None or not IActionProvider.providedBy(candidate):
00353             at.deleteActionProvider(provider)
00354             out.append("%s is no longer an action provider" % provider)
00355 
00356 def hidePropertiesAction(portal, out):
00357     tt = getToolByName(portal, 'portal_types', None)
00358     if not IActionProvider.providedBy(tt):
00359         return
00360     for ti in tt.listTypeInfo():
00361         actions = ti.listActions()
00362         index=[i for i in range(len(actions) )
00363                 if actions[i].category=="object" and 
00364                    actions[i].id=="metadata"]
00365         if index:
00366             ti.deleteActions(index)
00367             out.append("Removed properties action from type %s" % ti.id)
00368