Completed
Push — master ( 87f3f9...e861eb )
by Jochen
04:09
created

create()   B

Complexity

Conditions 5

Size

Total Lines 30
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 21
nop 0
dl 0
loc 30
rs 8.9093
c 0
b 0
f 0
1
"""
2
byceps.blueprints.api.tourney.avatar.views
3
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4
5
:Copyright: 2006-2019 Jochen Kupperschmidt
6
:License: Modified BSD, see LICENSE for details.
7
"""
8
9
from flask import abort, request
10
11
from .....services.party import service as party_service
12
from .....services.tourney.avatar import service as avatar_service
13
from .....services.user import service as user_service
14
from .....util.framework.blueprint import create_blueprint
15
from .....util.image.models import ImageType
16
from .....util.views import respond_created, respond_no_content
17
18
from ...decorators import api_token_required
19
20
from .forms import CreateForm
21
22
23
blueprint = create_blueprint('api_tourney_avatar', __name__)
24
25
26
ALLOWED_IMAGE_TYPES = frozenset([
27
    ImageType.jpeg,
28
    ImageType.png,
29
])
30
31
32
@blueprint.route('', methods=['POST'])
33
@api_token_required
34
@respond_created
35
def create():
36
    """Create an avatar image."""
37
    # Make `InputRequired` work on `FileField`.
38
    form_fields = request.form.copy()
39
    if request.files:
40
        form_fields.update(request.files)
41
42
    form = CreateForm(form_fields)
43
44
    if not form.validate():
45
        abort(400, 'Form validation failed.')
46
47
    party_id = form.party_id.data
48
    creator_id = form.creator_id.data
49
    image = request.files.get('image')
50
51
    party = party_service.find_party(party_id)
52
    if not party:
53
        abort(400, 'Unknown party ID')
54
55
    creator = user_service.find_user(creator_id)
56
    if not creator:
57
        abort(400, 'Unknown creator ID')
58
59
    avatar = _create(party.id, creator.id, image)
60
61
    return avatar.url_path
62
63
64
def _create(party_id, creator_id, image):
65
    if not image or not image.filename:
66
        abort(400, 'No file to upload has been specified.')
67
68
    try:
69
        return avatar_service.create_avatar_image(
70
            party_id, creator_id, image.stream, ALLOWED_IMAGE_TYPES
71
        )
72
    except avatar_service.ImageTypeProhibited as e:
73
        abort(400, str(e))
74
    except FileExistsError:
75
        abort(409, 'File already exists, not overwriting.')
76
77
78
@blueprint.route('/<uuid:avatar_id>', methods=['DELETE'])
79
@api_token_required
80
@respond_no_content
81
def delete(avatar_id):
82
    """Delete the avatar image."""
83
    try:
84
        avatar_service.delete_avatar_image(avatar_id)
85
    except ValueError:
86
        abort(404)
87