libs.dispatcher

libs/dispatcher.py

  1"""
  2libs/dispatcher.py
  3"""
  4
  5import logging
  6import re
  7from typing import TYPE_CHECKING
  8
  9import libs.global_value as g
 10from cls.score import GameResult
 11from integrations import factory
 12from libs.data import lookup, modify
 13from libs.functions import message
 14from libs.types import StyleOptions
 15from libs.utils import formatter
 16
 17if TYPE_CHECKING:
 18    from integrations.protocols import MessageParserProtocol
 19
 20
 21def by_keyword(m: "MessageParserProtocol"):
 22    """メイン処理"""
 23
 24    logging.debug("keyword=%s, argument=%s", m.keyword, m.argument)
 25    logging.debug(
 26        "status=%s, event_ts=%s, thread_ts=%s, in_thread=%s, keyword=%s, user_id=%s,",
 27        m.data.status, m.data.event_ts, m.data.thread_ts, m.in_thread, m.keyword, m.data.user_id,
 28    )
 29
 30    # 許可されていないユーザのコマンドは処理しない
 31    if m.ignore_user:
 32        logging.debug("event skip[ignore user]: %s", m.data.user_id)
 33        return
 34
 35    # メッセージが削除された場合
 36    if m.data.status == "message_deleted":
 37        message_deleted(m)
 38        return
 39
 40    match m.keyword:
 41        # キーワード実行
 42        case word if word in g.keyword_dispatcher and not m.is_command:
 43            if m.data.status == "message_append":
 44                g.keyword_dispatcher[word](m)
 45        # コマンド実行
 46        case word if word in g.command_dispatcher and m.is_command:
 47            if m.data.status == "message_append":
 48                g.command_dispatcher[word](m)
 49        # リマインダ実行
 50        case "Reminder:":
 51            if m.data.text in g.keyword_dispatcher and m.is_bot:
 52                g.keyword_dispatcher[m.data.text](m)
 53        # その他(ディスパッチテーブルにない場合)
 54        case _ as word:
 55            other_words(word, m)
 56
 57    g.adapter.api.post(m)
 58
 59
 60def other_words(word: str, m: "MessageParserProtocol"):
 61    """コマンド以外のワードの処理
 62
 63    Args:
 64        word (str): 入力ワード
 65        m (MessageParserProtocol): メッセージデータ
 66    """
 67
 68    if re.match(rf"^{g.cfg.setting.remarks_word}$", word) and m.in_thread:  # 追加メモ
 69        if lookup.db.exsist_record(m.data.thread_ts).has_valid_data():
 70            modify.check_remarks(m)
 71    else:
 72        # スコア取り出し
 73        detection = GameResult(**m.get_score(g.cfg.setting.keyword), **g.cfg.mahjong.to_dict())
 74        if detection:  # 結果報告フォーマットに一致したポストの処理
 75            # 名前ブレ修正
 76            g.params.update(unregistered_replace=False)  # ゲスト無効
 77            g.params.update(individual=True)  # チーム戦オフ
 78            for k, p in detection.to_dict().items():
 79                if str(k).endswith("_name"):
 80                    detection.set(**{k: formatter.name_replace(str(p))})
 81                    continue
 82
 83            match m.data.status:
 84                case "message_append":
 85                    message_append(detection, m)
 86                case "message_changed":
 87                    message_changed(detection, m)
 88        else:
 89            record_data = lookup.db.exsist_record(m.data.event_ts)
 90            if record_data and m.data.status == "message_changed":
 91                message_deleted(m)
 92
 93
 94def message_append(detection: GameResult, m: "MessageParserProtocol"):
 95    """メッセージの追加処理
 96
 97    Args:
 98        detection (GameResult): スコアデータ
 99        m (MessageParserProtocol): メッセージデータ
100    """
101
102    if _thread_check(m):
103        modify.db_insert(detection, m)
104    else:
105        m.post.ts = m.data.event_ts
106        m.set_data("0", message.random_reply(m, "inside_thread"), StyleOptions(key_title=False))
107        logging.debug("skip (inside thread). event_ts=%s, thread_ts=%s", m.data.event_ts, m.data.thread_ts)
108
109    g.adapter.functions.post_processing(m)
110
111
112def message_changed(detection: GameResult, m: "MessageParserProtocol"):
113    """メッセージの変更処理
114
115    Args:
116        detection (GameResult): スコアデータ
117        m (MessageParserProtocol): メッセージデータ
118    """
119
120    record_data = lookup.db.exsist_record(m.data.event_ts)
121
122    if detection.to_dict() == record_data.to_dict():  # スコア比較
123        return  # 変更箇所がなければ何もしない
124    if _thread_check(m):
125        if record_data.has_valid_data():
126            if record_data.rule_version == g.cfg.mahjong.rule_version:
127                modify.db_update(detection, m)
128            else:
129                logging.debug("skip (rule_version not match). event_ts=%s", m.data.event_ts)
130        else:
131            modify.db_insert(detection, m)
132            modify.reprocessing_remarks(m)
133    else:
134        m.post.ts = m.data.event_ts
135        m.set_data("0", message.random_reply(m, "inside_thread"), StyleOptions(key_title=False))
136        logging.debug("skip (inside thread). event_ts=%s, thread_ts=%s", m.data.event_ts, m.data.thread_ts)
137
138    g.adapter.functions.post_processing(m)
139
140
141def message_deleted(m: "MessageParserProtocol"):
142    """メッセージの削除処理
143
144    Args:
145        m (MessageParserProtocol): メッセージデータ
146    """
147
148    if re.match(rf"^{g.cfg.setting.remarks_word}", m.keyword):  # 追加メモ
149        modify.remarks_delete(m)
150    else:
151        modify.db_delete(m)
152
153    g.adapter.functions.post_processing(m)
154
155
156def _thread_check(m: "MessageParserProtocol") -> bool:
157    """スレッド内判定関数"""
158
159    if isinstance(g.adapter, factory.slack_adapter):
160        if not m.in_thread or (m.in_thread == g.adapter.conf.thread_report):
161            return True
162        return False
163    return not m.in_thread
def by_keyword(m: integrations.protocols.MessageParserProtocol):
22def by_keyword(m: "MessageParserProtocol"):
23    """メイン処理"""
24
25    logging.debug("keyword=%s, argument=%s", m.keyword, m.argument)
26    logging.debug(
27        "status=%s, event_ts=%s, thread_ts=%s, in_thread=%s, keyword=%s, user_id=%s,",
28        m.data.status, m.data.event_ts, m.data.thread_ts, m.in_thread, m.keyword, m.data.user_id,
29    )
30
31    # 許可されていないユーザのコマンドは処理しない
32    if m.ignore_user:
33        logging.debug("event skip[ignore user]: %s", m.data.user_id)
34        return
35
36    # メッセージが削除された場合
37    if m.data.status == "message_deleted":
38        message_deleted(m)
39        return
40
41    match m.keyword:
42        # キーワード実行
43        case word if word in g.keyword_dispatcher and not m.is_command:
44            if m.data.status == "message_append":
45                g.keyword_dispatcher[word](m)
46        # コマンド実行
47        case word if word in g.command_dispatcher and m.is_command:
48            if m.data.status == "message_append":
49                g.command_dispatcher[word](m)
50        # リマインダ実行
51        case "Reminder:":
52            if m.data.text in g.keyword_dispatcher and m.is_bot:
53                g.keyword_dispatcher[m.data.text](m)
54        # その他(ディスパッチテーブルにない場合)
55        case _ as word:
56            other_words(word, m)
57
58    g.adapter.api.post(m)

メイン処理

def other_words(word: str, m: integrations.protocols.MessageParserProtocol):
61def other_words(word: str, m: "MessageParserProtocol"):
62    """コマンド以外のワードの処理
63
64    Args:
65        word (str): 入力ワード
66        m (MessageParserProtocol): メッセージデータ
67    """
68
69    if re.match(rf"^{g.cfg.setting.remarks_word}$", word) and m.in_thread:  # 追加メモ
70        if lookup.db.exsist_record(m.data.thread_ts).has_valid_data():
71            modify.check_remarks(m)
72    else:
73        # スコア取り出し
74        detection = GameResult(**m.get_score(g.cfg.setting.keyword), **g.cfg.mahjong.to_dict())
75        if detection:  # 結果報告フォーマットに一致したポストの処理
76            # 名前ブレ修正
77            g.params.update(unregistered_replace=False)  # ゲスト無効
78            g.params.update(individual=True)  # チーム戦オフ
79            for k, p in detection.to_dict().items():
80                if str(k).endswith("_name"):
81                    detection.set(**{k: formatter.name_replace(str(p))})
82                    continue
83
84            match m.data.status:
85                case "message_append":
86                    message_append(detection, m)
87                case "message_changed":
88                    message_changed(detection, m)
89        else:
90            record_data = lookup.db.exsist_record(m.data.event_ts)
91            if record_data and m.data.status == "message_changed":
92                message_deleted(m)

コマンド以外のワードの処理

Arguments:
  • word (str): 入力ワード
  • m (MessageParserProtocol): メッセージデータ
def message_append( detection: cls.score.GameResult, m: integrations.protocols.MessageParserProtocol):
 95def message_append(detection: GameResult, m: "MessageParserProtocol"):
 96    """メッセージの追加処理
 97
 98    Args:
 99        detection (GameResult): スコアデータ
100        m (MessageParserProtocol): メッセージデータ
101    """
102
103    if _thread_check(m):
104        modify.db_insert(detection, m)
105    else:
106        m.post.ts = m.data.event_ts
107        m.set_data("0", message.random_reply(m, "inside_thread"), StyleOptions(key_title=False))
108        logging.debug("skip (inside thread). event_ts=%s, thread_ts=%s", m.data.event_ts, m.data.thread_ts)
109
110    g.adapter.functions.post_processing(m)

メッセージの追加処理

Arguments:
  • detection (GameResult): スコアデータ
  • m (MessageParserProtocol): メッセージデータ
def message_changed( detection: cls.score.GameResult, m: integrations.protocols.MessageParserProtocol):
113def message_changed(detection: GameResult, m: "MessageParserProtocol"):
114    """メッセージの変更処理
115
116    Args:
117        detection (GameResult): スコアデータ
118        m (MessageParserProtocol): メッセージデータ
119    """
120
121    record_data = lookup.db.exsist_record(m.data.event_ts)
122
123    if detection.to_dict() == record_data.to_dict():  # スコア比較
124        return  # 変更箇所がなければ何もしない
125    if _thread_check(m):
126        if record_data.has_valid_data():
127            if record_data.rule_version == g.cfg.mahjong.rule_version:
128                modify.db_update(detection, m)
129            else:
130                logging.debug("skip (rule_version not match). event_ts=%s", m.data.event_ts)
131        else:
132            modify.db_insert(detection, m)
133            modify.reprocessing_remarks(m)
134    else:
135        m.post.ts = m.data.event_ts
136        m.set_data("0", message.random_reply(m, "inside_thread"), StyleOptions(key_title=False))
137        logging.debug("skip (inside thread). event_ts=%s, thread_ts=%s", m.data.event_ts, m.data.thread_ts)
138
139    g.adapter.functions.post_processing(m)

メッセージの変更処理

Arguments:
  • detection (GameResult): スコアデータ
  • m (MessageParserProtocol): メッセージデータ
def message_deleted(m: integrations.protocols.MessageParserProtocol):
142def message_deleted(m: "MessageParserProtocol"):
143    """メッセージの削除処理
144
145    Args:
146        m (MessageParserProtocol): メッセージデータ
147    """
148
149    if re.match(rf"^{g.cfg.setting.remarks_word}", m.keyword):  # 追加メモ
150        modify.remarks_delete(m)
151    else:
152        modify.db_delete(m)
153
154    g.adapter.functions.post_processing(m)

メッセージの削除処理

Arguments:
  • m (MessageParserProtocol): メッセージデータ