source: trunk/Extensions/Install.py @ 1919

Revision 1919, 13.4 KB checked in by jukka, 12 years ago (diff)

Refactored groups to not use portal_groups. Things should be faster and users from weird sources shouldn't cause so much problems. Not much tested yet, but archetype update and quickinstaller reinstall works fine.

Line 
1# Copyright 2006 by the LeMill Team (see AUTHORS)
2#
3# This file is part of Calibrate LeMill.
4#
5# Calibrate LeMill is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 2 of the License, or
8# (at your option) any later version.
9#
10# Calibrate LeMill is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with Calibrate LeMill; if not, write to the Free Software
17# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
19"""Plone product installer script"""
20
21from Products.CMFCore.utils import getToolByName
22from Products.Archetypes.Extensions.utils import install_subskin, installTypes
23from Products.Archetypes.public import listTypes
24from Products.CMFPlone.migrations.migration_util import safeEditProperty
25
26
27from StringIO import StringIO
28import string
29from itertools import chain
30
31from Products.LeMill.config import *
32from Products.LeMill.Resources import Resource, Redirector
33
34
35
36
37
38def doWeMigrate(old,new):
39    """ Returns True if old version is smaller. """
40    # If the version numbers are equal, then True is returned
41    if old == new:
42        return True
43    # This one will check if the new version is larger that the old one
44    old_ver = old.split('.')
45    new_ver = new.split('.')
46    old_len = len(old_ver)
47    new_len = len(new_ver)
48
49    if old_len >= new_len:
50        length = old_len
51    else:
52        length = new_len
53
54    if old_len > new_len:
55        for k in range(old_len - new_len):
56            new_ver.append('0')
57    if old_len < new_len:
58        for k in range(new_len - old_len):
59            old_ver.append('0')
60
61    for a in range(0,length):
62        if int(new_ver[a]) > int(old_ver[a]):
63            return True
64        if int(old_ver[a]) > int(new_ver[a]):
65            return False
66   
67    # Check the modified versions with same length if they are equal
68    if new_ver == old_ver:
69        return True
70
71
72def install(self):
73        """Installs this Plone product. Called by the quick_installer tool."""
74        # HOOK: This is executed when the Plone site with LeMill customization
75        # is created, or when a reinstall for the LeMill product is called from
76        # quick_installer.
77       
78        out = StringIO()
79        # Don't install the skin layer here - the configuration methods setup a
80        # whole new skin for us.
81
82        # Check whether we're upgrading or not
83        qi=getToolByName(self, 'portal_quickinstaller')
84        p=qi._getOb(PROJECTNAME, None)
85        if p:
86                oldVersion=p.getInstalledVersion()
87        else:
88                oldVersion="0"
89        newVersion=qi.getProductVersion(PROJECTNAME)
90
91
92        print >>out,"Installing content archetypes..."
93        installTypes(self, out, listTypes(PROJECTNAME), PROJECTNAME)
94
95        print >>out,"Installing portal tools..."
96        if not hasattr(self, 'lemill_search'):
97                addTool = self.manage_addProduct[PROJECTNAME].manage_addTool
98                # Add the tool by its meta_type
99                addTool('LeMillSearch')
100        if not hasattr(self, 'lemill_tool'):
101                addTool = self.manage_addProduct[PROJECTNAME].manage_addTool
102                # Add the tool by its meta_type
103                addTool('LeMillTool')
104        if not hasattr(self, 'lemill_usertool'):
105                addTool = self.manage_addProduct[PROJECTNAME].manage_addTool
106                # Add the tool by its meta_type
107                addTool('LeMillUserTool')
108
109
110        print >>out,"Registering remote search preference panel..."
111        # Register lemill_search_conf under controlpanel.
112        # admins can register additional search locations there.
113        # ticket #107
114        cp = getToolByName( self, 'portal_controlpanel')
115        REMOTE_SEARCH_ID='lemill_remote_search'
116        cp.unregisterConfiglet(REMOTE_SEARCH_ID)
117        cp.addAction(REMOTE_SEARCH_ID,
118                'LeMill search',
119                'string:${portal_url}/prefs_lemill_search_form',
120                permission='Manage portal',
121                category='Products',
122                appId='LeMill')
123
124        # Call migration script
125        migrate(self,out,oldVersion,newVersion)
126
127        print >>out,"Installation completed."
128        # Done, return whatever messages we got
129        return out.getvalue()
130
131def migrate(self,out,old,new):
132    """Migrate existing content. If we're installing a newer version
133    of LeMill over an existing one, we may need to alter the existing
134    content so that it's compatible with the new version."""
135
136    ltool = getToolByName(self, 'lemill_tool')
137
138    # Note that versions are strings, not numbers.
139   
140    if not old or not new: return
141    if new==old: return
142    if not doWeMigrate(old,new):
143            print >>out,"Can't downgrade content from %s to %s!" % (old,new)
144            return
145
146    print >>out,"Migrating from %s to %s" % (old,new)
147
148    # NB: All setupXXX methods from ConfigurationMethods are executed when
149    # running a reinstall from quick_installer.
150
151    # Example iteration, changing all content objects
152    # Adapt this to change objects so they are compatible with the
153    # changes made into the system
154    if 1 == 0: # Let's not really run it...
155            for ob in self.content.objectValues(('Piece','Material')):
156                    ob.edit(title=ob.Title()+"!")
157
158    if doWeMigrate(old,"1.6"):
159            print >>out, "Migration not supported for versions 1.6 or below - upgrade using an older version first."
160            return
161
162    # Add migration stuff here, in ascending order of version
163    # NOTE: If you make a syntax error here, portal_quickinstaller
164    # will just report LeMill as "removed from Products folder"
165    # (running "python Extensions/Install.py" will report syntax errors)
166
167    if doWeMigrate(old,'1.6.1'):
168        print >>out, "Starting migration from 1.6.1"
169        print >>out, "Owners for collections and stories"
170        # Create collections and stories folders for those users who do not have then yet
171        for member in self.community.objectValues('MemberFolder'):
172            if not hasattr(member.aq_base, 'collections'):
173                member.invokeFactory('CollectionsFolder', id='collections')
174            if not hasattr(member.aq_base, 'stories'):
175                member.invokeFactory('StoryFolder', id='stories')
176        # Check if collections and stories folders have correct Owner, if not then just change the owner to the right one
177        for member in self.community.objectValues('MemberFolder'):               
178            member_id = member.users_with_local_role('Owner')
179            member_as_owner = member.getId()
180            if member_id != member.collections.users_with_local_role('Owner'):
181                to_delete_owner_collections = str(member.collections.getOwner())
182                member.collections.changeOwnership(getattr(member.collections,member_as_owner))
183                member.collections.manage_delLocalRoles([to_delete_owner_collections,])
184                member.collections.manage_addLocalRoles(member_as_owner, ['Owner',])
185            if member_id != member.stories.users_with_local_role('Owner'):
186                to_delete_owner_stories = str(member.stories.getOwner())
187                member.stories.changeOwnership(getattr(member.stories,member_as_owner))
188                member.stories.manage_delLocalRoles([to_delete_owner_stories,])
189                member.stories.manage_addLocalRoles(member_as_owner, ['Owner',])
190        print >>out, "Migration from 1.6.1 complete"
191    if doWeMigrate(old,'1.7'):
192        print >>out, "Starting migration from 1.7"
193        old_id='activities'
194        new_id='methods'
195        folder = getattr(self,old_id)
196        for o in folder.objectValues('Activity'):
197            if not o.getField('latestEdit', False):
198                o._updateSchema()
199        self.manage_renameObject(old_id,new_id)
200        folder.id=new_id
201        # Set up redirector
202        red = Redirector(old_id)
203        red.redirect_to = folder.UID()
204        self._setObject(old_id,red)
205        # Change folder title
206        folder.setTitle('Methods')
207        # Remove unnecessary topic - it will be replaced with a properly named one
208        folder._delObject('activities')
209        print >>out, "Migration from 1.7 complete"           
210    if doWeMigrate(old,'1.7.1'):
211        print >>out, "Starting migration from 1.7.1"
212        print >>out, "Split existing collections to refer resources/methods/tools separately"
213        # Get collections folder and run cleaning script     
214        for member in self.community.objectValues('MemberFolder'):
215            if hasattr(member.aq_base, 'collections'):
216                for c in member.collections.objectValues('Collection'):
217                    c.cleanRefsToResources()
218        print >>out, "Migration from 1.7.1 complete"           
219    if doWeMigrate(old,'1.7.2'):
220        print >>out, "Starting migration from 1.7.2"
221        print >>out, "Removing stories from the system"
222        # Get stories folder and delete stuff there       
223        for member in self.community.objectValues('MemberFolder'):
224            if hasattr(member.aq_base, 'stories'):
225                member.stories.manage_delObjects(member.stories.objectIds('Story'))
226                member.manage_delObjects(['stories',])
227        print >>out, "Migration from 1.7.2 complete"
228    if doWeMigrate(old,'1.7.3'):
229        print >>out, "Starting migration from 1.7.3"
230        print >>out, "Bringing tables back"
231        k = getToolByName(self, 'kupu_library_tool')
232        new_tag_exclusions = (('center', 'span', 'tt', 'big', 'small', 'u', 's', 'strike', 'basefont', 'font', 'div', 'img'), ())
233        k.html_exclusions[0] = new_tag_exclusions
234        print >>out, "Migration from 1.7.3 complete"
235    if doWeMigrate(old,'1.8.1'):
236        print >>out, "Starting migration from 1.8.1"
237        print >>out, "Set syndication on for all groups"
238        syn_tool = getToolByName(self, 'portal_syndication', None)
239        if syn_tool is not None:
240            for group in self.community.objectValues('GroupBlog'):
241                try:
242                    syn_tool.enableSyndication(group)
243                except: # might get 'Syndication Information Exists'
244                    pass
245                for post in group.objectValues('BlogPost'):
246                    try:
247                        syn_tool.enableSyndication(post)
248                    except: # might get 'Syndication Information Exists'
249                        pass
250    if doWeMigrate(old,'1.8.2'):
251        print >>out, "Starting migration from 1.8.2"
252        mtool = getToolByName(self, 'portal_membership')
253        for mfolder in self.community.objectValues('MemberFolder'):
254            mfolder._updateSchema()
255            portrait = mtool.getPersonalPortrait(mfolder.Creator())
256            if portrait.getId()=='defaultUser.gif':
257                continue
258            mfolder.setCoverImage(portrait)
259            print >>out, "Migration from 1.8.2 complete"
260    if doWeMigrate(old,'1.11.0'):
261        print >>out, "Starting migration from 1.11.0"
262        for obj in self.content.objectValues(('LeMillReference', 'MultimediaMaterial','PILOTMaterial', 'PresentationMaterial')):
263            if 'Informatics/ICT' in obj.getSubject_area():
264                new=list(obj.getSubject_area())
265                new.remove('Informatics/ICT')
266                new.append('Informatics or ICT')
267                obj.setSubject_area(new)
268        for obj in self.community.objectValues(('MemberFolder', 'GroupBlog')):
269            if hasattr(obj, 'getSubject_area'):
270                if 'Informatics/ICT' in obj.getSubject_area():
271                    new=list(obj.getSubject_area())
272                    new.remove('Informatics/ICT')
273                    new.append('Informatics or ICT')
274                    obj.setSubject_area(new)
275        print >>out, "Migration from 1.11.0 complete"
276    if doWeMigrate(old,'1.12.0'):
277        print >>out, "Starting migration from 1.12.0"
278        community=self.community
279        groups = community.objectIds('GroupBlog')
280        gtool= getToolByName(self, 'portal_groups')
281        for gid in groups:
282            print gid
283            acl_group=gtool.getGroupById(gid)
284            groupblog=community.getGroupById(gid)
285            if not acl_group:
286                print 'Missing acl_group: %s' % gid
287            for m in acl_group.getGroupMembers():
288                mid=m.getId()
289                groupblog.addMember(mid)
290                self.acl_users.source_groups.removePrincipalFromGroup(mid, gid)
291            if acl_group.getGroupMembers():
292                print acl_group.getGroupMembers()
293            else:
294                gtool.removeGroups([gid], keep_workspaces=1)
295    if doWeMigrate(old,'1.12.1'):
296        print >>out, "Starting migration from 1.12.1"
297        community=self.community
298        for obj in self.content.objectValues(('MultimediaMaterial','PILOTMaterial', 'PresentationMaterial')):
299            gid=obj.getGroupsShared()
300            print gid
301            print obj.id
302            if gid and gid!='no_group':
303                try:
304                    group=community.getGroupById(gid)
305                except:
306                    group=None
307                if group:
308                    obj.setGroupEditing(group.UID())
309           
310
311def uninstall(self):
312        """ uninstall """
313        out = StringIO()
314        # We don't have any way of uninstalling, at this point.
315        return out.getvalue()
316
Note: See TracBrowser for help on using the repository browser.