Completed
Push — master ( ac716c...f12d05 )
by Arma
07:15
created

st2common.match_wildcard()   A

Complexity

Conditions 2

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 2
dl 0
loc 5
rs 9.4285
1
# Licensed to the StackStorm, Inc ('StackStorm') under one or more
2
# contributor license agreements.  See the NOTICE file distributed with
3
# this work for additional information regarding copyright ownership.
4
# The ASF licenses this file to You under the Apache License, Version 2.0
5
# (the "License"); you may not use this file except in compliance with
6
# the License.  You may obtain a copy of the License at
7
#
8
#     http://www.apache.org/licenses/LICENSE-2.0
9
#
10
# Unless required by applicable law or agreed to in writing, software
11
# distributed under the License is distributed on an "AS IS" BASIS,
12
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
# See the License for the specific language governing permissions and
14
# limitations under the License.
15
16
import re
17
import fnmatch
18
19
from st2common.util import date as date_utils
20
21
__all__ = [
22
    'get_operator',
23
    'get_allowed_operators'
24
]
25
26
27
def get_allowed_operators():
28
    return operators
29
30
31
def get_operator(op):
32
    op = op.lower()
33
    if op in operators:
34
        return operators[op]
35
    else:
36
        raise Exception('Invalid operator: ' + op)
37
38
# Operation implementations
39
40
41
def equals(value, criteria_pattern):
42
    if criteria_pattern is None:
43
        return False
44
    return value == criteria_pattern
45
46
47
def nequals(value, criteria_pattern):
48
    return value != criteria_pattern
49
50
51
def iequals(value, criteria_pattern):
52
    if criteria_pattern is None:
53
        return False
54
    return value.lower() == criteria_pattern.lower()
55
56
57
def contains(value, criteria_pattern):
58
    if criteria_pattern is None:
59
        return False
60
    return criteria_pattern in value
61
62
63
def icontains(value, criteria_pattern):
64
    if criteria_pattern is None:
65
        return False
66
    return criteria_pattern.lower() in value.lower()
67
68
69
def ncontains(value, criteria_pattern):
70
    if criteria_pattern is None:
71
        return False
72
    return criteria_pattern not in value
73
74
75
def incontains(value, criteria_pattern):
76
    if criteria_pattern is None:
77
        return False
78
    return criteria_pattern.lower() not in value.lower()
79
80
81
def startswith(value, criteria_pattern):
82
    if criteria_pattern is None:
83
        return False
84
    return value.startswith(criteria_pattern)
85
86
87
def istartswith(value, criteria_pattern):
88
    if criteria_pattern is None:
89
        return False
90
    return value.lower().startswith(criteria_pattern.lower())
91
92
93
def endswith(value, criteria_pattern):
94
    if criteria_pattern is None:
95
        return False
96
    return value.endswith(criteria_pattern)
97
98
99
def iendswith(value, criteria_pattern):
100
    if criteria_pattern is None:
101
        return False
102
    return value.lower().endswith(criteria_pattern.lower())
103
104
105
def less_than(value, criteria_pattern):
106
    if criteria_pattern is None:
107
        return False
108
    return value < criteria_pattern
109
110
111
def greater_than(value, criteria_pattern):
112
    if criteria_pattern is None:
113
        return False
114
    return value > criteria_pattern
115
116
117
def match_wildcard(value, criteria_pattern):
118
    if criteria_pattern is None:
119
        return False
120
121
    return fnmatch.fnmatch(value, criteria_pattern)
122
123
124
def match_regex(value, criteria_pattern):
125
    if criteria_pattern is None:
126
        return False
127
    regex = re.compile(criteria_pattern, re.DOTALL)
128
    # check for a match and not for details of the match.
129
    return regex.match(value) is not None
130
131
132
def _timediff(diff_target, period_seconds, operator):
133
    """
134
    :param diff_target: Date string.
135
    :type diff_target: ``str``
136
137
    :param period_seconds: Seconds.
138
    :type period_seconds: ``int``
139
140
    :rtype: ``bool``
141
    """
142
    # Pickup now in UTC to compare against
143
    utc_now = date_utils.get_datetime_utc_now()
144
145
    # assuming diff_target is UTC and specified in python iso format.
146
    # Note: date_utils.parse uses dateutil.parse which is way more flexible then strptime and
147
    # supports many date formats
148
    diff_target_utc = date_utils.parse(diff_target)
149
    return operator((utc_now - diff_target_utc).total_seconds(), period_seconds)
150
151
152
def timediff_lt(value, criteria_pattern):
153
    if criteria_pattern is None:
154
        return False
155
    return _timediff(diff_target=value, period_seconds=criteria_pattern, operator=less_than)
156
157
158
def timediff_gt(value, criteria_pattern):
159
    if criteria_pattern is None:
160
        return False
161
    return _timediff(diff_target=value, period_seconds=criteria_pattern, operator=greater_than)
162
163
164
def exists(value, criteria_pattern):
165
    return value is not None
166
167
168
def nexists(value, criteria_pattern):
169
    return value is None
170
171
# operator match strings
172
MATCH_WILDCARD = 'matchwildcard'
173
MATCH_REGEX = 'matchregex'
174
EQUALS_SHORT = 'eq'
175
EQUALS_LONG = 'equals'
176
NEQUALS_LONG = 'nequals'
177
NEQUALS_SHORT = 'neq'
178
IEQUALS_SHORT = 'ieq'
179
IEQUALS_LONG = 'iequals'
180
CONTAINS_LONG = 'contains'
181
ICONTAINS_LONG = 'icontains'
182
NCONTAINS_LONG = 'ncontains'
183
INCONTAINS_LONG = 'incontains'
184
STARTSWITH_LONG = 'startswith'
185
ISTARTSWITH_LONG = 'istartswith'
186
ENDSWITH_LONG = 'endswith'
187
IENDSWITH_LONG = 'iendswith'
188
LESS_THAN_SHORT = 'lt'
189
LESS_THAN_LONG = 'lessthan'
190
GREATER_THAN_SHORT = 'gt'
191
GREATER_THAN_LONG = 'greaterthan'
192
TIMEDIFF_LT_SHORT = 'td_lt'
193
TIMEDIFF_LT_LONG = 'timediff_lt'
194
TIMEDIFF_GT_SHORT = 'td_gt'
195
TIMEDIFF_GT_LONG = 'timediff_gt'
196
KEY_EXISTS = 'exists'
197
KEY_NOT_EXISTS = 'nexists'
198
199
# operator lookups
200
operators = {
201
    MATCH_WILDCARD: match_wildcard,
202
    MATCH_REGEX: match_regex,
203
    EQUALS_SHORT: equals,
204
    EQUALS_LONG: equals,
205
    NEQUALS_SHORT: nequals,
206
    NEQUALS_LONG: nequals,
207
    IEQUALS_SHORT: iequals,
208
    IEQUALS_LONG: iequals,
209
    CONTAINS_LONG: contains,
210
    ICONTAINS_LONG: icontains,
211
    NCONTAINS_LONG: ncontains,
212
    INCONTAINS_LONG: incontains,
213
    STARTSWITH_LONG: startswith,
214
    ISTARTSWITH_LONG: istartswith,
215
    ENDSWITH_LONG: endswith,
216
    IENDSWITH_LONG: iendswith,
217
    LESS_THAN_SHORT: less_than,
218
    LESS_THAN_LONG: less_than,
219
    GREATER_THAN_SHORT: greater_than,
220
    GREATER_THAN_LONG: greater_than,
221
    TIMEDIFF_LT_SHORT: timediff_lt,
222
    TIMEDIFF_LT_LONG: timediff_lt,
223
    TIMEDIFF_GT_SHORT: timediff_gt,
224
    TIMEDIFF_GT_LONG: timediff_gt,
225
    KEY_EXISTS: exists,
226
    KEY_NOT_EXISTS: nexists
227
}
228