Coverage for src/botadi/mokadi/mokadi_engine.py: 78%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# -*- coding: utf-8 -*-
2"""
3@file
4@brief Make Mokadi's engine.
5"""
6import os
7import random
8from pyquickhelper.loghelper import CustomLog
9from .mokadi_message import MokadiMessage
10from .mokadi_info import MokadiInfo
11from .mokadi_exceptions import MokadiException
14class MokadiEngine:
15 """
16 Defines results for mokadi.
17 """
19 _messages = {"dontunderstand": ["Je n'ai pas compris.", "Parlez vous mokadi?"],
20 "failure": ["Un imprévu s'est produit. Je n'ai pas su faire.",
21 "Grosse tuile. Je pensais avoir compris. Mais non."]}
23 @staticmethod
24 def peak_random(mes: list):
25 """
26 Pick a random message
28 @param mes list of strings
29 @return one string
30 """
31 i = random.randint(0, len(mes) - 1)
32 return mes[i]
34 def __init__(self, root, clog: CustomLog, actions,
35 MokadiGrammarParser, MokadiGrammarLexer, MokadiGrammarListener):
36 """
37 Constructor
39 @param root root folder
40 @param clog custom log
41 @param actions list of actions
42 @param MokadiGrammarParser parser for a specific language
43 @param MokadiGrammarLexer lexer for a specific language
44 @param MokadiGrammarListener listener for a specific language
45 """
46 self._clog = clog
47 self._root = root
48 self._actions = actions
49 self._MokadiGrammarParser = MokadiGrammarParser
50 self._MokadiGrammarLexer = MokadiGrammarLexer
51 self._MokadiGrammarListener = MokadiGrammarListener
53 if not os.path.exists(root):
54 raise FileNotFoundError(root)
56 def fLOG(self, *args, **kwargs):
57 """
58 message to string
59 """
60 self._clog(*args, **kwargs)
62 def process(self, message: MokadiMessage, exc=False):
63 """
64 Process one message and returns an iterator on @see cl MokadiInfo.
66 @param message @see cl MokadiMessage
67 @param exc raises an exception if an error happens
68 @return iterator on @see cl MokadiInfo
69 """
70 self.fLOG("[MokadiEngine.process]", message)
71 prefix_error = "MOKADI error,"
72 if message.message is not None and message.message.startswith(prefix_error):
73 info = MokadiInfo("error", message.message[len(prefix_error):])
74 self.fLOG("[MokadiEngine.process]", info)
75 yield info
76 else:
77 res = message.interpret(exc, self._MokadiGrammarParser,
78 self._MokadiGrammarLexer, self._MokadiGrammarListener)
79 if isinstance(res, Exception):
80 info = MokadiInfo("error", MokadiEngine.peak_random(
81 MokadiEngine._messages["dontunderstand"]), str(res), None)
82 self.fLOG("[MokadiEngine.process]", info)
83 yield info
84 else:
85 if exc:
86 for info in self.process_interpreted_message(res, message):
87 self.fLOG("[MokadiEngine.process]", info)
88 yield info
89 else:
90 try:
91 for info in self.process_interpreted_message(res, message):
92 self.fLOG("[MokadiEngine.process]", info)
93 yield info
94 except Exception as e:
95 info = MokadiInfo("error", MokadiEngine.peak_random(
96 MokadiEngine._messages["failure"]), str(e), None)
97 self.fLOG("[MokadiEngine.process]", info)
98 yield info
100 def process_interpreted_message(self, interpretation, message):
101 """
102 Process the interpreted message.
104 @param interpretation interpretation
105 @param message original message
106 @return iterator on Info
107 """
108 done = False
109 for act in self._actions:
110 if act.can_do(interpretation, message):
111 self.fLOG(
112 "[MokadiEngine.process_interpreted_message] '%s' processes the message" % str(act))
113 for info in act.process_interpreted_message(interpretation, message):
114 yield info
115 done = True
116 break
117 if not done:
118 raise MokadiException(
119 "Unable to process '{0}' - '{1}'.".format(interpretation, message))