1 | import re |
||
2 | import validators |
||
3 | from collections import Iterable, OrderedDict |
||
4 | |||
5 | from coalib.misc import Constants |
||
6 | from coalib.parsing.StringProcessing import ( |
||
7 | unescape, unescaped_split, unescaped_strip) |
||
8 | |||
9 | |||
10 | class StringConverter: |
||
11 | """ |
||
12 | Converts strings to other things as needed. If you need some kind of string |
||
13 | conversion that is not implemented here, consider adding it so everyone |
||
14 | gets something out of it. |
||
15 | """ |
||
16 | |||
17 | def __init__(self, |
||
18 | value, |
||
19 | strip_whitespaces=True, |
||
20 | list_delimiters=None, |
||
21 | dict_delimiter=":", |
||
22 | remove_empty_iter_elements=True): |
||
23 | if list_delimiters is None: |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
![]() |
|||
24 | list_delimiters = [",", ";"] |
||
25 | |||
26 | if not isinstance(list_delimiters, Iterable): |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
27 | raise TypeError("list_delimiters has to be an Iterable.") |
||
28 | if not isinstance(strip_whitespaces, bool): |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Comprehensibility
Best Practice
introduced
by
|
|||
29 | raise TypeError("strip_whitespaces has to be a bool parameter") |
||
30 | |||
31 | self.__strip_whitespaces = strip_whitespaces |
||
32 | self.__list_delimiters = list_delimiters |
||
33 | self.__dict_delimiter = dict_delimiter |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
34 | self.__remove_empty_iter_elements = remove_empty_iter_elements |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
35 | |||
36 | self.__escaped_list = None |
||
37 | self.__unescaped_list = None |
||
38 | self.__dict = None |
||
39 | self.value = value |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
40 | |||
41 | def __str__(self): |
||
42 | return unescape(self.value) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
43 | |||
44 | def __bool__(self): |
||
45 | if str(self).lower() in Constants.TRUE_STRINGS: |
||
46 | return True |
||
47 | if str(self).lower() in Constants.FALSE_STRINGS: |
||
48 | return False |
||
49 | raise ValueError |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
50 | |||
51 | def __len__(self): |
||
52 | return len(str(self)) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
53 | |||
54 | def __int__(self): |
||
55 | return int(str(self)) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
56 | |||
57 | def __float__(self): |
||
58 | return float(str(self)) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
59 | |||
60 | def __url__(self): |
||
61 | """ |
||
62 | Determines the url validity of this setting. |
||
63 | |||
64 | :return: url string |
||
65 | :raises ValueError: If the url is not valid. |
||
66 | """ |
||
67 | strrep = str(self).strip() |
||
68 | if validators.url(strrep): |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
69 | return strrep |
||
70 | |||
71 | raise ValueError(repr(strrep) + " is not a valid url.") |
||
72 | |||
73 | def __iter__(self, remove_backslashes=True): |
||
74 | """ |
||
75 | Converts the value to a list using the delimiters given at construction |
||
76 | time. |
||
77 | |||
78 | Note that escaped values will be unescaped and escaped list delimiters |
||
79 | will be allowed in values. If you need the escapes you should not |
||
80 | use this routine. |
||
81 | |||
82 | :param remove_backslashes: Whether or not to remove the backslashes |
||
83 | after conversion. |
||
84 | :return: An iterator over all values. |
||
85 | """ |
||
86 | if remove_backslashes: |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
87 | return iter(self.__unescaped_list) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
88 | else: |
||
89 | return iter(self.__escaped_list) |
||
90 | |||
91 | def __getitem__(self, item): |
||
92 | return self.__dict.__getitem__(item) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
93 | |||
94 | def keys(self): |
||
95 | return self.__dict.keys() |
||
96 | |||
97 | def __get_raw_list(self): |
||
98 | pattern = ("(?:" + |
||
99 | "|".join(re.escape(v) for v in self.__list_delimiters) + |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Comprehensibility
Best Practice
introduced
by
|
|||
100 | ")") |
||
101 | |||
102 | return list(unescaped_split(pattern, |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
103 | self.value, |
||
104 | use_regex=True)) |
||
105 | |||
106 | def __prepare_list(self): |
||
107 | self.__escaped_list = self.__get_raw_list() |
||
108 | |||
109 | if self.__strip_whitespaces: |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
110 | self.__escaped_list = [unescaped_strip(elem) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
111 | for elem in self.__escaped_list] |
||
112 | |||
113 | self.__unescaped_list = [unescape(elem) |
||
114 | for elem in self.__escaped_list] |
||
115 | |||
116 | if self.__remove_empty_iter_elements: |
||
117 | # Need to do after stripping, cant use builtin functionality of |
||
118 | # split. |
||
119 | while "" in self.__unescaped_list: |
||
120 | self.__unescaped_list.remove("") |
||
121 | while "" in self.__escaped_list: |
||
122 | self.__escaped_list.remove("") |
||
123 | |||
124 | def __prepare_dict(self): |
||
125 | # We must keep order here, user can drop it later. |
||
126 | self.__dict = OrderedDict() |
||
127 | for elem in self.__get_raw_list(): |
||
128 | key_val = unescaped_split(self.__dict_delimiter, elem, max_split=1) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Comprehensibility
Best Practice
introduced
by
|
|||
129 | |||
130 | if self.__strip_whitespaces: |
||
131 | key_val = [unescaped_strip(item) for item in key_val] |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Comprehensibility
Best Practice
introduced
by
|
|||
132 | |||
133 | key_val = [unescape(item) for item in key_val] |
||
134 | |||
135 | if not any(item != "" for item in key_val): |
||
136 | continue |
||
137 | |||
138 | if len(key_val) < 2: |
||
139 | self.__dict[key_val[0]] = "" |
||
140 | else: |
||
141 | self.__dict[key_val[0]] = key_val[1] |
||
142 | |||
143 | @property |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
144 | def value(self): |
||
145 | return self.__value |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
146 | |||
147 | @value.setter |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
148 | def value(self, newval): |
||
149 | self.__value = str(newval) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
150 | if self.__strip_whitespaces: |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
151 | self.__value = unescaped_strip(self.__value) |
||
152 | |||
153 | self.__prepare_list() |
||
154 | self.__prepare_dict() |
||
155 | |||
156 | def __eq__(self, other): |
||
157 | return isinstance(other, StringConverter) and self.value == other.value |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Comprehensibility
Best Practice
introduced
by
Comprehensibility
Best Practice
introduced
by
|
|||
158 | |||
159 | def __ne__(self, other): |
||
160 | return not self.__eq__(other) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
161 |