class GenericPayloadSchema(OneOfSchema): type_field = 'callback_id' type_schemas = { get_full_class_name(TimeReportingFormPayload): TimeReportingFormPayload.Schema, get_full_class_name(ReportGenerateFormPayload): ReportGenerateFormPayload.Schema, get_full_class_name(ListCommandPayload): ListCommandPayload.Schema, get_full_class_name(DeleteTimeEntryPayload): DeleteTimeEntryPayload.Schema, get_full_class_name(FoodOrderFormPayload): FoodOrderFormPayload.Schema, get_full_class_name(FoodOrderPayload): FoodOrderPayload.Schema, get_full_class_name(RemindTimeReportBtnPayload): RemindTimeReportBtnPayload.Schema, get_full_class_name(RequestFreeDaysPayload): RequestFreeDaysPayload.Schema, get_full_class_name(ProjectAddPayload): ProjectAddPayload.Schema } def get_obj_type(self, obj): return get_full_class_name(obj)
def create_project_selected_message(last_time_entries, selected_project) -> Message: actions = [ Action( name="time_entries_list", text="Select time entry", type=ActionType.SELECT.value, options=[TextSelectOption(text=string_helper.make_option_time_string(te), value=te.time_entry_id) for te in last_time_entries], confirm=Confirmation(title="Delete confirmation", text="Click 'Remove' to confirm", ok_text="Remove", dismiss_text="Cancel") ), ] attachments = [ Attachment( text="Select time entry to remove", fallback="Select time entry", color="#3AA3E3", attachment_type="default", callback_id=string_helper.get_full_class_name(DeleteTimeEntryPayload), actions=actions ) ] return Message( text="There are the last time entries for *" + selected_project.name + "*:", response_type="ephemeral", mrkdwn=True, attachments=attachments )
def create_dialog(self, command_body, argument, action) -> Dialog: slack_user_id = command_body['user_id'] report_date = self.current_date().strftime("%Y-%m-%d") if ( isinstance(action, str) or action is None) else action.value slack_user_details = self.get_user_by_slack_user_id(slack_user_id) project_options_list: List[ LabelSelectOption] = self.get_projects_option_list_as_label( slack_user_details.user_id) user_default_project_id: str = self.get_default_project_id( project_options_list[0].value, slack_user_details) elements = [ Element("Project", "select", "project", "Select a project", user_default_project_id, None, None, project_options_list), Element("Day", "text", "day", "Specify date", report_date), Element("Duration hours", "select", "hours", None, "8", None, None, SubmitTimeCommandHandler.get_duration_hours()), Element("Duration minutes", "select", "minutes", None, "0", None, None, SubmitTimeCommandHandler.get_duration_minutes()), Element("Note", "textarea", "comment", None, None, None, "Provide short description") ] return Dialog( "Submitting time", "Submit", string_helper.get_full_class_name(TimeReportingFormPayload), elements)
def create_select_period_for_listing_model(self, command_body, inner_user_id): actions = [ Action(name=inner_user_id if inner_user_id is not None else command_body['user_id'], text="Select time range...", type=ActionType.SELECT.value, options=[ TextSelectOption(text=tr.value, value=tr.value) for tr in TimeRanges ]) ] attachments = [ Attachment(text="Show record for", fallback="Select time range to list saved time records", color="#3AA3E3", attachment_type="default", callback_id=string_helper.get_full_class_name( ListCommandPayload), actions=actions) ] return Message(text="I'm going to list saved time records...", response_type="ephemeral", mrkdwn=True, attachments=attachments)
def get_friday_slack_message(config, remind_dates): actions = [] for (date) in remind_dates: actions.append( { "name": "report", "text": date.strftime("%A, %d %B"), "style": "success", "type": "button", "value": date.strftime("%Y-%m-%d"), }) return "It looks like you didn't report work time for `This week`", [ { "text": "Click appropriate buttons or use */ni* command:", "color": "#3AA3E3", "attachment_type": "default", "callback_id": get_full_class_name(RemindTimeReportBtnPayload), "actions": actions, "mrkdwn_in": ["text"] }, { "text": "", "footer": config['MESSAGE_REMINDER_RUN_TIP'], "mrkdwn_in": ["footer"] }, ]
def create_dialog(self, command_body, argument, action) -> Dialog: slack_user_id = command_body['user_id'] report_date = self.current_date().strftime("%Y-%m-%d") if(isinstance(action, str) or action is None) else action.value slack_user_details = self.get_user_by_slack_user_id( slack_user_id) project_options_list: List[LabelSelectOption] = self.get_projects_option_list_as_label( slack_user_details.user_id) user_default_project_id: str = self.get_default_project_id( project_options_list[0].value, slack_user_details) elements = [ Element("Project", "select", "project", "Select a project", user_default_project_id, None, None, project_options_list), Element("Day", "text", "day", "Specify date", report_date), Element("Duration hours", "select", "hours", None, "8", None, None, SubmitTimeCommandHandler.get_duration_hours()), Element("Duration minutes", "select", "minutes", None, "0", None, None, SubmitTimeCommandHandler.get_duration_minutes()), Element("Note", "textarea", "comment", None, None, None, "Provide short description") ] return Dialog("Submitting time", "Submit", string_helper.get_full_class_name(TimeReportingFormPayload), elements)
def get_everyday_slack_message(config, remind_date): return "It looks like you didn't report work time for `{0}`".format(remind_date.strftime("%A, %d %B")), [ { "text": "Click 'Report' or use */ni* command:", "color": "#3AA3E3", "attachment_type": "default", "callback_id": get_full_class_name(RemindTimeReportBtnPayload), "actions": [ { "name": "report", "text": "Report", "style": "success", "type": "button", 'value': remind_date.strftime("%Y-%m-%d"), } ], "mrkdwn_in": ["text"] }, { "text": "", "footer": config['MESSAGE_REMINDER_RUN_TIP'], "mrkdwn_in": ["footer"] }, ]
def create_select_project_message(user_default_project_id, project_options_list): actions = [ Action( name="projects_list", text="Select project...", type=ActionType.SELECT.value, value=user_default_project_id, options=project_options_list ), ] attachments = [ Attachment( text="Select project first", fallback="Select project", color="#3AA3E3", attachment_type="default", callback_id=string_helper.get_full_class_name(DeleteTimeEntryPayload), actions=actions ) ] return Message( text="I'm going to remove time entry :wastebasket:...", response_type="ephemeral", attachments=attachments )
def create_project_selected_message(last_time_entries, selected_project) -> Message: actions = [ Action(name="time_entries_list", text="Select time entry", type=ActionType.SELECT.value, options=[ TextSelectOption( text=string_helper.make_option_time_string(te), value=te.time_entry_id) for te in last_time_entries ], confirm=Confirmation(title="Delete confirmation", text="Click 'Remove' to confirm", ok_text="Remove", dismiss_text="Cancel")), ] attachments = [ Attachment(text="Select time entry to remove", fallback="Select time entry", color="#3AA3E3", attachment_type="default", callback_id=string_helper.get_full_class_name( DeleteTimeEntryPayload), actions=actions) ] return Message(text="There are the last time entries for *" + selected_project.name + "*:", response_type="ephemeral", mrkdwn=True, attachments=attachments)
def get_everyday_slack_message(config, remind_date): return "It looks like you didn't report work time for `{0}`".format( remind_date.strftime("%A, %d %B")), [ { "text": "Click 'Report' or use */ni* command:", "color": "#3AA3E3", "attachment_type": "default", "callback_id": get_full_class_name(RemindTimeReportBtnPayload), "actions": [{ "name": "report", "text": "Report", "style": "success", "type": "button", 'value': remind_date.strftime("%Y-%m-%d"), }], "mrkdwn_in": ["text"] }, { "text": "", "footer": config['MESSAGE_REMINDER_RUN_TIP'], "mrkdwn_in": ["footer"] }, ]
def prepare_debts_list(self, debts): attachments = [] for debt in debts: user = self.user_service.get_user_by_id(debt.user_id) phone_text = "\nPay with BLIK using phone number: *" + user.phone + "*" if user.phone else '' actions = [] debt_text = "You owe " + str( debt.debt) + " PLN for " + get_user_name(user) + phone_text if debt.debt < 0: actions.append( Action(name="debt-pay", text="I just paid " + str(-debt.debt) + " PLN", type="button", value="pay-" + str(debt.user_id))) debt_text = "You owe " + str( -debt.debt) + " PLN for " + get_user_name( user) + phone_text elif debt.debt > 0: debt_text = get_user_name(user) + " owes you " + str( debt.debt) + " PLN" attachments.append( Attachment(callback_id=string_helper.get_full_class_name( FoodOrderPayload), attachment_type="default", text=debt_text, color="#3AA3E3", actions=actions).dump()) return attachments
def create_select_period_for_listing_model(self, command_body, inner_user_id): actions = [ Action( name=inner_user_id if inner_user_id is not None else command_body['user_id'], text="Select time range...", type=ActionType.SELECT.value, options=[TextSelectOption( text=tr.value, value=tr.value) for tr in TimeRanges] ) ] attachments = [ Attachment( text="Show record for", fallback="Select time range to list saved time records", color="#3AA3E3", attachment_type="default", callback_id=string_helper.get_full_class_name( ListCommandPayload), actions=actions ) ] return Message( text="I'm going to list saved time records...", response_type="ephemeral", mrkdwn=True, attachments=attachments )
def order_start(self, command_body, arguments: list, action): if len(arguments) == 0: return "Use format: */ni food _URL_*" ordering_link = arguments[0] user = self.get_user_by_slack_user_id(command_body['user_id']) self.food_order_service.remove_incomplete_food_order_items( datetime.today(), command_body['channel_name']) post_at: int = round( (datetime.now() + CHECKOUT_REMINDER_IN).timestamp()) reminder_response = self.slack_client.api_call( "chat.scheduleMessage", channel=command_body['channel_name'], user=user.slack_user_id, post_at=post_at, text= "@{} Looks like you forgot to order from {}.\nUrge your friends to place an order and call */ni order*" .format(command_body['user_name'], ordering_link), link_names=True) if not reminder_response["ok"]: self.logger.error(reminder_response) raise RuntimeError('failed') scheduled_message_id = reminder_response['scheduled_message_id'] order = self.food_order_service.create_food_order( user, datetime.today(), ordering_link, scheduled_message_id, command_body['channel_name']) self.logger.info("Created order %d for user %s with reminder %s", order.food_order_id, command_body['user_name'], scheduled_message_id) order_prompt_response = self.slack_client.api_call( "chat.postMessage", channel=command_body['channel_name'], mrkdwn=True, as_user=True, attachments=[ Attachment( callback_id=string_helper.get_full_class_name( FoodOrderPayload), attachment_type="default", text=get_user_name(user) + " orders from " + ordering_link, color="#3AA3E3", actions=[ Action(name="order-prompt", text="I'm ordering right now", type="button", value="order-" + str(order.food_order_id)), Action(name="order-prompt", text="Not today", type="button", value="pas-" + str(order.food_order_id)), ]).dump() ]) if not order_prompt_response["ok"]: self.logger.error(order_prompt_response) raise RuntimeError('failed') return None
def create_select_project_message(action_name, user_default_project_id, project_options_list): actions = [ Action( name=str(action_name), text="Select project...", type=ActionType.SELECT.value, value=user_default_project_id, options=project_options_list ), ] attachments = [ Attachment( text="Select project first", fallback="Select project", color="#3AA3E3", attachment_type="default", callback_id=string_helper.get_full_class_name(ProjectAddPayload), actions=actions ) ] return Message( text="I'm going to (un)assign user to the project...", response_type="ephemeral", attachments=attachments )
def get_friday_slack_message(config, remind_dates): actions = [] for (date) in remind_dates: actions.append({ "name": "report", "text": date.strftime("%A, %d %B"), "style": "success", "type": "button", "value": date.strftime("%Y-%m-%d"), }) return "It looks like you didn't report work time for `This week`", [ { "text": "Click appropriate buttons or use */ni* command:", "color": "#3AA3E3", "attachment_type": "default", "callback_id": get_full_class_name(RemindTimeReportBtnPayload), "actions": actions, "mrkdwn_in": ["text"] }, { "text": "", "footer": config['MESSAGE_REMINDER_RUN_TIP'], "mrkdwn_in": ["footer"] }, ]
def create_dialog(self, command_body, argument, action): elements: Element = [ Element(label="Project name", type="text", name='project_name', placeholder="Specify project name") ] return Dialog(title="Create new project", submit_label="Create", callback_id=string_helper.get_full_class_name(ProjectAddPayload), elements=elements)
def create_dialog(self, command_body, argument, action) -> Dialog: tomorrow_date = datetime.now().date() + timedelta(days=1) elements = [ Element("Start day", "text", "start_date", "specify date", tomorrow_date), Element("End day", "text", "end_date", "specify date", tomorrow_date) ] return Dialog("Submit free days", "Submit", string_helper.get_full_class_name(RequestFreeDaysPayload), elements)
def create_dialog(self, command_body, argument, action) -> Dialog: tomorrow_date = datetime.now().date() + timedelta(days=1) elements = [ Element("Start day", "text", "start_date", "specify date", tomorrow_date), Element("End day", "text", "end_date", "specify date", tomorrow_date) ] return Dialog( "Submit free days", "Submit", string_helper.get_full_class_name(RequestFreeDaysPayload), elements)
def create_dialog(self, command_body, argument, action): elements: Element = [ Element(label="Project name", type="text", name='project_name', placeholder="Specify project name") ] return Dialog( title="Create new project", submit_label="Create", callback_id=string_helper.get_full_class_name(ProjectAddPayload), elements=elements)
def create_order_dialog(self): elements = [ Element(label="Order", type="text", name='ordered_item', placeholder="What do you order?"), Element(label="Price", type="text", name='ordered_item_price', placeholder="Price", value='0.00'), ] dialog: Dialog = Dialog(title="Place an order", submit_label="Order", callback_id=string_helper.get_full_class_name( FoodOrderFormPayload), elements=elements) return dialog
def create_vacation_selected_message(vacation_id): actions = [ Action(name="remove", text="Remove", style="danger", type=ActionType.BUTTON.value, value=str(vacation_id)), Action(name="cancel", text="Cancel", type=ActionType.BUTTON.value, value="remove") ] attachments = [ Attachment( text="Click 'Remove' to confirm:", color="#3AA3E3", attachment_type="default", callback_id=string_helper.get_full_class_name(RequestFreeDaysPayload), actions=actions) ] return Message( text="Vacation will be removed...", response_type="ephemeral", mrkdwn=True, attachments=attachments )
def create_select_user_message(action_name, subaction_name, user_options_list): actions = [ Action(name=action_name + ":" + subaction_name, text="Select user...", type=ActionType.SELECT.value, options=user_options_list), ] attachments = [ Attachment(text="Select user for " + action_name + "...", fallback="Select user", color="#3AA3E3", attachment_type="default", callback_id=string_helper.get_full_class_name( ProjectAddPayload), actions=actions) ] return Message(text="", response_type="ephemeral", attachments=attachments)
def create_select_project_message(action_name, user_default_project_id, project_options_list): actions = [ Action(name=str(action_name), text="Select project...", type=ActionType.SELECT.value, value=user_default_project_id, options=project_options_list), ] attachments = [ Attachment(text="Select project first", fallback="Select project", color="#3AA3E3", attachment_type="default", callback_id=string_helper.get_full_class_name( ProjectAddPayload), actions=actions) ] return Message(text="I'm going to (un)assign user to the project...", response_type="ephemeral", attachments=attachments)
def create_select_project_message(user_default_project_id, project_options_list): actions = [ Action(name="projects_list", text="Select project...", type=ActionType.SELECT.value, value=user_default_project_id, options=project_options_list), ] attachments = [ Attachment(text="Select project first", fallback="Select project", color="#3AA3E3", attachment_type="default", callback_id=string_helper.get_full_class_name( DeleteTimeEntryPayload), actions=actions) ] return Message(text="I'm going to remove time entry :wastebasket:...", response_type="ephemeral", attachments=attachments)
def create_dialog(self, command_body, argument, action) -> Dialog: selected_period = None if action and len(action.selected_options): selected_period = next(iter(action.selected_options), None).value start_end = get_start_end_date(selected_period) # todo cache it globally e.g. Flask-Cache projects = self.project_service.get_projects() project_options_list: List[LabelSelectOption] = [LabelSelectOption(label=p.name, value=p.project_id) for p in projects] # admin see users list user = self.get_user_by_slack_user_id(action.name) elements: Element = [ Element(label="Date from", type="text", name='day_from', placeholder="Specify date", value=start_end[0]), Element(label="Date to", type="text", name='day_to', placeholder="Specify date", value=start_end[1]), Element(label="Project", type="select", name='project', optional='true', placeholder="Select a project", options=project_options_list) ] dialog: Dialog = Dialog(title="Generate report", submit_label="Generate", callback_id=string_helper.get_full_class_name(ReportGenerateFormPayload), elements=elements) if action.name: prompted_user = self.get_user_by_slack_user_id(action.name) if user.role.role == 'admin': users = self.user_service.get_users() user_options_list = [LabelSelectOption(label=string_helper.get_user_name(p), value=p.user_id) for p in users] dialog.elements.append( Element(label="User", value=(prompted_user.user_id if prompted_user else None), optional='true', type="select", name='user', placeholder="Select user", options=user_options_list)) return dialog
def select_vacation_to_remove(self, command_body, argument, action): user = self.get_user_by_slack_user_id(command_body['user_id']) user_vacations: List[Vacation] = self.vacation_service.get_ten_newest_user_vacations(user.user_id) if not user_vacations: return Message( text="There is nothing to delete... ", response_type="ephemeral", mrkdwn=True ).dump() actions = [ Action( name="vacation_list", text="Select vacation to delete", type=ActionType.SELECT.value, options=[TextSelectOption(text=string_helper.make_option_vacations_string(vac), value=vac.vacation_id) for vac in user_vacations] ), ] attachments = [ Attachment( text="Select vacation to delete", fallback="Select vacation to delete", color="#3AA3E3", attachment_type="default", callback_id=string_helper.get_full_class_name(RequestFreeDaysPayload), actions=actions ) ] return Message( text="I'm going to remove some vacations :wastebasket:...", response_type="ephemeral", mrkdwn=True, attachments=attachments ).dump()
def select_vacation_to_remove(self, command_body, argument, action): user = self.get_user_by_slack_user_id(command_body['user_id']) user_vacations: List[ Vacation] = self.vacation_service.get_ten_newest_user_vacations( user.user_id) if not user_vacations: return Message(text="There is nothing to delete... ", response_type="ephemeral", mrkdwn=True).dump() actions = [ Action( name="vacation_list", text="Select vacation to delete", type=ActionType.SELECT.value, options=[ TextSelectOption( text=string_helper.make_option_vacations_string(vac), value=vac.vacation_id) for vac in user_vacations ]), ] attachments = [ Attachment(text="Select vacation to delete", fallback="Select vacation to delete", color="#3AA3E3", attachment_type="default", callback_id=string_helper.get_full_class_name( RequestFreeDaysPayload), actions=actions) ] return Message( text="I'm going to remove some vacations :wastebasket:...", response_type="ephemeral", mrkdwn=True, attachments=attachments).dump()
def report_pre_dialog(self, command_body, arguments, action): message_text = "I'm going to generate report..." inner_user_id = None if len(arguments): user = arguments[0] inner_user_id = self.extract_slack_user_id(user) self.get_user_by_slack_user_id(inner_user_id) actions = [ Action( name=inner_user_id if inner_user_id is not None else command_body['user_id'], text="Select time range...", type=ActionType.SELECT.value, options=[TextSelectOption(text=tr.value, value=tr.value) for tr in TimeRanges] ) ] attachments = [ Attachment( text="Generate report for", fallback="Select time range to report", color="#3AA3E3", attachment_type="default", callback_id=string_helper.get_full_class_name(ReportGenerateFormPayload), actions=actions ) ] return Message( text=message_text, response_type="ephemeral", mrkdwn=True, attachments=attachments ).dump()
def create_select_user_message(action_name, subaction_name, user_options_list): actions = [ Action( name=action_name + ":" + subaction_name, text="Select user...", type=ActionType.SELECT.value, options=user_options_list ), ] attachments = [ Attachment( text="Select user for " + action_name + "...", fallback="Select user", color="#3AA3E3", attachment_type="default", callback_id=string_helper.get_full_class_name(ProjectAddPayload), actions=actions ) ] return Message( text="", response_type="ephemeral", attachments=attachments )
def report_pre_dialog(self, command_body, arguments, action): message_text = "I'm going to generate report..." inner_user_id = None if len(arguments): user = arguments[0] inner_user_id = self.extract_slack_user_id(user) self.get_user_by_slack_user_id(inner_user_id) actions = [ Action(name=inner_user_id if inner_user_id is not None else command_body['user_id'], text="Select time range...", type=ActionType.SELECT.value, options=[ TextSelectOption(text=tr.value, value=tr.value) for tr in TimeRanges ]) ] attachments = [ Attachment(text="Generate report for", fallback="Select time range to report", color="#3AA3E3", attachment_type="default", callback_id=string_helper.get_full_class_name( ReportGenerateFormPayload), actions=actions) ] return Message(text=message_text, response_type="ephemeral", mrkdwn=True, attachments=attachments).dump()
def create_vacation_selected_message(vacation_id): actions = [ Action(name="remove", text="Remove", style="danger", type=ActionType.BUTTON.value, value=str(vacation_id)), Action(name="cancel", text="Cancel", type=ActionType.BUTTON.value, value="remove") ] attachments = [ Attachment(text="Click 'Remove' to confirm:", color="#3AA3E3", attachment_type="default", callback_id=string_helper.get_full_class_name( RequestFreeDaysPayload), actions=actions) ] return Message(text="Vacation will be removed...", response_type="ephemeral", mrkdwn=True, attachments=attachments)
def get_obj_type(self, obj): return get_full_class_name(obj)
def create_dialog(self, command_body, argument, action) -> Dialog: selected_period = None if action and len(action.selected_options): selected_period = next(iter(action.selected_options), None).value start_end = get_start_end_date(selected_period) # todo cache it globally e.g. Flask-Cache projects = self.project_service.get_projects() project_options_list: List[LabelSelectOption] = [ LabelSelectOption(label=p.name, value=p.project_id) for p in projects ] # admin see users list user = self.get_user_by_slack_user_id(action.name) elements: Element = [ Element(label="Date from", type="text", name='day_from', placeholder="Specify date", value=start_end[0]), Element(label="Date to", type="text", name='day_to', placeholder="Specify date", value=start_end[1]), Element(label="Project", type="select", name='project', optional='true', placeholder="Select a project", options=project_options_list) ] dialog: Dialog = Dialog(title="Generate report", submit_label="Generate", callback_id=string_helper.get_full_class_name( ReportGenerateFormPayload), elements=elements) if action.name: prompted_user = self.get_user_by_slack_user_id(action.name) if user.role.role == 'admin': users = self.user_service.get_users() user_options_list = [ LabelSelectOption(label=string_helper.get_user_name(p), value=p.user_id) for p in users ] dialog.elements.append( Element( label="User", value=(prompted_user.user_id if prompted_user else None), optional='true', type="select", name='user', placeholder="Select user", options=user_options_list)) return dialog