integrations.slack.events.home_tab.personal
integrations/slack/events/home_tab/personal.py
1""" 2integrations/slack/events/home_tab/personal.py 3""" 4 5import logging 6from typing import TYPE_CHECKING, Any, cast 7 8import libs.global_value as g 9from integrations.slack.adapter import ServiceAdapter 10from integrations.slack.events.handler_registry import register 11from integrations.slack.events.home_tab import ui_parts 12from libs.commands.results import detail 13from libs.types import CommandType 14from libs.utils import dictutil 15from libs.utils.timekit import Delimiter, Format 16from libs.utils.timekit import ExtendedDatetime as ExtDt 17 18if TYPE_CHECKING: 19 from slack_bolt import App 20 from slack_sdk.models.views import View 21 22 from integrations.protocols import MessageParserProtocol 23 24 25def build_personal_menu(adapter: ServiceAdapter) -> "View": 26 """ 27 個人成績メニュー作成 28 29 Args: 30 adapter (ServiceAdapter): インターフェースアダプタ 31 32 """ 33 adapter.conf.tab_var["screen"] = "PersonalMenu" 34 adapter.conf.tab_var["no"] = 0 35 adapter.conf.tab_var["view"] = {"type": "home", "blocks": []} 36 adapter.conf.tab_var.setdefault("sday", ExtDt().format(Format.YMD, Delimiter.HYPHEN)) 37 adapter.conf.tab_var.setdefault("eday", ExtDt().format(Format.YMD, Delimiter.HYPHEN)) 38 ui_parts.header(adapter, text="【個人成績】") 39 40 # プレイヤー選択リスト 41 ui_parts.user_select_pulldown(adapter, text="対象プレイヤー") 42 43 # 検索範囲設定 44 date_dict = {x: ExtDt(hours=-g.cfg.setting.time_adjust).range(x).dict_format(Format.YMD, Delimiter.HYPHEN) for x in ["今月", "先月", "全部"]} 45 ui_parts.divider(adapter) 46 ui_parts.radio_buttons( 47 adapter=adapter, 48 id_suffix="search_range", 49 title="検索範囲", 50 flag={ 51 "今月": f"今月:{date_dict['今月']['start']} ~ {date_dict['今月']['end']}", 52 "先月": f"先月:{date_dict['先月']['start']} ~ {date_dict['先月']['end']}", 53 "全部": f"全部:{date_dict['全部']['start']} ~ {date_dict['全部']['end']}", 54 "指定": f"範囲指定:{adapter.conf.tab_var['sday']} ~ {adapter.conf.tab_var['eday']}", 55 }, 56 ) 57 ui_parts.button(adapter, text="検索範囲設定", action_id="modal-open-period") 58 59 # オプション 60 ui_parts.divider(adapter) 61 ui_parts.checkboxes( 62 adapter=adapter, 63 id_suffix="search_option", 64 title="検索オプション", 65 flag={ 66 "unregistered_replace": "ゲスト無効", 67 }, 68 initial=["unregistered_replace"], 69 ) 70 ui_parts.checkboxes( 71 adapter=adapter, 72 id_suffix="display_option", 73 title="表示オプション", 74 flag={ 75 "versus_matrix": "対戦結果", 76 "game_results": "戦績(簡易)", 77 "verbose": "戦績(詳細)", 78 }, 79 ) 80 81 ui_parts.divider(adapter) 82 ui_parts.button(adapter, text="集計", action_id="personal_aggregation", style="primary") 83 ui_parts.button(adapter, text="戻る", action_id="actionId-back", style="danger") 84 85 return cast("View", adapter.conf.tab_var) 86 87 88@register 89def register_personal_handlers(app: "App", adapter: ServiceAdapter) -> None: 90 """個人成績メニュー""" 91 92 @app.action("personal_menu") 93 def handle_menu_action(ack: Any, body: Any) -> None: 94 """ 95 メニュー項目生成 96 97 Args: 98 ack (Any): ack 99 body (Any): イベント内容 100 101 """ 102 ack() 103 logging.trace(body) # type: ignore 104 105 adapter.conf.tab_var["user_id"] = body["user"]["id"] 106 adapter.conf.tab_var["view_id"] = body["view"]["id"] 107 logging.debug("[personal_menu] %s", adapter.conf.tab_var) 108 109 build_personal_menu(adapter) 110 adapter.api.appclient.views_publish( 111 user_id=adapter.conf.tab_var["user_id"], 112 view=adapter.conf.tab_var["view"], 113 ) 114 115 @app.action("personal_aggregation") 116 def handle_aggregation_action(ack: Any, body: Any) -> None: 117 """ 118 メニュー項目生成 119 120 Args: 121 ack (Any): ack 122 body (Any): イベント内容 123 124 """ 125 ack() 126 logging.trace(body) # type: ignore 127 128 m = cast("MessageParserProtocol", adapter.parser()) 129 130 m.parser(body) 131 add_argument, app_msg, update_flag = ui_parts.set_command_option(adapter, body) 132 m.data.text = f"dummy {' '.join(add_argument)}" 133 g.params = dictutil.placeholder(g.cfg.results, m) 134 g.params.update_from_dict(update_flag) 135 136 search_options = body["view"]["state"]["values"] 137 if "bid-user_select" in search_options: 138 user_select = search_options["bid-user_select"]["player"]["selected_option"] 139 if user_select is None: 140 return 141 142 adapter.api.appclient.views_update(view_id=adapter.conf.tab_var["view_id"], view=ui_parts.plain_text(f"{chr(10).join(app_msg)}")) 143 144 app_msg.pop() 145 app_msg.append("集計完了") 146 147 m.status.command_type = CommandType.RESULTS 148 detail.aggregation(m) 149 adapter.api.post(m) 150 151 ui_parts.update_view(adapter, m, app_msg) 152 153 @app.view("PersonalMenu_ModalPeriodSelection") 154 def handle_view_submission(ack: Any, view: Any) -> None: 155 """ 156 view更新 157 158 Args: 159 ack (Any): ack 160 view (Any): 描写内容 161 162 """ 163 ack() 164 165 for i in view["state"]["values"].keys(): 166 if "aid-sday" in view["state"]["values"][i]: 167 adapter.conf.tab_var["sday"] = view["state"]["values"][i]["aid-sday"]["selected_date"] 168 if "aid-eday" in view["state"]["values"][i]: 169 adapter.conf.tab_var["eday"] = view["state"]["values"][i]["aid-eday"]["selected_date"] 170 171 logging.debug("[global var] %s", adapter.conf.tab_var) 172 173 adapter.api.appclient.views_update( 174 view_id=adapter.conf.tab_var["view_id"], 175 view=build_personal_menu(adapter), 176 )
register_personal_handlers =
None
個人成績メニュー