1 from dataclasses
import dataclass
5 from typing
import Optional
6 import xml.etree.ElementTree
as ET
8 DEFAULT_DEBOUNCE_SEC = 3
17 return f
"{self.__class__.__name__}({repr(self.markup)})"
19 return getattr(other,
'markup',
None) == self.
markupmarkup
25 return f
"{self.__class__.__name__}({repr(self.path)})"
27 return getattr(other,
'path',
None) == self.
pathpath
31 if elem.tag ==
'file':
32 return Recording(os.path.join(os.path.dirname(file_path), elem.attrib[
'name']))
34 return SSML(ET.tostring(elem,
'utf-8').decode(
'utf8').strip())
47 @dataclass(eq=True, frozen=True)
49 value : Optional[purepyindi2.AnyIndiValue]
50 value_2 : Optional[purepyindi2.AnyIndiValue]
51 debounce_sec : float = DEFAULT_DEBOUNCE_SEC
52 op : Optional[Operation] =
None
57 if self.op
is Operation.EQ:
58 return new_value == self.value
59 elif self.op
is Operation.NE:
60 return new_value != self.value
63 new_value =
float(new_value)
64 except (ValueError, TypeError):
66 if self.op
is Operation.LT:
67 return new_value < self.value
68 elif self.op
is Operation.LE:
69 return new_value <= self.value
70 elif self.op
is Operation.GT:
71 return new_value > self.value
72 elif self.op
is Operation.GE:
73 return new_value >= self.value
74 elif self.op
is Operation.BETWEEN:
75 lo = min(self.value, self.value_2)
76 hi = max(self.value, self.value_2)
77 return lo <= new_value < hi
83 transitions : dict[Transition, list[SpeechRequest]]
87 reactions : list[Reaction]
89 random_utterances : list[SpeechRequest]
90 soundboard : dict[str, SpeechRequest]
94 tree = ET.parse(file_path)
97 random_utterances = []
103 if el.tag ==
'default-voice':
104 default_voice = el.attrib[
'name']
106 elif el.tag ==
'random-utterances':
110 elif el.tag ==
'soundboard':
115 assert el.tag ==
'react-to'
116 indi_id = el.attrib[
'indi-id']
117 for transition
in el:
118 assert transition.tag ==
'transition'
119 if 'low' in transition.attrib:
120 value = purepyindi2.parse_string_into_any_indi_value(transition.attrib[
'low'])
121 value_2 = purepyindi2.parse_string_into_any_indi_value(transition.attrib[
'high'])
122 operation = Operation.BETWEEN
123 elif 'value' in transition.attrib:
124 value = purepyindi2.parse_string_into_any_indi_value(transition.attrib[
'value'])
126 operation = purepyindi2.parse_string_into_enum(transition.attrib.get(
'op',
'eq'), Operation)
131 if 'debounce_sec' in transition.attrib:
132 debounce_sec = float(transition.attrib[
'debounce_sec'])
134 debounce_sec = DEFAULT_DEBOUNCE_SEC
135 trans =
Transition(op=operation, value=value, value_2=value_2, debounce_sec=debounce_sec)
136 if trans
in transitions:
137 raise RuntimeError(f
"Multiply defined for {indi_id} {operation=} {value=}")
138 transitions[trans] = []
139 for utterance
in transition:
140 assert utterance.tag
in (
'speak',
'file')
142 reactions.append(
Reaction(indi_id=indi_id, transitions=transitions))
145 default_voice=default_voice,
146 random_utterances=random_utterances,
147 soundboard=soundboard,
150 if __name__ ==
"__main__":
152 pprint.pprint(Personality.from_path(
'./default.xml'), width=255)
def from_path(cls, file_path)
def __init__(self, markup)
def compare(self, new_value)
def xml_to_speechrequest(elem, file_path)