]> us-delaporte.pagekite.me Git - matrix-goal-bot.git/blob - matrix_goal_bot/bot.py
417fca92eb93d99afa23238035b8d7e41a436a21
[matrix-goal-bot.git] / matrix_goal_bot / bot.py
1 '''
2 Prefix: !goal
3
4 Synax:
5 !goal COMMAND ARGS
6
7 Commands:
8 help - show this help
9 extra.help - show extended help
10 add - add a goal
11 task ID - add a task under the goal specified by ID
12 close.goal ID - mark goal done by ID
13 done ID - mark task done by ID
14 list - list incomplete goals
15 print GOAL_ID - print a goal and all tasks
16 '''
17
18 ex_help = '''
19 More commands:
20 add.vision - add a new vision (collection of goals)
21 close.vision ID - mark vision as complete by ID
22 list.all - list everything
23 print.vision ID - print a vision and all goals
24 set.vision GOAL_ID VISION_ID- associate GOAL_ID with VISION_ID
25 visions - list incomplete visions
26 list.done - list completed goals
27 visionless - list goals with no set vision
28 '''
29
30
31 from datetime import datetime as dt
32 import logging
33 import os
34
35 import simplematrixbotlib as botlib
36
37 from .db import Data, pretty_print
38
39 DATE_FORMAT = '%Y-%m-%d'
40
41 def today():
42 return dt.now().strftime(DATE_FORMAT)
43
44 logger = logging.getLogger(__name__)
45
46 snark = [
47 'Ye cannot get ye flask.',
48 'Ye flask must be load bearing, or something...',
49 '''You have:
50 no tea
51 ''',
52 'How are you gentlemen?',
53 'All your base are belong to us.',
54 'You have been eaten by a groo.'
55 ]
56
57 class GoalBot():
58 def __init__(self, matrix_server,
59 bot_name,
60 bot_pwd,
61 db_file=None,
62 bot_prefix='!goal'):
63
64 creds = botlib.Creds(matrix_server, bot_name, bot_pwd)
65 self.bot = botlib.Bot(creds)
66 self.prefix = bot_prefix
67 self.data = Data(db_file)
68
69 def run(self):
70 logger.debug('Running goal bot...')
71 self.bot.run()
72
73 async def handle_message(self, room, message):
74 logger.debug(f'Message: {message}')
75 match = botlib.MessageMatch(room, message, self.bot, self.prefix)
76
77 if not match.is_not_from_this_bot() and match.prefix():
78 logger.debug(f'Message: {message} was not for this bot.')
79 return
80
81 if not match.prefix():
82 logger.debug(f'{message} - did not match {self.prefix}')
83
84 if match.prefix():
85 try:
86 result_lines = await self._handle_match(match)
87 for line in result_lines:
88 await self.bot.api.send_text_message(
89 room.room_id, str(line))
90 except Exception as ex:
91 logger.warn(f'Caught exception: {str(ex)}')
92 dumb_msg_idx = len(str(ex)) % len(snark)
93 dumb_msg = snark[dumb_msg_idx]
94 await self.bot.api.send_text_message(
95 room.room_id, dumb_msg)
96
97 await self.bot.api.send_text_message(
98 room.room_id, str(ex))
99
100
101 async def _handle_match(self, match):
102 logger.debug(f'Try to match {str(match)}')
103
104 if match.command('setup'):
105 result = self.data.setup()
106 return [result]
107
108 if match.command('add'):
109 new = ' '.join(match.args()[1:])
110 goal_id = self.data.add_goal(new)
111 results = [f'Goal added with id {goal_id}']
112
113 goals = self.data.get_all_goals()
114 results.append('# Goals list...')
115 for goal in goals:
116 results.append(str(goal))
117
118 return results
119
120 if match.command('list'):
121 logger.debug('Asked to list goals...')
122 goals = self.data.get_all_goals()
123 results = ['# Goals list...']
124 for goal in goals:
125 results.append(str(goal))
126 return results
127
128
129 if match.command('list.done'):
130 goals = self.data.get_done_goals()
131 results = ['# Completed Goals...']
132 for goal in goals:
133 results.append(str(goal))
134 return results
135
136 if match.command('task'):
137 new = ' '.join(match.args()[1:])
138 goal_id = self.data.quick_add_task(new)
139 goal,tasks = self.data.get_goal(goal_id)
140 results = pretty_print(goal, tasks)
141 return results
142
143 if match.command('add.vision'):
144 new = ' '.join(match.args()[1:])
145 result = self.data.add_vision(new)
146 return [f'Vision added with id {result}']
147
148 if match.command('print'):
149 if len(match.args()) > 1:
150 goal_id = int(match.args()[1])
151 else:
152 goal_id = self.data._get_pref_goal_id()
153
154 logger.debug(f'Searching for goal {goal_id}...')
155 goal,tasks = self.data.get_goal(goal_id)
156 results = pretty_print(goal, tasks)
157
158 return results
159
160
161 if match.command('print.vision'):
162 get_id = int(match.args()[1])
163 vision,goals = self.data.get_vision(get_id)
164 results = pretty_print(vision, goals)
165 return results
166
167 if match.command('close.goal'):
168 goal_id = int(match.args()[1])
169 vision_id = self.data.complete_goal(goal_id)
170 vision,goals = self.data.get_vision(vision_id)
171 results = pretty_print(vision, goals)
172 return results
173
174 if match.command('close.vision'):
175 vision_id = int(match.args()[1])
176 self.data.complete_vision(vision_id)
177 vision,goals = self.data.get_vision(vision_id)
178 results = pretty_print(vision, goals)
179 return results
180
181 if match.command('done'):
182 ids = match.args()[1:]
183 for task_id in ids:
184 goal_id = self.data.complete_task(int(task_id))
185 # Print the goal of the last closed task
186 goal,tasks = self.data.get_goal(goal_id)
187 results = pretty_print(goal, tasks)
188 return results
189
190 if match.command('list.all'):
191 goals = self.data.get_all_goals()
192 results = ['# Everything is...']
193 for goal in goals:
194 _,tasks = self.data.get_goal(goal.id)
195 details = pretty_print(goal, tasks)
196 results += details
197 return results
198
199 if match.command('visions'):
200 items = self.data.get_all_visions()
201 results = ['# Visions']
202 if not items:
203 results.append('-- No current visions --')
204
205 for item in items:
206 results.append(item)
207 return results
208
209 if match.command('visionless'):
210 items = self.data.visionless()
211 results = ['# Goals with no vision']
212 if not items:
213 results.append('-- No visionless goals --')
214
215 for item in items:
216 results.append(item)
217 return results
218
219 if match.command('set.vision'):
220 goal_id = int(match.args()[1])
221 vision_id = int(match.args()[2])
222 self.data.assign_vision(goal_id=goal_id, vision_id=vision_id)
223 vision,goals = self.data.get_vision(vision_id)
224 results = pretty_print(vision, goals)
225 return results
226
227
228 if match.command('rename'):
229 goal_id = int(match.args()[1])
230 name = ' '.join(match.args()[2:])
231 self.data.rename_goal(goal_id=goal_id, name=name)
232 goal,tasks = self.data.get_goal(goal_id)
233 results = pretty_print(goal, tasks)
234 return results
235
236 if match.command('remove'):
237 task_id = int(match.args()[1])
238 result = self.data.remove_task(task_id)
239 return [result]
240
241 if match.command('extra.help'):
242 return [ex_help]
243
244 # Help text
245 return [__doc__]
246
247
248