libs.dispatcher
libs/dispatcher.py
1""" 2libs/dispatcher.py 3""" 4 5import logging 6from typing import TYPE_CHECKING 7 8import libs.global_value as g 9from integrations import factory 10from libs.domain import modify 11from libs.domain.score import GameResult 12from libs.functions import lookup, message 13from libs.types import MessageStatus, StyleOptions 14from libs.utils import formatter, validator 15 16if TYPE_CHECKING: 17 from integrations.protocols import MessageParserProtocol 18 19 20def by_keyword(m: "MessageParserProtocol") -> None: 21 """メイン処理""" 22 g.params.default_reset() 23 g.params.update_from_dict( 24 { 25 "database_file": g.cfg.setting.database_file, 26 "logging_verbose": g.args.verbose, 27 } 28 ) 29 30 logging.debug("keyword=%s, argument=%s, source=%s", m.keyword, m.argument, m.status.source) 31 logging.debug( 32 "status=%s, event_ts=%s, thread_ts=%s, in_thread=%s, is_command=%s, user_id=%s,", 33 m.data.status.value, 34 m.data.event_ts, 35 m.data.thread_ts, 36 m.in_thread, 37 m.is_command, 38 m.data.user_id, 39 ) 40 41 # 変更がないイベントは処理をスキップ 42 if m.data.status == MessageStatus.DO_NOTHING: 43 return 44 45 # 許可されていないユーザのコマンドは処理しない 46 if m.ignore_user: 47 logging.debug("event skip[ignore user]: %s", m.data.user_id) 48 return 49 50 # メッセージが削除された場合 51 if m.data.status == MessageStatus.DELETED: 52 message_deleted(m) 53 return 54 55 match m.keyword: 56 # キーワード実行 57 case word if word in g.keyword_dispatcher and not m.is_command: 58 logging.debug("dispatch keyword") 59 if m.data.status == MessageStatus.APPEND: 60 g.keyword_dispatcher[word](m) 61 # コマンド実行 62 case word if word in g.command_dispatcher and m.is_command: 63 logging.debug("dispatch command") 64 if m.data.status == MessageStatus.APPEND: 65 g.command_dispatcher[word](m) 66 # リマインダ実行 67 case "Reminder:": 68 logging.debug("dispatch keyword for reminder") 69 if m.data.text in g.keyword_dispatcher and m.is_bot: 70 g.keyword_dispatcher[m.data.text](m) 71 # その他(ディスパッチテーブルにない場合) 72 case _ as word: 73 logging.debug("dispatch other words") 74 other_words(word, m) 75 76 g.adapter.api.post(m) 77 78 79def other_words(word: str, m: "MessageParserProtocol") -> None: 80 """ 81 コマンド以外のワードの処理 82 83 Args: 84 word (str): 入力ワード 85 m (MessageParserProtocol): メッセージデータ 86 87 """ 88 if word in g.cfg.rule.remarks_words and m.in_thread: # 追加メモ 89 if lookup.exsist_record(m.data.thread_ts).has_valid_data(): 90 modify.check_remarks(m) 91 else: # スコア登録 92 if detection_dict := validator.check_score(m): # 結果報告フォーマットに一致するポストの処理 93 score = GameResult(**detection_dict) 94 # 名前ブレ修正 95 for k, p in score.to_dict().items(): 96 if k.endswith("_name"): 97 score.set(**{k: formatter.name_replace(str(p), not_replace=True)}) 98 continue 99 100 match m.data.status: 101 case MessageStatus.APPEND: 102 message_append(score, m) 103 case MessageStatus.CHANGED: 104 message_changed(score, m) 105 case _: 106 pass 107 else: 108 record_data = lookup.exsist_record(m.data.event_ts) 109 if record_data and m.data.status == MessageStatus.CHANGED: 110 message_deleted(m) 111 112 113def message_append(detection: GameResult, m: "MessageParserProtocol") -> None: 114 """ 115 メッセージの追加処理 116 117 Args: 118 detection (GameResult): スコアデータ 119 m (MessageParserProtocol): メッセージデータ 120 121 """ 122 if _thread_check(m): 123 modify.db_insert(detection, m) 124 else: 125 m.post.ts = m.data.event_ts 126 m.set_message(message.random_reply(m, "inside_thread"), StyleOptions(key_title=False)) 127 logging.debug("skip (inside thread). event_ts=%s, thread_ts=%s", m.data.event_ts, m.data.thread_ts) 128 129 130def message_changed(detection: GameResult, m: "MessageParserProtocol") -> None: 131 """ 132 メッセージの変更処理 133 134 Args: 135 detection (GameResult): スコアデータ 136 m (MessageParserProtocol): メッセージデータ 137 138 """ 139 record_data = lookup.exsist_record(m.data.event_ts) 140 141 # 変更がない場合は終了 142 if detection.to_dict() == record_data.to_dict(): 143 return 144 145 # スレッド内チェック → 処理対象外なら終了 146 if not _thread_check(m): 147 m.post.ts = m.data.event_ts 148 m.set_message(message.random_reply(m, "inside_thread"), StyleOptions(key_title=False)) 149 logging.debug("skip (inside thread). event_ts=%s, thread_ts=%s", m.data.event_ts, m.data.thread_ts) 150 return 151 152 # 既存データなし → 新規挿入 153 if not record_data.has_valid_data(): 154 modify.db_insert(detection, m) 155 modify.reprocessing_remarks(m) 156 return 157 158 # 全条件クリア → 更新実行 159 modify.db_update(detection, m) 160 161 162def message_deleted(m: "MessageParserProtocol") -> None: 163 """ 164 メッセージの削除処理 165 166 Args: 167 m (MessageParserProtocol): メッセージデータ 168 169 """ 170 if m.keyword in g.cfg.rule.remarks_words: # 追加メモ 171 modify.remarks_delete(m) 172 else: 173 modify.db_delete(m) 174 175 176def _thread_check(m: "MessageParserProtocol") -> bool: 177 """スレッド内判定関数""" 178 if isinstance(g.adapter, factory.slack_adapter): # type: ignore[attr-defined] 179 if not m.in_thread or (m.in_thread == g.adapter.conf.thread_report): 180 return True 181 return False 182 return not m.in_thread
21def by_keyword(m: "MessageParserProtocol") -> None: 22 """メイン処理""" 23 g.params.default_reset() 24 g.params.update_from_dict( 25 { 26 "database_file": g.cfg.setting.database_file, 27 "logging_verbose": g.args.verbose, 28 } 29 ) 30 31 logging.debug("keyword=%s, argument=%s, source=%s", m.keyword, m.argument, m.status.source) 32 logging.debug( 33 "status=%s, event_ts=%s, thread_ts=%s, in_thread=%s, is_command=%s, user_id=%s,", 34 m.data.status.value, 35 m.data.event_ts, 36 m.data.thread_ts, 37 m.in_thread, 38 m.is_command, 39 m.data.user_id, 40 ) 41 42 # 変更がないイベントは処理をスキップ 43 if m.data.status == MessageStatus.DO_NOTHING: 44 return 45 46 # 許可されていないユーザのコマンドは処理しない 47 if m.ignore_user: 48 logging.debug("event skip[ignore user]: %s", m.data.user_id) 49 return 50 51 # メッセージが削除された場合 52 if m.data.status == MessageStatus.DELETED: 53 message_deleted(m) 54 return 55 56 match m.keyword: 57 # キーワード実行 58 case word if word in g.keyword_dispatcher and not m.is_command: 59 logging.debug("dispatch keyword") 60 if m.data.status == MessageStatus.APPEND: 61 g.keyword_dispatcher[word](m) 62 # コマンド実行 63 case word if word in g.command_dispatcher and m.is_command: 64 logging.debug("dispatch command") 65 if m.data.status == MessageStatus.APPEND: 66 g.command_dispatcher[word](m) 67 # リマインダ実行 68 case "Reminder:": 69 logging.debug("dispatch keyword for reminder") 70 if m.data.text in g.keyword_dispatcher and m.is_bot: 71 g.keyword_dispatcher[m.data.text](m) 72 # その他(ディスパッチテーブルにない場合) 73 case _ as word: 74 logging.debug("dispatch other words") 75 other_words(word, m) 76 77 g.adapter.api.post(m)
メイン処理
80def other_words(word: str, m: "MessageParserProtocol") -> None: 81 """ 82 コマンド以外のワードの処理 83 84 Args: 85 word (str): 入力ワード 86 m (MessageParserProtocol): メッセージデータ 87 88 """ 89 if word in g.cfg.rule.remarks_words and m.in_thread: # 追加メモ 90 if lookup.exsist_record(m.data.thread_ts).has_valid_data(): 91 modify.check_remarks(m) 92 else: # スコア登録 93 if detection_dict := validator.check_score(m): # 結果報告フォーマットに一致するポストの処理 94 score = GameResult(**detection_dict) 95 # 名前ブレ修正 96 for k, p in score.to_dict().items(): 97 if k.endswith("_name"): 98 score.set(**{k: formatter.name_replace(str(p), not_replace=True)}) 99 continue 100 101 match m.data.status: 102 case MessageStatus.APPEND: 103 message_append(score, m) 104 case MessageStatus.CHANGED: 105 message_changed(score, m) 106 case _: 107 pass 108 else: 109 record_data = lookup.exsist_record(m.data.event_ts) 110 if record_data and m.data.status == MessageStatus.CHANGED: 111 message_deleted(m)
コマンド以外のワードの処理
Arguments:
- word (str): 入力ワード
- m (MessageParserProtocol): メッセージデータ
def
message_append( detection: libs.domain.score.GameResult, m: integrations.protocols.MessageParserProtocol) -> None:
114def message_append(detection: GameResult, m: "MessageParserProtocol") -> None: 115 """ 116 メッセージの追加処理 117 118 Args: 119 detection (GameResult): スコアデータ 120 m (MessageParserProtocol): メッセージデータ 121 122 """ 123 if _thread_check(m): 124 modify.db_insert(detection, m) 125 else: 126 m.post.ts = m.data.event_ts 127 m.set_message(message.random_reply(m, "inside_thread"), StyleOptions(key_title=False)) 128 logging.debug("skip (inside thread). event_ts=%s, thread_ts=%s", m.data.event_ts, m.data.thread_ts)
メッセージの追加処理
Arguments:
- detection (GameResult): スコアデータ
- m (MessageParserProtocol): メッセージデータ
def
message_changed( detection: libs.domain.score.GameResult, m: integrations.protocols.MessageParserProtocol) -> None:
131def message_changed(detection: GameResult, m: "MessageParserProtocol") -> None: 132 """ 133 メッセージの変更処理 134 135 Args: 136 detection (GameResult): スコアデータ 137 m (MessageParserProtocol): メッセージデータ 138 139 """ 140 record_data = lookup.exsist_record(m.data.event_ts) 141 142 # 変更がない場合は終了 143 if detection.to_dict() == record_data.to_dict(): 144 return 145 146 # スレッド内チェック → 処理対象外なら終了 147 if not _thread_check(m): 148 m.post.ts = m.data.event_ts 149 m.set_message(message.random_reply(m, "inside_thread"), StyleOptions(key_title=False)) 150 logging.debug("skip (inside thread). event_ts=%s, thread_ts=%s", m.data.event_ts, m.data.thread_ts) 151 return 152 153 # 既存データなし → 新規挿入 154 if not record_data.has_valid_data(): 155 modify.db_insert(detection, m) 156 modify.reprocessing_remarks(m) 157 return 158 159 # 全条件クリア → 更新実行 160 modify.db_update(detection, m)
メッセージの変更処理
Arguments:
- detection (GameResult): スコアデータ
- m (MessageParserProtocol): メッセージデータ
163def message_deleted(m: "MessageParserProtocol") -> None: 164 """ 165 メッセージの削除処理 166 167 Args: 168 m (MessageParserProtocol): メッセージデータ 169 170 """ 171 if m.keyword in g.cfg.rule.remarks_words: # 追加メモ 172 modify.remarks_delete(m) 173 else: 174 modify.db_delete(m)
メッセージの削除処理
Arguments:
- m (MessageParserProtocol): メッセージデータ