~homeworkprod/byceps

ref: 4237b3ec9496efe95dcce82bea3207ab9de4d520 byceps/byceps/services/newsletter/models.py -rw-r--r-- 2.3 KiB
4237b3ec — Jochen Kupperschmidt Move ticketing blueprint into `site` subpackage 1 year, 11 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
"""
byceps.services.newsletter.models
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:Copyright: 2006-2020 Jochen Kupperschmidt
:License: Modified BSD, see LICENSE for details.
"""

from dataclasses import dataclass
from datetime import datetime

from sqlalchemy.ext.hybrid import hybrid_property

from ...database import db
from ...typing import UserID
from ...util.instances import ReprBuilder

from .transfer.models import ListID
from .types import SubscriptionState


class List(db.Model):
    """A newsletter list users can subscribe to."""

    __tablename__ = 'newsletter_lists'

    id = db.Column(db.UnicodeText, primary_key=True)
    title = db.Column(db.UnicodeText, nullable=False)

    def __init__(self, list_id: ListID, title: str) -> None:
        self.id = list_id
        self.title = title

    def __repr__(self) -> str:
        return ReprBuilder(self) \
            .add_with_lookup('id') \
            .build()


@dataclass(frozen=True)
class Subscriber:
    screen_name: str
    email_address: str


class SubscriptionUpdate(db.Model):
    """A user's declaration on wanting/not wanting to receive
    newsletters from this list.
    """

    __tablename__ = 'newsletter_subscription_updates'

    user_id = db.Column(db.Uuid, db.ForeignKey('users.id'), primary_key=True)
    list_id = db.Column(db.UnicodeText, db.ForeignKey('newsletter_lists.id'), primary_key=True)
    expressed_at = db.Column(db.DateTime, primary_key=True)
    _state = db.Column('state', db.UnicodeText, nullable=False)

    def __init__(
        self,
        user_id: UserID,
        list_id: ListID,
        expressed_at: datetime,
        state: SubscriptionState,
    ) -> None:
        self.user_id = user_id
        self.list_id = list_id
        self.expressed_at = expressed_at
        self.state = state

    @hybrid_property
    def state(self) -> SubscriptionState:
        return SubscriptionState[self._state]

    @state.setter
    def state(self, state: SubscriptionState) -> None:
        assert state is not None
        self._state = state.name

    def __repr__(self) -> str:
        return ReprBuilder(self) \
            .add_with_lookup('user_id') \
            .add_with_lookup('list_id') \
            .add_with_lookup('expressed_at') \
            .add('state', self.state.name) \
            .build()