def upgradeId(self, REQUEST=None): """ Make sure a page's id conforms with its title (may also change title!) See also canonicalIdFrom, http://zwiki.org/HowZwikiTitleAndIdWorks . Does not leave a placeholder, so may break incoming links. Does update backlinks, because it's less work than fixing up links by hand afterward. This makes it too slow to use in auto-upgrade, though, so people must call this manually or more usually via upgradeAll. With legacy pages (or manually renamed pages), it may happen that there's a clash between two similarly-named pages mapping to the same canonical id. In this case we just log the error and move on. The tracker plugin modifies this to also rename old IssueNoNNNN pages to the new #NNNN style. """ # let plugins influence the new title & id.. name = callHooks(upgradeId_hooks, self) or self.pageName() # now we can just call rename, it will do what's necessary try: self.rename(name, updatebacklinks=1, sendmail=0, REQUEST=REQUEST) except CopyError: BLATHER( 'upgradeId for "%s" (%s) failed - does %s already exist ?' \ % (self.pageName(),self.getId(),self.canonicalIdFrom(name)))
def upgradeId(self,REQUEST=None): """ Make sure a page's id conforms with its title (may also change title!) See also canonicalIdFrom, http://zwiki.org/HowZwikiTitleAndIdWorks . Does not leave a placeholder, so may break incoming links. Does update backlinks, because it's less work than fixing up links by hand afterward. This makes it too slow to use in auto-upgrade, though, so people must call this manually or more usually via upgradeAll. With legacy pages (or manually renamed pages), it may happen that there's a clash between two similarly-named pages mapping to the same canonical id. In this case we just log the error and move on. The tracker plugin modifies this to also rename old IssueNoNNNN pages to the new #NNNN style. """ # let plugins influence the new title & id.. name = callHooks(upgradeId_hooks, self) or self.pageName() # now we can just call rename, it will do what's necessary try: self.rename(name,updatebacklinks=1,sendmail=0,REQUEST=REQUEST) except CopyError: BLATHER( 'upgradeId for "%s" (%s) failed - does %s already exist ?' \ % (self.pageName(),self.getId(),self.canonicalIdFrom(name)))
def upgrade(self, REQUEST=None): """ Upgrade an old page instance (and possibly the folder as well). Called on every page view (set AUTO_UPGRADE=0 in Default.py to prevent this). You could also call this on every page in your wiki to do a batch upgrade. Affects bobobase_modification_time. If you later downgrade zwiki, the upgraded pages may not work so well. """ # Note that the objects don't get very far unpickling, some # by-hand adjustment via command-line interaction is necessary # to get them over the transition, sigh. --ken # not sure what this means --SM # What happens in the zodb when class definitions change ? I think # all instances in the zodb conform to the new class shape # immediately on refresh/restart, but what happens to # (a) old _properties lists ? not sure, assume they remain in # unaffected and we need to add the new properties # and (b) old properties & attributes no longer in the class # definition ? I think these lurk around, and we need to delete # them. changed = 0 # As of 0.17, page ids are always canonicalIdFrom(title); we'll # rename to conform with this where necessary # too slow! # changed = self.upgradeId() # fix up attributes first, then properties # NB be a bit careful about acquisition while doing this # migrate a WikiForNow _st_data attribute if safe_hasattr(self.aq_base, '_st_data'): self.raw = self._st_data del self._st_data changed = 1 # upgrade old page types pagetype = self.pageTypeId() if pagetype in PAGE_TYPE_UPGRADES.keys(): self.setPageType(self.modernPageTypeFor(pagetype)) # clear render cache; don't bother prerendering just now self.clearCache() changed = 1 # Pre-0.9.10, creation_time has been a string in custom format and # last_edit_time has been a DateTime. Now both are kept as # ISO 8601-format strings. Might not be strictly necessary to upgrade # in all cases.. will cause a lot of bobobase_mod_time # updates.. do it anyway. if not self.last_edit_time: self.last_edit_time = self.bobobase_modification_time().ISO8601() changed = 1 elif type(self.last_edit_time) is not StringType: self.last_edit_time = self.last_edit_time.ISO8601() changed = 1 elif len(self.last_edit_time) != 25: try: if len(self.last_edit_time) == 19: # older "ISO()" format # we're using the behaviour that was standard in # Zope <= 2.9, where a timestamp without timezone # information was assumed to be in UTC (aka GMT) self.last_edit_time = \ DateTime(self.last_edit_time+' GMT+0').ISO8601() else: # some other timestamp format, leave tz information # untouched, or let DateTime guess at it self.last_edit_time = \ DateTime(self.last_edit_time).ISO8601() changed = 1 except DateTimeSyntaxError: # can't convert to ISO 8601, just leave it be pass # If no creation_time, just leave it blank for now. # we shouldn't find DateTimes here, but check anyway if not self.creation_time: pass elif type(self.creation_time) is not StringType: self.creation_time = self.creation_time.ISO8601() changed = 1 elif len(self.creation_time) != 25: try: if len(self.creation_time) == 19: # older "ISO()" format self.creation_time = \ DateTime(self.creation_time+' GMT+0').ISO8601() else: self.creation_time = \ DateTime(self.creation_time).ISO8601() changed = 1 except DateTimeSyntaxError: # can't convert to ISO 8601, just leave it be pass # _wikilinks, _links and _prelinked are no longer used for a in ( '_wikilinks', '_links', '_prelinked', ): if safe_hasattr(self.aq_base, a): delattr(self, a) self.clearCache() changed = 1 # update _properties # keep in sync with _properties above. Better if we used that as # the template (efficiently) oldprops = { # not implemented 'page_type' :{'id':'page_type','type':'string'}, } newprops = { #'page_type' :{'id':'page_type','type':'selection','mode': 'w', # 'select_variable': 'ZWIKI_PAGE_TYPES'}, 'creator': { 'id': 'creator', 'type': 'string', 'mode': 'r' }, 'creator_ip': { 'id': 'creator_ip', 'type': 'string', 'mode': 'r' }, 'creation_time': { 'id': 'creation_time', 'type': 'string', 'mode': 'r' }, 'last_editor': { 'id': 'last_editor', 'type': 'string', 'mode': 'r' }, 'last_editor_ip': { 'id': 'last_editor_ip', 'type': 'string', 'mode': 'r' }, 'last_edit_time': { 'id': 'creation_time', 'type': 'string', 'mode': 'r' }, 'last_log': { 'id': 'last_log', 'type': 'string', 'mode': 'r' }, 'NOT_CATALOGED': { 'id': 'NOT_CATALOGED', 'type': 'boolean', 'mode': 'w' }, } props = map(lambda x: x['id'], self._properties) for p in oldprops.keys(): if p in props: # and oldprops[p]['type'] != blah blah blah : pass #ack! #self._properties = filter(lambda x:x['id'] != p, # self._properties) #changed = 1 # XXX this does work in python 1.5 surely.. what's the # problem ? for p in newprops.keys(): if not p in props: self._properties = self._properties + (newprops[p], ) changed = 1 # ensure parents property is a list if self.ensureParentsPropertyIsList(): changed = 1 # call any extra upgrade actions eg from plugins if callHooks(upgrade_hooks, self): changed = 1 if changed: # do a commit now so the current render will have the correct # bobobase_modification_time for display (many headers/footers # still show it) # XXX I don't think we need to dick around with commits any more #get_transaction().commit() BLATHER('upgraded ' + self.id()) self.upgradeComments(REQUEST) # PageMailSupport does a bit more (merge here ?) self._upgradeSubscribers() # make sure there is a catalog for this wiki self.ensureCatalog() # make sure there is an up-to-date outline cache self.ensureWikiOutline()
def upgrade(self,REQUEST=None): """ Upgrade an old page instance (and possibly the folder as well). Called on every page view (set AUTO_UPGRADE=0 in Default.py to prevent this). You could also call this on every page in your wiki to do a batch upgrade. Affects bobobase_modification_time. If you later downgrade zwiki, the upgraded pages may not work so well. """ # Note that the objects don't get very far unpickling, some # by-hand adjustment via command-line interaction is necessary # to get them over the transition, sigh. --ken # not sure what this means --SM # What happens in the zodb when class definitions change ? I think # all instances in the zodb conform to the new class shape # immediately on refresh/restart, but what happens to # (a) old _properties lists ? not sure, assume they remain in # unaffected and we need to add the new properties # and (b) old properties & attributes no longer in the class # definition ? I think these lurk around, and we need to delete # them. changed = 0 # As of 0.17, page ids are always canonicalIdFrom(title); we'll # rename to conform with this where necessary # too slow! # changed = self.upgradeId() # fix up attributes first, then properties # NB be a bit careful about acquisition while doing this # migrate a WikiForNow _st_data attribute if hasattr(self.aq_base, '_st_data'): self.raw = self._st_data del self._st_data changed = 1 # upgrade old page types pagetype = self.pageTypeId() if pagetype in PAGE_TYPE_UPGRADES.keys(): self.setPageType(self.newPageTypeIdFor(pagetype)) # clear render cache; don't bother prerendering just now self.clearCache() changed = 1 # Pre-0.9.10, creation_time has been a string in custom format and # last_edit_time has been a DateTime. Now both are kept as # ISO-format strings. Might not be strictly necessary to upgrade # in all cases.. will cause a lot of bobobase_mod_time # updates.. do it anyway. if not self.last_edit_time: self.last_edit_time = self.bobobase_modification_time().ISO() changed = 1 elif type(self.last_edit_time) is not StringType: self.last_edit_time = self.last_edit_time.ISO() changed = 1 elif len(self.last_edit_time) != 19: try: self.last_edit_time = DateTime(self.last_edit_time).ISO() changed = 1 except DateTimeSyntaxError: # can't convert to ISO, just leave it be pass # If no creation_time, just leave it blank for now. # we shouldn't find DateTimes here, but check anyway if not self.creation_time: pass elif type(self.creation_time) is not StringType: self.creation_time = self.creation_time.toZone('UTC').ISO() changed = 1 elif len(self.creation_time) != 19: try: self.creation_time = DateTime(self.creation_time).toZone('UTC').ISO() changed = 1 except DateTimeSyntaxError: # can't convert to ISO, just leave it be pass # _wikilinks, _links and _prelinked are no longer used for a in ( '_wikilinks', '_links', '_prelinked', ): if hasattr(self.aq_base,a): delattr(self,a) self.clearCache() changed = 1 # update _properties # keep in sync with _properties above. Better if we used that as # the template (efficiently) oldprops = { # not implemented 'page_type' :{'id':'page_type','type':'string'}, } newprops = { #'page_type' :{'id':'page_type','type':'selection','mode': 'w', # 'select_variable': 'ZWIKI_PAGE_TYPES'}, 'creator' :{'id':'creator','type':'string','mode':'r'}, 'creator_ip' :{'id':'creator_ip','type':'string','mode':'r'}, 'creation_time' :{'id':'creation_time','type':'string','mode':'r'}, 'last_editor' :{'id':'last_editor','type':'string','mode':'r'}, 'last_editor_ip':{'id':'last_editor_ip','type':'string','mode':'r'}, 'last_edit_time':{'id':'creation_time','type':'string','mode':'r'}, 'last_log' :{'id':'last_log', 'type': 'string', 'mode': 'r'}, 'NOT_CATALOGED' :{'id':'NOT_CATALOGED', 'type': 'boolean', 'mode': 'w'}, } props = map(lambda x:x['id'], self._properties) for p in oldprops.keys(): if p in props: # and oldprops[p]['type'] != blah blah blah : pass #ack! #self._properties = filter(lambda x:x['id'] != p, # self._properties) #changed = 1 # XXX this does work in python 1.5 surely.. what's the # problem ? for p in newprops.keys(): if not p in props: self._properties = self._properties + (newprops[p],) changed = 1 # ensure parents property is a list if self.ensureParentsPropertyIsList(): changed = 1 # call any extra upgrade actions eg from plugins if callHooks(upgrade_hooks, self): changed = 1 if changed: # do a commit now so the current render will have the correct # bobobase_modification_time for display (many headers/footers # still show it) # XXX I don't think we need to dick around with commits any more #get_transaction().commit() BLATHER('upgraded '+self.id()) self.upgradeComments(REQUEST) # PageMailSupport does a bit more (merge here ?) self._upgradeSubscribers() # also make sure there is an up-to-date outline cache self.wikiOutline()