Back to index

plone3  3.1.7
betas.py
Go to the documentation of this file.
00001 import re
00002 from Acquisition import aq_base
00003 
00004 from Products.GenericSetup.tool import SetupTool
00005 
00006 from Products.CMFPlone.migrations.v2_1.two12_two13 import normalizeNavtreeProperties
00007 from Products.CMFPlone.migrations.v2_1.two12_two13 import removeVcXMLRPC
00008 from Products.CMFPlone.migrations.v2_1.two12_two13 import addActionDropDownMenuIcons
00009 from Products.CMFPlone.migrations.v2_5.alphas import installDeprecated
00010 from Products.CMFPlone.migrations.v3_0.alphas import migrateOldActions
00011 from Products.CMFPlone.migrations.v3_0.alphas import enableZope3Site
00012 from Products.CMFPlone.migrations.v3_0.alphas import registerToolsAsUtilities
00013 from Products.CMFPlone.factory import _TOOL_ID as SETUP_TOOL_ID
00014 
00015 from Products.CMFCore.ActionInformation import Action
00016 from Products.CMFCore.utils import getToolByName
00017 from Products.CMFCore.permissions import View
00018 
00019 
00020 def alpha2_beta1(portal):
00021     """2.5-alpha2 -> 2.5-beta1
00022     """
00023     out = []
00024 
00025     # Make the portal a Zope3 site
00026     enableZope3Site(portal, out)
00027 
00028     # register some tools as utilities
00029     registerToolsAsUtilities(portal, out)
00030 
00031     # Add dragdropreorder.js to ResourceRegistries.
00032     addDragDropReorderJS(portal, out)
00033 
00034     # Add getEventTypes KeywordIndex to portal_catalog
00035     addGetEventTypeIndex(portal, out)
00036 
00037     # We need to migrate all existing actions to new-style actions first
00038     migrateOldActions(portal, out)
00039     # Fix 'home' portal action
00040     fixHomeAction(portal, out)
00041 
00042     # Fixup the navtree properties (this was already done in 2.1.3, but may
00043     # need to be done again for those migrating from alphas)
00044     normalizeNavtreeProperties(portal, out)
00045 
00046     return out
00047 
00048 
00049 def beta1_beta2(portal):
00050     """2.5-beta1 - > 2.5-beta2
00051     """
00052     out = []
00053 
00054     # Make the portal a Zope3 site
00055     enableZope3Site(portal, out)
00056 
00057     # register some tools as utilities
00058     registerToolsAsUtilities(portal, out)
00059 
00060     # The migration done during the alpha screwed things up, so we do it again
00061     # and fix the mistake while we're at it
00062     installDeprecated(portal, out)
00063     removeBogusSkin(portal, out)
00064 
00065     # add a property indicating if this is a big or small site, so the UI can
00066     # change depending on it
00067     propTool = getToolByName(portal, 'portal_properties', None)
00068     propSheet = getattr(propTool, 'site_properties', None)
00069     if not propSheet.hasProperty('large_site'):
00070         propSheet.manage_addProperty('large_site', 0, 'boolean')
00071         out.append("Added 'large_site' property to site_properties.")
00072 
00073     # Remove vcXMLRPC.js from ResourceRegistries (this was already done in
00074     # 2.1.3, but may need to be done again for those migrating from alphas)
00075     removeVcXMLRPC(portal, out)
00076 
00077     # add icons for copy, cut, paste and delete
00078     addActionDropDownMenuIcons(portal, out)
00079 
00080     # add any appropriate plone skin layers to custom skins
00081     addPloneSkinLayers(portal, out)
00082 
00083     # Install portal_setup
00084     installPortalSetup(portal, out)
00085 
00086     # We need to migrate all existing actions to new-style actions first
00087     migrateOldActions(portal, out)
00088     # Simplify actions using the @@plone view
00089     simplifyActions(portal, out)
00090 
00091     # Use the @@plone view for the RTL.css expression entry
00092     migrateCSSRegExpression(portal, out)
00093 
00094     return out
00095 
00096 
00097 def addDragDropReorderJS(portal, out):
00098     """Add dragdropreorder.js to ResourceRegistries.
00099     """
00100     jsreg = getToolByName(portal, 'portal_javascripts', None)
00101     script = 'dragdropreorder.js'
00102     if jsreg is not None:
00103         script_ids = jsreg.getResourceIds()
00104         # Failsafe: first make sure the stylesheet doesn't exist in the list
00105         if script not in script_ids:
00106             jsreg.registerScript(script)
00107             try:
00108                 jsreg.moveResourceAfter(script, 'dropdown.js')
00109             except ValueError:
00110                 # put it at the bottom of the stack
00111                 jsreg.moveResourceToBottom(script)
00112             out.append("Added " + script + " to portal_javascipt")
00113 
00114 
00115 def addGetEventTypeIndex(portal, out):
00116     """Adds the getEventType KeywordIndex."""
00117     catalog = getToolByName(portal, 'portal_catalog', None)
00118     if catalog is not None:
00119         if 'getEventType' in catalog.indexes():
00120             index = [i for i in catalog.index_objects() if
00121                                          i.getId() == 'getEventType']
00122             indextype = index.__class__.__name__
00123             if indextype == 'KeywordIndex':
00124                 return 0
00125             catalog.delIndex('getEventType')
00126             out.append("Deleted %s 'getEventType' from portal_catalog." %
00127                        indextype)
00128 
00129         catalog.addIndex('getEventType', 'KeywordIndex')
00130         out.append("Added KeywordIndex 'getEventType' to portal_catalog.")
00131         return 1 # Ask for reindexing
00132     return 0
00133 
00134 
00135 def fixHomeAction(portal, out):
00136     """Make the 'home' action use the @@plone view to get a properly rooted
00137     navtree.
00138     """
00139     home = Action('index_html',
00140         title='Home',
00141         i18n_domain='plone',
00142         url_expr='string:${here/@@plone/navigationRootUrl}',
00143         available_expr='',
00144         permissions=(View,),
00145         visible=True)
00146 
00147     actionsTool = getToolByName(portal, 'portal_actions', None)
00148     if actionsTool is not None:
00149         category = actionsTool.portal_tabs
00150         for action in category.objectIds():
00151             # if action exists, remove and re-add
00152             if action == 'index_html':
00153                 category._delObject('index_html')
00154                 break
00155 
00156         category['index_html'] = home
00157         category.moveObjectsToTop(('index_html',))
00158         out.append("Added/modified home/index_html portal_tabs action.")
00159 
00160 
00161 def removeBogusSkin(portal, out):
00162     skins = getToolByName(portal, 'portal_skins', None)
00163     if skins is not None:
00164         if skins._getSelections().has_key('cmf_legacy'):
00165             skins.manage_skinLayers(('cmf_legacy',), del_skin=True)
00166             out.append("Deleted incorrectly added 'cmf_legacy' skin")
00167 
00168 def addPloneSkinLayers(portal, out):
00169     st = getToolByName(portal, 'portal_skins', None)
00170     if st is None:
00171         out.append('No portal_skins tool')
00172         return
00173 
00174     for skin in st._getSelections().keys():
00175         path = st.getSkinPath(skin)
00176         path = [p.strip() for p in path.split(',')]
00177         if not 'plone_deprecated' in path:
00178             path.append('plone_deprecated')
00179             st.addSkinSelection(skin, ','.join(path))
00180             out.append('Added plone_deprecated to %s' % skin)
00181 
00182 
00183 def installPortalSetup(portal, out):
00184     """Adds portal_setup if not installed yet."""
00185     if SETUP_TOOL_ID not in portal.objectIds():
00186         portal._setObject(SETUP_TOOL_ID, SetupTool(SETUP_TOOL_ID))
00187         out.append('Added setup_tool.')
00188 
00189 
00190 # A set of regexes and substitution strings for cleaning up the current
00191 # actions, in particular to make optimal use of the methods provided by
00192 # @@plone and remove deprecation warnings.
00193 action_replacements = [
00194 # Remove leading space from string and python expressions, it is annoying
00195 (re.compile(r"^string: "),
00196  r"string:"),
00197 (re.compile(r"^python: "),
00198  r"python:"),
00199 (re.compile(r"portal\.portal_membership\.checkPermission"),
00200  r"checkPermission"),
00201 (re.compile(r"^python:\(\(object\.isDefaultPageInFolder\(\) and object.getParentNode\(\)\.absolute_url\(\)\) or folder_url\)\+(?:\"|')/(.+)(?:\"|')$"),
00202  r"string:${globals_view/getCurrentFolderUrl}/\1"),
00203 (re.compile(r"python:(?:\"|')%s/(.+)(?:\"|')%\(\(object\.isDefaultPageInFolder\(\) or not object\.is_folderish\(\)\) and object\.getParentNode\(\)\.absolute_url\(\) or object_url\)$"),
00204  r"string:${globals_view/getCurrentFolderUrl}/\1"),
00205 (re.compile(r"^python:(?:\"|')%s/(.+)(?:\"|')%\(object\.isDefaultPageInFolder\(\) and object.getParentNode\(\)\.absolute_url\(\) or object_url\)$"),
00206  r"string:${globals_view/getCurrentObjectUrl}/\1"),
00207 (re.compile(r"object is not portal and not \(object\.isDefaultPageInFolder\(\) and object\.getParentNode\(\) is portal\)"),
00208  r"not globals_view.isPortalOrPortalDefaultPage()"),
00209 (re.compile(r"object\.aq_inner\.getParentNode\(\)"),
00210  r"globals_view.getParentObject()"),
00211 (re.compile("here/@@plone"),
00212  r"globals_view"),
00213 (re.compile(r"^python:portal\.portal_membership\.getHomeUrl\(\)\+(?:\"|')/(.+)(?:\"|')$"),
00214  r"string:${portal/portal_membership/getHomeUrl}/\1"),
00215 ]
00216 
00217 
00218 def simplifyActions(portal, out):
00219     from Products.CMFCore.ActionInformation import ActionCategory
00220     tool = getToolByName(portal, 'portal_actions', None)
00221     if tool is not None:
00222         categories = [obj for obj in tool.objectItems()
00223                                   if isinstance(obj[1], ActionCategory)]
00224         if not categories:
00225             return
00226         actions = tool.listActions()
00227         # iterate through the actions and for each action check if it
00228         # matches any of the patterns we want to replace
00229         for action in actions:
00230             action_id = '%s/%s'%(action.getInfoData()[0]['category'], action.id)
00231             cur_expr = action.getProperty('url_expr')
00232             cur_condition = action.getProperty('available_expr')
00233             for regex, replacement in action_replacements:
00234                 new_expr = regex.sub(replacement, cur_expr)
00235                 new_condition = regex.sub(replacement, cur_condition)
00236                 if new_expr != cur_expr:
00237                     action._updateProperty('url_expr', new_expr)
00238                     out.append(
00239                     'Changed url expression on action %s from: \n%s\nto:\n%s'%(
00240                                                 action_id, cur_expr, new_expr))
00241                 if new_condition != cur_condition:
00242                     action._updateProperty('available_expr', new_condition)
00243                     out.append(
00244                     'Changed condition on action %s from: \n"%s"\nto:\n"%s"'%(
00245                                      action_id, cur_condition, new_condition))
00246                 cur_expr = new_expr
00247                 cur_condition = new_condition
00248 
00249 
00250 def migrateCSSRegExpression(portal, out):
00251     """Changes calls to the isRightToLeft script to use the view, also
00252        replaces the use of restrictedTraverse with a more compact path
00253        expression."""
00254     css_reg = getToolByName(portal, 'portal_css', None)
00255     if css_reg is not None:
00256         resource = css_reg.getResource('RTL.css')
00257         # The None that comes out of RR is apparently acquisition wrapped,
00258         # nasty.
00259         if aq_base(resource) is not None:
00260             css_expr = resource.getExpression()
00261             new_expr = 'object/@@plone/isRightToLeft'
00262             if "object.isRightToLeft" in css_expr or \
00263                "object.restrictedTraverse('@@plone')" in css_expr:
00264                 resource.setExpression(new_expr)
00265                 css_reg.cookResources()
00266                 out.append("Fixed RTL.css expression to use the @@plone view")