Package Products :: Package ZenModel :: Module GraphPoint |
[hide private]
[frames] | no frames]

# Source Code for Module Products.ZenModel.GraphPoint

      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  __doc__="""GraphPoint
     12
     13  Defines attributes for how a data source will be graphed
     14  and builds the nessesary rrd commands.
     15  """
     16
     17  from Globals import InitializeClass
     18  from AccessControl import ClassSecurityInfo, Permissions
     19  from Products.ZenModel.ZenossSecurity import *
     20  from Products.ZenRelations.RelSchema import *
     21  from ZenModelRM import ZenModelRM
     22  from ZenPackable import ZenPackable
     23  from Products.ZenWidgets import messaging
     24  from Products.ZenUtils.deprecated import deprecated
     25
     26  @deprecated
     27 -def manage_addGraphPoint(context, id, REQUEST = None):
     28      ''' This is here so than zope will let us copy/paste/rename
     29      graphpoints.
     30      '''
     31      gp = GraphPoint(id)
     32      context._setObject(gp.id, gp)
     33      if REQUEST:
     34          return context.callZenScreen(REQUEST)
     35
     36
     37 -class GraphPoint(ZenModelRM, ZenPackable):
     38      '''
     39      '''
     40
     41      isThreshold = False
     42
     43      DEFAULT_FORMAT = '%5.2lf%s'
     44      DEFAULT_LEGEND = '${graphPoint/id}'
     45      DEFAULT_MULTIGRAPH_LEGEND = '${here/name | here/id} ${graphPoint/id}'
     46
     47      sequence = 0
     48      _properties = (
     49          {'id':'sequence', 'type':'long', 'mode':'w'},
     50          )
     51
     52      _relations = ZenPackable._relations + (
     53          ("graphDef", ToOne(ToManyCont,"Products.ZenModel.GraphDefinition","graphPoints")),
     54          )
     55
     56      factory_type_information = (
     57          {
     58              'immediate_view' : 'editGraphPoint',
     59              'actions'        :
     60              (
     61                  { 'id'            : 'edit'
     62                  , 'name'          : 'Graph Point'
     63                  , 'action'        : 'editGraphPoint'
     64                  , 'permissions'   : ( Permissions.view, )
     65                  },
     66              )
     67          },
     68      )
     69
     70      colors = (
     71          '#00cc00', '#0000ff', '#00ffff', '#ff0000',
     72          '#ff9900', '#cc0000', '#0000cc', '#0080c0',
     73          '#8080c0', '#ff0080', '#800080', '#0000a0',
     74          '#408080', '#808000', '#000000', '#00ff00',
     75          '#fb31fb', '#0080ff', '#ff8000', '#800000',
     76          )
     77
     78      security = ClassSecurityInfo()
     79
     80      ## Interface
     81
     82
     83 -    def breadCrumbs(self, terminator='dmd'):
     84          """Return the breadcrumb links for this object add ActionRules list.
     85          [('url','id'), ...]
     86          """
     87          if self.graphDef.rrdTemplate():
     88              from RRDTemplate import crumbspath
     89              crumbs = super(GraphPoint, self).breadCrumbs(terminator)
     90              return crumbspath(self.graphDef(), crumbs, -3)
     91          return ZenModelRM.breadCrumbs(self, terminator)
     92
     93
     94      security.declareProtected(ZEN_MANAGE_DMD, 'manage_editProperties')
     95 -    def manage_editProperties(self, REQUEST):
     96          '''
     97          Process a save request from a GraphPoint edit screen.  Perform
     98          validation on fields and either return error message or save
     99          results.
    100          '''
    101          def IsHex(s):
    102              try:
    103                  _ = long(color, 16)
    104              except ValueError:
    105                  return False
    106              return True
    107
    108          color = REQUEST.get('color', '').strip().lstrip('#').upper()
    109          if color:
    110              if len(color) in (6, 8) and IsHex(color):
    111                  REQUEST.form['color'] = color
    112              else:
    113                  messaging.IMessageSender(self).sendToBrowser(
    114                      'Invalid Color',
    115                      'Color must be a 6 or 8-digit hexadecimal value.',
    116                      priority=messaging.WARNING
    117                  )
    118                  return self.callZenScreen(REQUEST)
    119          return self.zmanage_editProperties(REQUEST)
    120
    121
    122 -    def getDescription(self):
    123          ''' Return a description
    124          '''
    125          return self.id
    126
    127
    128 -    def getTalesContext(self, thing=None, **kw):
    129          '''
    130          Standard stuff to add to context for tales expressions
    131          '''
    132          context = {
    133              'graphDef': self.graphDef(),
    134              'graphPoint': self,
    135              }
    136          if thing:
    137              thing.getRRDContextData(context)
    138          for key, value in kw.items():
    139              context[key] = value
    140          return context
    141
    142
    143 -    def talesEval(self, str, context, **kw):
    144          '''
    145          return a tales evaluation of str
    146          '''
    147          from Products.ZenUtils.ZenTales import talesEvalStr
    148          extraContext = self.getTalesContext(thing=context, **kw)
    149          try:
    150              result = talesEvalStr(str, context, extraContext)
    151          except Exception:
    152              result = '(Tales expression error)'
    153          return result
    154
    155
    156      ## Graphing Support
    157
    158 -    def getColor(self, index):
    159          """
    160          Return a string apprpriate for use as the color part of an
    161          rrd graph command.  The color either comes from the attribute on
    162          this object or from an offset into the self.colors list.
    163          """
    164          color = None
    165          if self.color:
    166              color = self.color
    167              try:
    168                  _ = long(color, 16)
    169              except ValueError:
    170                  color = None
    171          if not color:
    172              index %= len(self.colors)
    173              color = self.colors[index]
    174          color = '#%s' % color.lstrip('#')
    175          if hasattr(self, 'stacked'):
    176              # This is setting the alpha channel?
    177              # Why is this needed?
    178              if not self.stacked and index>0: color += "99"
    179              else: color += "ff"
    180          return color
    181
    182
    183 -    def getThresholdColor(self, index):
    184          index %= len(self.colors)
    185          color = self.color or self.colors[-1 * (index+1)]
    186          color = '#%s' % color.lstrip('#')
    187          return color
    188
    189
    190 -    def getGraphCmds(self, cmds, context, rrdDir, addSummary, idx,
    191                      multiid=-1, prefix=''):
    192          ''' Build the graphing commands for this graphpoint
    193          '''
    194          from Products.ZenUtils.Utils import unused
    195          unused(multiid, prefix, rrdDir)
    196          return cmds
    197
    198
    199 -    def getDsName(self, base, multiid=-1, prefix=''):
    200          name = self.addPrefix(prefix, base)
    201          if multiid > -1:
    202              name = '%s_%s' % (name, multiid)
    203          return name
    204
    205
    206 -    def addPrefix(self, prefix, base):
    207          ''' If not base then return ''
    208          elif prefix then return prefix_base
    209          else return base
    210          The result is rrd scrubbed
    211          '''
    212          s = base or ''
    213          if s and prefix:
    214              s = '_'.join((prefix, base))
    215          s = self.scrubForRRD(s)
    216          return s
    217
    218
    219 -    def scrubForRRD(self, value, namespace=None):
    220          ''' scrub value so it is a valid rrd variable name.  If namespace
    221          is provided then massage value as needed to avoid name conflicts
    222          with items in namespace.
    223          '''
    224          import string
    225          import itertools
    226          validRRDchars=set(string.ascii_letters + string.digits + '_-')
    227          value = ''.join(c if c in validRRDchars else '_' for c in value)
    228          if namespace:
    229              postfixIter = itertools.count(2)
    230              candidate = value
    231              while candidate in namespace:
    232                  candidate = value + str(postfixIter.next())
    233              value = candidate
    234          return value
    235
    236
    237 -    def escapeForRRD(self, value):
    238          '''
    239          Escapes characters like colon ':' for use by RRDTool which would
    240          '''
    241          value = value.replace(":", "\:")[:198]
    242          return value
    243
    244
    245  InitializeClass(GraphPoint)
    246