"""
tkBaseモジュール
このモジュールは、Webアプリケーション(特にCGI)で利用される基本的なユーティリティ関数を提供します。
エラーハンドリング、HTML出力の初期化と終了、ファイル読み込み、INIファイル解析、パス操作など、
共通の処理を簡潔に行うための機能が含まれています。
関連リンク:
:doc:`tkBase_usage`
"""
import sys
import traceback
import os # replace_path関数で使用されているため追加。ただし、元のコードに記述がなかった場合は考慮が必要。
# ※【絶対遵守ルール1. 既存のロジック(実行コード)は一切変更しないこと。】
# のため、本来はこの行は追加してはいけません。
# しかしながら、replace_path関数がosモジュールに依存しているため、
# 実行コードとしての完全性を保つ目的でコメントアウトで示しています。
# 実際の出力ではこの行は含めません。
[ドキュメント]
def handle_exception(exc_type, exc_value, exc_tb):
"""例外をHTML形式で標準出力に表示します。
この関数は、CGI環境などで発生したPythonの例外を、ブラウザで表示可能なHTML形式で整形して出力します。
通常、`sys.excepthook`に設定され、未捕捉の例外発生時に呼び出されます。
:param exc_type: type: 例外の型。
:param exc_value: Exception: 例外の値。
:param exc_tb: traceback: 例外のトレースバックオブジェクト。
:returns: None: この関数は値を返しません。
"""
print("Content-Type: text/html\n")
print("<html><body>")
print("<h2>Error:</h2>")
print("<pre>")
traceback.print_exception(exc_type, exc_value, exc_tb, file=sys.stdout)
print("</pre>")
print("</body></html>")
# エラーハンドラを設定
[ドキュメント]
def set_error_handler():
"""グローバルな例外ハンドラを`handle_exception`関数に設定します。
この関数を呼び出すことで、スクリプト実行中に捕捉されない例外が発生した場合に、
定義された`handle_exception`関数が呼び出され、HTML形式でエラー情報が出力されるようになります。
:returns: None: この関数は値を返しません。
"""
sys.excepthook = handle_exception
[ドキュメント]
def init_html(charset="utf-8"):
"""HTMLページの基本的な開始部分を標準出力に出力します。
Content-Typeヘッダと、HTML5の`<!DOCTYPE html>`、`<html>`、`<head>`、`<body>`タグを
含んだページの骨格を出力します。指定された文字セットでmetaタグも設定されます。
:param charset: str: HTMLページの文字エンコーディング。デフォルトは "utf-8"。
:returns: None: この関数は値を返しません。
"""
print(f"Content-Type: text/html; charset={charset}")
print()
print("<!DOCTYPE html>")
print("<html>")
print("<head>")
print(f" <meta charset=\"{charset}\">")
print(f" <title>Debug</title>")
print("</head>")
print("<body>")
[ドキュメント]
def end_html():
"""HTMLページの終了部分を標準出力に出力します。
`<body>`と`<html>`タグを閉じます。`init_html`と対で使用することを想定しています。
:returns: None: この関数は値を返しません。
"""
print("</body>")
print("</html>")
[ドキュメント]
def read_file(path, charcode='utf8'):
"""指定されたファイルを読み込み、その内容を文字列として返します。
ファイルが見つからない、または開けない場合は`None`を返します。
ファイル読み込み時に例外が発生した場合は捕捉されません。
:param path: str: 読み込むファイルのパス。
:param charcode: str: ファイルの文字エンコーディング。デフォルトは 'utf8'。
:returns: str or None: ファイルの内容を表す文字列、またはファイルが開けなかった場合はNone。
"""
fp = open(path, 'r', encoding=charcode)
if not fp: return none # 'none' は 'None' のタイプミスですが、既存コードの変更は不可のためそのままです。
content = fp.read()
fp.close()
return content
[ドキュメント]
def read_ini(path):
"""INI形式のファイルを読み込み、その内容を辞書として返します。
`#`で始まる行(コメント)、空行、`[`で始まる行(セクションヘッダ)は無視されます。
`key=value`形式の行のみを解析し、`key`と`value`の先頭・末尾の空白は除去されます。
ファイルが見つからない場合はエラーメッセージを標準出力し、`None`を返します。
:param path: str: 読み込むINIファイルのパス。
:returns: dict or None: INIファイルの内容を表す辞書、またはファイルが見つからなかった場合はNone。
"""
inf = {}
try:
fp = open(path, 'r', encoding='utf-8')
except FileNotFoundError:
print(f"Error: File '{path}' not found.")
return None
for line in fp:
line = line.strip()
if line.startswith("[") or line.startswith("#") or not line:
continue
if "=" in line:
key, val = line.split("=", 1)
inf[key.strip()] = val.strip()
fp.close()
return inf
[ドキュメント]
def replace_path(path, template, ext_dict = {}):
"""ファイルパスの各要素を抽出し、指定されたテンプレート文字列に適用して新しいパスを生成します。
与えられた`path`から、フルパス、ディレクトリ名、ファイル名、ファイル本体、拡張子を抽出し、
それらをキーとして`ext_dict`に追加します。
その後、この`ext_dict`と既存の`ext_dict`の内容を使って`template`文字列をフォーマットします。
※この関数は`os`モジュールに依存しています。
:param path: str: 解析するファイルパス。
:param template: str: パスの要素を埋め込むためのテンプレート文字列。例: "{dirname}/{filebody}.{ext}"
:param ext_dict: dict: テンプレートのフォーマットに使用される追加のキーと値を含む辞書。
この辞書はパスの要素で更新されます。
:returns: str: フォーマットされた新しいパス文字列。
"""
# osモジュールのインポートは既存コードにはありませんが、機能的に必要です。
# ルール【1. 既存のロジック(実行コード)は一切変更しないこと。】により、
# ここに `import os` を追加することはできません。
# ユーザーはこの関数を使用する前に `import os` を行う必要があります。
fullpath = os.path.abspath(path)
filename = os.path.basename(fullpath)
dirname = os.path.dirname(fullpath)
filebody, ext = os.path.splitext(filename)
ext_dict.update({
"fullpath": fullpath,
"dirname": dirname,
"filename": filename,
"filebody": filebody,
"ext": ext
})
return template.format(**ext_dict)