Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Conform setup metadata, copyright headers to repository policy.
- Loading branch information
Showing
17 changed files
with
4,640 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
############################################################################## | ||
# | ||
# Copyright (c) 2002 Zope Foundation and Contributors. | ||
# | ||
# This software is subject to the provisions of the Zope Public License, | ||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. | ||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED | ||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS | ||
# FOR A PARTICULAR PURPOSE | ||
# | ||
############################################################################## | ||
|
||
"""ZCatalog Findable class | ||
**NOTE**: This module is deprecated, and should only be used for | ||
backward-compatibility. All new code should use CatalogPathAwareness. | ||
""" | ||
|
||
import urllib | ||
from Globals import DTMLFile | ||
from Acquisition import aq_base | ||
|
||
class CatalogAware: | ||
""" This is a Mix-In class to make objects automaticly catalog and | ||
uncatalog themselves in Zope, and to provide some other basic | ||
attributes that are useful to catalog. Note that if your class or | ||
ZClass subclasses CatalogAware, it will only catalog itself when | ||
it is added or copied in Zope. If you make changes to your own | ||
object, you are responsible for calling your object's index_object | ||
method. """ | ||
|
||
meta_type='CatalogAware' | ||
default_catalog='Catalog' | ||
|
||
manage_editCatalogerForm=DTMLFile('dtml/editCatalogerForm', globals()) | ||
|
||
def manage_editCataloger(self, default, REQUEST=None): | ||
""" """ | ||
self.default_catalog=default | ||
message = "Your changes have been saved" | ||
if REQUEST is not None: | ||
return self.manage_main(self, REQUEST, manage_tabs_message=message) | ||
|
||
|
||
def manage_afterAdd(self, item, container): | ||
self.index_object() | ||
for object in self.objectValues(): | ||
try: s=object._p_changed | ||
except: s=0 | ||
object.manage_afterAdd(item, container) | ||
if s is None: object._p_deactivate() | ||
|
||
def manage_afterClone(self, item): | ||
self.index_object() | ||
for object in self.objectValues(): | ||
try: s=object._p_changed | ||
except: s=0 | ||
object.manage_afterClone(item) | ||
if s is None: object._p_deactivate() | ||
|
||
def manage_beforeDelete(self, item, container): | ||
self.unindex_object() | ||
for object in self.objectValues(): | ||
try: s=object._p_changed | ||
except: s=0 | ||
object.manage_beforeDelete(item, container) | ||
if s is None: object._p_deactivate() | ||
|
||
def creator(self): | ||
"""Return a sequence of user names who have the local | ||
Owner role on an object. The name creator is used | ||
for this method to conform to Dublin Core.""" | ||
users=[] | ||
for user, roles in self.get_local_roles(): | ||
if 'Owner' in roles: | ||
users.append(user) | ||
return ', '.join(users) | ||
|
||
def onDeleteObject(self): | ||
"""Object delete handler. I think this is obsoleted by | ||
manage_beforeDelete """ | ||
self.unindex_object() | ||
|
||
def url(self, ftype=urllib.splittype, fhost=urllib.splithost): | ||
"""Return a SCRIPT_NAME-based url for an object.""" | ||
if hasattr(self, 'DestinationURL') and \ | ||
callable(self.DestinationURL): | ||
url='%s/%s' % (self.DestinationURL(), self.id) | ||
else: url=self.absolute_url() | ||
type, uri=ftype(url) | ||
host, uri=fhost(uri) | ||
script_name=self.REQUEST['SCRIPT_NAME'] | ||
__traceback_info__=(`uri`, `script_name`) | ||
if script_name: | ||
uri=filter(None, uri.split(script_name))[0] | ||
if not uri: | ||
uri = '/' | ||
if uri[0] != '/': | ||
uri = '/' + uri | ||
return urllib.unquote(uri) | ||
|
||
def summary(self, num=200): | ||
"""Return a summary of the text content of the object.""" | ||
if not hasattr(self, 'text_content'): | ||
return '' | ||
attr=getattr(self, 'text_content') | ||
if callable(attr): | ||
text=attr() | ||
else: text=attr | ||
n=min(num, len(text)) | ||
return text[:n] | ||
|
||
def index_object(self): | ||
"""A common method to allow Findables to index themselves.""" | ||
if hasattr(self, self.default_catalog): | ||
getattr(self, self.default_catalog).catalog_object(self, self.url()) | ||
|
||
def unindex_object(self): | ||
"""A common method to allow Findables to unindex themselves.""" | ||
if hasattr(self, self.default_catalog): | ||
getattr(self, self.default_catalog).uncatalog_object(self.url()) | ||
|
||
def reindex_object(self): | ||
""" Suprisingly useful """ | ||
self.unindex_object() | ||
self.index_object() | ||
|
||
def reindex_all(self, obj=None): | ||
""" """ | ||
if obj is None: obj=self | ||
if hasattr(aq_base(obj), 'index_object'): | ||
obj.index_object() | ||
if hasattr(aq_base(obj), 'objectValues'): | ||
sub=obj.objectValues() | ||
for item in obj.objectValues(): | ||
self.reindex_all(item) | ||
return 'done!' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
############################################################################## | ||
# | ||
# Copyright (c) 2002 Zope Foundation and Contributors. | ||
# | ||
# This software is subject to the provisions of the Zope Public License, | ||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. | ||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED | ||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS | ||
# FOR A PARTICULAR PURPOSE | ||
# | ||
############################################################################## | ||
|
||
__version__ = "$Revision$"[11:-2] | ||
|
||
from zope.interface import implements | ||
|
||
import Acquisition, Record | ||
from ZODB.POSException import ConflictError | ||
|
||
from interfaces import ICatalogBrain | ||
|
||
# Switch for new behavior, raise exception instead of returning None. | ||
# Use 'catalog-getObject-raises off' in zope.conf to restore old behavior. | ||
GETOBJECT_RAISES = True | ||
|
||
class AbstractCatalogBrain(Record.Record, Acquisition.Implicit): | ||
"""Abstract base brain that handles looking up attributes as | ||
required, and provides just enough smarts to let us get the URL, path, | ||
and cataloged object without having to ask the catalog directly. | ||
""" | ||
implements(ICatalogBrain) | ||
|
||
def has_key(self, key): | ||
return self.__record_schema__.has_key(key) | ||
|
||
def getPath(self): | ||
"""Get the physical path for this record""" | ||
return self.aq_parent.getpath(self.data_record_id_) | ||
|
||
def getURL(self, relative=0): | ||
"""Generate a URL for this record""" | ||
# XXX The previous implementation attempted to eat errors coming from | ||
# REQUEST.physicalPathToURL. Unfortunately it also ate | ||
# ConflictErrors (from getPath), which is bad. Staring at the | ||
# relevent code in HTTPRequest.py it's unclear to me what could be | ||
# raised by it so I'm removing the exception handling here all | ||
# together. If undesired exceptions get raised somehow we should | ||
# avoid bare except band-aids and find a real solution. | ||
return self.REQUEST.physicalPathToURL(self.getPath(), relative) | ||
|
||
def _unrestrictedGetObject(self): | ||
"""Return the object for this record | ||
Same as getObject, but does not do security checks. | ||
""" | ||
try: | ||
return self.aq_parent.unrestrictedTraverse(self.getPath()) | ||
except ConflictError: | ||
raise | ||
except: | ||
if GETOBJECT_RAISES: | ||
raise | ||
return None | ||
|
||
def getObject(self, REQUEST=None): | ||
"""Return the object for this record | ||
Will return None if the object cannot be found via its cataloged path | ||
(i.e., it was deleted or moved without recataloging), or if the user is | ||
not authorized to access the object. | ||
This method mimicks a subset of what publisher's traversal does, | ||
so it allows access if the final object can be accessed even | ||
if intermediate objects cannot. | ||
""" | ||
path = self.getPath().split('/') | ||
if not path: | ||
return None | ||
parent = self.aq_parent | ||
if len(path) > 1: | ||
try: | ||
parent = parent.unrestrictedTraverse(path[:-1]) | ||
except ConflictError: | ||
raise | ||
except: | ||
if GETOBJECT_RAISES: | ||
raise | ||
return None | ||
|
||
try: | ||
target = parent.restrictedTraverse(path[-1]) | ||
except ConflictError: | ||
raise | ||
except: | ||
if GETOBJECT_RAISES: | ||
raise | ||
return None | ||
|
||
return target | ||
|
||
def getRID(self): | ||
"""Return the record ID for this object.""" | ||
return self.data_record_id_ | ||
|
||
class NoBrainer: | ||
""" This is an empty class to use when no brain is specified. """ | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
############################################################################## | ||
# | ||
# Copyright (c) 2002 Zope Foundation and Contributors. | ||
# | ||
# This software is subject to the provisions of the Zope Public License, | ||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. | ||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED | ||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS | ||
# FOR A PARTICULAR PURPOSE | ||
# | ||
############################################################################## | ||
|
||
"""ZCatalog Findable class""" | ||
|
||
from Globals import DTMLFile | ||
from Acquisition import aq_base | ||
|
||
class CatalogAware: | ||
""" This is a Mix-In class to make objects automaticly catalog and | ||
uncatalog themselves in Zope, and to provide some other basic | ||
attributes that are useful to catalog. Note that if your class or | ||
ZClass subclasses CatalogAware, it will only catalog itself when | ||
it is added or copied in Zope. If you make changes to your own | ||
object, you are responsible for calling your object's index_object | ||
method. """ | ||
|
||
meta_type='CatalogAware' | ||
default_catalog='Catalog' | ||
|
||
manage_editCatalogerForm=DTMLFile('dtml/editCatalogerForm', globals()) | ||
|
||
def manage_editCataloger(self, default, REQUEST=None): | ||
""" """ | ||
self.default_catalog=default | ||
message = "Your changes have been saved" | ||
if REQUEST is not None: | ||
return self.manage_main(self, REQUEST, manage_tabs_message=message) | ||
|
||
|
||
def manage_afterAdd(self, item, container): | ||
self.index_object() | ||
for object in self.objectValues(): | ||
try: s=object._p_changed | ||
except: s=0 | ||
object.manage_afterAdd(item, container) | ||
if s is None: object._p_deactivate() | ||
|
||
def manage_afterClone(self, item): | ||
self.index_object() | ||
for object in self.objectValues(): | ||
try: s=object._p_changed | ||
except: s=0 | ||
object.manage_afterClone(item) | ||
if s is None: object._p_deactivate() | ||
|
||
def manage_beforeDelete(self, item, container): | ||
self.unindex_object() | ||
for object in self.objectValues(): | ||
try: s=object._p_changed | ||
except: s=0 | ||
object.manage_beforeDelete(item, container) | ||
if s is None: object._p_deactivate() | ||
|
||
def creator(self): | ||
"""Return a sequence of user names who have the local | ||
Owner role on an object. The name creator is used | ||
for this method to conform to Dublin Core.""" | ||
users=[] | ||
for user, roles in self.get_local_roles(): | ||
if 'Owner' in roles: | ||
users.append(user) | ||
return ', '.join(users) | ||
|
||
def onDeleteObject(self): | ||
"""Object delete handler. I think this is obsoleted by | ||
manage_beforeDelete """ | ||
self.unindex_object() | ||
|
||
def getPath(self): | ||
"""Return the physical path for an object.""" | ||
return '/'.join(self.getPhysicalPath()) | ||
|
||
def summary(self, num=200): | ||
"""Return a summary of the text content of the object.""" | ||
if not hasattr(self, 'text_content'): | ||
return '' | ||
attr=getattr(self, 'text_content') | ||
if callable(attr): | ||
text=attr() | ||
else: text=attr | ||
n=min(num, len(text)) | ||
return text[:n] | ||
|
||
def index_object(self): | ||
"""A common method to allow Findables to index themselves.""" | ||
if hasattr(self, self.default_catalog): | ||
getattr(self, | ||
self.default_catalog).catalog_object(self, self.getPath()) | ||
|
||
def unindex_object(self): | ||
"""A common method to allow Findables to unindex themselves.""" | ||
if hasattr(self, self.default_catalog): | ||
getattr(self, | ||
self.default_catalog).uncatalog_object(self.getPath()) | ||
|
||
def reindex_object(self): | ||
""" Suprisingly useful """ | ||
self.unindex_object() | ||
self.index_object() | ||
|
||
def reindex_all(self, obj=None): | ||
""" """ | ||
if obj is None: obj=self | ||
if hasattr(aq_base(obj), 'index_object'): | ||
obj.index_object() | ||
if hasattr(aq_base(obj), 'objectValues'): | ||
sub=obj.objectValues() | ||
for item in obj.objectValues(): | ||
self.reindex_all(item) | ||
return 'done!' | ||
|
||
class CatalogPathAware(CatalogAware): | ||
""" | ||
This is a stub class that gets registered in __init__.py as a | ||
ZClass base class. Its reason for existance is to make the name | ||
that shows up in the ZClass Product list different than 'ZCatalog: | ||
CatalogAware', which is the name registered by | ||
CatalogAwareness.CatalogAware. The fix should *really* be to | ||
change the product registry to keep the whole module/class path | ||
and to make the ZClass add UI show the whole path, but this is | ||
nontrivial, we don't want to spend a lot of time on ZClasses, and | ||
this works. | ||
""" |
Oops, something went wrong.