"""取り込み元の形ごとの読み取りと登録(1 つの形 = 1 モジュール).
設定ファイルの `sources.<名前>.importer` の名前から importer を選ぶ.取り込み元の形を増やすときは
モジュールを追加して `IMPORTERS` に登録する(既存の importer に分岐を足さない).
"""
from contextlib import closing
from pathlib import Path
from tiasdata import catalog
from tiasdata.catalog import identity
from tiasdata.config import Config
from tiasdata.importers import holds as holds_module
from tiasdata.importers import tongue_color_folders
from tiasdata.importers.base import ImportContext, Importer, ImportResult
# importer の名前(設定の `importer`)→ 取り込みの関数
IMPORTERS: dict[str, Importer] = {
tongue_color_folders.NAME: tongue_color_folders.run,
}
def run_import(
config: Config,
source_name: str,
*,
holds_dir: Path | None = None,
show_source_names: bool = False,
) -> ImportResult:
"""設定ファイルの取り込み元を名前で指定して取り込む.
対応表(`identity.sqlite`)は目録の接続に ATTACH し,目録と対応表への登録を
1 つのトランザクションにまとめる.
Args:
config: 設定.
source_name: 取り込み元の名前(`sources.<名前>`).
holds_dir: 保留リストのフォルダ.省略時はリポジトリの `holds/`.
show_source_names: エラーメッセージに取り込み元での番号・名前を出すか.
Returns:
取り込みの結果(件数).
Raises:
ValueError: 取り込み元・importer が無い,目録・対応表が無いか古い,保留リストの誤り,
取り込み元・対応表の不備,または登録済みの内容との食い違い.
"""
source = config.sources.get(source_name)
if source is None:
raise ValueError(f"設定ファイルに取り込み元 '{source_name}' が無い")
importer = IMPORTERS.get(source.importer)
if importer is None:
raise ValueError(
f"取り込み元 '{source_name}' の importer '{source.importer}' が無い"
f"(使えるもの: {', '.join(sorted(IMPORTERS))})"
)
# 保留リストの場所は呼び出し時に引く(テストで差し替えられるようにモジュール経由で呼ぶ)
directory = holds_dir if holds_dir is not None else holds_module.default_holds_dir()
holds = holds_module.load_holds(directory, source_name)
paths = config.catalog
context = ImportContext(
source_name=source_name,
source=source,
store_dir=paths.store_dir,
holds=holds,
show_source_names=show_source_names,
)
with closing(catalog.connect_latest(paths.catalog_path)) as conn:
identity.attach_identity(conn, paths.identity)
return importer(conn, context)
__all__ = ["IMPORTERS", "ImportContext", "ImportResult", "Importer", "run_import"]