Back to index

plone3  3.1.7
Favorite.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.1 (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 """ Favorites are references to other objects within the same CMF site.
00014 
00015 $Id: Favorite.py 78467 2007-07-29 16:44:46Z yuppie $
00016 """
00017 
00018 import urlparse
00019 
00020 from AccessControl import ClassSecurityInfo
00021 from Acquisition import aq_base
00022 from Globals import InitializeClass
00023 from zope.app.container.interfaces import IObjectAddedEvent
00024 from zope.component import adapter
00025 from zope.component import getUtility
00026 from zope.component.factory import Factory
00027 from zope.interface import implements
00028 
00029 from Products.CMFCore.interfaces import ISiteRoot
00030 from Products.CMFCore.utils import getToolByName
00031 
00032 from DublinCore import DefaultDublinCoreImpl
00033 from interfaces import IFavorite
00034 from interfaces import IMutableFavorite
00035 from Link import Link
00036 from permissions import View
00037 
00038 
00039 def addFavorite(self, id, title='', remote_url='', description=''):
00040     """Add a Favorite.
00041     """
00042     o = Favorite(id, title, remote_url, description)
00043     self._setObject(id, o)
00044 
00045 
00046 class Favorite(Link):
00047 
00048     """A Favorite (special kind of Link).
00049     """
00050 
00051     implements(IMutableFavorite, IFavorite)
00052     __implements__ = Link.__implements__ # redundant, but explicit
00053 
00054     security = ClassSecurityInfo()
00055 
00056     def __init__( self
00057                 , id
00058                 , title=''
00059                 , remote_url=''
00060                 , description=''
00061                 ):
00062         DefaultDublinCoreImpl.__init__(self)
00063         self.id=id
00064         self.title=title
00065         self.remote_url=remote_url
00066         self.description = description
00067 
00068     def _getUidByUrl(self):
00069         """Registers and returns the uid of the remote object if
00070         the unique id handler tool is available.
00071         """
00072         # check for unique id handler tool
00073         handler = getToolByName(self, 'portal_uidhandler', None)
00074         if handler is None:
00075             return
00076 
00077         obj = getUtility(ISiteRoot).restrictedTraverse(self.remote_url)
00078         return handler.register(obj)
00079 
00080     def _getObjectByUid(self):
00081         """Registers and returns the uid of the remote object if
00082         the unique id handler tool is available.
00083         """
00084         # check for unique id handler tool
00085         handler = getToolByName(self, 'portal_uidhandler', None)
00086         if handler is None:
00087             return
00088 
00089         # check for remote uid info on object
00090         uid = getattr(aq_base(self), 'remote_uid', None)
00091         if uid is None:
00092             return
00093 
00094         return handler.queryObject(uid, None)
00095 
00096     security.declareProtected(View, 'getRemoteUrl')
00097     def getRemoteUrl(self):
00098         """
00099             returns the remote URL of the Link
00100         """
00101         # try getting the remote object by unique id
00102         remote_url = self._getRemoteUrlTheOldWay()
00103         remote_obj = self._getObjectByUid()
00104         if remote_obj:
00105             url = remote_obj.absolute_url()
00106             # update the url when changed (avoid unnecessary ZODB writes)
00107             if url != remote_url:
00108                 self.edit(url)
00109             return url
00110 
00111         return remote_url
00112 
00113     def _getRemoteUrlTheOldWay(self):
00114         """Build the url without having taking the uid into account
00115         """
00116         portal_url = getToolByName(self, 'portal_url')
00117         if self.remote_url:
00118             return portal_url() + '/' + self.remote_url
00119         else:
00120             return portal_url()
00121 
00122 
00123     security.declareProtected(View, 'getIcon')
00124     def getIcon(self, relative_to_portal=0):
00125         """
00126         Instead of a static icon, like for Link objects, we want
00127         to display an icon based on what the Favorite links to.
00128         """
00129         try:
00130             return self.getObject().getIcon(relative_to_portal)
00131         except:
00132             return 'p_/broken'
00133 
00134     security.declareProtected(View, 'getObject')
00135     def getObject(self):
00136         """ Get the actual object that the Favorite is linking to.
00137         """
00138         # try getting the remote object by unique id
00139         remote_obj = self._getObjectByUid()
00140         if remote_obj is not None:
00141             return remote_obj
00142 
00143         # XXX: can't use ISiteRoot because absolute_url() depends on REQUEST
00144         portal_url = getToolByName(self, 'portal_url')
00145         return portal_url.getPortalObject().restrictedTraverse(self.remote_url)
00146 
00147     security.declarePrivate('_edit')
00148     def _edit( self, remote_url ):
00149         """
00150         Edit the Favorite. Unlike Links, Favorites have URLs that are
00151         relative to the root of the site.
00152         """
00153         # strip off scheme and machine from URL if present
00154         tokens = urlparse.urlparse( remote_url, 'http' )
00155         if tokens[1]:
00156             # There is a nethost, remove it
00157             t=('', '') + tokens[2:]
00158             remote_url=urlparse.urlunparse(t)
00159         # if URL begins with site URL, remove site URL
00160         portal_url = getToolByName(self, 'portal_url').getPortalPath()
00161         i = remote_url.find(portal_url)
00162         if i==0:
00163             remote_url=remote_url[len(portal_url):]
00164         # if site is still absolute, make it relative
00165         if remote_url[:1]=='/':
00166             remote_url=remote_url[1:]
00167         self.remote_url=remote_url
00168 
00169         # save unique id of favorite
00170         self.remote_uid = self._getUidByUrl()
00171 
00172 InitializeClass(Favorite)
00173 
00174 FavoriteFactory = Factory(Favorite)
00175 
00176 
00177 @adapter(IFavorite, IObjectAddedEvent)
00178 def handleFavoriteAddedEvent(obj, event):
00179     """Event subscriber.
00180     """
00181     if obj.remote_url:
00182         obj.edit(obj.remote_url)