source: ZMS/trunk/_pathhandler.py @ 1859

Revision 1859, 14.9 KB checked in by fhoffmann, 5 weeks ago (diff)

Added typo fix to Ticket #53

Line 
1################################################################################
2# _pathhandler.py
3#
4# This program is free software; you can redistribute it and/or
5# modify it under the terms of the GNU General Public License
6# as published by the Free Software Foundation; either version 2
7# of the License, or (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program; if not, write to the Free Software
16# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17################################################################################
18
19# Imports.
20from OFS.CopySupport import absattr
21import copy
22# Product Imports.
23import _blobfields
24import _fileutil
25import _globals
26
27
28# ------------------------------------------------------------------------------
29#  _pathhandler.validateId:
30#
31#  Validates id against list of possible declarative id.
32# ------------------------------------------------------------------------------
33def validateId(self, id, REQUEST):
34  langs = []
35  lang = REQUEST.get( 'lang')
36  if lang is None:
37    for lang in self.getLanguages():
38      req={ 'lang': lang, 'preview': REQUEST.get('preview','')}
39      decl_id = self.getDeclId( req)
40      if id == decl_id:
41        langs.append( lang)
42    if len( langs) == 1:
43      self.REQUEST.set( 'lang', langs[0])
44  else:
45    decl_id = self.getDeclId( REQUEST)
46    if id == decl_id:
47      langs.append( lang)
48  if len( langs) > 0:
49    return True
50  return False
51
52
53# ------------------------------------------------------------------------------
54#  _pathhandler.filterId:
55#
56#  Filters object by id.
57# ------------------------------------------------------------------------------
58def filterId(self, id, REQUEST):
59  obs = self.objectValues( self.dGlobalAttrs.keys())
60  filtered_obs = filter( lambda x: x.id == id, obs)
61  if len( filtered_obs) > 0:
62    return filtered_obs[0]
63  elif self.getConfProperty( 'ZMS.pathhandler', 0) != 0:
64    req = { 'lang': REQUEST.get('lang'), 'preview': REQUEST.get('preview')}
65    filtered_obs = filter( lambda x: x.isVisible( req) and x.isPage() and validateId( x, id, req), obs)
66    if len( filtered_obs) > 0:
67      return filtered_obs[0]
68  return None
69
70
71# ------------------------------------------------------------------------------
72#  _pathhandler.handleBlobAttrs:
73#
74#  If the object has blob-fields find by filename and display data.
75# ------------------------------------------------------------------------------
76def handleBlobAttrs(self, name, REQUEST):
77  langs = self.getLangIds()
78  name_without_lang_suffix = name
79  if len(langs) == 1 and name.find('_%s.'%langs[0]) > 0:
80    name_without_lang_suffix = name.replace('_%s.'%langs[0],'.')
81  for ob in [self]+self.filteredChildNodes(REQUEST,['ZMSFile']):
82    for key in ob.getObjAttrs().keys():
83      obj_attr = ob.getObjAttr(key)
84      datatype = obj_attr['datatype_key']
85      if datatype in _globals.DT_BLOBS:
86        lang = ob.getLanguageFromName( REQUEST['URL'])
87        REQUEST.set( 'lang', lang)
88        value = ob.getObjProperty( key, REQUEST)
89        if value is not None:
90          href = value.getHref( REQUEST)
91          langfilename = href.split( '/')[ -1]
92          if langfilename.find( '?') > 0:
93            langfilename = langfilename[ :langfilename.find( '?')]
94          if langfilename == name or \
95             langfilename == _globals.url_encode(name) or \
96             langfilename == name_without_lang_suffix or \
97             langfilename == _globals.url_encode(name_without_lang_suffix):
98            return value
99  return None
100
101
102
103################################################################################
104################################################################################
105###
106###   class PathHandler:
107###
108###   Based on the Zope-Product PathHandler
109###   http://www.zope.org/Members/NIP/PathHandler).
110###
111################################################################################
112################################################################################
113class PathHandler:
114
115    # --------------------------------------------------------------------------
116    #  PathHandler.base_url
117    # --------------------------------------------------------------------------
118    def base_url(self):
119      if  self.getConfProperty( 'ZMS.pathcoherence', 1) == 1:
120        # return self.REQUEST.get('BASE0') + '/'.join( list( self.getPhysicalPath()))
121        return '/'.join( list( self.getPhysicalPath()))
122      else:
123        return self.absolute_url()
124
125
126    # --------------------------------------------------------------------------
127    #  PathHandler.__bobo_traverse__
128    # --------------------------------------------------------------------------
129    def __bobo_traverse__(self, TraversalRequest, name):
130      # If this is the first time this __bob_traverse__ method has been called
131      # in handling this traversal request, store the path_to_handle
132      req = self.REQUEST
133      url = self.REQUEST.get('URL','')
134      zmi = url.find('/manage') >= 0
135     
136      if not TraversalRequest.has_key('path_to_handle'):
137     
138          # Make a reversed copy of the TraversalRequestNameStack
139          TraversalRequestNameStackReversed=copy.copy(TraversalRequest['TraversalRequestNameStack'])
140          TraversalRequestNameStackReversed.reverse()
141         
142          # Set path_to_handle in the TraversalRequest.
143          TraversalRequest['path_to_handle']=[name]+TraversalRequestNameStackReversed
144         
145          # Set path_to_handle for VirtualHosts.
146          if '/' in TraversalRequest[ 'path_to_handle']:
147            path_physical = req.get( 'path_physical', list( self.getDocumentElement().getPhysicalPath())[1:])
148            if len( path_physical) > 1:
149              b = TraversalRequest[ 'path_to_handle'].index( '/')
150              TraversalRequest[ 'path_to_handle'] = TraversalRequest[ 'path_to_handle'][ b+1:]
151              for i in range( 1, len( path_physical)):
152                TraversalRequest[ 'path_to_handle'].insert( i-1, path_physical[ i])
153     
154      # Set language.
155      lang = req.get( 'lang')
156      if lang is None:
157        lang = self.getLanguageFromName( TraversalRequest['path_to_handle'][-1])
158      if lang is not None:
159        req.set( 'lang', lang)
160     
161      # If the name is in the list of attributes, call it.
162      ob = getattr( self, name, None)
163      if ob is None or getattr(ob,'meta_type',None) == 'Folder':
164        obContext = filterId( self, name, req)
165        if obContext is not None:
166          ob = obContext
167      if ob is not None:
168        if not zmi and TraversalRequest['path_to_handle'][-1] == name:
169          lang = req.get( 'lang')
170          if lang is None:
171            lang = self.getHttpAcceptLanguage( self.REQUEST)
172          if lang is not None:
173            self.REQUEST.set( 'lang', lang)
174       
175        return ob
176     
177      # otherwise do some 'magic'
178      else:
179        _globals.writeLog( self, '[__bobo_traverse__]: otherwise do some magic')
180       
181        # Package-Home.
182        if name == '$ZMS_HOME':
183          i = TraversalRequest['path_to_handle'].index(name)
184          filepath = self.localfs_package_home()+'/'+'/'.join(TraversalRequest['path_to_handle'][i+1:])
185          data, mt, enc, size = _fileutil.readFile(filepath)
186          filename = TraversalRequest['path_to_handle'][-1]
187          f = self.FileFromData( data, filename, mt)
188          f.aq_parent = self
189          f.key = 'None'
190          f.lang = req.get('lang', self.getPrimaryLanguage())
191          return f
192       
193        # Pathhandler-Hook.
194        if 'pathhandler' in self.getMetaobjAttrIds( self.meta_id, types=['method','py']):
195          if name == TraversalRequest['path_to_handle'][-1]:
196            req.set( 'path_', '/'.join(req.get('path_',[])+[name]))
197            return self.getObjProperty('pathhandler',req)
198          else:
199            req.set( 'path_', req.get('path_',[])+[name])
200            return self
201       
202        if not zmi or req.get( 'ZMS_PATH_HANDLER', False):
203         
204          # Recursive inclusions.
205          thisOb = _globals.nvl( filterId( self, name, req), self)
206          if thisOb.meta_type == 'ZMSLinkElement':
207            recursive = thisOb.isEmbeddedRecursive( req)
208            if recursive:
209              ob = thisOb.getRefObj()
210              proxy = thisOb.initProxy( thisOb.aq_parent, thisOb.absolute_url(), ob, recursive)
211              c = 0
212              l = TraversalRequest[ 'path_to_handle']
213              if thisOb.id in l:
214                i = l.index( thisOb.id) + 1
215              elif thisOb.getDeclId( req) in l:
216                i = l.index( thisOb.getDeclId( req)) + 1
217              for k in range( i, len(l)):
218                newOb = None
219                obs = ob.getChildNodes( req)
220                filtered_obs = filter( lambda x: ( x.id == l[k] or x.getDeclId( req) == l[k]), obs)
221                if len( filtered_obs) == 1:
222                  newOb = filtered_obs[0]
223                try:
224                  if newOb.meta_type not in self.dGlobalAttrs.keys():
225                    newOb = None
226                except:
227                  pass
228                if newOb is None:
229                  break
230                ob = newOb
231                proxy = thisOb.initProxy( proxy, proxy.absolute_url()+'/'+ob.id, ob, recursive)
232                c += 1
233              if c > 0:
234                req.set( 'ZMS_PROXY_%s'%self.id, proxy)
235            if req.get( 'ZMS_PROXY_%s'%self.id) and req.get( 'ZMS_PROXY_%s'%self.id).id != TraversalRequest[ 'path_to_handle'][-1]:
236              v = handleBlobAttrs( req.get( 'ZMS_PROXY_%s'%self.id).proxy, TraversalRequest[ 'path_to_handle'][-1], req)
237              if v is not None:
238                return v
239            return thisOb
240       
241        # Declarative Urls.
242        ob = self.pathob([name],self.REQUEST)
243        if ob is not None:
244          return ob
245       
246        # If the object is record-set and has blob-fields find by filename and
247        # display data.
248        if name.find( '@') == 0:
249          if self.getType()=='ZMSRecordSet':
250            try:
251              i = int( name[1:])
252              r = self.getObjProperty( self.getMetaobj( self.meta_id)['attrs'][0]['id'], self.REQUEST)
253              d = r[i]
254              for key in d.keys():
255                value = d[key]
256                if isinstance(value,_blobfields.MyImage) or isinstance(value,_blobfields.MyFile):
257                  value = value._getCopy()
258                  value.aq_parent = self
259                  value.key = key
260                  value.lang = req.get('lang', self.getPrimaryLanguage())
261                  langfilename = value.getHref( req).split( '/')[ -1]
262                  if langfilename.find( '?') > 0:
263                    langfilename = langfilename[ :langfilename.find( '?')]
264                  if langfilename == TraversalRequest['path_to_handle'][-1]:
265                    return value
266            except:
267              _globals.writeError( self, '[__bobo_traverse__]')
268          else:
269            try:
270              i = int( name[1:])
271              obj_attrs = self.getObjAttrs()
272              for key in self.getObjAttrs().keys():
273                obj_attr = obj_attrs[ key]
274                if obj_attr['datatype_key'] == _globals.DT_LIST and \
275                   obj_attr['repetitive']:
276                  lp = [ self.REQUEST.get('preview')]
277                  if lp[ 0] != 'preview':
278                    lp.append( 'preview')
279                  par = None
280                  for ip in lp:
281                    try:
282                      self.REQUEST.set( 'preview', ip)
283                      r = self.getObjProperty( key, self.REQUEST, par)
284                      value = r[i]
285                      value = value._getCopy()
286                      value.aq_parent = self
287                      value.key = key
288                      value.lang = req.get('lang', self.getPrimaryLanguage())
289                      langfilename = value.getHref( req).split( '/')[ -1]
290                      if langfilename.find( '?') > 0:
291                        langfilename = langfilename[ :langfilename.find( '?')]
292                      if langfilename == TraversalRequest['path_to_handle'][-1]:
293                        return value
294                    except:
295                      _globals.writeError( self, '[__bobo_traverse__]: ip=%s'%str(ip))
296                    par = {'fetchReqBuff':0}
297                  self.REQUEST.set( 'preview', lp[ 0])
298            except:
299              _globals.writeError( self, '[__bobo_traverse__]')
300       
301        # If the object has blob-fields find by filename and display data.
302        v = handleBlobAttrs( self, name, req)
303        if v is not None: return v
304       
305        # Skins
306        if name == TraversalRequest['path_to_handle'][-1]:
307          l = name
308          i = l.rfind('_')
309          j = l.rfind('.')
310          if i > 0 and j > 0:
311            lang = l[i+1:j]
312            if lang in self.getLangIds():
313              auth_user = self.REQUEST.get('AUTHENTICATED_USER')
314              access = (auth_user is None and self.hasPublicAccess()) or \
315                       (auth_user is not None and auth_user.has_permission( 'View', self) in [ 1, True])
316              if access:
317                self.REQUEST.set('ZMS_SKIN',l[:i])
318                self.REQUEST.set('ZMS_EXT',l[j+1:])
319                self.REQUEST.set('lang',lang)
320                return self
321       
322        # If there's no more names left to handle, return the path handling
323        # method to the traversal machinery so it gets called next
324        exc_value='<h2>Site-Error</h2><b>Sorry, there is no web page matching your request.</b> It is possible you typed the address incorrectly, or that the page no longer exists.<hr><b>Resource<b> <i>'+name+'</i> '+''.join(map(lambda x: x+'/',TraversalRequest['path_to_handle']))+' GET'
325        return self.standard_error_message( self,
326          exc_type='Resource not found',
327          exc_value=exc_value,
328          REQUEST=self.REQUEST)
329
330
331    # --------------------------------------------------------------------------
332    #  PathHandler.pathob
333    # --------------------------------------------------------------------------
334    def pathob(self, path_to_handle, REQUEST):
335      path_ob = self
336      path_index = 0
337      while True:
338        if path_index == len(path_to_handle):
339          return path_ob
340        path_item = path_to_handle[path_index]
341        obs = path_ob.objectValues( self.dGlobalAttrs.keys())
342        path_ob = filterId( path_ob, path_item, REQUEST)
343        if path_ob is None:
344          return path_ob
345        path_index += 1
346
347################################################################################
Note: See TracBrowser for help on using the repository browser.