Package Products :: Package ZenRelations :: Module ZItem |
[hide private]
[frames] | no frames]

# Source Code for Module Products.ZenRelations.ZItem

      1  ###########################################################################
      2  #
      3  # This program is part of Zenoss Core, an open source monitoring platform.
      4  # Copyright (C) 2007, Zenoss Inc.
      5  #
      6  # This program is free software; you can redistribute it and/or modify it
      7  # under the terms of the GNU General Public License version 2 as published by
      8  # the Free Software Foundation.
      9  #
     10  # For complete information please visit: http://www.zenoss.com/oss/
     11  #
     12  ###########################################################################
     13  import marshal, re, sys, time
     14
     15  import Globals, Acquisition
     16  import App
     17  import App.Management
     18  import AccessControl
     19  import AccessControl.Role, AccessControl.Owned, App.Common
     20  from ExtensionClass import Base
     21  from ComputedAttribute import ComputedAttribute
     22  from AccessControl import getSecurityManager, Unauthorized
     23  from AccessControl.ZopeSecurityPolicy import getRoles
     24  from Acquisition import aq_base, aq_parent, aq_inner
     25  from DocumentTemplate.html_quote import html_quote
     26  from DocumentTemplate.ustr import ustr
     27  from zExceptions.ExceptionFormatter import format_exception
     28  from zExceptions import Redirect
     29
     30  from OFS.CopySupport import CopySource
     31  from OFS.Traversable import Traversable
     32
     33  from Products.ZenUtils.Utils import unused
     34
     35
     36  HTML=Globals.HTML
     37
     38  import logging
     39  logger = logging.getLogger()
     40
     41 -class ZItem(Base, CopySource, App.Management.Tabs, Traversable,
     42             AccessControl.Owned.Owned,
     43             ):
     44
     45
     46      """A common base class for simple, non-container objects."""
     47
     48      isPrincipiaFolderish=0
     49      isTopLevelPrincipiaApplicationObject=0
     50
     51      # Direct use of the 'id' attribute is deprecated - use getId()
     52      id=''
     53
     54      getId__roles__=None
     55 -    def getId(self):
     56          """Return the id of the object as a string.
     57
     58          This method should be used in preference to accessing an id attribute
     59          of an object directly. The getId method is public.
     60          """
     61          name=getattr(self, 'id', None)
     62          if callable(name):
     63              return name()
     64          if name is not None:
     65              return name
     66          if hasattr(self, '__name__'):
     67              return self.__name__
     68          raise AttributeError, 'This object has no id'
     69
     70      # Alias id to __name__, which will make tracebacks a good bit nicer:
     71      __name__=ComputedAttribute(lambda self: self.getId())
     72
     73      # Name, relative to SOFTWARE_URL of icon used to display item
     74      # in folder listings.
     75      icon=''
     76
     77      # Meta type used for selecting all objects of a given type.
     78      meta_type='simple item'
     79
     80      # Default title.
     81      title=''
     82
     83      # Default propertysheet info:
     84      __propsets__=()
     85
     86      manage_options=(
     87          AccessControl.Owned.Owned.manage_options
     88          )
     89
     90      # Attributes that must be acquired
     91      REQUEST=Acquisition.Acquired
     92
     93      # Allow (reluctantly) access to unprotected attributes
     94      __allow_access_to_unprotected_subobjects__=1
     95
     96 -    def title_or_id(self):
     97          """Return the title if it is not blank and the id otherwise.
     98          """
     99          title=self.title
    100          if callable(title):
    101              title=title()
    102          if title: return title
    103          return self.getId()
    104
    105 -    def titleOrId(self):
    106          """Return the title if it is not blank and the id otherwise
    107          """
    108          return self.title_or_id()
    109
    110 -    def title_and_id(self):
    111          """Return the title if it is not blank and the id otherwise.
    112
    113          If the title is not blank, then the id is included in parens.
    114          """
    115          title=self.title
    116          if callable(title):
    117              title=title()
    118          id = self.getId()
    119          return title and ("%s (%s)" % (title,id)) or id
    120
    121 -    def this(self):
    122          # Handy way to talk to ourselves in document templates.
    123          return self
    124
    125 -    def tpURL(self):
    126          # My URL as used by tree tag
    127          return self.getId()
    128
    129 -    def tpValues(self):
    130          # My sub-objects as used by the tree tag
    131          return ()
    132
    133      _manage_editedDialog=Globals.DTMLFile('dtml/editedDialog', globals())
    134 -    def manage_editedDialog(self, REQUEST, **args):
    135          return apply(self._manage_editedDialog,(self, REQUEST), args)
    136
    137 -    def raise_standardErrorMessage(
    138          self, client=None, REQUEST={},
    139          error_type=None, error_value=None, tb=None,
    140          error_tb=None, error_message='',
    141          tagSearch=re.compile(r'[a-zA-Z]>').search,
    142          error_log_url=''):
    143
    144          try:
    145              if error_type  is None: error_type =sys.exc_info()[0]
    146              if error_value is None: error_value=sys.exc_info()[1]
    147
    148              # allow for a few different traceback options
    149              if tb is None and error_tb is None:
    150                  tb=sys.exc_info()[2]
    151              if type(tb) is not type('') and (error_tb is None):
    152                  error_tb = pretty_tb(error_type, error_value, tb)
    153              elif type(tb) is type('') and not error_tb:
    154                  error_tb = tb
    155
    156              # turn error_type into a string
    157              if hasattr(error_type, '__name__'):
    158                  error_type=error_type.__name__
    159
    160              if hasattr(self, '_v_eek'):
    161                  # Stop if there is recursion.
    162                  raise error_type, error_value, tb
    163              self._v_eek=1
    164
    165              if str(error_type).lower() in ('redirect',):
    166                  raise error_type, error_value, tb
    167
    168              if not error_message:
    169                  try:
    170                      s = ustr(error_value)
    171                  except:
    172                      s = error_value
    173                  try:
    174                      match = tagSearch(s)
    175                  except TypeError:
    176                      match = None
    177                  if match is not None:
    178                      error_message=error_value
    179
    180              if client is None: client=self
    181              if not REQUEST: REQUEST=self.aq_acquire('REQUEST')
    182
    183              try:
    184                  if hasattr(client, 'standard_error_message'):
    185                      s=client.standard_error_message
    186                  else:
    187                      client = client.aq_parent
    188                      s=client.standard_error_message
    189                  kwargs = {'error_type': error_type,
    190                            'error_value': error_value,
    191                            'error_tb': error_tb,
    192                            'error_traceback': error_tb,
    193                            'error_message': error_message,
    194                            'error_log_url': error_log_url}
    195
    196                  if getattr(aq_base(s),'isDocTemp',0):
    197                      v = s(client, REQUEST, **kwargs)
    198                  elif callable(s):
    199                      v = s(**kwargs)
    200                  else:
    201                      __pychecker__='self="s"'
    202                      v = HTML.__call__(s, client, REQUEST, **kwargs)
    203              except:
    204                  logger.error(
    205                      'Exception while rendering an error message',
    206                      exc_info=True
    207                      )
    208                  try:
    209                      strv = str(error_value)
    210                  except:
    211                      strv = ('<unprintable %s object>' %
    212                              str(type(error_value).__name__))
    213                  v = strv + (
    214                      (" (Also, the following error occurred while attempting "
    215                       "to render the standard error message, please see the "
    216                       "event log for full details: %s)")%(
    217                      html_quote(sys.exc_info()[1]),
    218                      ))
    219              raise error_type, v, tb
    220          finally:
    221              if hasattr(self, '_v_eek'): del self._v_eek
    222              tb=None
    223
    224 -    def manage(self, URL1):
    225          """
    226          """
    227          raise Redirect, "%s/manage_main" % URL1
    228
    229      # This keeps simple items from acquiring their parents
    230      # objectValues, etc., when used in simple tree tags.
    231 -    def objectValues(self, spec=None):
    232          unused(spec)
    233          return ()
    234      objectIds=objectItems=objectValues
    235
    236      # FTP support methods
    237
    238 -    def manage_FTPstat(self,REQUEST):
    239          """Psuedo stat, used by FTP for directory listings.
    240          """
    241          from AccessControl.User import nobody
    242          mode=0100000
    243
    244          if (hasattr(aq_base(self),'manage_FTPget')):
    245              try:
    246                  if getSecurityManager().validate(
    247                      None, self, 'manage_FTPget', self.manage_FTPget):
    248                      mode=mode | 0440
    249              except Unauthorized:
    250                  pass
    251
    252              if nobody.allowed(
    253                  self.manage_FTPget,
    254                  getRoles(self, 'manage_FTPget', self.manage_FTPget, ()),
    255                  ):
    256                  mode=mode | 0004
    257
    258          # check write permissions
    259          if hasattr(aq_base(self),'PUT'):
    260              try:
    261                  if getSecurityManager().validate(None, self, 'PUT', self.PUT):
    262                      mode=mode | 0220
    263              except Unauthorized:
    264                  pass
    265
    266              if nobody.allowed(
    267                  self.PUT,
    268                  getRoles(self, 'PUT', self.PUT, ()),
    269                  ):
    270                  mode=mode | 0002
    271
    272          # get size
    273          if hasattr(aq_base(self), 'get_size'):
    274              size=self.get_size()
    275          elif hasattr(aq_base(self),'manage_FTPget'):
    276              size=len(self.manage_FTPget())
    277          else:
    278              size=0
    279          # get modification time
    280          if hasattr(aq_base(self), 'bobobase_modification_time'):
    281              mtime=self.bobobase_modification_time().timeTime()
    282          else:
    283              mtime=time.time()
    284          # get owner and group
    285          owner=group='Zope'
    286          if hasattr(aq_base(self), 'get_local_roles'):
    287              for user, roles in self.get_local_roles():
    288                  if 'Owner' in roles:
    289                      owner=user
    290                      break
    291          return marshal.dumps((mode,0,0,1,owner,group,size,mtime,mtime,mtime))
    292
    293 -    def manage_FTPlist(self,REQUEST):
    294          """Directory listing for FTP.
    295
    296          In the case of non-Foldoid objects, the listing should contain one
    297          object, the object itself.
    298          """
    299          # check to see if we are being acquiring or not
    300          ob=self
    301          while 1:
    302              if App.Common.is_acquired(ob):
    303                  raise ValueError('FTP List not supported on acquired objects')
    304              if not hasattr(ob,'aq_parent'):
    305                  break
    306              ob=ob.aq_parent
    307
    308          stat=marshal.loads(self.manage_FTPstat(REQUEST))
    309          id = self.getId()
    310          return marshal.dumps((id,stat))
    311
    312 -    def __len__(self):
    313          return 1
    314
    315 -    def __repr__(self):
    316          """Show the physical path of the object and its context if available.
    317          """
    318          try:
    319              path = '/'.join(self.getPhysicalPath())
    320          except:
    321              return Base.__repr__(self)
    322          context_path = None
    323          context = aq_parent(self)
    324          container = aq_parent(aq_inner(self))
    325          if aq_base(context) is not aq_base(container):
    326              try:
    327                  context_path = '/'.join(context.getPhysicalPath())
    328              except:
    329                  context_path = None
    330          res = '<%s' % self.__class__.__name__
    331          res += ' at %s' % path
    332          if context_path:
    333              res += ' used for %s' % context_path
    334          res += '>'
    335          return res
    336
    337 -def pretty_tb(t, v, tb, as_html=1):
    338      tb = format_exception(t, v, tb, as_html=as_html)
    339      tb = '\n'.join(tb)
    340      return tb
    341
    342  #from OFS.SimpleItem import SimpleItem
    343  #ZItem = SimpleItem
    344