示例#1
0
 def cleanupLockData(self, user_id):
     # This gets called on lock to avoid write-on-read, and its
     # possible to lock more than one object in a request so we
     # want to avoid doing this multiple times in a request!
     if self.REQUEST.get('_lock_gc_%s' % user_id, None):
         return
     mapping = getattr(self, '_locks', None)
     if mapping is None:
         return
     items = mapping.get(user_id, None)
     if items is None:
         return
     # stupid heuristic to occasionally go through and clean out
     # timed out and otherwise invalid lock records without taking
     # the hit on every lock request.
     if len(items) < self._lock_gc_threshold:
         return
     for key in items.keys():
         try:
             obj = self.unrestrictedTraverse(key, None)
         except NotFound:
             obj = None
         if obj is None or self.locker(obj) != user_id:
             del items[key]
         if hasattr(obj, '_p_deactivate'):
             unproxied(obj)._p_deactivate()
     setattr(self.REQUEST, '_lock_gc_%s' % user_id, 1)
示例#2
0
文件: LockTool.py 项目: goschtl/zope
 def cleanupLockData(self, user_id):
     # This gets called on lock to avoid write-on-read, and its
     # possible to lock more than one object in a request so we
     # want to avoid doing this multiple times in a request!
     if self.REQUEST.get('_lock_gc_%s' % user_id, None):
         return
     mapping = getattr(self, '_locks', None)
     if mapping is None:
         return
     items = mapping.get(user_id, None)
     if items is None:
         return
     # stupid heuristic to occasionally go through and clean out
     # timed out and otherwise invalid lock records without taking
     # the hit on every lock request.
     if len(items) < self._lock_gc_threshold:
         return
     for key in items.keys():
         try: obj = self.unrestrictedTraverse(key, None)
         except NotFound:
             obj = None
         if obj is None or self.locker(obj) != user_id:
             del items[key]
         if hasattr(obj, '_p_deactivate'):
             unproxied(obj)._p_deactivate()
     setattr(self.REQUEST, '_lock_gc_%s' % user_id, 1)
示例#3
0
    def updateStages2(self, obj, to_stages, message=''):
        """Updates objects to match the version in the source stage.
        """
        verifyPermission(StageObjects, obj)
        from_stage = self.getStageOf(obj)
        if from_stage is None:
            raise StagingError("Object %s is not in any stage" %
                               '/'.join(obj.getPhysicalPath()))
        if from_stage in to_stages or not to_stages:
            raise StagingError("Invalid to_stages parameter")

        if aq_base(unproxied(obj)) is not aq_base(obj):

            ref = obj.__dict__.get("_Proxy__reference")

            if ref is None:
                # Carefully wrap an *un*proxied version of obj in the same
                # context:
                IAW = ImplicitAcquisitionWrapper
                obj = IAW(unproxied(obj), aq_parent(aq_inner(obj)))
                proxy = None
            else:
                # obj is a proxy.  Find the wrapped target and update that
                # instead of the reference.  Note that the reference will
                # be updated with the container.
                proxy = obj
                obj = ref.getTarget(obj)
                # Decide whether the reference should be staged at the
                # same time.  If the reference is contained in a
                # non-versioned container, the reference should be staged.
                # OTOH, if the reference is in a versioned container,
                # staging the container will create the reference, so the
                # reference should not be staged by this operation.
                repo = self._getVersionRepository()
                if repo.isUnderVersionControl(aq_parent(aq_inner(proxy))):
                    proxy = None
        else:
            proxy = None

        # Check containers first.
        cmap = self._getObjectStages(obj, get_container=1)
        self._checkContainers(obj, to_stages, cmap)
        proxy_cmap = None
        if proxy is not None:
            # Check the containers of the reference also.
            proxy_cmap = self._getObjectStages(proxy, get_container=1)
            self._checkContainers(proxy, to_stages, proxy_cmap)

        # Update the stages.
        if self.auto_checkin:
            self._autoCheckin(obj, message)
        self._updateObjectStates(obj, cmap, to_stages)
        if proxy is not None:
            # Create and update the reference objects also.
            self._updateReferences(proxy, proxy_cmap, to_stages)
示例#4
0
 def getLogEntries(self, obj, only_checkins=0):
     """Returns the log entries for an object as a sequence of mappings.
     """
     verifyPermission(UseVersionControl, obj)
     obj = unproxied(obj)
     repo = self._getVersionRepository()
     if not repo.isUnderVersionControl(obj):
         return []
     entries = repo.getLogEntries(obj)
     res = []
     for entry in entries:
         a = entry.action
         if a == entry.ACTION_CHECKOUT:
             action = 'checkout'
         elif a == entry.ACTION_CHECKIN:
             action = 'checkin'
         elif a == entry.ACTION_UNCHECKOUT:
             action = 'uncheckout'
         elif a == entry.ACTION_UPDATE:
             action = 'update'
         else:
             action = '?'
         if only_checkins and action != 'checkin':
             continue
         res.append({'timestamp': entry.timestamp,
                     'version_id': entry.version_id,
                     'action': action,
                     'message': entry.message,
                     'user_id': entry.user_id,
                     'path': entry.path,
                     })
     return res
示例#5
0
 def getHistoryId(self, obj):
     """Returns the version history ID of the object.
     """
     verifyPermission(UseVersionControl, obj)
     obj = unproxied(obj)
     repo = self._getVersionRepository()
     return repo.getVersionInfo(obj).history_id
示例#6
0
 def checkin(self, obj, message=None):
     """Checks in a new version.
     """
     verifyPermission(UseVersionControl, obj)
     obj = unproxied(obj)
     repo = self._getVersionRepository()
     if not repo.isUnderVersionControl(obj):
         repo.applyVersionControl(obj, message)
     else:
         if (not repo.isResourceUpToDate(obj, require_branch=1)
                 and self.isCheckedOut(obj)):
             # This is a strange state, but it can be fixed.
             # Revert the object to the branch, replace the
             # reverted state with the new state, and check in.
             new_dict = obj.__dict__.copy()
             # Uncheckout
             obj = repo.uncheckoutResource(obj)
             info = repo.getVersionInfo(obj)
             obj = repo.updateResource(obj, self._getBranchName(info))
             # Checkout
             obj = repo.checkoutResource(obj)
             # Restore the new state
             for key in obj.__dict__.keys():
                 if key != '__vc_info__':
                     if not new_dict.has_key(key):
                         del obj.__dict__[key]
             for key, value in new_dict.items():
                 if key != '__vc_info__':
                     obj.__dict__[key] = value
         repo.checkinResource(obj, message or '')
     return None
示例#7
0
 def getLogEntries(self, obj, only_checkins=0):
     """Returns the log entries for an object as a sequence of mappings.
     """
     verifyPermission(UseVersionControl, obj)
     obj = unproxied(obj)
     repo = self._getVersionRepository()
     if not repo.isUnderVersionControl(obj):
         return []
     entries = repo.getLogEntries(obj)
     res = []
     for entry in entries:
         a = entry.action
         if a == entry.ACTION_CHECKOUT:
             action = 'checkout'
         elif a == entry.ACTION_CHECKIN:
             action = 'checkin'
         elif a == entry.ACTION_UNCHECKOUT:
             action = 'uncheckout'
         elif a == entry.ACTION_UPDATE:
             action = 'update'
         else:
             action = '?'
         if only_checkins and action != 'checkin':
             continue
         res.append({
             'timestamp': entry.timestamp,
             'version_id': entry.version_id,
             'action': action,
             'message': entry.message,
             'user_id': entry.user_id,
             'path': entry.path,
         })
     return res
示例#8
0
 def getHistoryId(self, obj):
     """Returns the version history ID of the object.
     """
     verifyPermission(UseVersionControl, obj)
     obj = unproxied(obj)
     repo = self._getVersionRepository()
     return repo.getVersionInfo(obj).history_id
示例#9
0
 def checkin(self, obj, message=None):
     """Checks in a new version.
     """
     verifyPermission(UseVersionControl, obj)
     obj = unproxied(obj)
     repo = self._getVersionRepository()
     if not repo.isUnderVersionControl(obj):
         repo.applyVersionControl(obj, message)
     else:
         if (not repo.isResourceUpToDate(obj, require_branch=1)
             and self.isCheckedOut(obj)):
             # This is a strange state, but it can be fixed.
             # Revert the object to the branch, replace the
             # reverted state with the new state, and check in.
             new_dict = obj.__dict__.copy()
             # Uncheckout
             obj = repo.uncheckoutResource(obj)
             info = repo.getVersionInfo(obj)
             obj = repo.updateResource(obj, self._getBranchName(info))
             # Checkout
             obj = repo.checkoutResource(obj)
             # Restore the new state
             for key in obj.__dict__.keys():
                 if key != '__vc_info__':
                     if not new_dict.has_key(key):
                         del obj.__dict__[key]
             for key, value in new_dict.items():
                 if key != '__vc_info__':
                     obj.__dict__[key] = value
         repo.checkinResource(obj, message or '')
     return None
示例#10
0
 def isCheckedOut(self, obj):
     """Returns a true value if the object is checked out.
     """
     obj = unproxied(obj)
     repo = self._getVersionRepository()
     if not repo.isUnderVersionControl(obj):
         return 0
     info = repo.getVersionInfo(obj)
     return (info.status == info.CHECKED_OUT)
示例#11
0
 def isCheckedOut(self, obj):
     """Returns a true value if the object is checked out.
     """
     obj = unproxied(obj)
     repo = self._getVersionRepository()
     if not repo.isUnderVersionControl(obj):
         return 0
     info = repo.getVersionInfo(obj)
     return (info.status == info.CHECKED_OUT)
示例#12
0
 def getVersionIds(self, obj):
     """Returns the version IDs of all revisions for an object.
     """
     verifyPermission(UseVersionControl, obj)
     obj = unproxied(obj)
     repo = self._getVersionRepository()
     ids = repo.getVersionIds(obj)
     ids = map(int, ids)
     ids.sort()
     return map(str, ids)
示例#13
0
 def getVersionIds(self, obj):
     """Returns the version IDs of all revisions for an object.
     """
     verifyPermission(UseVersionControl, obj)
     obj = unproxied(obj)
     repo = self._getVersionRepository()
     ids = repo.getVersionIds(obj)
     ids = map(int, ids)
     ids.sort()
     return map(str, ids)
示例#14
0
 def _getObjectVersionIds(self, obj, include_status=0):
     repo = self._getVersionRepository()
     stages = self._getObjectStages(obj)
     res = {}
     for stage_name, obj in stages.items():
         u_obj = unproxied(obj)
         if obj is None or not repo.isUnderVersionControl(u_obj):
             res[stage_name] = None
         else:
             info = repo.getVersionInfo(u_obj)
             v = info.version_id
             if include_status and info.status == info.CHECKED_OUT:
                 v = str(v) + '+'
             res[stage_name] = v
     return res
示例#15
0
 def isStageable(self, obj):
     """Returns a true value if the object can be staged."""
     verifyPermission(StageObjects, obj)
     repo = self._getVersionRepository()
     if not repo.isAVersionableResource(unproxied(obj)):
         return 0
     if not getattr(obj, '_stageable', 1):
         return 0
     # An object is stageable only if it is located in one of the stages.
     portal = aq_parent(aq_inner(self))
     for stage_name, stage_title, path in self._stages:
         stage = self._getStage(portal, path)
         if stage is not None and obj.aq_inContextOf(stage, 1):
             return 1
     return 0
示例#16
0
    def revertToVersion(self, obj, version_id):
        """Reverts the object to the given version.

        If make_new_revision, a new revision is created, so that
        the object's state can progress along a new line without
        making the user deal with branches, labels, etc.
        """
        verifyPermission(UseVersionControl, obj)
        obj = unproxied(obj)
        repo = self._getVersionRepository()
        # Verify the object is under version control.
        repo.getVersionInfo(obj)
        if self.isCheckedOut(obj):
            # Save the current data.
            self.checkin(obj, 'Auto-saved')
        repo.updateResource(obj, version_id)
示例#17
0
    def revertToVersion(self, obj, version_id):
        """Reverts the object to the given version.

        If make_new_revision, a new revision is created, so that
        the object's state can progress along a new line without
        making the user deal with branches, labels, etc.
        """
        verifyPermission(UseVersionControl, obj)
        obj = unproxied(obj)
        repo = self._getVersionRepository()
        # Verify the object is under version control.
        repo.getVersionInfo(obj)
        if self.isCheckedOut(obj):
            # Save the current data.
            self.checkin(obj, 'Auto-saved')
        repo.updateResource(obj, version_id)
示例#18
0
    def getVersionId(self, obj, plus=0):
        """Returns the version ID of the current revision.

        If the 'plus' flag is set and the object is checked out, the
        version ID will include a plus sign to indicate that when the
        object is checked in, it will have a higher version number.
        """
        obj = unproxied(obj)
        repo = self._getVersionRepository()
        if repo.isUnderVersionControl(obj):
            info = repo.getVersionInfo(obj)
            res = info.version_id
            if plus and info.status == info.CHECKED_OUT:
                res += '+'
            return res
        else:
            return ''
示例#19
0
    def getVersionId(self, obj, plus=0):
        """Returns the version ID of the current revision.

        If the 'plus' flag is set and the object is checked out, the
        version ID will include a plus sign to indicate that when the
        object is checked in, it will have a higher version number.
        """
        obj = unproxied(obj)
        repo = self._getVersionRepository()
        if repo.isUnderVersionControl(obj):
            info = repo.getVersionInfo(obj)
            res = info.version_id
            if plus and info.status == info.CHECKED_OUT:
                res += '+'
            return res
        else:
            return ''
示例#20
0
    def checkout(self, obj):
        """Opens the object for development.

        Returns the object, which might be different from what was passed to
        the method if the object was replaced.
        """
        verifyPermission(UseVersionControl, obj)
        obj = unproxied(obj)
        repo = self._getVersionRepository()
        old_state = None
        if not repo.isUnderVersionControl(obj):
            repo.applyVersionControl(obj)
        elif self.auto_copy_forward:
            if not repo.isResourceUpToDate(obj, require_branch=1):
                # The object is not at the latest revision or has a
                # sticky tag.  Get it unstuck by copying the old state
                # forward after the object has been checked out.
                info = repo.getVersionInfo(obj)
                old_state = repo.getVersionOfResource(info.history_id,
                                                      info.version_id)
                # Momentarily revert to the branch.
                obj = repo.updateResource(obj, self._getBranchName(info))
                obj = repo.checkoutResource(obj)

                # Copy the old state into the object, minus __vc_info__.
                # XXX There ought to be some way to do this more cleanly.
                obj._p_changed = 1
                for key in obj.__dict__.keys():
                    if key != '__vc_info__':
                        if not old_state.__dict__.has_key(key):
                            del obj.__dict__[key]
                for key, value in old_state.__dict__.items():
                    if key != '__vc_info__':
                        obj.__dict__[key] = value
                # Check in as a copy.
                obj = repo.checkinResource(
                    obj, 'Copied from revision %s' % info.version_id)
        repo.checkoutResource(obj)
        return None
示例#21
0
    def checkout(self, obj):
        """Opens the object for development.

        Returns the object, which might be different from what was passed to
        the method if the object was replaced.
        """
        verifyPermission(UseVersionControl, obj)
        obj = unproxied(obj)
        repo = self._getVersionRepository()
        old_state = None
        if not repo.isUnderVersionControl(obj):
            repo.applyVersionControl(obj)
        elif self.auto_copy_forward:
            if not repo.isResourceUpToDate(obj, require_branch=1):
                # The object is not at the latest revision or has a
                # sticky tag.  Get it unstuck by copying the old state
                # forward after the object has been checked out.
                info = repo.getVersionInfo(obj)
                old_state = repo.getVersionOfResource(
                    info.history_id, info.version_id)
                # Momentarily revert to the branch.
                obj = repo.updateResource(obj, self._getBranchName(info))
                obj = repo.checkoutResource(obj)

                # Copy the old state into the object, minus __vc_info__.
                # XXX There ought to be some way to do this more cleanly.
                obj._p_changed = 1
                for key in obj.__dict__.keys():
                    if key != '__vc_info__':
                        if not old_state.__dict__.has_key(key):
                            del obj.__dict__[key]
                for key, value in old_state.__dict__.items():
                    if key != '__vc_info__':
                        obj.__dict__[key] = value
                # Check in as a copy.
                obj = repo.checkinResource(
                    obj, 'Copied from revision %s' % info.version_id)
        repo.checkoutResource(obj)
        return None
示例#22
0
    def _updateObjectStates(self, source_object, container_map, to_stages):
        """Internal: updates the state of an object in specified stages.

        Uses version control to do the propagation.
        """
        repo = self._getVersionRepository()
        object_map = self._getObjectStages(source_object)
        version_info = repo.getVersionInfo(source_object)
        version_id = version_info.version_id
        history_id = version_info.history_id

        # Update and/or copy the object to the different stages.
        for stage_name, ob in object_map.items():
            if stage_name in to_stages:
                if ob is None:
                    # The object has not yet been created in the stage.
                    # Copy from the repository to the given stage.
                    ob = repo.getVersionOfResource(history_id, version_id)
                    container = container_map[stage_name]
                    # Make a copy and put it in the new place.
                    id = source_object.getId()
                    container._setObject(id, ob)
                else:
                    if not repo.isUnderVersionControl(ob):
                        p = '/'.join(ob.getPhysicalPath())
                        raise StagingError(
                            'The object "%s", not under version control, '
                            'is in the way.' % p)
                    if repo.getVersionInfo(ob).history_id != history_id:
                        p = '/'.join(ob.getPhysicalPath())
                        p2 = '/'.join(source_object.getPhysicalPath())
                        raise StagingError(
                            'The object "%s", backed by a different '
                            'version history than "%s", '
                            'is in the way.' % (p, p2))
                    repo.updateResource(unproxied(ob), version_id)
示例#23
0
 def isUnderVersionControl(self, obj):
     """Returns a true value if the object is under version control.
     """
     obj = unproxied(obj)
     repo = self._getVersionRepository()
     return repo.isUnderVersionControl(obj)
示例#24
0
 def isResourceUpToDate(self, obj, require_branch=0):
     """Return true if a version-controlled resource is up to date.
     """
     obj = unproxied(obj)
     repo = self._getVersionRepository()
     return repo.isResourceUpToDate(obj, require_branch)
示例#25
0
 def isResourceUpToDate(self, obj, require_branch=0):
     """Return true if a version-controlled resource is up to date.
     """
     obj = unproxied(obj)
     repo = self._getVersionRepository()
     return repo.isResourceUpToDate(obj, require_branch)
示例#26
0
 def isUnderVersionControl(self, obj):
     """Returns a true value if the object is under version control.
     """
     obj = unproxied(obj)
     repo = self._getVersionRepository()
     return repo.isUnderVersionControl(obj)