integrations.slack.events.home_tab.ranking
integrations/slack/events/home_tab/ranking.py
1""" 2integrations/slack/events/home_tab/ranking.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.ranking import ranking 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_ranking_menu(adapter: ServiceAdapter) -> "View": 26 """ 27 ランキングメニュー生成 28 29 Args: 30 adapter (ServiceAdapter): インターフェースアダプタ 31 32 """ 33 adapter.conf.tab_var["screen"] = "RankingMenu" 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 date_dict = {x: ExtDt(hours=-g.cfg.setting.time_adjust).range(x).dict_format(Format.YMD, Delimiter.HYPHEN) for x in ["今月", "先月", "全部"]} 42 ui_parts.divider(adapter) 43 ui_parts.radio_buttons( 44 adapter=adapter, 45 id_suffix="search_range", 46 title="検索範囲", 47 flag={ 48 "今月": f"今月:{date_dict['今月']['start']} ~ {date_dict['今月']['end']}", 49 "先月": f"先月:{date_dict['先月']['start']} ~ {date_dict['先月']['end']}", 50 "全部": f"全部:{date_dict['全部']['start']} ~ {date_dict['全部']['end']}", 51 "指定": f"範囲指定:{adapter.conf.tab_var['sday']} ~ {adapter.conf.tab_var['eday']}", 52 }, 53 ) 54 ui_parts.button(adapter, text="検索範囲設定", action_id="modal-open-period") 55 56 # 検索オプション 57 ui_parts.divider(adapter) 58 ui_parts.checkboxes( 59 adapter=adapter, 60 id_suffix="search_option", 61 title="検索オプション", 62 flag={ 63 "unregistered_replace": "ゲスト無効", 64 }, 65 initial=["unregistered_replace"], 66 ) 67 68 ui_parts.input_ranked(adapter, block_id="bid-ranked") 69 70 ui_parts.divider(adapter) 71 ui_parts.button(adapter, text="集計", action_id="ranking_aggregation", style="primary") 72 ui_parts.button(adapter, text="戻る", action_id="actionId-back", style="danger") 73 74 return cast("View", adapter.conf.tab_var) 75 76 77@register 78def register_ranking_handlers(app: "App", adapter: ServiceAdapter) -> None: 79 """ランキングメニュー""" 80 81 @app.action("ranking_menu") 82 def handle_menu_action(ack: Any, body: Any) -> None: 83 """ 84 メニュー項目生成 85 86 Args: 87 ack (Any): ack 88 body (Any): イベント内容 89 90 """ 91 ack() 92 logging.trace(body) # type: ignore 93 94 adapter.conf.tab_var["user_id"] = body["user"]["id"] 95 adapter.conf.tab_var["view_id"] = body["view"]["id"] 96 logging.debug("[ranking_menu] %s", adapter.conf.tab_var) 97 98 build_ranking_menu(adapter) 99 adapter.api.appclient.views_publish( 100 user_id=adapter.conf.tab_var["user_id"], 101 view=adapter.conf.tab_var["view"], 102 ) 103 104 @app.action("ranking_aggregation") 105 def handle_aggregation_action(ack: Any, body: Any) -> None: 106 """ 107 メニュー項目生成 108 109 Args: 110 ack (Any): ack 111 body (Any): イベント内容 112 113 """ 114 ack() 115 logging.trace(body) # type: ignore 116 117 m = cast("MessageParserProtocol", adapter.parser()) 118 119 m.parser(body) 120 add_argument, app_msg, update_flag = ui_parts.set_command_option(adapter, body) 121 m.data.text = f"dummy {' '.join(add_argument)}" 122 g.params = dictutil.placeholder(g.cfg.ranking, m) 123 g.params.update_from_dict(update_flag) 124 125 adapter.api.appclient.views_update( 126 view_id=adapter.conf.tab_var["view_id"], 127 view=ui_parts.plain_text(f"{chr(10).join(app_msg)}"), 128 ) 129 130 search_options = body["view"]["state"]["values"] 131 if "bid-ranked" in search_options: 132 if "value" in search_options["bid-ranked"]["aid-ranked"]: 133 ranked = int(search_options["bid-ranked"]["aid-ranked"]["value"]) 134 if ranked > 0: 135 g.params.ranked = ranked 136 137 app_msg.pop() 138 app_msg.append("集計完了") 139 140 m.status.command_type = CommandType.RANKING 141 ranking.aggregation(m) 142 adapter.api.post(m) 143 144 ui_parts.update_view(adapter, m, app_msg) 145 146 @app.view("RankingMenu_ModalPeriodSelection") 147 def handle_view_submission(ack: Any, view: Any) -> None: 148 """ 149 view更新 150 151 Args: 152 ack (Any): ack 153 view (Any): 描写内容 154 155 """ 156 ack() 157 158 for i in view["state"]["values"].keys(): 159 if "aid-sday" in view["state"]["values"][i]: 160 adapter.conf.tab_var["sday"] = view["state"]["values"][i]["aid-sday"]["selected_date"] 161 if "aid-eday" in view["state"]["values"][i]: 162 adapter.conf.tab_var["eday"] = view["state"]["values"][i]["aid-eday"]["selected_date"] 163 164 logging.debug("[global var] %s", adapter.conf.tab_var) 165 166 adapter.api.appclient.views_update( 167 view_id=adapter.conf.tab_var["view_id"], 168 view=build_ranking_menu(adapter), 169 )
register_ranking_handlers =
None
ランキングメニュー