# 組み込みプラグイン 組み込みプラグインは AB に同梱され、`module/plugins/builtin/` にあります。サードパーティのプラグインと同じ SDK で実装されているので、書き方の参考になります。設定 → プラグインで有効化・無効化・設定ができます。 | id | 既定 | 用途 | | --- | --- | --- | | `rename` | 有効 | リネーム方式 `pn`、`advance`、`template` | | `ingest-filters` | 有効 | 包含フィルター(`torrent.filter`) | | `media-server-refresh` | 有効 | 整理後に Jellyfin / Emby / Plex を更新(アドレスとキーを設定するまで何もしません) | | `hardlink` | 無効 | 整理したファイルをメディアライブラリへハードリンク | ## rename ホストが持つのは `none`(元の名前のまま)だけです。`pn` はファイル名から解析したタイトルで命名し、`advance` は作品フォルダ名で命名します。出力は 3.x とバイト単位で同一です。`template` は、サンドボックス化された Jinja2 テンプレートでファイル名の本体を描画します。 ::: v-pre テンプレートは設定 → プラグイン → rename に入力します。例:`{{ title }} - S{{ season|pad(2) }}E{{ episode|pad(2) }}`。使える変数は `title`、`bangumi_name`、`season`、`episode`、`episode_type`、`group`、`kind`、`language` です。フィルター `pad(n)` はゼロ埋めをし、半話の小数部分は保ちます。保存時に一度試しに描画し、不正なテンプレートは拒否されます(HTTP 422)。実行時に描画に失敗した場合、または結果が空かパス区切りを含む場合、そのファイルは元の名前のままになり、通知が送られます。**`pn` に戻ることはありません。** ::: ## ingest-filters ルール自身の「除外フィルター」に加えて、「包含フィルター」を追加します。正規表現(大文字小文字を区別しない)のリストを設定すると、名前がいずれかに一致するトレントだけをダウンロードします。空ならフィルターしません。不正な正規表現は文字列としてそのまま照合されます。 ## media-server-refresh `torrent.organized` と、`hardlink` が新しいファイルをライブラリに置いたときに発行する `hardlink.linked` を購読します。最初のイベントを受け取ってから `delay` 秒待ち、その間のイベントを 1 回の更新リクエストにまとめます。リクエスト送信後に届いたイベントは、もう 1 回の更新になります。 | オプション | 説明 | | --- | --- | | `server` | `jellyfin`、`emby`、`plex` | | `url` | サーバーのアドレス。例:`http://192.168.1.10:8096`(Plex の既定ポートは 32400)。空なら更新しません | | `api_key` | Jellyfin / Emby の API キー、または Plex の `X-Plex-Token` | | `delay` | 待ち時間(秒)。既定は 30 | ## hardlink `torrent.organized` を購読し、本編と字幕をメディアライブラリのディレクトリにリンクします。ダウンロードディレクトリはそのまま残り、シードを続けます。 | オプション | 説明 | | --- | --- | | `source_root` | ダウンロードのルート(AB のローカルパス)。ライブラリは同じ構造を保ちます:`library_root / (source_root からの相対パス)` | | `library_root` | メディアライブラリのディレクトリ(AB のローカルパス)。`source_root` の中に置けません | | `path_map` | `[{downloader, from, to}]`:ダウンローダーのパスの接頭辞 `from` を AB のローカルパス `to` に置き換えます。`downloader` の既定は `default`。最長一致で、一致しないパスはそのまま使います | | `cross_device` | ハードリンクがファイルシステムをまたぐ(EXDEV)場合:`copy`(既定)、`symlink`、`skip`(スキップして通知) | - 初回の有効化時は `source_root` と `library_root` が未入力なので、プラグインは読み込み失敗と表示されます。設定フォームは既に表示されています。入力して保存すると、プラグインが再読み込みされます。 - リンクまたはコピーは、まず保存先の隣の一時ファイルに作り、その後アトミックにリネームします。コピーが中断しても、中途半端なファイルは残りません。 - ライブラリに同名のファイルがあり、このプラグインが作ったものでない場合は、スキップして上書きせず、`hardlink.failed` 通知を送ります。 - このプラグインが同じ話のために作ったリンクは、バージョンアップ後(新バージョンが古いトレントを置換し、正規のファイル名が同じ場合)にアトミックに置き換えられ、新しいファイルを指します。 - 既にリンク済みのファイルのイベントを受け取っても、何もしません。作成したパスはプラグイン自身のキーバリューストアに記録されます。プラグインが配置した後にユーザーが削除したファイルは、イベントを再び受け取っても再作成されません。バックフィルだけが再作成します。 - **トレントを削除しても、ライブラリのリンクは削除されません。** - プラグインを有効にする前にダウンロードしたファイルは自動では処理されません。プラグインの設定セクションで「既存ファイルをリンク」をクリックするか、`POST /api/v1/plugins/hardlink/backfill` を呼びます。`source_root` 以下の `.mp4` / `.mkv` / `.ass` / `.srt` を走査し、`{"linked", "exists", "conflict", "failed"}` の件数を返します。 ::: tip Docker ハードリンクはファイルシステムをまたげません。Docker では、ダウンロードディレクトリとメディアライブラリを同じディスクに置き、**同じマウントポイント**で AB コンテナにマップしてください(例:`/mnt/media` 全体を `/media` としてマウントし、両方をその下に置く)。別々にマウントしたディレクトリは、同じディスクにあっても別のファイルシステムとして扱われ、リンクは `cross_device` の動作に切り替わります。ダウンローダーが別のコンテナで動作し、AB とパスの見え方が違う場合は、`path_map` で変換します。 :::