libs.functions.message
libs/functions/message.py
1""" 2libs/functions/message.py 3""" 4 5import logging 6import random 7import textwrap 8from typing import TYPE_CHECKING, cast 9 10import libs.global_value as g 11from cls.timekit import ExtendedDatetime as ExtDt 12from libs.functions import compose 13 14if TYPE_CHECKING: 15 from configparser import ConfigParser 16 17 from integrations.protocols import MessageParserProtocol 18 from libs.datamodels import GameInfo 19 20 21def random_reply(m: "MessageParserProtocol", message_type: str) -> str: 22 """メッセージをランダムに返す 23 24 Args: 25 m (MessageParserProtocol): メッセージデータ 26 message_type (str): 応答メッセージの種類 27 28 Returns: 29 str: 応答メッセージ 30 """ 31 32 correct_score = g.cfg.mahjong.origin_point * 4 # 配給原点 33 rpoint_diff = abs(correct_score - m.status.rpoint_sum) 34 35 default_message_type = { 36 "invalid_argument": "使い方が間違っています。", 37 "no_hits": "{start} ~ {end} に≪{keyword}≫はありません。", 38 "no_target": "集計対象データがありません。", 39 "invalid_score": "素点合計:{rpoint_sum}\n点数差分:{rpoint_diff}", 40 "restricted_channel": "<@{user_id}> この投稿はデータベースに反映されません。", 41 "inside_thread": "<@{user_id}> スレッド内から成績登録はできません。", 42 "same_player": "同名のプレイヤーがいます。", 43 "not_implemented": "未実装", 44 "access_denied": "アクセスが拒否されました。", 45 } 46 47 msg = default_message_type.get(message_type, "invalid_argument") 48 49 if cast("ConfigParser", getattr(g.cfg, "_parser")).has_section("custom_message"): 50 msg_list = [] 51 for key, val in cast("ConfigParser", getattr(g.cfg, "_parser")).items("custom_message"): 52 if key.startswith(message_type): 53 msg_list.append(val) 54 if msg_list: 55 msg = random.choice(msg_list) 56 57 try: 58 msg = str(msg.format( 59 user_id=m.data.user_id, 60 keyword=g.cfg.setting.keyword, 61 start=ExtDt(g.params.get("starttime", ExtDt())).format("ymd"), 62 end=ExtDt(g.params.get("onday", ExtDt())).format("ymd"), 63 rpoint_diff=rpoint_diff * 100, 64 rpoint_sum=m.status.rpoint_sum * 100, 65 )) 66 except KeyError as e: 67 logging.error("[unknown keywords] %s: %s", e, msg) 68 msg = msg.replace("{user_id}", m.data.user_id) 69 70 return msg 71 72 73def header(game_info: "GameInfo", m: "MessageParserProtocol", add_text="", indent=1): 74 """見出し生成 75 76 Args: 77 game_info (GameInfo): 集計範囲のゲーム情報 78 m (MessageParserProtocol): メッセージデータ 79 add_text (str, optional): 追加表示するテキスト. Defaults to "". 80 indent (int, optional): 先頭のタブ数. Defaults to 1. 81 82 Returns: 83 str: 生成した見出し 84 """ 85 86 msg = "" 87 assert isinstance(game_info.first_game, ExtDt) 88 assert isinstance(game_info.last_game, ExtDt) 89 90 # 集計範囲 91 if g.params.get("search_word"): # コメント検索の場合はコメントで表示 92 game_range1 = f"最初のゲーム:{game_info.first_comment}\n" 93 game_range1 += f"最後のゲーム:{game_info.last_comment}\n" 94 else: 95 game_range1 = f"最初のゲーム:{game_info.first_game.format("ymdhms")}\n" 96 game_range1 += f"最後のゲーム:{game_info.last_game.format("ymdhms")}\n" 97 game_range2 = f"集計範囲:{compose.text_item.aggregation_range(game_info)}\n" 98 99 # ゲーム数 100 if game_info.count == 0: 101 msg += f"{random_reply(m, "no_hits")}" 102 else: 103 match m.status.command_type: 104 case "results": 105 if g.params.get("target_count"): # 直近指定がない場合は検索範囲を付ける 106 msg += game_range1 107 msg += f"集計対象:{game_info.count} ゲーム {add_text}\n" 108 else: 109 msg += f"検索範囲:{str(compose.text_item.search_range(time_pattern="time"))}\n" 110 msg += game_range1 111 msg += f"集計対象:{game_info.count} ゲーム {add_text}\n" 112 case "ranking" | "report": 113 msg += game_range2 114 msg += f"集計対象:{game_info.count} ゲーム\n" 115 case _: 116 msg += game_range2 117 msg += f"集計対象:{game_info.count} ゲーム\n" 118 119 if (remarks_text := compose.text_item.remarks(True)): 120 msg += f"{remarks_text}\n" 121 if (word_text := compose.text_item.search_word(True)): 122 msg += f"{word_text}\n" 123 124 return textwrap.indent(msg, "\t" * indent)
22def random_reply(m: "MessageParserProtocol", message_type: str) -> str: 23 """メッセージをランダムに返す 24 25 Args: 26 m (MessageParserProtocol): メッセージデータ 27 message_type (str): 応答メッセージの種類 28 29 Returns: 30 str: 応答メッセージ 31 """ 32 33 correct_score = g.cfg.mahjong.origin_point * 4 # 配給原点 34 rpoint_diff = abs(correct_score - m.status.rpoint_sum) 35 36 default_message_type = { 37 "invalid_argument": "使い方が間違っています。", 38 "no_hits": "{start} ~ {end} に≪{keyword}≫はありません。", 39 "no_target": "集計対象データがありません。", 40 "invalid_score": "素点合計:{rpoint_sum}\n点数差分:{rpoint_diff}", 41 "restricted_channel": "<@{user_id}> この投稿はデータベースに反映されません。", 42 "inside_thread": "<@{user_id}> スレッド内から成績登録はできません。", 43 "same_player": "同名のプレイヤーがいます。", 44 "not_implemented": "未実装", 45 "access_denied": "アクセスが拒否されました。", 46 } 47 48 msg = default_message_type.get(message_type, "invalid_argument") 49 50 if cast("ConfigParser", getattr(g.cfg, "_parser")).has_section("custom_message"): 51 msg_list = [] 52 for key, val in cast("ConfigParser", getattr(g.cfg, "_parser")).items("custom_message"): 53 if key.startswith(message_type): 54 msg_list.append(val) 55 if msg_list: 56 msg = random.choice(msg_list) 57 58 try: 59 msg = str(msg.format( 60 user_id=m.data.user_id, 61 keyword=g.cfg.setting.keyword, 62 start=ExtDt(g.params.get("starttime", ExtDt())).format("ymd"), 63 end=ExtDt(g.params.get("onday", ExtDt())).format("ymd"), 64 rpoint_diff=rpoint_diff * 100, 65 rpoint_sum=m.status.rpoint_sum * 100, 66 )) 67 except KeyError as e: 68 logging.error("[unknown keywords] %s: %s", e, msg) 69 msg = msg.replace("{user_id}", m.data.user_id) 70 71 return msg
メッセージをランダムに返す
Arguments:
- m (MessageParserProtocol): メッセージデータ
- message_type (str): 応答メッセージの種類
Returns:
str: 応答メッセージ
def
header( game_info: libs.datamodels.GameInfo, m: integrations.protocols.MessageParserProtocol, add_text='', indent=1):
74def header(game_info: "GameInfo", m: "MessageParserProtocol", add_text="", indent=1): 75 """見出し生成 76 77 Args: 78 game_info (GameInfo): 集計範囲のゲーム情報 79 m (MessageParserProtocol): メッセージデータ 80 add_text (str, optional): 追加表示するテキスト. Defaults to "". 81 indent (int, optional): 先頭のタブ数. Defaults to 1. 82 83 Returns: 84 str: 生成した見出し 85 """ 86 87 msg = "" 88 assert isinstance(game_info.first_game, ExtDt) 89 assert isinstance(game_info.last_game, ExtDt) 90 91 # 集計範囲 92 if g.params.get("search_word"): # コメント検索の場合はコメントで表示 93 game_range1 = f"最初のゲーム:{game_info.first_comment}\n" 94 game_range1 += f"最後のゲーム:{game_info.last_comment}\n" 95 else: 96 game_range1 = f"最初のゲーム:{game_info.first_game.format("ymdhms")}\n" 97 game_range1 += f"最後のゲーム:{game_info.last_game.format("ymdhms")}\n" 98 game_range2 = f"集計範囲:{compose.text_item.aggregation_range(game_info)}\n" 99 100 # ゲーム数 101 if game_info.count == 0: 102 msg += f"{random_reply(m, "no_hits")}" 103 else: 104 match m.status.command_type: 105 case "results": 106 if g.params.get("target_count"): # 直近指定がない場合は検索範囲を付ける 107 msg += game_range1 108 msg += f"集計対象:{game_info.count} ゲーム {add_text}\n" 109 else: 110 msg += f"検索範囲:{str(compose.text_item.search_range(time_pattern="time"))}\n" 111 msg += game_range1 112 msg += f"集計対象:{game_info.count} ゲーム {add_text}\n" 113 case "ranking" | "report": 114 msg += game_range2 115 msg += f"集計対象:{game_info.count} ゲーム\n" 116 case _: 117 msg += game_range2 118 msg += f"集計対象:{game_info.count} ゲーム\n" 119 120 if (remarks_text := compose.text_item.remarks(True)): 121 msg += f"{remarks_text}\n" 122 if (word_text := compose.text_item.search_word(True)): 123 msg += f"{word_text}\n" 124 125 return textwrap.indent(msg, "\t" * indent)
見出し生成
Arguments:
- game_info (GameInfo): 集計範囲のゲーム情報
- m (MessageParserProtocol): メッセージデータ
- add_text (str, optional): 追加表示するテキスト. Defaults to "".
- indent (int, optional): 先頭のタブ数. Defaults to 1.
Returns:
str: 生成した見出し