integrations.slack.events.home_tab.versus

integrations/slack/events/home_tab/versus.py

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

対戦結果メニュー生成

register_versus_handlers = None

直接対戦メニュー