feat: add Gitea as webhook-based service provider
First webhook-based provider integration (Immich uses polling).
Gitea pushes events via POST /api/webhooks/gitea/{provider_id} with
HMAC-SHA256 signature validation.
- 9 event types: push, issue opened/closed/commented, PR opened/closed/merged/commented, release published
- Generic filters system on NotificationTracker (collections, senders, exclude_senders)
- Provider capabilities include supported_filters and webhook_based flag
- Gitea API client for connection testing and repository listing
- 18 default Jinja2 notification templates (EN + RU)
- Frontend: conditional provider forms, Gitea event toggles in tracking config
- Auto-migration for filters column and Gitea tracking flags
This commit is contained in:
@@ -130,6 +130,34 @@ async def migrate_schema(engine: AsyncEngine) -> None:
|
||||
)
|
||||
logger.info("Added memory_source column to tracking_config table")
|
||||
|
||||
# Add filters JSON column to notification_tracker if missing
|
||||
if await _has_table(conn, tracker_table):
|
||||
if not await _has_column(conn, tracker_table, "filters"):
|
||||
await conn.execute(
|
||||
text(f"ALTER TABLE {tracker_table} ADD COLUMN filters TEXT DEFAULT '{{}}'")
|
||||
)
|
||||
logger.info("Added filters column to %s table", tracker_table)
|
||||
|
||||
# Add Gitea tracking flags to tracking_config if missing
|
||||
if await _has_table(conn, "tracking_config"):
|
||||
gitea_flags = [
|
||||
("track_push", "INTEGER DEFAULT 1"),
|
||||
("track_issue_opened", "INTEGER DEFAULT 1"),
|
||||
("track_issue_closed", "INTEGER DEFAULT 1"),
|
||||
("track_issue_commented", "INTEGER DEFAULT 0"),
|
||||
("track_pr_opened", "INTEGER DEFAULT 1"),
|
||||
("track_pr_closed", "INTEGER DEFAULT 1"),
|
||||
("track_pr_merged", "INTEGER DEFAULT 1"),
|
||||
("track_pr_commented", "INTEGER DEFAULT 0"),
|
||||
("track_release_published", "INTEGER DEFAULT 1"),
|
||||
]
|
||||
for col_name, col_type in gitea_flags:
|
||||
if not await _has_column(conn, "tracking_config", col_name):
|
||||
await conn.execute(
|
||||
text(f"ALTER TABLE tracking_config ADD COLUMN {col_name} {col_type}")
|
||||
)
|
||||
logger.info("Added %s column to tracking_config table", col_name)
|
||||
|
||||
# Add collection_name and shared to tracker_state if missing
|
||||
state_table = "notification_tracker_state" if await _has_table(conn, "notification_tracker_state") else "tracker_state"
|
||||
if await _has_table(conn, state_table):
|
||||
|
||||
@@ -115,6 +115,19 @@ class TrackingConfig(SQLModel, table=True):
|
||||
track_collection_renamed: bool = Field(default=True)
|
||||
track_collection_deleted: bool = Field(default=True)
|
||||
track_sharing_changed: bool = Field(default=False)
|
||||
|
||||
# Gitea event tracking
|
||||
track_push: bool = Field(default=True)
|
||||
track_issue_opened: bool = Field(default=True)
|
||||
track_issue_closed: bool = Field(default=True)
|
||||
track_issue_commented: bool = Field(default=False)
|
||||
track_pr_opened: bool = Field(default=True)
|
||||
track_pr_closed: bool = Field(default=True)
|
||||
track_pr_merged: bool = Field(default=True)
|
||||
track_pr_commented: bool = Field(default=False)
|
||||
track_release_published: bool = Field(default=True)
|
||||
|
||||
# Immich asset display
|
||||
track_images: bool = Field(default=True)
|
||||
track_videos: bool = Field(default=True)
|
||||
notify_favorites_only: bool = Field(default=False)
|
||||
@@ -247,6 +260,7 @@ class NotificationTracker(SQLModel, table=True):
|
||||
name: str
|
||||
icon: str = Field(default="")
|
||||
collection_ids: list[str] = Field(default_factory=list, sa_column=Column(JSON))
|
||||
filters: dict[str, Any] = Field(default_factory=dict, sa_column=Column(JSON))
|
||||
scan_interval: int = Field(default=60)
|
||||
batch_duration: int = Field(default=0) # seconds to accumulate events before dispatch (0=immediate)
|
||||
enabled: bool = Field(default=True)
|
||||
|
||||
Reference in New Issue
Block a user