Back to index

plone3  3.1.7
Link.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 """ Link instances represent explicit links-as-content.
00014 
00015 $Id: Link.py 74063 2007-04-09 21:23:43Z tseaver $
00016 """
00017 
00018 import urlparse
00019 
00020 import transaction
00021 from AccessControl import ClassSecurityInfo
00022 from Globals import DTMLFile
00023 from Globals import InitializeClass
00024 from zope.component.factory import Factory
00025 from zope.interface import implements
00026 
00027 from Products.CMFCore.PortalContent import PortalContent
00028 from Products.CMFCore.utils import contributorsplitter
00029 from Products.CMFCore.utils import keywordsplitter
00030 from Products.GenericSetup.interfaces import IDAVAware
00031 
00032 from DublinCore import DefaultDublinCoreImpl
00033 from exceptions import ResourceLockedError
00034 from interfaces import ILink
00035 from interfaces import IMutableLink
00036 from permissions import ModifyPortalContent
00037 from permissions import View
00038 from utils import _dtmldir
00039 from utils import formatRFC822Headers
00040 from utils import parseHeadersBody
00041 
00042 
00043 def addLink( self
00044            , id
00045            , title=''
00046            , remote_url=''
00047            , description=''
00048            ):
00049     """Add a Link instance to 'self'.
00050     """
00051     o=Link( id, title, remote_url, description )
00052     self._setObject(id,o)
00053 
00054 
00055 class Link(PortalContent, DefaultDublinCoreImpl):
00056 
00057     """A Link.
00058     """
00059 
00060     implements(IMutableLink, ILink, IDAVAware)
00061     __implements__ = ( PortalContent.__implements__
00062                      , DefaultDublinCoreImpl.__implements__
00063                      )
00064 
00065     URL_FORMAT = format = 'text/url'
00066     effective_date = expiration_date = None
00067 
00068     security = ClassSecurityInfo()
00069 
00070     def __init__( self
00071                 , id
00072                 , title=''
00073                 , remote_url=''
00074                 , description=''
00075                 ):
00076         DefaultDublinCoreImpl.__init__(self)
00077         self.id=id
00078         self.title=title
00079         self.description=description
00080         self._edit(remote_url)
00081         self.format=self.URL_FORMAT
00082 
00083     security.declareProtected(ModifyPortalContent, 'manage_edit')
00084     manage_edit = DTMLFile( 'zmi_editLink', _dtmldir )
00085 
00086     security.declareProtected(ModifyPortalContent, 'manage_editLink')
00087     def manage_editLink( self, remote_url, REQUEST=None ):
00088         """
00089             Update the Link via the ZMI.
00090         """
00091         self._edit( remote_url )
00092         if REQUEST is not None:
00093             REQUEST['RESPONSE'].redirect( self.absolute_url()
00094                                         + '/manage_edit'
00095                                         + '?manage_tabs_message=Link+updated'
00096                                         )
00097 
00098     security.declarePrivate( '_edit' )
00099     def _edit( self, remote_url ):
00100         """
00101             Edit the Link
00102         """
00103         tokens = urlparse.urlparse( remote_url, 'http' )
00104         if tokens[0] == 'http':
00105             if tokens[1]:
00106                 # We have a nethost. All is well.
00107                 url = urlparse.urlunparse(tokens)
00108             elif tokens[2:] == ('', '', '', ''):
00109                 # Empty URL
00110                 url = ''
00111             else:
00112                 # Relative URL, keep it that way, without http:
00113                 tokens = ('', '') + tokens[2:]
00114                 url = urlparse.urlunparse(tokens)
00115         else:
00116             # Other scheme, keep original
00117             url = urlparse.urlunparse(tokens)
00118         self.remote_url = url
00119 
00120     security.declareProtected(ModifyPortalContent, 'edit')
00121     def edit(self, remote_url ):
00122         """ Update and reindex. """
00123         self._edit( remote_url )
00124         self.reindexObject()
00125 
00126     security.declareProtected(View, 'SearchableText')
00127     def SearchableText(self):
00128         """
00129             text for indexing
00130         """
00131         return "%s %s" % (self.title, self.description)
00132 
00133     security.declareProtected(View, 'getRemoteUrl')
00134     def getRemoteUrl(self):
00135         """
00136             returns the remote URL of the Link
00137         """
00138         return self.remote_url
00139 
00140     security.declarePrivate( '_writeFromPUT' )
00141     def _writeFromPUT( self, body ):
00142         headers = {}
00143         headers, body = parseHeadersBody(body, headers)
00144         lines = body.split('\n')
00145         self.edit( lines[0] )
00146         headers['Format'] = self.URL_FORMAT
00147         new_subject = keywordsplitter(headers)
00148         headers['Subject'] = new_subject or self.Subject()
00149         new_contrib = contributorsplitter(headers)
00150         headers['Contributors'] = new_contrib or self.Contributors()
00151         haveheader = headers.has_key
00152         for key, value in self.getMetadataHeaders():
00153             if not haveheader(key):
00154                 headers[key] = value
00155 
00156         self._editMetadata(title=headers['Title'],
00157                           subject=headers['Subject'],
00158                           description=headers['Description'],
00159                           contributors=headers['Contributors'],
00160                           effective_date=headers['Effective_date'],
00161                           expiration_date=headers['Expiration_date'],
00162                           format=headers['Format'],
00163                           language=headers['Language'],
00164                           rights=headers['Rights'],
00165                           )
00166 
00167     ## FTP handlers
00168     security.declareProtected(ModifyPortalContent, 'PUT')
00169     def PUT(self, REQUEST, RESPONSE):
00170         """
00171             Handle HTTP / WebDAV / FTP PUT requests.
00172         """
00173         self.dav__init(REQUEST, RESPONSE)
00174         self.dav__simpleifhandler(REQUEST, RESPONSE, refresh=1)
00175         body = REQUEST.get('BODY', '')
00176         try:
00177             self._writeFromPUT( body )
00178             RESPONSE.setStatus(204)
00179             return RESPONSE
00180         except ResourceLockedError, msg:
00181             transaction.abort()
00182             RESPONSE.setStatus(423)
00183             return RESPONSE
00184 
00185     security.declareProtected(View, 'manage_FTPget')
00186     def manage_FTPget(self):
00187         """
00188             Get the link as text for WebDAV src / FTP download.
00189         """
00190         hdrlist = self.getMetadataHeaders()
00191         hdrtext = formatRFC822Headers( hdrlist )
00192         bodytext = '%s\n\n%s' % ( hdrtext, self.getRemoteUrl() )
00193 
00194         return bodytext
00195 
00196     security.declareProtected(View, 'get_size')
00197     def get_size( self ):
00198         """ Used for FTP and apparently the ZMI now too.
00199         """
00200         return len(self.manage_FTPget())
00201 
00202 InitializeClass(Link)
00203 
00204 LinkFactory = Factory(Link)