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

59 statements  

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 

12 

13 

14class MokadiEngine: 

15 """ 

16 Defines results for mokadi. 

17 """ 

18 

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."]} 

22 

23 @staticmethod 

24 def peak_random(mes: list): 

25 """ 

26 Pick a random message 

27 

28 @param mes list of strings 

29 @return one string 

30 """ 

31 i = random.randint(0, len(mes) - 1) 

32 return mes[i] 

33 

34 def __init__(self, root, clog: CustomLog, actions, 

35 MokadiGrammarParser, MokadiGrammarLexer, MokadiGrammarListener): 

36 """ 

37 Constructor 

38 

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 

52 

53 if not os.path.exists(root): 

54 raise FileNotFoundError(root) 

55 

56 def fLOG(self, *args, **kwargs): 

57 """ 

58 message to string 

59 """ 

60 self._clog(*args, **kwargs) 

61 

62 def process(self, message: MokadiMessage, exc=False): 

63 """ 

64 Process one message and returns an iterator on @see cl MokadiInfo. 

65 

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 

99 

100 def process_interpreted_message(self, interpretation, message): 

101 """ 

102 Process the interpreted message. 

103 

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))