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