Modernized codebase with tooling configuration and CI/CD workflows.
Audit / Dependencies (push) Successful in 8s
CI / Formatting (push) Successful in 6s
CI / Linting (push) Successful in 6s
CI / Type Checking (push) Successful in 9s
CI / Spelling (push) Successful in 6s

- Replaced legacy typing (Optional, List, Type, Union, Tuple) with PEP 604/585 equivalents.
- Added pyproject.toml with configurations for hatch-vcs, mypy, ruff, and codespell.
- Added CI workflows for formatting, linting, type checking, and spelling.
- Added CD workflow for building and uploading plugin artifacts on push to master and version tags.
- Added dependency auditing workflow with pip-audit.
- Added comprehensive docstrings and inline comments across all modules.
- Fixed User-Agent header using hardcoded version instead of actual plugin version.
- Fixed grammar and terminology in log messages and comments.
- Removed unreachable error handling branch in unsubscribe command.
This commit is contained in:
2026-03-11 14:37:56 -04:00
parent 314e1bf399
commit d05d73eddc
18 changed files with 2472 additions and 598 deletions
+45 -38
View File
@@ -1,58 +1,69 @@
# Copyright 2026 Logan Fick
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at: https://www.apache.org/licenses/LICENSE-2.0
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from mautrix.util.async_db import UpgradeTable, Connection
"""Database migration definitions for OwncastSentry."""
from mautrix.util.async_db import Connection, UpgradeTable
upgrade_table = UpgradeTable()
@upgrade_table.register(description="Initial revision")
@upgrade_table.register(description="Initial revision") # type: ignore[arg-type, call-arg, untyped-decorator]
async def upgrade_v1(conn: Connection) -> None:
"""
Runs migrations to upgrade database schema to verison 1 format.
Version 1 is the initial format of the database.
"""Create the initial database schema.
Creates the streams and subscriptions tables.
:param conn: A connection to run the v1 database migration on.
:return: Nothing.
"""
await conn.execute(
"""CREATE TABLE "streams" (
"domain" TEXT NOT NULL UNIQUE,
"name" TEXT,
"title" TEXT,
"last_connect_time" TEXT,
"last_disconnect_time" TEXT,
PRIMARY KEY("domain")
"domain" TEXT NOT NULL UNIQUE,
"name" TEXT,
"title" TEXT,
"last_connect_time" TEXT,
"last_disconnect_time" TEXT,
PRIMARY KEY("domain")
)"""
)
await conn.execute(
"""CREATE TABLE "subscriptions" (
"stream_domain" INTEGER NOT NULL,
"room_id" TEXT NOT NULL,
UNIQUE("room_id","stream_domain")
"stream_domain" INTEGER NOT NULL,
"room_id" TEXT NOT NULL,
UNIQUE("room_id","stream_domain")
)"""
)
@upgrade_table.register(description="Fix stream_domain column type from INTEGER to TEXT")
@upgrade_table.register( # type: ignore[arg-type, call-arg, untyped-decorator]
description="Fix stream_domain column type from INTEGER to TEXT"
)
async def upgrade_v2(conn: Connection) -> None:
"""
Runs migrations to upgrade database schema to version 2 format.
Version 2 fixes the stream_domain column type in subscriptions table from INTEGER to TEXT.
"""Upgrade database schema to version 2 format.
Fixes the stream_domain column type in the subscriptions table
from INTEGER to TEXT.
:param conn: A connection to run the v2 database migration on.
:return: Nothing.
"""
# Create new subscriptions table with correct schema
await conn.execute(
"""CREATE TABLE "subscriptions_new" (
"stream_domain" TEXT NOT NULL,
"room_id" TEXT NOT NULL,
UNIQUE("room_id","stream_domain")
"stream_domain" TEXT NOT NULL,
"room_id" TEXT NOT NULL,
UNIQUE("room_id","stream_domain")
)"""
)
@@ -62,21 +73,21 @@ async def upgrade_v2(conn: Connection) -> None:
SELECT stream_domain, room_id FROM subscriptions"""
)
# Drop the old table
# Drop the old table and rename new table to original name
await conn.execute("DROP TABLE subscriptions")
# Rename new table to original name
await conn.execute("ALTER TABLE subscriptions_new RENAME TO subscriptions")
@upgrade_table.register(description="Add failure_counter column for backoff and auto-cleanup")
@upgrade_table.register( # type: ignore[arg-type, call-arg, untyped-decorator]
description="Add failure_counter column for backoff and auto-cleanup"
)
async def upgrade_v3(conn: Connection) -> None:
"""
Runs migrations to upgrade database schema to version 3 format.
Version 3 adds the failure_counter column to track connection failures for backoff and auto-cleanup.
"""Upgrade database schema to version 3 format.
Adds the failure_counter column to track connection failures
for backoff and auto-cleanup.
:param conn: A connection to run the v3 database migration on.
:return: Nothing.
"""
# Add failure_counter column with default value of 0
await conn.execute(
@@ -85,9 +96,5 @@ async def upgrade_v3(conn: Connection) -> None:
def get_upgrade_table() -> UpgradeTable:
"""
Helper function for retrieving the upgrade table.
:return: The upgrade table with registered migrations.
"""
"""Return the upgrade table with registered migrations."""
return upgrade_table