mirror of
https://github.com/EstrellaXD/Auto_Bangumi.git
synced 2026-10-29 03:36:15 +08:00
标签在发布之前打上,之后的轮次不再检查该种子:订阅者处理中被取消 (重启、插件重载)的事件永远不会再投递,硬链接漏掉这一集。现在每个 进程按当前文件名为已打标签的种子补发一次,丢失的事件在下次启动时 重新投递,投递恢复为至少一次;没有事件总线时不查询文件。 test_renamed_tag_skips_before_file_and_offset_queries 改为在已发布的 稳态下断言。文档与 TorrentOrganized 说明同步更新。
6.5 KiB
6.5 KiB
イベント
イベントは凍結された dataclass です。クラス変数 kind がイベント名です。ホストとプラグインは 1 つのイベントバスを共有します。
from ab_sdk import subscribe
from ab_sdk.events import RssFailureEvent
@subscribe("rss_failure")
async def on_rss_failure(self, event: RssFailureEvent):
self.ctx.log.warning("購読 %s が失敗しました:%s", event.rss_name, event.error)
- 購読者は専用のキューで、発行順に非同期で実行されます。失敗やタイムアウトは発行側に影響せず、プラグインのブレーカーに数えられます。既定のタイムアウトは 30 秒です。大きなファイルのコピーのような長い処理には
@subscribe(kind, timeout=600)を使います。 "*"は全イベントを購読します。- 発行は
self.ctx.bus.publish(event)で行います。プラグインのイベントのkindは<プラグイン id>.で始める必要があります。ホストのイベントとの衝突を防ぐためです。 - フロントエンドコンポーネントは
host.events.on(kind, callback)で同じバスを購読します。コールバックはイベントのフィールドを受け取ります(フロントエンドスロット を参照)。
システムイベント
AB が通知センターに送るイベントは、すべて ab_sdk.events.SystemEvent のサブクラスです。severity、payload()、describe()(既定の中国語タイトルと本文)、i18n()(フロントエンドの i18n キーと引数)を持ちます。AB はまず通知センターに書き込み、次にイベントバスへ発行し、最後に外部チャンネルへプッシュします。「通知」スイッチが影響するのは外部へのプッシュだけです。プラグインは常にイベントを受け取ります。
| kind | イベントクラス | 発行のタイミング |
|---|---|---|
rss_failure |
RssFailureEvent |
RSS 購読が正常から接続異常に変わったとき |
download_failure |
DownloadFailureEvent |
リトライ後もトレントの追加に失敗したとき |
offset_review |
OffsetReviewEvent |
作品のシーズン / 話数オフセットの確認が必要なとき |
downloader_unavailable |
DownloaderUnavailableEvent |
ダウンローダーに接続できない、認証情報が違う、IP が遮断された。各インスタンスが利用可能から利用不可に変わるたびに 1 回 |
update_available |
UpdateAvailableEvent |
新しいバージョンを検出したとき |
update_applied / update_failed |
UpdateAppliedEvent |
オンライン更新が成功 / 失敗したとき |
llm_auth_failure |
LLMAuthFailureEvent |
サブスクリプション型 LLM プロバイダーの認証情報が無効になったとき |
llm_plugin_install_failed |
LLMPluginInstallFailedEvent |
LLM プラグインのインストールに失敗したとき |
rename_conflict |
RenameConflictEvent |
メディアファイルのリネームで保存先が競合したとき |
rename_skipped |
RenameSkippedEvent |
リネーム方式がファイル名を決められず、元の名前のままにしたとき |
plugin.loaded |
PluginLoaded |
プラグインの読み込みに成功したとき |
plugin.disabled |
PluginDisabled |
プラグインの読み込みに失敗した、またはブレーカーが作動したとき |
システムイベントの kind は 3.x の値のままです(通知センターはこれで保存と翻訳を行います)。そのため . のプレフィックスはありません。
整理イベント
| kind | イベントクラス | フィールド | 発行のタイミング |
|---|---|---|---|
file.renamed |
FileRenamed |
bangumi_id、old_path、new_path、file_kind、downloader_id |
ファイルが実際にリネームされたとき(バージョン置換後のリネームを含む) |
torrent.organized |
TorrentOrganized |
torrent_hash、bangumi_id、files(OrganizedFile(path, kind) のタプル)、downloader_id |
トレントの整理が完了したとき。リネーム方式が none でも発行され、files は元のパスです。選択したリネーム方式が未登録(プラグインが無効、または遮断済み)の間は発行されません |
- パスはダウンローダーから見た絶対パスで、
/で連結されます(Windows ダウンローダーの\も/に統一されます)。AB とダウンローダーで見えるディレクトリが異なる場合(別々のコンテナで動作している場合など)は、購読者側でパスを変換する必要があります。 bangumi_idはトレントのab:<id>タグに由来します。古いトレントではNoneの場合があります。downloader_idはトレントがあるダウンローダーインスタンスの id です。インスタンスごとにパスの見え方が異なることがあります。torrent.organizedの配信は少なくとも 1 回(at-least-once)です。ダウンローダーにある整理済みのトレントは、「リネーム済み」タグがあっても、AB を再起動するたびにもう一度発行されます。購読者は冪等にしてください。- この 2 つのイベントはイベントバスにだけ発行されます。通知センターには入りません。
独自イベント
通常のイベントは Event を継承して定義します。通知できるイベントは SystemEvent を継承します。発行すると、ホストのイベントと同じ経路をたどります。通知センターへの書き込み(フロントエンドに翻訳がなければ describe() のタイトルと本文を表示)、イベントバスへの発行、外部チャンネルへのプッシュです。dedup_key() が同じイベントは、通知センターで 1 件にまとめられます。
from dataclasses import dataclass
from typing import ClassVar
from ab_sdk.events import SystemEvent
@dataclass(frozen=True, slots=True)
class SyncFailed(SystemEvent):
kind: ClassVar[str] = "my-plugin.sync_failed"
severity: ClassVar[str] = "warning"
reason: str
def describe(self) -> tuple[str, str]:
return ("同期に失敗しました", self.reason)
組み込みの hardlink の hardlink.failed も、この方法で発行しています。