Back to index

plone3  3.1.7
Utility.py
Go to the documentation of this file.
00001 ##############################################################################
00002 #
00003 # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
00004 # 
00005 # This software is subject to the provisions of the Zope Public License,
00006 # Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
00007 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
00008 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00009 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
00010 # FOR A PARTICULAR PURPOSE
00011 # 
00012 ##############################################################################
00013 
00014 import os
00015 import time
00016 
00017 from AccessControl import ClassSecurityInfo
00018 from AccessControl import getSecurityManager
00019 from App.Common import package_home
00020 from DateTime import DateTime
00021 from Globals import InitializeClass, Persistent
00022 from ZODB.TimeStamp import TimeStamp
00023 
00024 try:
00025     from ZODB.serialize import referencesf
00026 except ImportError:  # < Zope 2.8 / ZODB 3.3
00027     from ZODB.referencesf import referencesf
00028 
00029 _dtmldir = os.path.join( package_home( globals() ), 'dtml' )
00030 
00031 use_vc_permission = 'Use version control'
00032 
00033 
00034 def isAVersionableResource(obj):
00035     """ True if an object is versionable.
00036 
00037     To qualify, the object must be persistent (have its own db record), and
00038     must not have an true attribute named '__non_versionable__'."""
00039 
00040     if getattr(obj, '__non_versionable__', 0):
00041         return 0
00042     return hasattr(obj, '_p_oid')
00043 
00044 class VersionInfo(Persistent):
00045     """A VersionInfo object contains bookkeeping information for version
00046        controlled objects. The bookkeeping information can be read (but
00047        not changed) by restricted code."""
00048 
00049     __allow_access_to_unprotected_subobjects__ = 1
00050 
00051     def __init__(self, history_id, version_id, status):
00052         self.timestamp = time.time()
00053         self.history_id = history_id
00054         self.version_id = version_id
00055         self.status = status
00056         self.user_id = _findUserId()
00057 
00058     sticky = None
00059 
00060     CHECKED_OUT = 0
00061     CHECKED_IN = 1
00062 
00063     def branchName(self):
00064         if self.sticky is not None and self.sticky[0] == 'B':
00065             return self.sticky[1]
00066         return 'mainline'
00067 
00068     def clone(self, clear_sticky=0):
00069         info = VersionInfo(self.history_id, self.version_id, self.status)
00070         dict = info.__dict__
00071         for name, value in self.__dict__.items():
00072             dict[name] = value
00073         if clear_sticky:
00074             if dict.has_key('sticky'):
00075                 del dict['sticky']
00076         info.user_id = _findUserId()
00077         info.timestamp = time.time()
00078         return info
00079 
00080 InitializeClass(VersionInfo)
00081 
00082 
00083 
00084 class ReadOnlyJar:
00085     """A read-only ZODB connection-like object that prevents changes."""
00086 
00087     def __init__(self, base):
00088         self.__base__ = base
00089 
00090     _invalidating = []
00091 
00092     def __getattr__(self, name):
00093         return getattr(self.__base__, name)
00094 
00095     def commit(*args, **kw):
00096         raise VersionWriteError(
00097             'Old versions of objects cannot be modified.'
00098             )
00099 
00100     def abort(*args, **kw):
00101         pass
00102 
00103 
00104 
00105 class VersionControlError(Exception):
00106     pass
00107 
00108 
00109 
00110 def _findUserId():
00111     user = getSecurityManager().getUser()
00112     return user.getUserName()
00113 
00114 def _findPath(object):
00115     path = object.getPhysicalPath()
00116     return '/'.join(path)
00117 
00118 def _findModificationTime(object):
00119     """Find the last modification time for a version-controlled object.
00120        The modification time reflects the latest modification time of
00121        the object or any of its persistent subobjects that are not
00122        themselves version-controlled objects. Note that this will
00123        return None if the object has no modification time."""
00124 
00125     mtime = getattr(object, '_p_mtime', None)
00126     if mtime is None:
00127         return None
00128 
00129     latest = mtime
00130     conn = object._p_jar
00131     load = conn._storage.load
00132     version = conn._version
00133     refs = referencesf
00134 
00135     oids=[object._p_oid]
00136     done_oids={}
00137     done=done_oids.has_key
00138     first = 1
00139 
00140     while oids:
00141         oid=oids[0]
00142         del oids[0]
00143         if done(oid):
00144             continue
00145         done_oids[oid]=1
00146         try: p, serial = load(oid, version)
00147         except: pass # invalid reference!
00148         else:
00149             if first is not None:
00150                 first = None
00151             else:
00152                 if p.find('U\x0b__vc_info__') == -1:
00153                     mtime = TimeStamp(serial).timeTime()
00154                     if mtime > latest:
00155                         latest = mtime
00156             refs(p, oids)
00157 
00158     return latest
00159