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

# Source Code for Module Products.ZenRelations.ZItem

      1  ##############################################################################
      2  #
      3  # Copyright (C) Zenoss, Inc. 2007, all rights reserved.
      4  #
      5  # This content is made available according to terms specified in
      6  # License.zenoss under the directory where your Zenoss product is installed.
      7  #
      8  ##############################################################################
      9
     10
     11  import marshal, re, sys, time
     12
     13  import Globals, Acquisition
     14  import App
     15  import App.Management
     16  import AccessControl
     17  import AccessControl.Role, AccessControl.Owned, App.Common
     18  from ExtensionClass import Base
     19  from ComputedAttribute import ComputedAttribute
     20  from AccessControl import getSecurityManager, Unauthorized
     21  from AccessControl.ZopeSecurityPolicy import getRoles
     22  from Acquisition import aq_base, aq_parent, aq_inner
     23  from DocumentTemplate.html_quote import html_quote
     24  from DocumentTemplate.ustr import ustr
     25  from zExceptions.ExceptionFormatter import format_exception
     26  from zExceptions import Redirect
     27
     28  from OFS.CopySupport import CopySource
     29  from OFS.Traversable import Traversable
     30
     31  from Products.ZenUtils.Utils import unused
     32
     33
     34  HTML=Globals.HTML
     35
     36  import logging
     37  logger = logging.getLogger()
     38
     39 -class ZItem(Base, CopySource, App.Management.Tabs, Traversable,
     40             AccessControl.Owned.Owned,
     41             ):
     42
     43
     44      """A common base class for simple, non-container objects."""
     45
     46      isPrincipiaFolderish=0
     47      isTopLevelPrincipiaApplicationObject=0
     48
     49      # Direct use of the 'id' attribute is deprecated - use getId()
     50      id=''
     51
     52      getId__roles__=None
     53 -    def getId(self):
     54          """Return the id of the object as a string.
     55
     56          This method should be used in preference to accessing an id attribute
     57          of an object directly. The getId method is public.
     58          """
     59          name=getattr(self, 'id', None)
     60          if callable(name):
     61              return name()
     62          if name is not None:
     63              return name
     64          if hasattr(self, '__name__'):
     65              return self.__name__
     66          raise AttributeError, 'This object has no id'
     67
     68      # Alias id to __name__, which will make tracebacks a good bit nicer:
     69      __name__=ComputedAttribute(lambda self: self.getId())
     70
     71      # Name, relative to SOFTWARE_URL of icon used to display item
     72      # in folder listings.
     73      icon=''
     74
     75      # Meta type used for selecting all objects of a given type.
     76      meta_type='simple item'
     77
     78      # Default title.
     79      title=''
     80
     81      # Default propertysheet info:
     82      __propsets__=()
     83
     84      manage_options=(
     85          AccessControl.Owned.Owned.manage_options
     86          )
     87
     88      # Attributes that must be acquired
     89      REQUEST=Acquisition.Acquired
     90
     91      # Allow (reluctantly) access to unprotected attributes
     92      __allow_access_to_unprotected_subobjects__=1
     93
     94 -    def title_or_id(self):
     95          """Return the title if it is not blank and the id otherwise.
     96          """
     97          title=self.title
     98          if callable(title):
     99              title=title()
    100          if title: return title
    101          return self.getId()
    102
    103 -    def titleOrId(self):
    104          """Return the title if it is not blank and the id otherwise
    105          """
    106          return self.title_or_id()
    107
    108 -    def title_and_id(self):
    109          """Return the title if it is not blank and the id otherwise.
    110
    111          If the title is not blank, then the id is included in parens.
    112          """
    113          title=self.title
    114          if callable(title):
    115              title=title()
    116          id = self.getId()
    117          return title and ("%s (%s)" % (title,id)) or id
    118
    119 -    def this(self):
    120          # Handy way to talk to ourselves in document templates.
    121          return self
    122
    123 -    def tpURL(self):
    124          # My URL as used by tree tag
    125          return self.getId()
    126
    127 -    def tpValues(self):
    128          # My sub-objects as used by the tree tag
    129          return ()
    130
    131      _manage_editedDialog=Globals.DTMLFile('dtml/editedDialog', globals())
    132 -    def manage_editedDialog(self, REQUEST, **args):
    133          return apply(self._manage_editedDialog,(self, REQUEST), args)
    134
    135      """
    136      def raise_standardErrorMessage(
    137          self, client=None, REQUEST={},
    138          error_type=None, error_value=None, tb=None,
    139          error_tb=None, error_message='',
    140          tagSearch=re.compile(r'[a-zA-Z]>').search,
    141          error_log_url=''):
    142
    143          try:
    144              if error_type  is None: error_type =sys.exc_info()[0]
    145              if error_value is None: error_value=sys.exc_info()[1]
    146
    147              # allow for a few different traceback options
    148              if tb is None and error_tb is None:
    149                  tb=sys.exc_info()[2]
    150              if type(tb) is not type('') and (error_tb is None):
    151                  error_tb = pretty_tb(error_type, error_value, tb)
    152              elif type(tb) is type('') and not error_tb:
    153                  error_tb = tb
    154
    155              # turn error_type into a string
    156              if hasattr(error_type, '__name__'):
    157                  error_type=error_type.__name__
    158
    159              if hasattr(self, '_v_eek'):
    160                  # Stop if there is recursion.
    161                  raise error_type, error_value, tb
    162              self._v_eek=1
    163
    164              if str(error_type).lower() in ('redirect',):
    165                  raise error_type, error_value, tb
    166
    167              if not error_message:
    168                  try:
    169                      s = ustr(error_value)
    170                  except:
    171                      s = error_value
    172                  try:
    173                      match = tagSearch(s)
    174                  except TypeError:
    175                      match = None
    176                  if match is not None:
    177                      error_message=error_value
    178
    179              if client is None: client=self
    180              if not REQUEST: REQUEST=self.aq_acquire('REQUEST')
    181
    182              try:
    183                  if hasattr(client, 'standard_error_message'):
    184                      s=client.standard_error_message
    185                  else:
    186                      client = client.aq_parent
    187                      s=client.standard_error_message
    188                  kwargs = {'error_type': error_type,
    189                            'error_value': error_value,
    190                            'error_tb': error_tb,
    191                            'error_traceback': error_tb,
    192                            'error_message': error_message,
    193                            'error_log_url': error_log_url}
    194
    195                  if getattr(aq_base(s),'isDocTemp',0):
    196                      v = s(client, REQUEST, **kwargs)
    197                  elif callable(s):
    198                      v = s(**kwargs)
    199                  else:
    200                      __pychecker__='self="s"'
    201                      v = HTML.__call__(s, client, REQUEST, **kwargs)
    202              except:
    203                  logger.error(
    204                      'Exception while rendering an error message',
    205                      exc_info=True
    206                      )
    207                  try:
    208                      strv = str(error_value)
    209                  except:
    210                      strv = ('<unprintable %s object>' %
    211                              str(type(error_value).__name__))
    212                  v = strv + (
    213                      (" (Also, the following error occurred while attempting "
    214                       "to render the standard error message, please see the "
    215                       "event log for full details: %s)")%(
    216                      html_quote(sys.exc_info()[1]),
    217                      ))
    218              raise error_type, v, tb
    219          finally:
    220              if hasattr(self, '_v_eek'): del self._v_eek
    221              tb=None
    222      """
    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