Passed
Push — master ( a65c88...e2c8b9 )
by Jochen
02:49
created

category_hide()   A

Complexity

Conditions 1

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 8
nop 1
dl 0
loc 11
rs 10
c 0
b 0
f 0
1
"""
2
byceps.blueprints.admin.board.views
3
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4
5
:Copyright: 2006-2019 Jochen Kupperschmidt
6
:License: Modified BSD, see LICENSE for details.
7
"""
8
9
from collections import namedtuple
10
11
from flask import abort, request
12
13
from ....services.board import board_service
14
from ....services.board import \
15
    category_command_service as board_category_command_service, \
16
    category_query_service as board_category_query_service, \
17
    posting_query_service as board_posting_query_service, \
18
    topic_query_service as board_topic_query_service
19
from ....services.board.transfer.models import Board, Category
20
from ....services.brand import service as brand_service
21
from ....util.framework.blueprint import create_blueprint
22
from ....util.framework.flash import flash_error, flash_success
23
from ....util.framework.templating import templated
24
from ....util.views import redirect_to, respond_no_content
25
26
from ...authorization.decorators import permission_required
27
from ...authorization.registry import permission_registry
28
from ...board.authorization import BoardPermission
29
30
from .authorization import BoardCategoryPermission
31
from .forms import BoardCreateForm, CategoryCreateForm, CategoryUpdateForm
32
33
34
blueprint = create_blueprint('board_admin', __name__)
35
36
37
permission_registry.register_enum(BoardPermission)
38
permission_registry.register_enum(BoardCategoryPermission)
39
40
41
BoardStats = namedtuple('BoardStats', [
42
    'category_count',
43
    'topic_count',
44
    'posting_count',
45
])
46
47
48
# -------------------------------------------------------------------- #
49
# boards
50
51
52
@blueprint.route('/brands/<brand_id>')
53
@permission_required(BoardCategoryPermission.view)
54
@templated
55
def board_index_for_brand(brand_id):
56
    """List categories for that brand."""
57
    brand = _get_brand_or_404(brand_id)
58
59
    boards = board_service.get_boards_for_brand(brand.id)
60
    board_ids = [board.id for board in boards]
61
62
    stats_by_board_id = {
63
        board_id: BoardStats(
64
            board_category_query_service.count_categories_for_board(board_id),
65
            board_topic_query_service.count_topics_for_board(board_id),
66
            board_posting_query_service.count_postings_for_board(board_id),
67
        )
68
        for board_id in board_ids}
69
70
    return {
71
        'board_ids': board_ids,
72
        'brand': brand,
73
        'stats_by_board_id': stats_by_board_id,
74
    }
75
76
77
@blueprint.route('/boards/<board_id>')
78
@permission_required(BoardCategoryPermission.view)
79
@templated
80
def board_view(board_id):
81
    """View the board."""
82
    board = _get_board_or_404(board_id)
83
84
    brand = brand_service.find_brand(board.brand_id)
85
86
    categories = board_category_query_service.get_categories(board.id)
87
88
    return {
89
        'board_id': board.id,
90
        'board_brand_id': board.brand_id,
91
        'brand': brand,
92
        'categories': categories,
93
    }
94
95
96
@blueprint.route('/for_brand/<brand_id>/boards/create')
97
@permission_required(BoardPermission.create)
98
@templated
99
def board_create_form(brand_id, erroneous_form=None):
100
    """Show form to create a board."""
101
    brand = _get_brand_or_404(brand_id)
102
103
    form = erroneous_form if erroneous_form else BoardCreateForm()
104
105
    return {
106
        'brand': brand,
107
        'form': form,
108
    }
109
110
111
@blueprint.route('/for_brand/<brand_id>/boards', methods=['POST'])
112
@permission_required(BoardPermission.create)
113
def board_create(brand_id):
114
    """Create a board."""
115
    brand = _get_brand_or_404(brand_id)
116
117
    form = BoardCreateForm(request.form)
118
    if not form.validate():
119
        return board_create_form(brand.id, form)
120
121
    board_id = form.board_id.data.strip().lower()
122
123
    board = board_service.create_board(brand.id, board_id)
124
125
    flash_success('Das Forum mit der ID "{}" wurde angelegt.', board.id)
126
    return redirect_to('.board_view', board_id=board.id)
127
128
129
# -------------------------------------------------------------------- #
130
# categories
131
132
133
@blueprint.route('/for_board/<board_id>/create')
134
@permission_required(BoardCategoryPermission.create)
135
@templated
136
def category_create_form(board_id, erroneous_form=None):
137
    """Show form to create a category."""
138
    board = _get_board_or_404(board_id)
139
140
    brand = brand_service.find_brand(board.brand_id)
141
142
    form = erroneous_form if erroneous_form else CategoryCreateForm()
143
144
    return {
145
        'board_id': board_id,
146
        'brand': brand,
147
        'form': form,
148
    }
149
150
151
@blueprint.route('/for_board/<board_id>', methods=['POST'])
152
@permission_required(BoardCategoryPermission.create)
153
def category_create(board_id):
154
    """Create a category."""
155
    board = _get_board_or_404(board_id)
156
157
    form = CategoryCreateForm(request.form)
158
    if not form.validate():
159
        return category_create_form(board.id, form)
160
161
    slug = form.slug.data.strip().lower()
162
    title = form.title.data.strip()
163
    description = form.description.data.strip()
164
165
    category = board_category_command_service \
166
        .create_category(board.id, slug, title, description)
167
168
    flash_success('Die Kategorie "{}" wurde angelegt.', category.title)
169
    return redirect_to('.board_view', board_id=board.id)
170
171
172
@blueprint.route('/categories/<uuid:category_id>/update')
173
@permission_required(BoardCategoryPermission.update)
174
@templated
175
def category_update_form(category_id, erroneous_form=None):
176
    """Show form to update the category."""
177
    category = _get_category_or_404(category_id)
178
179
    board = board_service.find_board(category.board_id)
180
    brand = brand_service.find_brand(board.brand_id)
181
182
    form = erroneous_form if erroneous_form \
183
           else CategoryUpdateForm(obj=category)
184
185
    return {
186
        'category': category,
187
        'brand': brand,
188
        'form': form,
189
    }
190
191
192
@blueprint.route('/categories/<uuid:category_id>', methods=['POST'])
193
@permission_required(BoardCategoryPermission.update)
194
def category_update(category_id):
195
    """Update the category."""
196
    category = _get_category_or_404(category_id)
197
198
    form = CategoryUpdateForm(request.form)
199
    if not form.validate():
200
        return category_update_form(category_id, form)
201
202
    slug = form.slug.data
203
    title = form.title.data
204
    description = form.description.data
205
206
    category = board_category_command_service \
207
        .update_category(category.id, slug, title, description)
208
209
    flash_success('Die Kategorie "{}" wurde aktualisiert.', category.title)
210
    return redirect_to('.board_view', board_id=category.board_id)
211
212
213
@blueprint.route('/categories/<uuid:category_id>/flags/hidden',
214
                 methods=['POST'])
215
@permission_required(BoardCategoryPermission.update)
216
@respond_no_content
217
def category_hide(category_id):
218
    """Hide the category."""
219
    category = _get_category_or_404(category_id)
220
221
    board_category_command_service.hide_category(category.id)
222
223
    flash_success('Die Kategorie "{}" wurde versteckt.', category.title)
224
225
226
@blueprint.route('/categories/<uuid:category_id>/flags/hidden',
227
                 methods=['DELETE'])
228
@permission_required(BoardCategoryPermission.update)
229
@respond_no_content
230
def category_unhide(category_id):
231
    """Un-hide the category."""
232
    category = _get_category_or_404(category_id)
233
234
    board_category_command_service.unhide_category(category.id)
235
236
    flash_success('Die Kategorie "{}" wurde sichtbar gemacht.', category.title)
237
238
239
@blueprint.route('/categories/<uuid:category_id>/up', methods=['POST'])
240
@permission_required(BoardCategoryPermission.update)
241
@respond_no_content
242
def category_move_up(category_id):
243
    """Move the category upwards by one position."""
244
    category = _get_category_or_404(category_id)
245
246
    try:
247
        board_category_command_service.move_category_up(category.id)
248
    except ValueError:
249
        flash_error('Die Kategorie "{}" befindet sich bereits ganz oben.', category.title)
250
    else:
251
        flash_success('Die Kategorie "{}" wurde eine Position nach oben verschoben.', category.title)
252
253
254
@blueprint.route('/categories/<uuid:category_id>/down', methods=['POST'])
255
@permission_required(BoardCategoryPermission.update)
256
@respond_no_content
257
def category_move_down(category_id):
258
    """Move the category downwards by one position."""
259
    category = _get_category_or_404(category_id)
260
261
    try:
262
        board_category_command_service.move_category_down(category.id)
263
    except ValueError:
264
        flash_error('Die Kategorie "{}" befindet sich bereits ganz unten.', category.title)
265
    else:
266
        flash_success('Die Kategorie "{}" wurde eine Position nach unten verschoben.', category.title)
267
268
269
# -------------------------------------------------------------------- #
270
# helpers
271
272
273
def _get_brand_or_404(brand_id):
274
    brand = brand_service.find_brand(brand_id)
275
276
    if brand is None:
277
        abort(404)
278
279
    return brand
280
281
282
def _get_board_or_404(board_id) -> Board:
283
    board = board_service.find_board(board_id)
284
285
    if board is None:
286
        abort(404)
287
288
    return board
289
290
291
def _get_category_or_404(category_id) -> Category:
292
    category = board_category_query_service.find_category_by_id(category_id)
293
294
    if category is None:
295
        abort(404)
296
297
    return category
298