Ticket #14: Install.py

Line 
1 import string
2 from cStringIO import StringIO
3
4 from Products.CMFCore.utils import getToolByName
5 from Products.CMFCore.DirectoryView import addDirectoryViews
6
7 from Products.CMFPlone.migrations.migration_util import safeEditProperty
8 from Products.CMFCore.Expression import Expression, createExprContext
9
10 from Products.qPloneDropDownMenu.config import *
11
12 configlets = ({'id':PROJECT_NAME,
13     'name':'Drop Down Menu',
14     'action':'string:${portal_url}/prefs_dropdownmenu_edit_form',
15     'condition':'',
16     'category':'Products',
17     'visible':1,
18     'appId':PROJECT_NAME,
19     'permission':VIEW_PERMISSION,
20     'imageUrl':'qplonedropdownmenu.gif' },)
21
22 def registerCSS(self, out):
23
24     qi = getToolByName(self, 'portal_quickinstaller', None)
25     if qi is not None:
26         try:
27             if not qi.isProductInstalled('ResourceRegistries'):
28                 qi.installProduct('ResourceRegistries', locked=0)
29             cssreg = getToolByName(self, 'portal_css', None)
30             if cssreg is not None:
31                 stylesheet_ids = cssreg.getResourceIds()
32
33                 if 'drop_down.css' not in stylesheet_ids:
34                     cssreg.registerStylesheet('drop_down.css',
35                                                expression="python:portal.portal_dropdownmenu")
36                     out.write('Register drop_down.css... \n')
37                 else:
38                     out.write('drop_down.css already exists... \n')
39         except:
40             pass
41
42 def unregisterCSS(self, out):
43
44     qi = getToolByName(self, 'portal_quickinstaller', None)
45     if qi is not None:
46         try:
47             if not qi.isProductInstalled('ResourceRegistries'):
48                 qi.installProduct('ResourceRegistries', locked=0)
49             cssreg = getToolByName(self, 'portal_css', None)
50             if cssreg is not None:
51                 stylesheet_ids = cssreg.getResourceIds()
52
53                 if 'drop_down.css' in stylesheet_ids:
54                     cssreg.unregisterResource('drop_down.css')
55                     out.write('Unregister drop_down.css... \n')
56         except:
57             pass
58
59 def createMenuString(children, level=1, maxlevel=0, urls=None):
60     """Iterates through dictionary of objects n levels down in site structure.
61     Creates a HTML list to be used in drop down menu.
62
63     Returns string.
64     """
65    
66     retval = ''
67
68     for child in children:
69         # Test if the toplevel URL is supposed to be a tab
70         if level == 1 and urls and not child['getURL'] in urls:
71             continue
72         if not child['no_display'] and not child['portal_type'] == 'Plone Site':
73             retval += '<li id="portaltab-%s" class="plain"><a href="%s" accesskey="t">' % \
74                       (child['path'], child['getURL']) + child['Title'] + '</a>'
75             subchildren = child['children']
76             if level <= maxlevel and len(subchildren) > 0:
77                 retval += '<ul>'
78                 retval += createMenuString(subchildren, level+1, maxlevel)
79                 retval += '</ul>'
80             retval += '</li>\n'
81     return retval
82
83 def updateMenu(self):
84     out = ''
85
86     # We work with the property sheet now - so we can keep existing dropdownmenu_level
87     portal_props = getToolByName(self, 'portal_properties')
88     if not hasattr(portal_props, PROPERTY_SHEET):
89         portal_props.addPropertySheet(PROPERTY_SHEET, 'DropDown Menu Properties')
90     ap = getattr(portal_props, PROPERTY_SHEET)
91
92     dropdownmenu_level = 1
93     if ap.hasProperty('dropdownmenu_level'):
94         dropdownmenu_level = ap.getProperty('dropdownmenu_level')
95
96     pu = getToolByName(self, 'plone_utils')
97
98     # Uses createNavTree to autogenerate deeper menu structure
99     if hasattr(pu, 'createNavTree'):
100        
101         #Translation service - used to translate homepage title
102         homepage_title = 'Home'
103         if hasattr(pu, 'translation_service'):
104             translation_service = getToolByName(self, 'translation_service', None)
105             if translation_service is not None:
106                 homepage_title = translation_service.utranslate( \
107                     domain='plone', msgid='Home', \
108                     context=self, \
109                     default='Home')
110                 homepage_title = translation_service.encode(homepage_title, errors='replace')
111
112         #Generates a list of toplevel URL's to test against in createMenuString()
113         tl_urls = []
114         if hasattr(pu, 'createTopLevelTabs'):
115             pactions = getToolByName(self, 'portal_actions').listFilteredActionsFor(self)
116             tl_tabs = pu.createTopLevelTabs(pactions)
117             for url in tl_tabs:
118                 tl_urls.append(url['url'])
119
120         # We are ready to get the navigation tree and generate an output string
121         tl_nav = pu.createNavTree(self, sitemap=dropdownmenu_level)
122
123         out += '<li id="portaltab-%s" class="plain"><a href="%s" accesskey="t">' % \
124                (tl_nav['path'], tl_nav['getURL']) + homepage_title + '</a></li>\n'
125         children = tl_nav.get('children', [])
126         out += createMenuString(children, maxlevel=dropdownmenu_level, urls=tl_urls)
127        
128     else:
129         portal = getToolByName(self, 'portal_url').getPortalObject()
130
131         portal_act = getToolByName(self, 'portal_actions')
132         actions=portal_act._cloneActions()
133
134         for act in actions:
135             if act.category == 'portal_tabs':
136                 out += '<li id="portaltab-%s" class="plain"><a href="%s" accesskey="t">%s</a></li>\n' % \
137                     (act.id, \
138                      Expression(act.getActionExpression())(createExprContext(portal, portal, portal)), \
139                      act.title)
140
141     safeEditProperty(ap, 'menu', out, 'text')
142     safeEditProperty(ap, 'dropdownmenu_level', dropdownmenu_level, 'int')
143  
144 def setupSkin(self, out, skinFolder):
145
146     skinstool=getToolByName(self, 'portal_skins')
147
148     addDirectoryViews(skinstool, SKINS_DIR, GLOBALS)
149
150     for skin in skinstool.getSkinSelections():
151         path = skinstool.getSkinPath(skin)
152         path = map( string.strip, string.split( path,',' ) )
153
154         if not skinFolder in path:
155             try:
156                 path.insert( path.index( 'custom')+1, skinFolder )
157             except ValueError:
158                 path.append(skinFolder)
159             path = string.join( path, ', ' )
160             skinstool.addSkinSelection( skin, path )
161             out.write('  %s layer sucessfully installed into skin %s.\n' % (skinFolder, skin))
162         else:
163             out.write('  %s layer was already installed into skin %s.\n' % (skinFolder, skin))
164
165 def setupTool(self):
166
167     portal_url = getToolByName(self, 'portal_url')
168     p = portal_url.getPortalObject()
169     x = p.manage_addProduct[PROJECT_NAME].manage_addTool(type='DropDownMenu Tool')
170
171 def install(self):
172     out = StringIO()
173
174     registerCSS(self, out)
175
176     configTool = getToolByName(self, 'portal_controlpanel', None)
177     if configTool:
178         for conf in configlets:
179             configTool.registerConfiglet(**conf)
180             out.write('Added configlet %s\n' % conf['id'])
181
182     if hasattr(self, UNIQUE_ID):
183         self.manage_delObjects([UNIQUE_ID])
184         out.write('Deleting old %s\n' % (UNIQUE_ID))
185     setupTool(self)
186     out.write('Added %s to the portal root folder\n' % (UNIQUE_ID))
187
188     portal_props = getToolByName(self, 'portal_properties')
189     if not hasattr(portal_props, PROPERTY_SHEET):
190         out.write('updateMenu... \n')
191         updateMenu(self)
192     else:
193         out.write('skipping updateMenu... \n')
194
195     out.write('setupSkin... \n')
196     setupSkin(self, out, 'qPloneDropDownMenu')
197
198     return out.getvalue()
199
200 def uninstall(self):
201     out = StringIO()
202
203     unregisterCSS(self, out)
204
205     configTool = getToolByName(self, 'portal_controlpanel', None)
206     if configTool:
207         for conf in configlets:
208             configTool.unregisterConfiglet(conf['id'])
209             out.write('Removed configlet %s\n' % conf['id'])
210
211     return out.getvalue()