Test Failed
Push — main ( 2ac75e...34ff35 )
by Jochen
08:37
created

DbPageVersion.is_current()   A

Complexity

Conditions 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
nop 1
dl 0
loc 6
rs 10
c 0
b 0
f 0
ccs 3
cts 3
cp 1
crap 1
1
"""
2
byceps.services.page.dbmodels
3
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4
5
Pages of database-stored content. Can contain HTML and template engine
6
syntax.
7
8
:Copyright: 2014-2022 Jochen Kupperschmidt
9
:License: Revised BSD (see `LICENSE` file for details)
10
"""
11
12 1
from datetime import datetime
13 1
from typing import Optional
14
15 1
from sqlalchemy.ext.associationproxy import association_proxy
16
17 1
from ...database import db, generate_uuid
18 1
from ...typing import UserID
19
20 1
from ..language.dbmodels import DbLanguage
21 1
from ..site.transfer.models import SiteID
22 1
from ..site_navigation.dbmodels import DbMenu
23 1
from ..user.dbmodels.user import DbUser
24
25
26 1
class DbPage(db.Model):
27
    """A content page.
28
29
    Any page is expected to have at least one version (the initial one).
30
    """
31
32 1
    __tablename__ = 'pages'
33 1
    __table_args__ = (
34
        db.UniqueConstraint('site_id', 'name'),
35
        db.UniqueConstraint('site_id', 'language_code', 'url_path'),
36
    )
37
38 1
    id = db.Column(db.Uuid, default=generate_uuid, primary_key=True)
39 1
    site_id = db.Column(
40
        db.UnicodeText, db.ForeignKey('sites.id'), index=True, nullable=False
41
    )
42 1
    name = db.Column(db.UnicodeText, index=True, nullable=False)
43 1
    language_code = db.Column(
44
        db.UnicodeText,
45
        db.ForeignKey('languages.code'),
46
        index=True,
47
        nullable=False,
48
    )
49 1
    language = db.relationship(DbLanguage)
50 1
    url_path = db.Column(db.UnicodeText, index=True, nullable=False)
51 1
    published = db.Column(db.Boolean, nullable=False)
52 1
    nav_menu_id = db.Column(
53
        db.Uuid, db.ForeignKey('site_nav_menus.id'), nullable=True
54
    )
55 1
    nav_menu = db.relationship(DbMenu)
56
57 1
    current_version = association_proxy(
58
        'current_version_association', 'version'
59
    )
60
61 1
    def __init__(
62
        self, site_id: SiteID, name: str, language_code: str, url_path: str
63
    ) -> None:
64 1
        self.site_id = site_id
65 1
        self.name = name
66 1
        self.language_code = language_code
67 1
        self.url_path = url_path
68 1
        self.published = False
69
70
71 1
class DbPageVersion(db.Model):
72
    """A snapshot of a page at a certain time."""
73
74 1
    __tablename__ = 'page_versions'
75
76 1
    id = db.Column(db.Uuid, default=generate_uuid, primary_key=True)
77 1
    page_id = db.Column(
78
        db.Uuid, db.ForeignKey('pages.id'), index=True, nullable=False
79
    )
80 1
    page = db.relationship(DbPage)
81 1
    created_at = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
82 1
    creator_id = db.Column(db.Uuid, db.ForeignKey('users.id'), nullable=False)
83 1
    creator = db.relationship(DbUser)
84 1
    title = db.Column(db.UnicodeText, nullable=False)
85 1
    head = db.Column(db.UnicodeText, nullable=True)
86 1
    body = db.Column(db.UnicodeText, nullable=False)
87
88 1
    def __init__(
89
        self,
90
        page: DbPage,
91
        creator_id: UserID,
92
        title: str,
93
        head: Optional[str],
94
        body: str,
95
    ) -> None:
96 1
        self.page = page
97 1
        self.creator_id = creator_id
98 1
        self.title = title
99 1
        self.head = head
100 1
        self.body = body
101
102 1
    @property
103 1
    def is_current(self) -> bool:
104
        """Return `True` if this version is the current version of the
105
        page it belongs to.
106
        """
107 1
        return self.id == self.page.current_version.id
108
109
110 1
class DbCurrentPageVersionAssociation(db.Model):
111 1
    __tablename__ = 'page_current_versions'
112
113 1
    page_id = db.Column(db.Uuid, db.ForeignKey('pages.id'), primary_key=True)
114 1
    page = db.relationship(
115
        DbPage, backref=db.backref('current_version_association', uselist=False)
116
    )
117 1
    version_id = db.Column(
118
        db.Uuid, db.ForeignKey('page_versions.id'), unique=True, nullable=False
119
    )
120 1
    version = db.relationship(DbPageVersion)
121
122 1
    def __init__(self, page: DbPage, version: DbPageVersion) -> None:
123 1
        self.page = page
124
        self.version = version
125