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