-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbase.py
More file actions
105 lines (86 loc) · 2.82 KB
/
base.py
File metadata and controls
105 lines (86 loc) · 2.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import re
class StringConditionsException( Exception ):
pass
def array_has_any( any, array ):
matched = False
for a in any:
if a in array:
matched = True
return matched
def array_has_all( all, array ):
for a in all:
if a not in array:
return False
return True
def remove_values_from_list( the_list, val ):
return [value for value in the_list if value != val]
def compute_or( condition, values ):
# We got an OR operator. At least one must match
a_any = condition.split( "|" )
if "&" not in condition and not array_has_any( a_any, values ):
raise StringConditionsException(
"At least one value from ({}) must be provided".format(
"|".join( a_any ) ) )
elif "&" in condition:
# The OR condition contains an AND
for a in a_any:
if "&" in a:
compute_and( condition, a )
def compute_and( condition, values ):
a_and_condition = condition.split( "&" )
# Everything that is bounded by & must be present IF ANY is present
for and_condition in a_and_condition:
if "|" not in and_condition:
if and_condition not in values:
raise StringConditionsException(
"The following values must be present: `{0}`".format(
", ".join( a_and_condition ) ) )
else:
compute_or( and_condition, values )
def validate( condition, values ):
# Split by whitespace but only if it's not
# between parenthesis, accolades or squared bracckets
# I only got ideas for parenthesis and I don't know
# why the fuck I consider accolades and squareds but who knows
a_condition = re.compile( "\s+(?![^\[]*\]|[^(]*\)|[^\{]*})" ).split( condition )
for c in a_condition:
if not c.startswith( "(" ):
if not "|" in c and not "&" in c:
# Simple condition matched, check
# if it's present in values list
if not c in values:
raise StringConditionsException(
"`{}` is a required value".format( c ) )
elif "|" in c:
compute_or( c, values )
elif "&" in c:
compute_and( c, values )
else:
# We got parenthesis which means only one
# from the provided values must be present
# ex: (red blue green). Similar to OR but with OR
# all values can be present
c = c[1:-1]
exists_counter = 0
a_exclusive = c.split( " " )
for exclusive in a_exclusive:
if "&" in exclusive:
try:
# If we get an error out of here it means
# that not all values are present. If exception
# is thrown no counter is incremented
compute_and( exclusive, values )
exists_counter += 1
except StringConditionsException:
pass
elif "|" in exclusive:
try:
compute_or( exclusive, values )
exists_counter += 1
except StringConditionsException:
pass
elif exclusive in values:
exists_counter += 1
if exists_counter > 1:
raise StringConditionsException(
"Only one of the following values are accepted: `{}`".format( c ) )