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        )
def build_ranking_menu( adapter: integrations.slack.adapter.ServiceAdapter) -> slack_sdk.models.views.View:
26def build_ranking_menu(adapter: ServiceAdapter) -> "View":
27    """
28    ランキングメニュー生成
29
30    Args:
31        adapter (ServiceAdapter): インターフェースアダプタ
32
33    """
34    adapter.conf.tab_var["screen"] = "RankingMenu"
35    adapter.conf.tab_var["no"] = 0
36    adapter.conf.tab_var["view"] = {"type": "home", "blocks": []}
37    adapter.conf.tab_var.setdefault("sday", ExtDt().format(Format.YMD, Delimiter.HYPHEN))
38    adapter.conf.tab_var.setdefault("eday", ExtDt().format(Format.YMD, Delimiter.HYPHEN))
39    ui_parts.header(adapter, text="【ランキング】")
40
41    # 検索範囲設定
42    date_dict = {x: ExtDt(hours=-g.cfg.setting.time_adjust).range(x).dict_format(Format.YMD, Delimiter.HYPHEN) for x in ["今月", "先月", "全部"]}
43    ui_parts.divider(adapter)
44    ui_parts.radio_buttons(
45        adapter=adapter,
46        id_suffix="search_range",
47        title="検索範囲",
48        flag={
49            "今月": f"今月:{date_dict['今月']['start']}{date_dict['今月']['end']}",
50            "先月": f"先月:{date_dict['先月']['start']}{date_dict['先月']['end']}",
51            "全部": f"全部:{date_dict['全部']['start']}{date_dict['全部']['end']}",
52            "指定": f"範囲指定:{adapter.conf.tab_var['sday']}{adapter.conf.tab_var['eday']}",
53        },
54    )
55    ui_parts.button(adapter, text="検索範囲設定", action_id="modal-open-period")
56
57    # 検索オプション
58    ui_parts.divider(adapter)
59    ui_parts.checkboxes(
60        adapter=adapter,
61        id_suffix="search_option",
62        title="検索オプション",
63        flag={
64            "unregistered_replace": "ゲスト無効",
65        },
66        initial=["unregistered_replace"],
67    )
68
69    ui_parts.input_ranked(adapter, block_id="bid-ranked")
70
71    ui_parts.divider(adapter)
72    ui_parts.button(adapter, text="集計", action_id="ranking_aggregation", style="primary")
73    ui_parts.button(adapter, text="戻る", action_id="actionId-back", style="danger")
74
75    return cast("View", adapter.conf.tab_var)

ランキングメニュー生成

Arguments:
  • adapter (ServiceAdapter): インターフェースアダプタ
register_ranking_handlers = None

ランキングメニュー