integrations.standard_io.api

integrations/standard_io/api.py

  1"""
  2integrations/standard_io/api.py
  3"""
  4
  5import textwrap
  6from pathlib import Path
  7from typing import TYPE_CHECKING
  8
  9import pandas as pd
 10
 11from integrations.base.interface import APIInterface
 12from libs.types import StyleOptions
 13from libs.utils import formatter
 14
 15if TYPE_CHECKING:
 16    from integrations.protocols import MessageParserProtocol
 17
 18
 19class AdapterAPI(APIInterface):
 20    """インターフェースAPI操作クラス"""
 21
 22    def _text_formatter(self, text: str, style: StyleOptions) -> str:
 23        """
 24        テキスト整形
 25
 26        Args:
 27            text (str): 対象テキスト
 28            style (StyleOptions): 修飾オプション
 29
 30        Returns:
 31            str: 整形済みテキスト
 32
 33        """
 34        ret: str = ""
 35        for line in text.splitlines():
 36            line = line.replace("<@>", "")
 37            if not style.keep_indent:
 38                line = textwrap.dedent(line)
 39            if line or style.keep_blank:
 40                ret += textwrap.indent(f"{line}\n", "\t" * style.indent)
 41        return ret.rstrip()
 42
 43    def post(self, m: "MessageParserProtocol") -> None:
 44        """
 45        メッセージ出力
 46
 47        Args:
 48            m (MessageParserProtocol): メッセージデータ
 49
 50        """
 51        # 見出し
 52        if m.post.headline:
 53            header_data, header_option = m.post.headline
 54            if isinstance(header_data, str):
 55                print("=" * 80)
 56                if header_option.title:
 57                    print(f"【{header_option.title}】")
 58                if isinstance(header_data, str):
 59                    print(textwrap.dedent(header_data).rstrip())
 60                    print("=" * 80)
 61
 62        # 本文
 63        for data, options in m.post.message:
 64            if options.key_title and options.title:
 65                print(options.print_title)
 66
 67            match data:
 68                case x if isinstance(x, str):
 69                    print(self._text_formatter(x, options))
 70                case x if isinstance(x, pd.DataFrame):
 71                    options.rename_type = StyleOptions.RenameType.NORMAL
 72                    match options.data_kind:  # 単位付与/文字列変換
 73                        case StyleOptions.DataKind.POINTS_TOTAL:
 74                            x["total_point"] = x["total_point"].map(lambda v: f"{v:+.1f}pt".replace("-", "▲"))
 75                            x["avg_point"] = x["avg_point"].map(lambda v: f"{v:+.1f}pt".replace("-", "▲"))
 76                        case StyleOptions.DataKind.POINTS_DIFF:
 77                            x["total_point"] = x["total_point"].map(lambda v: f"{v:+.1f}pt".replace("-", "▲"))
 78                            x["diff_from_above"] = x["diff_from_above"].map(lambda v: f"{v:.1f}pt" if pd.notna(v) else "------")
 79                            x["diff_from_top"] = x["diff_from_top"].map(lambda v: f"{v:.1f}pt" if pd.notna(v) else "------")
 80                        case StyleOptions.DataKind.RECORD_DATA:
 81                            x["rank"] = x["rank"].map(lambda v: f"{v:.0f}位")
 82                            x["rpoint"] = x["rpoint"].map(lambda v: f"{v:.0f}点".replace("-", "▲"))
 83                            x["point"] = x["point"].map(lambda v: f"{v:+.1f}pt".replace("-", "▲"))
 84                        case StyleOptions.DataKind.RECORD_DATA_ALL:
 85                            for prefix in ("p1", "p2", "p3", "p4"):
 86                                x[f"{prefix}_rank"] = x[f"{prefix}_rank"].map(lambda v: f"{v:.0f}位")
 87                                x[f"{prefix}_rpoint"] = x[f"{prefix}_rpoint"].map(lambda v: f"{v:.0f}点".replace("-", "▲"))
 88                                x[f"{prefix}_point"] = x[f"{prefix}_point"].map(lambda v: f"{v:+.1f}pt".replace("-", "▲"))
 89                        case _:
 90                            pass
 91                    disp = formatter.df_rename(x, options).to_markdown(
 92                        index=options.show_index,
 93                        tablefmt="simple_outline",
 94                        floatfmt=formatter.floatfmt_adjust(x, index=options.show_index),
 95                        colalign=formatter.column_alignment(x, index=options.show_index),
 96                    )
 97                    print(disp)
 98                case x if isinstance(x, Path):
 99                    print(f"{options.title}: {x.absolute()}")
100                case _:
101                    pass
102
103            print("")
class AdapterAPI(integrations.base.interface.APIInterface):
 20class AdapterAPI(APIInterface):
 21    """インターフェースAPI操作クラス"""
 22
 23    def _text_formatter(self, text: str, style: StyleOptions) -> str:
 24        """
 25        テキスト整形
 26
 27        Args:
 28            text (str): 対象テキスト
 29            style (StyleOptions): 修飾オプション
 30
 31        Returns:
 32            str: 整形済みテキスト
 33
 34        """
 35        ret: str = ""
 36        for line in text.splitlines():
 37            line = line.replace("<@>", "")
 38            if not style.keep_indent:
 39                line = textwrap.dedent(line)
 40            if line or style.keep_blank:
 41                ret += textwrap.indent(f"{line}\n", "\t" * style.indent)
 42        return ret.rstrip()
 43
 44    def post(self, m: "MessageParserProtocol") -> None:
 45        """
 46        メッセージ出力
 47
 48        Args:
 49            m (MessageParserProtocol): メッセージデータ
 50
 51        """
 52        # 見出し
 53        if m.post.headline:
 54            header_data, header_option = m.post.headline
 55            if isinstance(header_data, str):
 56                print("=" * 80)
 57                if header_option.title:
 58                    print(f"【{header_option.title}】")
 59                if isinstance(header_data, str):
 60                    print(textwrap.dedent(header_data).rstrip())
 61                    print("=" * 80)
 62
 63        # 本文
 64        for data, options in m.post.message:
 65            if options.key_title and options.title:
 66                print(options.print_title)
 67
 68            match data:
 69                case x if isinstance(x, str):
 70                    print(self._text_formatter(x, options))
 71                case x if isinstance(x, pd.DataFrame):
 72                    options.rename_type = StyleOptions.RenameType.NORMAL
 73                    match options.data_kind:  # 単位付与/文字列変換
 74                        case StyleOptions.DataKind.POINTS_TOTAL:
 75                            x["total_point"] = x["total_point"].map(lambda v: f"{v:+.1f}pt".replace("-", "▲"))
 76                            x["avg_point"] = x["avg_point"].map(lambda v: f"{v:+.1f}pt".replace("-", "▲"))
 77                        case StyleOptions.DataKind.POINTS_DIFF:
 78                            x["total_point"] = x["total_point"].map(lambda v: f"{v:+.1f}pt".replace("-", "▲"))
 79                            x["diff_from_above"] = x["diff_from_above"].map(lambda v: f"{v:.1f}pt" if pd.notna(v) else "------")
 80                            x["diff_from_top"] = x["diff_from_top"].map(lambda v: f"{v:.1f}pt" if pd.notna(v) else "------")
 81                        case StyleOptions.DataKind.RECORD_DATA:
 82                            x["rank"] = x["rank"].map(lambda v: f"{v:.0f}位")
 83                            x["rpoint"] = x["rpoint"].map(lambda v: f"{v:.0f}点".replace("-", "▲"))
 84                            x["point"] = x["point"].map(lambda v: f"{v:+.1f}pt".replace("-", "▲"))
 85                        case StyleOptions.DataKind.RECORD_DATA_ALL:
 86                            for prefix in ("p1", "p2", "p3", "p4"):
 87                                x[f"{prefix}_rank"] = x[f"{prefix}_rank"].map(lambda v: f"{v:.0f}位")
 88                                x[f"{prefix}_rpoint"] = x[f"{prefix}_rpoint"].map(lambda v: f"{v:.0f}点".replace("-", "▲"))
 89                                x[f"{prefix}_point"] = x[f"{prefix}_point"].map(lambda v: f"{v:+.1f}pt".replace("-", "▲"))
 90                        case _:
 91                            pass
 92                    disp = formatter.df_rename(x, options).to_markdown(
 93                        index=options.show_index,
 94                        tablefmt="simple_outline",
 95                        floatfmt=formatter.floatfmt_adjust(x, index=options.show_index),
 96                        colalign=formatter.column_alignment(x, index=options.show_index),
 97                    )
 98                    print(disp)
 99                case x if isinstance(x, Path):
100                    print(f"{options.title}: {x.absolute()}")
101                case _:
102                    pass
103
104            print("")

インターフェースAPI操作クラス

def post(self, m: integrations.protocols.MessageParserProtocol) -> None:
 44    def post(self, m: "MessageParserProtocol") -> None:
 45        """
 46        メッセージ出力
 47
 48        Args:
 49            m (MessageParserProtocol): メッセージデータ
 50
 51        """
 52        # 見出し
 53        if m.post.headline:
 54            header_data, header_option = m.post.headline
 55            if isinstance(header_data, str):
 56                print("=" * 80)
 57                if header_option.title:
 58                    print(f"【{header_option.title}】")
 59                if isinstance(header_data, str):
 60                    print(textwrap.dedent(header_data).rstrip())
 61                    print("=" * 80)
 62
 63        # 本文
 64        for data, options in m.post.message:
 65            if options.key_title and options.title:
 66                print(options.print_title)
 67
 68            match data:
 69                case x if isinstance(x, str):
 70                    print(self._text_formatter(x, options))
 71                case x if isinstance(x, pd.DataFrame):
 72                    options.rename_type = StyleOptions.RenameType.NORMAL
 73                    match options.data_kind:  # 単位付与/文字列変換
 74                        case StyleOptions.DataKind.POINTS_TOTAL:
 75                            x["total_point"] = x["total_point"].map(lambda v: f"{v:+.1f}pt".replace("-", "▲"))
 76                            x["avg_point"] = x["avg_point"].map(lambda v: f"{v:+.1f}pt".replace("-", "▲"))
 77                        case StyleOptions.DataKind.POINTS_DIFF:
 78                            x["total_point"] = x["total_point"].map(lambda v: f"{v:+.1f}pt".replace("-", "▲"))
 79                            x["diff_from_above"] = x["diff_from_above"].map(lambda v: f"{v:.1f}pt" if pd.notna(v) else "------")
 80                            x["diff_from_top"] = x["diff_from_top"].map(lambda v: f"{v:.1f}pt" if pd.notna(v) else "------")
 81                        case StyleOptions.DataKind.RECORD_DATA:
 82                            x["rank"] = x["rank"].map(lambda v: f"{v:.0f}位")
 83                            x["rpoint"] = x["rpoint"].map(lambda v: f"{v:.0f}点".replace("-", "▲"))
 84                            x["point"] = x["point"].map(lambda v: f"{v:+.1f}pt".replace("-", "▲"))
 85                        case StyleOptions.DataKind.RECORD_DATA_ALL:
 86                            for prefix in ("p1", "p2", "p3", "p4"):
 87                                x[f"{prefix}_rank"] = x[f"{prefix}_rank"].map(lambda v: f"{v:.0f}位")
 88                                x[f"{prefix}_rpoint"] = x[f"{prefix}_rpoint"].map(lambda v: f"{v:.0f}点".replace("-", "▲"))
 89                                x[f"{prefix}_point"] = x[f"{prefix}_point"].map(lambda v: f"{v:+.1f}pt".replace("-", "▲"))
 90                        case _:
 91                            pass
 92                    disp = formatter.df_rename(x, options).to_markdown(
 93                        index=options.show_index,
 94                        tablefmt="simple_outline",
 95                        floatfmt=formatter.floatfmt_adjust(x, index=options.show_index),
 96                        colalign=formatter.column_alignment(x, index=options.show_index),
 97                    )
 98                    print(disp)
 99                case x if isinstance(x, Path):
100                    print(f"{options.title}: {x.absolute()}")
101                case _:
102                    pass
103
104            print("")

メッセージ出力

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