libs.functions.configuration

libs/functions/configuration.py

  1"""
  2libs/functions/configuration.py
  3"""
  4
  5import argparse
  6import logging
  7import os
  8import shutil
  9import sys
 10from functools import partial
 11
 12from matplotlib import use
 13
 14import libs.global_value as g
 15from cls.config import AppConfig
 16from cls.parser import MessageParser
 17from libs.data import lookup
 18
 19
 20def set_loglevel():
 21    """ログレベル追加"""
 22
 23    # DEBUG : 10
 24    # INFO : 20
 25    # WARNING : 30
 26    # ERROR : 40
 27    # CRITICAL : 50
 28
 29    # TRACE
 30    logging.TRACE = 5  # type: ignore
 31    logging.trace = partial(logging.log, logging.TRACE)  # type: ignore
 32    logging.addLevelName(logging.TRACE, "TRACE")  # type: ignore
 33
 34    # NOTICE
 35    logging.NOTICE = 25  # type: ignore
 36    logging.notice = partial(logging.log, logging.NOTICE)  # type: ignore
 37    logging.addLevelName(logging.NOTICE, "NOTICE")  # type: ignore
 38
 39
 40def arg_parser() -> argparse.Namespace:
 41    """コマンドライン解析
 42
 43    Returns:
 44        argparse.ArgumentParser: オブジェクト
 45    """
 46
 47    p = argparse.ArgumentParser(
 48        formatter_class=argparse.RawTextHelpFormatter,
 49        add_help=True,
 50    )
 51
 52    p.add_argument(
 53        "--debug",
 54        action="store_true",
 55        help="デバッグ情報表示",
 56    )
 57
 58    p.add_argument(
 59        "--verbose", "--trace",
 60        dest="verbose",
 61        action="store_true",
 62        help="詳細デバッグ情報表示",
 63    )
 64
 65    p.add_argument(
 66        "--moderate",
 67        action="store_true",
 68        help="ログレベルがエラー以下のもを非表示",
 69    )
 70
 71    p.add_argument(
 72        "--notime",
 73        action="store_true",
 74        help="ログフォーマットから日時を削除",
 75    )
 76
 77    p.add_argument(
 78        "-c", "--config",
 79        default="config.ini",
 80        help="設定ファイル(default: %(default)s)",
 81    )
 82
 83    p.add_argument(
 84        "--profile",
 85        help=argparse.SUPPRESS,
 86    )
 87
 88    match os.path.basename(sys.argv[0]):
 89        case "dbtools.py":  # dbtools専用オプション
 90            group = p.add_mutually_exclusive_group()
 91            group.add_argument(
 92                "--compar",
 93                action="store_true",
 94                help="データ突合",
 95            )
 96
 97            group.add_argument(
 98                "--unification",
 99                nargs="?",
100                const="rename.ini",
101                help="ファイルの内容に従って記録済みのメンバー名を修正する(default: %(const)s)",
102            )
103
104            group.add_argument(
105                "--recalculation",
106                action="store_true",
107                help="ポイント再計算",
108            )
109
110            group.add_argument(
111                "--export",
112                dest="export_data",
113                nargs="?",
114                const="export",
115                metavar="PREFIX",
116                help="メンバー設定情報をエクスポート(default prefix: %(const)s)",
117            )
118
119            group.add_argument(
120                "--import",
121                nargs="?",
122                dest="import_data",
123                const="export",
124                metavar="PREFIX",
125                help="メンバー設定情報をインポート(default prefix: %(const)s)",
126            )
127
128            group.add_argument(
129                "--vacuum",
130                action="store_true",
131                help="database vacuum",
132            )
133
134            group.add_argument(
135                "--gen-test-data",
136                type=int,
137                dest="gen_test_data",
138                nargs="?",
139                const=1,
140                default=None,
141                metavar="count",
142                help="テスト用サンプルデータ生成(count=生成回数, default: %(const)s)",
143            )
144
145        case "test.py":  # 動作テスト用オプション
146            p.add_argument(
147                "-t", "--testcase",
148                dest="testcase",
149            )
150
151    return p.parse_args()
152
153
154def setup() -> None:
155    """設定ファイル読み込み"""
156    set_loglevel()
157
158    g.args = arg_parser()
159    if not hasattr(g.args, "testcase"):
160        g.args.testcase = False
161
162    if g.args.notime:
163        fmt = "[%(levelname)s][%(module)s:%(funcName)s] %(message)s"
164    else:
165        fmt = "[%(asctime)s][%(levelname)s][%(module)s:%(funcName)s] %(message)s"
166
167    if g.args.debug:
168        if g.args.verbose:
169            print("DEBUG MODE(verbose)")
170            logging.basicConfig(level=logging.TRACE, format=fmt)  # type: ignore
171        else:
172            print("DEBUG MODE")
173            logging.basicConfig(level=logging.INFO, format=fmt)
174    else:
175        if g.args.moderate:
176            logging.basicConfig(level=logging.WARNING, format=fmt)
177        else:
178            logging.basicConfig(level=logging.NOTICE, format=fmt)  # type: ignore
179
180    g.cfg = AppConfig(g.args.config)
181    g.msg = MessageParser()
182
183    logging.notice(  # type: ignore
184        "rule_version: %s, origin_point: %s, return_point: %s, time_adjust: %sh",
185        g.cfg.mahjong.rule_version, g.cfg.mahjong.origin_point, g.cfg.mahjong.return_point, g.cfg.setting.time_adjust
186    )
187
188    # 作業用ディレクトリ作成
189    try:
190        if os.path.isdir(g.cfg.setting.work_dir):
191            shutil.rmtree(g.cfg.setting.work_dir)
192        os.mkdir(g.cfg.setting.work_dir)
193    except Exception as e:
194        raise RuntimeError(e) from e
195
196
197def read_memberslist(log=True):
198    """メンバー/チームリスト読み込み
199
200    Args:
201        log (bool, optional): 読み込み時に内容をログに出力する. Defaults to True.
202    """
203
204    g.cfg.member.guest_name = lookup.db.get_guest()
205    g.member_list = lookup.db.get_member_list()
206    g.team_list = lookup.db.get_team_list()
207
208    if log:
209        logging.notice(f"guest_name: {g.cfg.member.guest_name}")  # type: ignore
210        logging.notice(f"member_list: {set(g.member_list.values())}")  # type: ignore
211        logging.notice(f"team_list: {[x["team"] for x in g.team_list]}")  # type: ignore
212
213
214def graph_setup(plt, fm) -> None:
215    """グラフ設定
216
217    Args:
218        plt (matplotlib.font_manager): matplotlibオブジェクト
219        fm (matplotlib.pyplot): matplotlibオブジェクト
220    """
221
222    use(backend="agg")
223    mlogger = logging.getLogger("matplotlib")
224    mlogger.setLevel(logging.WARNING)
225
226    # スタイルの適応
227    if (style := g.cfg.setting.graph_style) not in plt.style.available:
228        style = "ggplot"
229    plt.style.use(style)
230
231    # フォント再設定
232    for x in ("family", "serif", "sans-serif", "cursive", "fantasy", "monospace"):
233        if f"font.{x}" in plt.rcParams:
234            plt.rcParams[f"font.{x}"] = ""
235
236    fm.fontManager.addfont(g.cfg.setting.font_file)
237    font_prop = fm.FontProperties(fname=g.cfg.setting.font_file)
238    plt.rcParams["font.family"] = font_prop.get_name()
239
240    # グリッド線
241    if not plt.rcParams["axes.grid"]:
242        plt.rcParams["axes.grid"] = True
243        plt.rcParams["grid.alpha"] = 0.3
244        plt.rcParams["grid.linestyle"] = "--"
245    plt.rcParams["axes.axisbelow"] = True
def set_loglevel():
21def set_loglevel():
22    """ログレベル追加"""
23
24    # DEBUG : 10
25    # INFO : 20
26    # WARNING : 30
27    # ERROR : 40
28    # CRITICAL : 50
29
30    # TRACE
31    logging.TRACE = 5  # type: ignore
32    logging.trace = partial(logging.log, logging.TRACE)  # type: ignore
33    logging.addLevelName(logging.TRACE, "TRACE")  # type: ignore
34
35    # NOTICE
36    logging.NOTICE = 25  # type: ignore
37    logging.notice = partial(logging.log, logging.NOTICE)  # type: ignore
38    logging.addLevelName(logging.NOTICE, "NOTICE")  # type: ignore

ログレベル追加

def arg_parser() -> argparse.Namespace:
 41def arg_parser() -> argparse.Namespace:
 42    """コマンドライン解析
 43
 44    Returns:
 45        argparse.ArgumentParser: オブジェクト
 46    """
 47
 48    p = argparse.ArgumentParser(
 49        formatter_class=argparse.RawTextHelpFormatter,
 50        add_help=True,
 51    )
 52
 53    p.add_argument(
 54        "--debug",
 55        action="store_true",
 56        help="デバッグ情報表示",
 57    )
 58
 59    p.add_argument(
 60        "--verbose", "--trace",
 61        dest="verbose",
 62        action="store_true",
 63        help="詳細デバッグ情報表示",
 64    )
 65
 66    p.add_argument(
 67        "--moderate",
 68        action="store_true",
 69        help="ログレベルがエラー以下のもを非表示",
 70    )
 71
 72    p.add_argument(
 73        "--notime",
 74        action="store_true",
 75        help="ログフォーマットから日時を削除",
 76    )
 77
 78    p.add_argument(
 79        "-c", "--config",
 80        default="config.ini",
 81        help="設定ファイル(default: %(default)s)",
 82    )
 83
 84    p.add_argument(
 85        "--profile",
 86        help=argparse.SUPPRESS,
 87    )
 88
 89    match os.path.basename(sys.argv[0]):
 90        case "dbtools.py":  # dbtools専用オプション
 91            group = p.add_mutually_exclusive_group()
 92            group.add_argument(
 93                "--compar",
 94                action="store_true",
 95                help="データ突合",
 96            )
 97
 98            group.add_argument(
 99                "--unification",
100                nargs="?",
101                const="rename.ini",
102                help="ファイルの内容に従って記録済みのメンバー名を修正する(default: %(const)s)",
103            )
104
105            group.add_argument(
106                "--recalculation",
107                action="store_true",
108                help="ポイント再計算",
109            )
110
111            group.add_argument(
112                "--export",
113                dest="export_data",
114                nargs="?",
115                const="export",
116                metavar="PREFIX",
117                help="メンバー設定情報をエクスポート(default prefix: %(const)s)",
118            )
119
120            group.add_argument(
121                "--import",
122                nargs="?",
123                dest="import_data",
124                const="export",
125                metavar="PREFIX",
126                help="メンバー設定情報をインポート(default prefix: %(const)s)",
127            )
128
129            group.add_argument(
130                "--vacuum",
131                action="store_true",
132                help="database vacuum",
133            )
134
135            group.add_argument(
136                "--gen-test-data",
137                type=int,
138                dest="gen_test_data",
139                nargs="?",
140                const=1,
141                default=None,
142                metavar="count",
143                help="テスト用サンプルデータ生成(count=生成回数, default: %(const)s)",
144            )
145
146        case "test.py":  # 動作テスト用オプション
147            p.add_argument(
148                "-t", "--testcase",
149                dest="testcase",
150            )
151
152    return p.parse_args()

コマンドライン解析

Returns:

argparse.ArgumentParser: オブジェクト

def setup() -> None:
155def setup() -> None:
156    """設定ファイル読み込み"""
157    set_loglevel()
158
159    g.args = arg_parser()
160    if not hasattr(g.args, "testcase"):
161        g.args.testcase = False
162
163    if g.args.notime:
164        fmt = "[%(levelname)s][%(module)s:%(funcName)s] %(message)s"
165    else:
166        fmt = "[%(asctime)s][%(levelname)s][%(module)s:%(funcName)s] %(message)s"
167
168    if g.args.debug:
169        if g.args.verbose:
170            print("DEBUG MODE(verbose)")
171            logging.basicConfig(level=logging.TRACE, format=fmt)  # type: ignore
172        else:
173            print("DEBUG MODE")
174            logging.basicConfig(level=logging.INFO, format=fmt)
175    else:
176        if g.args.moderate:
177            logging.basicConfig(level=logging.WARNING, format=fmt)
178        else:
179            logging.basicConfig(level=logging.NOTICE, format=fmt)  # type: ignore
180
181    g.cfg = AppConfig(g.args.config)
182    g.msg = MessageParser()
183
184    logging.notice(  # type: ignore
185        "rule_version: %s, origin_point: %s, return_point: %s, time_adjust: %sh",
186        g.cfg.mahjong.rule_version, g.cfg.mahjong.origin_point, g.cfg.mahjong.return_point, g.cfg.setting.time_adjust
187    )
188
189    # 作業用ディレクトリ作成
190    try:
191        if os.path.isdir(g.cfg.setting.work_dir):
192            shutil.rmtree(g.cfg.setting.work_dir)
193        os.mkdir(g.cfg.setting.work_dir)
194    except Exception as e:
195        raise RuntimeError(e) from e

設定ファイル読み込み

def read_memberslist(log=True):
198def read_memberslist(log=True):
199    """メンバー/チームリスト読み込み
200
201    Args:
202        log (bool, optional): 読み込み時に内容をログに出力する. Defaults to True.
203    """
204
205    g.cfg.member.guest_name = lookup.db.get_guest()
206    g.member_list = lookup.db.get_member_list()
207    g.team_list = lookup.db.get_team_list()
208
209    if log:
210        logging.notice(f"guest_name: {g.cfg.member.guest_name}")  # type: ignore
211        logging.notice(f"member_list: {set(g.member_list.values())}")  # type: ignore
212        logging.notice(f"team_list: {[x["team"] for x in g.team_list]}")  # type: ignore

メンバー/チームリスト読み込み

Arguments:
  • log (bool, optional): 読み込み時に内容をログに出力する. Defaults to True.
def graph_setup(plt, fm) -> None:
215def graph_setup(plt, fm) -> None:
216    """グラフ設定
217
218    Args:
219        plt (matplotlib.font_manager): matplotlibオブジェクト
220        fm (matplotlib.pyplot): matplotlibオブジェクト
221    """
222
223    use(backend="agg")
224    mlogger = logging.getLogger("matplotlib")
225    mlogger.setLevel(logging.WARNING)
226
227    # スタイルの適応
228    if (style := g.cfg.setting.graph_style) not in plt.style.available:
229        style = "ggplot"
230    plt.style.use(style)
231
232    # フォント再設定
233    for x in ("family", "serif", "sans-serif", "cursive", "fantasy", "monospace"):
234        if f"font.{x}" in plt.rcParams:
235            plt.rcParams[f"font.{x}"] = ""
236
237    fm.fontManager.addfont(g.cfg.setting.font_file)
238    font_prop = fm.FontProperties(fname=g.cfg.setting.font_file)
239    plt.rcParams["font.family"] = font_prop.get_name()
240
241    # グリッド線
242    if not plt.rcParams["axes.grid"]:
243        plt.rcParams["axes.grid"] = True
244        plt.rcParams["grid.alpha"] = 0.3
245        plt.rcParams["grid.linestyle"] = "--"
246    plt.rcParams["axes.axisbelow"] = True

グラフ設定

Arguments:
  • plt (matplotlib.font_manager): matplotlibオブジェクト
  • fm (matplotlib.pyplot): matplotlibオブジェクト