integrations.slack.events.home_tab.summary
integrations/slack/events/home_tab/summary.py
1""" 2integrations/slack/events/home_tab/summary.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.graph import summary as graph_summary 13from libs.commands.ranking import rating 14from libs.commands.results import summary as results_summary 15from libs.types import CommandType 16from libs.utils import dictutil 17from libs.utils.timekit import Delimiter, Format 18from libs.utils.timekit import ExtendedDatetime as ExtDt 19 20if TYPE_CHECKING: 21 from slack_bolt import App 22 from slack_sdk.models.views import View 23 24 from integrations.protocols import MessageParserProtocol 25 26 27def build_summary_menu(adapter: ServiceAdapter) -> "View": 28 """サマリメニュー生成""" 29 adapter.conf.tab_var["screen"] = "SummaryMenu" 30 adapter.conf.tab_var["no"] = 0 31 adapter.conf.tab_var["view"] = {"type": "home", "blocks": []} 32 adapter.conf.tab_var.setdefault("sday", ExtDt().format(Format.YMD, Delimiter.HYPHEN)) 33 adapter.conf.tab_var.setdefault("eday", ExtDt().format(Format.YMD, Delimiter.HYPHEN)) 34 ui_parts.header(adapter, text="【成績サマリ】") 35 36 # 検索範囲設定 37 date_dict = {x: ExtDt(hours=-g.cfg.setting.time_adjust).range(x).dict_format(Format.YMD, Delimiter.HYPHEN) for x in ["今月", "先月", "全部"]} 38 ui_parts.divider(adapter) 39 ui_parts.radio_buttons( 40 adapter=adapter, 41 id_suffix="search_range", 42 title="検索範囲", 43 flag={ 44 "今月": f"今月:{date_dict['今月']['start']} ~ {date_dict['今月']['end']}", 45 "先月": f"先月:{date_dict['先月']['start']} ~ {date_dict['先月']['end']}", 46 "全部": f"全部:{date_dict['全部']['start']} ~ {date_dict['全部']['end']}", 47 "指定": f"範囲指定:{adapter.conf.tab_var['sday']} ~ {adapter.conf.tab_var['eday']}", 48 }, 49 ) 50 ui_parts.button(adapter, text="検索範囲設定", action_id="modal-open-period") 51 52 # オプション 53 ui_parts.divider(adapter) 54 ui_parts.checkboxes( 55 adapter=adapter, 56 id_suffix="search_option", 57 title="検索オプション", 58 flag={ 59 "unregistered_replace": "ゲスト無効", 60 }, 61 initial=["unregistered_replace"], 62 ) 63 ui_parts.radio_buttons( 64 adapter=adapter, 65 id_suffix="output_option", 66 title="出力オプション", 67 flag={ 68 "normal": "通算ポイント", 69 "score_comparisons": "通算ポイント比較", 70 "point": "ポイント推移グラフ", 71 "rank": "順位変動グラフ", 72 "rating": "レーティング", 73 }, 74 ) 75 76 ui_parts.divider(adapter) 77 ui_parts.button(adapter, text="集計", action_id="summary_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_summary_handlers(app: "App", adapter: ServiceAdapter) -> None: 85 """サマリメニュー""" 86 87 @app.action("summary_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("[summary_menu] %s", adapter.conf.tab_var) 103 104 build_summary_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("summary_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 adapter.api.appclient.views_update( 132 view_id=adapter.conf.tab_var["view_id"], 133 view=ui_parts.plain_text(f"{chr(10).join(app_msg)}"), 134 ) 135 136 app_msg.pop() 137 app_msg.append("集計完了") 138 139 match adapter.conf.tab_var.get("operation"): 140 case "point": 141 m.status.command_type = CommandType.GRAPH 142 graph_summary.point_plot(m) 143 adapter.api.post(m) 144 case "rank": 145 m.status.command_type = CommandType.GRAPH 146 graph_summary.rank_plot(m) 147 adapter.api.post(m) 148 case "rating": 149 m.status.command_type = CommandType.RATING 150 g.params.command = "ranking" 151 rating.aggregation(m) 152 adapter.api.post(m) 153 case _: 154 if g.params.score_comparisons: 155 m.status.command_type = CommandType.COMPARISON 156 results_summary.difference(m) 157 else: 158 m.status.command_type = CommandType.RESULTS 159 results_summary.aggregation(m) 160 adapter.api.post(m) 161 162 ui_parts.update_view(adapter, m, app_msg) 163 164 @app.view("SummaryMenu_ModalPeriodSelection") 165 def handle_view_submission(ack: Any, view: Any) -> None: 166 """ 167 view更新 168 169 Args: 170 ack (Any): ack 171 view (Any): 描写内容 172 173 """ 174 ack() 175 176 for i in view["state"]["values"].keys(): 177 if "aid-sday" in view["state"]["values"][i]: 178 adapter.conf.tab_var["sday"] = view["state"]["values"][i]["aid-sday"]["selected_date"] 179 if "aid-eday" in view["state"]["values"][i]: 180 adapter.conf.tab_var["eday"] = view["state"]["values"][i]["aid-eday"]["selected_date"] 181 182 logging.debug("[global var] %s", adapter.conf.tab_var) 183 184 adapter.api.appclient.views_update( 185 view_id=adapter.conf.tab_var["view_id"], 186 view=build_summary_menu(adapter), 187 )
register_summary_handlers =
None
サマリメニュー