1+ from enum import IntEnum
12from typing import MutableMapping , Optional
23
34from slack import methods
78from pybot .endpoints .slack .utils .action_messages import now
89from pybot .plugins .airtable .api import AirtableAPI
910
10- SERVICE_INDEX = 0
11- SKILLSET_INDEX = 1
12- MENTOR_INDEX = 2
13- DETAILS_INDEX = 3
14- GROUP_INDEX = 4
15- SUBMIT_INDEX = 5
1611
12+ class AttachmentIndex (IntEnum ):
13+ SERVICE = 0
14+ SKILLSET = 1
15+ MENTOR = 2
16+ DETAILS = 3
17+ GROUP = 4
18+ SUBMIT = 5
1719
18- class MentorRequest :
1920
20- def __init__ (self , action : Action , channel = None ):
21- self .action = action
22- self .channel = channel
21+ class MentorRequest (Action ):
2322
24- def __getitem__ (self , item ):
25- return self .action [item ]
23+ def __init__ (self , raw_action : MutableMapping ):
24+ super ().__init__ (raw_action )
25+ if 'original_message' not in self :
26+ self ['original_message' ] = {}
2627
27- def __setitem__ (self , key , value ):
28- self .action [key ] = value
28+ @property
29+ def channel (self ):
30+ return self ['channel' ]['id' ]
2931
3032 @classmethod
3133 def selected_option (cls , attachment ):
@@ -36,83 +38,90 @@ def selected_option(cls, attachment):
3638
3739 @property
3840 def attachments (self ):
39- return self ['attachments' ]
41+ return self ['original_message' ]['attachments' ]
42+
43+ @attachments .setter
44+ def attachments (self , value ):
45+ self ['original_message' ]['attachments' ] = value
4046
4147 @property
4248 def service (self ):
43- attachment = self .attachments [SERVICE_INDEX ]
49+ attachment = self .attachments [AttachmentIndex . SERVICE ]
4450 return self .selected_option (attachment )
4551
4652 @service .setter
4753 def service (self , new_service ):
48- action = self .attachments [SERVICE_INDEX ]['actions' ][0 ]
54+ action = self .attachments [AttachmentIndex . SERVICE ]['actions' ][0 ]
4955 action ['selected_options' ] = [{'value' : new_service , 'text' : new_service }]
50- self .attachments [SERVICE_INDEX ]['color' ] = ''
56+ self .attachments [AttachmentIndex . SERVICE ]['color' ] = ''
5157
5258 @property
5359 def skillsets (self ):
54- if 'text' in self .attachments [SKILLSET_INDEX ]:
55- return self .attachments [SKILLSET_INDEX ]['text' ].split ('\n ' )
60+ if 'text' in self .attachments [AttachmentIndex . SKILLSET ]:
61+ return self .attachments [AttachmentIndex . SKILLSET ]['text' ].split ('\n ' )
5662 return []
5763
58- def add_skillset (self , skillset ):
64+ def add_skillset (self , skillset : str ) -> None :
65+ """
66+ Appends the new skillset to the displayed skillsets
67+ """
5968 if skillset not in self .skillsets :
6069 skills = self .skillsets
6170 skills .append (skillset )
6271 else :
6372 skills = self .skillsets
64- self .attachments [SKILLSET_INDEX ]['text' ] = '\n ' .join (skills )
73+ self .attachments [AttachmentIndex . SKILLSET ]['text' ] = '\n ' .join (skills )
6574
6675 @property
67- def mentor (self ):
68- attachment = self .attachments [MENTOR_INDEX ]
76+ def mentor (self ) -> str :
77+ attachment = self .attachments [AttachmentIndex . MENTOR ]
6978 return self .selected_option (attachment )
7079
7180 @mentor .setter
72- def mentor (self , new_mentor ) :
73- action = self .attachments [MENTOR_INDEX ]['actions' ][0 ]
81+ def mentor (self , new_mentor : str ) -> None :
82+ action = self .attachments [AttachmentIndex . MENTOR ]['actions' ][0 ]
7483 action ['selected_options' ] = [{'value' : new_mentor , 'text' : new_mentor }]
7584 action ['color' ] = ''
7685
7786 @property
78- def certify_group (self ):
79- attachment = self .attachments [GROUP_INDEX ]
87+ def certify_group (self ) -> str :
88+ attachment = self .attachments [AttachmentIndex . GROUP ]
8089 return self .selected_option (attachment )
8190
8291 @certify_group .setter
83- def certify_group (self , group ) :
84- action = self .attachments [GROUP_INDEX ]['actions' ][0 ]
92+ def certify_group (self , group : str ) -> None :
93+ action = self .attachments [AttachmentIndex . GROUP ]['actions' ][0 ]
8594 action ['selected_options' ] = [{'value' : group , 'text' : group }]
86- self .attachments [GROUP_INDEX ]['color' ] = ''
95+ self .attachments [AttachmentIndex . GROUP ]['color' ] = ''
8796
8897 @property
8998 def details (self ):
90- attachment = self .attachments [DETAILS_INDEX ]
99+ attachment = self .attachments [AttachmentIndex . DETAILS ]
91100 if 'text' in attachment :
92101 return attachment ['text' ]
93102 return ''
94103
95104 @details .setter
96105 def details (self , new_details ):
97- self .attachments [DETAILS_INDEX ]['text' ] = new_details
106+ self .attachments [AttachmentIndex . DETAILS ]['text' ] = new_details
98107
99108 @property
100109 def update_params (self ):
101110 return {
102111 'channel' : self .channel ,
103- 'ts' : self ['ts' ] ,
112+ 'ts' : self ['original_message' ]. get ( 'ts' ) ,
104113 'attachments' : self .attachments
105114 }
106115
107116 def validate_self (self ):
108117 if not self .service or not self .certify_group :
109- submit_attachment = self .attachments [SUBMIT_INDEX ]
118+ submit_attachment = self .attachments [AttachmentIndex . SUBMIT ]
110119 submit_attachment ['text' ] = ':warning: Service and group certification are required. :warning:'
111120 submit_attachment ['color' ] = 'danger'
112121 if not self .service :
113- self .attachments [SERVICE_INDEX ]['color' ] = 'danger'
122+ self .attachments [AttachmentIndex . SERVICE ]['color' ] = 'danger'
114123 if not self .certify_group :
115- self .attachments [GROUP_INDEX ]['color' ] = 'danger'
124+ self .attachments [AttachmentIndex . GROUP ]['color' ] = 'danger'
116125 return False
117126 return True
118127
@@ -135,26 +144,26 @@ async def submit_request(self, username, email, airtable: AirtableAPI):
135144 return await airtable .add_record ('Mentor Request' , {'fields' : params })
136145
137146 def submission_error (self , airtable_response , slack : SlackAPI ):
138- self .attachments [SUBMIT_INDEX ]['text' ] = (
147+ self .attachments [AttachmentIndex . SUBMIT ]['text' ] = (
139148 f'Something went wrong.\n '
140149 f'Error Type:{ airtable_response ["error" ]["type" ]} \n '
141150 f'Error Message: { airtable_response ["error" ]["message" ]} '
142151 )
143- self .attachments [SUBMIT_INDEX ]['color' ] = 'danger'
144- return self .update (slack )
152+ self .attachments [AttachmentIndex . SUBMIT ]['color' ] = 'danger'
153+ return self .update_message (slack )
145154
146155 def submission_complete (self , slack : SlackAPI ):
147- done_attachment = self .attachments [SUBMIT_INDEX ]
156+ done_attachment = self .attachments [AttachmentIndex . SUBMIT ]
148157 done_attachment ['text' ] = 'Request submitted successfully!'
149158 done_attachment ['actions' ] = [{'type' : 'button' , 'text' : 'Dismiss' , 'name' : 'cancel' , 'value' : 'cancel' }]
150159
151- self ['attachments' ] = [done_attachment ]
152- return self .update (slack )
160+ self ['original_message' ][ ' attachments' ] = [done_attachment ]
161+ return self .update_message (slack )
153162
154163 def clear_skillsets (self ):
155- self .attachments [SKILLSET_INDEX ]['text' ] = ''
164+ self .attachments [AttachmentIndex . SKILLSET ]['text' ] = ''
156165
157- def update (self , slack : SlackAPI ):
166+ def update_message (self , slack : SlackAPI ):
158167 return slack .query (methods .CHAT_UPDATE , self .update_params )
159168
160169
@@ -173,29 +182,46 @@ def trigger(self) -> dict:
173182
174183 @property
175184 def click_type (self ) -> str :
185+ """
186+ Value of the button clicked.
187+ """
176188 return self .trigger ['value' ]
177189
178- def is_claim (self ):
190+ def is_claim (self ) -> bool :
191+ """
192+ Returns true if the Claim button was clicked
193+ """
179194 return self .click_type == 'mentee_claimed'
180195
181196 @property
182197 def record (self ) -> str :
183- """ Airtable record ID for the mentor request """
198+ """
199+ Airtable record ID for the mentor request
200+ """
184201 return self .trigger ['name' ]
185202
186203 @property
187- def clicker (self ):
204+ def clicker (self ) -> str :
205+ """
206+ The Slack User ID of the button clicker
207+ """
188208 return self ['user' ]['id' ]
189209
190210 @property
191- def attachment (self ):
211+ def attachment (self ) -> dict :
192212 return self ['original_message' ]['attachments' ][0 ]
193213
194214 @attachment .setter
195- def attachment (self , value ) :
215+ def attachment (self , value : dict ) -> None :
196216 self ['original_message' ]['attachments' ][0 ] = value
197217
198218 def claim_request (self , mentor_record ):
219+ """
220+ Updates the airtable entry with the given record.
221+
222+ If record couldn't be found this object's text field is changed
223+ to an error message to be displayed when update_message is called
224+ """
199225 if mentor_record :
200226 self .attachment = self .mentee_claimed_attachment ()
201227 else :
@@ -205,6 +231,10 @@ def claim_request(self, mentor_record):
205231 return self .update_airtable (mentor_record )
206232
207233 def unclaim_request (self ):
234+ """
235+ Changes the attachment to the un-claimed version and deletes the mentor from the
236+ Airtable record
237+ """
208238 self .attachment = self .mentee_unclaimed_attachment ()
209239 return self .update_airtable ('' )
210240
@@ -213,6 +243,9 @@ async def update_airtable(self, mentor_id: Optional[str]):
213243 return self .airtable .update_request (self .record , mentor_id )
214244
215245 async def update_message (self ):
246+ """
247+ Builds the slack API call to update the original message
248+ """
216249 response = {
217250 'channel' : self ['channel' ]['id' ],
218251 'ts' : self ['message_ts' ],
0 commit comments