From 5f2c91946ce54d1ee82e31536e50d32f6f580858 Mon Sep 17 00:00:00 2001 From: Jon Wood Date: Mon, 25 Mar 2024 13:11:20 +0000 Subject: [PATCH] Create a basic model for WebPush targets --- .../ee286bc4206a_create_webpush_target.py | 46 +++++++++++++++++++ models/user.py | 8 ++++ models/web_push.py | 22 +++++++++ 3 files changed, 76 insertions(+) create mode 100644 migrations/versions/ee286bc4206a_create_webpush_target.py create mode 100644 models/web_push.py diff --git a/migrations/versions/ee286bc4206a_create_webpush_target.py b/migrations/versions/ee286bc4206a_create_webpush_target.py new file mode 100644 index 000000000..93dd4312b --- /dev/null +++ b/migrations/versions/ee286bc4206a_create_webpush_target.py @@ -0,0 +1,46 @@ +"""create_webpush_target + +Revision ID: ee286bc4206a +Revises: 214878041f05 +Create Date: 2024-03-25 12:52:56.462206 + +""" + +# revision identifiers, used by Alembic. +revision = "ee286bc4206a" +down_revision = "214878041f05" + +from datetime import datetime + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + op.create_table( + "web_push_target", + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column("user_id", sa.Integer(), autoincrement=False, nullable=False), + sa.Column("endpoint", sa.String(), nullable=False), + sa.Column("expires", sa.DateTime(), nullable=True), + sa.Column("subscription_info", sa.JSON(), nullable=False), + sa.Column("created", sa.DateTime(), nullable=False, default=datetime.utcnow), + sa.PrimaryKeyConstraint("id"), + sa.ForeignKeyConstraint( + ["user_id"], + ["user.id"], + name=op.f("fk_web_push_target_mapping_user_id_user_id"), + ), + ) + op.create_index(op.f("ix_web_push_target_user_id"), "web_push_target", ["user_id"]) + op.create_index( + op.f("ix_web_push_target_user_id_endpoint"), + "web_push_target", + ["user_id", "endpoint"], + ) + + +def downgrade(): + op.drop_index("ix_web_push_target_user_id") + op.drop_index("ix_web_push_target_user_id_endpoint") + op.drop_table("web_push_target") diff --git a/models/user.py b/models/user.py index 6fb4a9c73..815d9a061 100644 --- a/models/user.py +++ b/models/user.py @@ -22,6 +22,7 @@ from . import bucketise, BaseModel from .permission import UserPermission, Permission from .volunteer.shift import ShiftEntry +from .web_push import WebPushTarget CHECKIN_CODE_LEN = 16 checkin_code_re = r"[0-9a-zA-Z_-]{%s}" % CHECKIN_CODE_LEN @@ -290,6 +291,13 @@ class User(BaseModel, UserMixin): ) village = association_proxy("village_membership", "village") + web_push_targets = db.relationship( + "WebPushTarget", + cascade="all, delete-orphan", + back_populates="user", + primaryjoin="WebPushTarget.user_id == User.id", + ) + def __init__(self, email: str, name: str): self.email = email self.name = name diff --git a/models/web_push.py b/models/web_push.py new file mode 100644 index 000000000..32839054d --- /dev/null +++ b/models/web_push.py @@ -0,0 +1,22 @@ +from datetime import datetime +from main import db + +from . import BaseModel + + +class WebPushTarget(BaseModel): + __table_name__ = "web_push_target" + id = db.Column(db.Integer, primary_key=True) + endpoint = db.Column(db.String, nullable=False) + subscription_info = db.Column(db.JSON, nullable=False) + expires = db.Column(db.DateTime, nullable=True) + user_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False) + created = db.Column(db.DateTime, default=datetime.utcnow, nullable=False) + + user = db.relationship("User") + + def __init__(self, user, endpoint, subscription_info, expires=None): + self.user = user + self.endpoint = endpoint + self.subscription_info = subscription_info + self.expires = expires