Passed
Push — master ( ba269f...37a7d8 )
by Jochen
03:39
created

_replace_body_with_rendered_body()   A

Complexity

Conditions 2

Size

Total Lines 7
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 6
nop 1
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
"""
2
byceps.blueprints.news.views
3
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4
5
:Copyright: 2006-2020 Jochen Kupperschmidt
6
:License: Modified BSD, see LICENSE for details.
7
"""
8
9
import dataclasses
10
11
from flask import abort, g
12
13
from ...services.news import service as news_service
14
from ...services.site import settings_service as site_settings_service
15
from ...util.framework.blueprint import create_blueprint
16
from ...util.framework.templating import templated
17
18
from ..admin.news.authorization import NewsItemPermission
19
from ..authorization.registry import permission_registry
20
21
22
blueprint = create_blueprint('news', __name__)
23
24
25
permission_registry.register_enum(NewsItemPermission)
26
27
28
DEFAULT_ITEMS_PER_PAGE = 4
29
30
31
@blueprint.route('/', defaults={'page': 1})
32
@blueprint.route('/pages/<int:page>')
33
@templated
34
def index(page):
35
    """Show a page of news items."""
36
    channel_id = _get_channel_id()
37
    items_per_page = _get_items_per_page_value()
38
    published_only = not _may_view_drafts(g.current_user)
39
40
    items = news_service.get_aggregated_items_paginated(
41
        channel_id, page, items_per_page, published_only=published_only
42
    )
43
44
    replacement_items = [
45
        _replace_body_with_rendered_body(item) for item in items.items
46
    ]
47
    items.items = replacement_items
48
49
    return {
50
        'items': items,
51
        'page': page,
52
    }
53
54
55
@blueprint.route('/<slug>')
56
@templated
57
def view(slug):
58
    """Show a single news item."""
59
    channel_id = _get_channel_id()
60
    published_only = not _may_view_drafts(g.current_user)
61
62
    item = news_service.find_aggregated_item_by_slug(
63
        channel_id, slug, published_only=published_only
64
    )
65
66
    if item is None:
67
        abort(404)
68
69
    item = _replace_body_with_rendered_body(item)
70
71
    return {
72
        'item': item,
73
    }
74
75
76
def _get_channel_id():
77
    channel_id = site_settings_service.find_setting_value(
78
        g.site_id, 'news_channel_id'
79
    )
80
81
    if channel_id is None:
82
        abort(404)
83
84
    return channel_id
85
86
87
def _get_items_per_page_value():
88
    items_per_page = site_settings_service.find_setting_value(
89
        g.site_id, 'news_items_per_page'
90
    )
91
92
    if items_per_page is None:
93
        return DEFAULT_ITEMS_PER_PAGE
94
95
    return int(items_per_page)
96
97
98
def _may_view_drafts(user):
99
    return user.has_permission(NewsItemPermission.view_draft)
100
101
102
def _replace_body_with_rendered_body(item):
103
    try:
104
        rendered_body = news_service.render_body(item.body)
105
    except Exception as e:
106
        rendered_body = None  # Not the best error indicator.
107
108
    return dataclasses.replace(item, body=rendered_body)
109