Passed
Push — master ( 0b7d34...61b3a3 )
by Jochen
02:49
created

_get_site_setting_int_value()   A

Complexity

Conditions 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nop 2
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
"""
2
byceps.blueprints.board.service
3
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4
5
:Copyright: 2006-2019 Jochen Kupperschmidt
6
:License: Modified BSD, see LICENSE for details.
7
"""
8
9
from datetime import datetime
10
from typing import Dict, Optional, Sequence, Set
11
12
from flask import g
13
14
from ...services.authentication.session.models.current_user import CurrentUser
15
from ...services.board.models.topic import Topic as DbTopic
16
from ...services.board.models.posting import Posting as DbPosting
17
from ...services.board import (
18
    last_view_service as board_last_view_service,
19
    posting_query_service as board_posting_query_service,
20
)
21
from ...services.board.transfer.models import CategoryWithLastUpdate
22
from ...services.party import service as party_service
23
from ...services.site import settings_service as site_settings_service
24
from ...services.ticketing import ticket_service
25
from ...services.user import service as user_service
26
from ...services.user_badge import service as badge_service
27
from ...services.user_badge.transfer.models import Badge
28
from ...typing import BrandID, PartyID, UserID
29
30
from .models import CategoryWithLastUpdateAndUnseenFlag, Creator, Ticket
31
32
33
DEFAULT_POSTINGS_PER_PAGE = 10
34
DEFAULT_TOPICS_PER_PAGE = 10
35
36
37
def add_unseen_postings_flag_to_categories(
38
    categories: Sequence[CategoryWithLastUpdate], user: CurrentUser
39
) -> Sequence[CategoryWithLastUpdateAndUnseenFlag]:
40
    """Add flag to each category stating if it contains postings unseen
41
    by the user.
42
    """
43
    categories_with_flag = []
44
45
    for category in categories:
46
        contains_unseen_postings = not user.is_anonymous \
47
            and board_last_view_service.contains_category_unseen_postings(
48
                category, user.id)
49
50
        category_with_flag = CategoryWithLastUpdateAndUnseenFlag.from_category_with_last_update(
51
            category, contains_unseen_postings
52
        )
53
54
        categories_with_flag.append(category_with_flag)
55
56
    return categories_with_flag
57
58
59
def add_topic_creators(topics: Sequence[DbTopic]) -> None:
60
    """Add each topic's creator as topic attribute."""
61
    creator_ids = {t.creator_id for t in topics}
62
    creators = user_service.find_users(creator_ids, include_avatars=True)
63
    creators_by_id = user_service.index_users_by_id(creators)
64
65
    for topic in topics:
66
        topic.creator = creators_by_id[topic.creator_id]
67
68
69
def add_topic_unseen_flag(topics: Sequence[DbTopic], user: CurrentUser) -> None:
70
    """Add `unseen` flag to topics."""
71
    for topic in topics:
72
        topic.contains_unseen_postings = not user.is_anonymous \
73
            and board_last_view_service.contains_topic_unseen_postings(
74
                topic, user.id)
75
76
77
def add_unseen_flag_to_postings(
78
    postings: Sequence[DbPosting], user: CurrentUser, last_viewed_at: datetime
79
) -> None:
80
    """Add the attribute 'unseen' to each posting."""
81
    for posting in postings:
82
        posting.unseen = posting.is_unseen(user, last_viewed_at)
83
84
85
def enrich_creators(
86
    postings: Sequence[DbPosting],
87
    brand_id: BrandID,
88
    party_id: Optional[PartyID],
89
) -> None:
90
    """Enrich creators with their badges."""
91
    creator_ids = {posting.creator_id for posting in postings}
92
93
    badges_by_user_id = _get_badges(creator_ids, brand_id)
94
95
    if party_id is not None:
96
        party = party_service.get_party(party_id)
97
        ticket_users = ticket_service.select_ticket_users_for_party(
98
            creator_ids, party.id
99
        )
100
    else:
101
        party = None
102
        ticket_users = set()
103
104
    for posting in postings:
105
        user_id = posting.creator_id
106
107
        badges = badges_by_user_id.get(user_id, frozenset())
108
109
        if user_id in ticket_users:
110
            ticket = Ticket(party.title)
111
        else:
112
            ticket = None
113
114
        posting.creator = Creator.from_(posting.creator, badges, ticket)
115
116
117
def _get_badges(
118
    user_ids: Set[UserID], brand_id: BrandID
119
) -> Dict[UserID, Set[Badge]]:
120
    """Fetch users' badges that are either global or belong to the brand."""
121
    badges_by_user_id = badge_service.get_badges_for_users(
122
        user_ids, featured_only=True
123
    )
124
125
    def generate_items():
126
        for user_id, badges in badges_by_user_id.items():
127
            selected_badges = {
128
                badge for badge in badges if badge.brand_id in {None, brand_id}
129
            }
130
            yield user_id, selected_badges
131
132
    return dict(generate_items())
133
134
135
def calculate_posting_page_number(posting: DbPosting, user: CurrentUser) -> int:
136
    """Calculate the number of postings to show per page."""
137
    postings_per_page = get_postings_per_page_value()
138
139
    return board_posting_query_service.calculate_posting_page_number(
140
        posting, user, postings_per_page
141
    )
142
143
144
def get_topics_per_page_value() -> int:
145
    """Return the configured number of topics per page."""
146
    return _get_site_setting_int_value(
147
        'board_topics_per_page', DEFAULT_TOPICS_PER_PAGE
148
    )
149
150
151
def get_postings_per_page_value() -> int:
152
    """Return the configured number of postings per page."""
153
    return _get_site_setting_int_value(
154
        'board_postings_per_page', DEFAULT_POSTINGS_PER_PAGE
155
    )
156
157
158
def _get_site_setting_int_value(key, default_value) -> int:
159
    value = site_settings_service.find_setting_value(g.site_id, key)
160
161
    if value is None:
162
        return default_value
163
164
    return int(value)
165