1
2
3
4
5
6
7
8
9
10
11
12
13 import types
14 from Products.ZenUtils.json import json
15
16 negativeModes = (
17 '!',
18 '!~',
19 '!^',
20 )
21
23
24 return "'%s'" % "''".join(s.split("'"))
25
26 -class Error(Exception): pass
27
29 "Base class for converting to/from javascript"
30 type = 'unknown'
34 return '%s:{type:"%s",label:"%s"}' % (name, self.type, self.label)
48
49 -class Text(WhereJavaScript):
50 "Convert to/from javascript for text entries"
51 type = 'text'
52 - def toJS(self, mode, value):
53 if mode == 'like':
54 if value.startswith('%') and not value.endswith('%'):
55 return '$', [value[1:]]
56 elif not value.startswith('%') and value.endswith('%'):
57 return '^', [value[:-1]]
58 elif value.startswith('%') and value.endswith('%'):
59 return '~', [value[1:-1]]
60 if mode == 'not like':
61 return '!~', [value[1:-1]]
62 if mode == '=':
63 return '', [value]
64 if mode == '!=':
65 return '!', [value]
66 - def buildClause1(self, name, v, mode):
67 if mode == '~':
68 return "%s like %s" % (name, q('%' + v + '%'))
69 if mode == '^':
70 return "%s like %s" % (name, q(v + '%'))
71 if mode == '$':
72 return "%s like %s" % (name, q('%' + v))
73 if mode == '!~':
74 return "%s not like %s" % (name, q('%' + v + '%'))
75 if mode == '':
76 return "%s = %s" % (name, q(v))
77 if mode == '!':
78 return "%s != %s" % (name, q(v))
79
80
82 "Convert to/from javascript and where clause element for select entries"
83 type = 'select'
91 return dict(self.options).get(value, 'Unknown')
93 return dict([(v, l) for l, v in self.options]).get(value, -1)
94 - def toJS(self, operator, value):
106 return '%s:{type:"%s",label:"%s", options:%r}' % (
107 name, self.type, self.label, [s[1] for s in self.options])
116
118 "Convert to/from javascript and where clause elements for numeric comparisons"
119 type = 'compare'
120 - def toJS(self, operator, value):
121 return operator, [value]
124
126 - def toJS(self, operator, value):
127 if operator == 'like':
128 return ['', [value[2:-1]]]
129 if operator == 'not like':
130 return ['!', [value[2:-1]]]
132 if mode == '':
133 return "%s like %s" % (name, q('%|' + v + '%'))
134 else:
135 return "%s not like %s" % (name, q('%|' + v + '%'))
136
138 type = 'evtClass'
139 - def toJS(self, operator, value):
140 value = value.rstrip('%')
141 if operator == '=':
142 return ['', [value]]
143 if operator == '!=':
144 return ['!', [value]]
145 if operator == 'like':
146 return ['^', [value]]
147 if operator == 'not like':
148 return ['!^', [value]]
150 if mode == '':
151 return "%s = %s" % (name, q(v))
152 elif mode == '^':
153 return "%s like %s" % (name, q(v + '%'))
154 elif mode == '!^':
155 return "%s not like %s" % (name, q(v + '%'))
156 else:
157 return "%s != %s" % (name, q(v))
158
159
160
162 "Convert to/from javascript and where clause elements for enumerated types"
163 type='cselect'
164 - def toJS(self, operator, value):
168
169 _Definitions = r'''
170 def u(s):
171 # turn string "'fo''o'" -> "fo'o"
172 c = s[0]
173 s = c.join(s.split(c+c))
174 return s[1:-1]
175
176 '''
177
178 _ParseSpec = r'''
179 parser WhereClause:
180 ignore: "[ \r\t\n]+"
181 token END: "$"
182 token NUM: "[0-9]+"
183 token VAR: "[a-zA-Z0-9_]+"
184 token BIN: ">=|<=|==|=|<|>|!=|<>"
185 token STR: r'"([^\\"]+|\\.)*"'
186 token STR2: r"'([^\\']+|\\.)*'"
187
188 rule goal: andexp ? END {{ return locals().get('andexp', None) }}
189
190 rule andexp: orexp {{ e = orexp }}
191 ( "and" orexp {{ e = ('and', e, orexp) }}
192 )* {{ return e }}
193
194 rule orexp: binary {{ e = binary }}
195 ( "or" binary {{ e = ('or', e, binary) }}
196 )* {{ return e }}
197
198 rule binary: term {{ e = term }}
199 ( BIN term {{ e = (BIN, e, term) }}
200 | 'like' term {{ e = ('like', e, term) }}
201 | 'not' 'like' term
202 {{ e = ('not like', e, term) }}
203 )* {{ return e }}
204
205 rule term: NUM {{ return int(NUM) }}
206 | VAR {{ return VAR }}
207 | STR {{ return u(STR) }}
208 | STR2 {{ return u(STR2) }}
209 | "\\(" andexp "\\)" {{ return andexp }}
210 '''
211
212
215 from yapps import grammar, yappsrt
216 from StringIO import StringIO
217 scanner = grammar.ParserDescriptionScanner(spec)
218 parser = grammar.ParserDescription(scanner)
219 parser = yappsrt.wrap_error_reporter(parser, 'Parser')
220 parser.preparser = _Definitions
221 parser.output = StringIO()
222 parser.generate_output()
223 exec parser.output.getvalue() in self.__dict__
224
225 where = _Parser(_ParseSpec)
226
227 @json
229
230 lmeta = dict([(n.lower(), n) for n in meta.keys()])
231 tree = where.parse('goal', clause)
232 def recurse(root, result):
233 if type(root) == types.TupleType:
234 n = len(root)
235 if n == 1:
236 recurse(root[0], result)
237 op, name, value = root
238 if op in ('and', 'or'):
239 recurse(root[1], result)
240 recurse(root[2], result)
241 else:
242 name = lmeta.get(name.lower(), None)
243 if name is not None:
244 op, value = meta[name].toJS(op, value)
245 result.append([name, op, value])
246 result = []
247 recurse(tree, result)
248 result.sort()
249 return result
250
263
264
265 if __name__ == '__main__':
266 meta = {}
267 toJavaScript(meta, 'severity = 3 or severity = 4')
268 toJavaScript(meta, "severity >= 4 and eventState = 0 and prodState = 1000")
269 toJavaScript(meta, "severity >= 2 and eventState = 0 and prodState = 1000")
270 print toJavaScript(meta, '(prodState = 1000) and (eventState = 0 or eventState = 1) and (severity >= 3)')
271 print fromFormVariables(meta,
272 dict(severity='Info',
273 severity_mode='>',
274 eventState='New',
275 eventState_mode='=',
276 prodState='Production',
277 prodState_mode='='))
278