1
|
|
|
""" |
2
|
|
|
byceps.blueprints.site.user.avatar.views |
3
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
4
|
|
|
|
5
|
|
|
:Copyright: 2006-2021 Jochen Kupperschmidt |
6
|
|
|
:License: Revised BSD (see `LICENSE` file for details) |
7
|
|
|
""" |
8
|
|
|
|
9
|
1 |
|
from flask import abort, g, request |
10
|
1 |
|
from flask_babel import gettext |
11
|
|
|
|
12
|
1 |
|
from .....services.image import service as image_service |
13
|
1 |
|
from .....services.user_avatar import service as avatar_service |
14
|
1 |
|
from .....signals import user_avatar as user_avatar_signals |
15
|
1 |
|
from .....util.framework.blueprint import create_blueprint |
16
|
1 |
|
from .....util.framework.flash import flash_notice, flash_success |
17
|
1 |
|
from .....util.image.models import ImageType |
18
|
1 |
|
from .....util.framework.templating import templated |
19
|
1 |
|
from .....util.views import redirect_to, respond_no_content |
20
|
|
|
|
21
|
1 |
|
from .forms import UpdateForm |
22
|
|
|
|
23
|
|
|
|
24
|
1 |
|
blueprint = create_blueprint('user_avatar', __name__) |
25
|
|
|
|
26
|
|
|
|
27
|
1 |
|
ALLOWED_IMAGE_TYPES = frozenset( |
28
|
|
|
[ |
29
|
|
|
ImageType.jpeg, |
30
|
|
|
ImageType.png, |
31
|
|
|
] |
32
|
|
|
) |
33
|
|
|
|
34
|
|
|
|
35
|
1 |
|
@blueprint.get('/me/avatar/update') |
36
|
1 |
|
@templated |
37
|
1 |
|
def update_form(erroneous_form=None): |
38
|
|
|
"""Show a form to update the current user's avatar image.""" |
39
|
|
|
_get_current_user_or_404() |
40
|
|
|
|
41
|
|
|
form = erroneous_form if erroneous_form else UpdateForm() |
42
|
|
|
|
43
|
|
|
image_type_names = image_service.get_image_type_names(ALLOWED_IMAGE_TYPES) |
44
|
|
|
|
45
|
|
|
return { |
46
|
|
|
'form': form, |
47
|
|
|
'allowed_types': image_type_names, |
48
|
|
|
'maximum_dimensions': avatar_service.MAXIMUM_DIMENSIONS, |
49
|
|
|
} |
50
|
|
|
|
51
|
|
|
|
52
|
1 |
|
@blueprint.post('/me/avatar') |
53
|
|
|
def update(): |
54
|
|
|
"""Update the current user's avatar image.""" |
55
|
|
|
user = _get_current_user_or_404() |
56
|
|
|
|
57
|
|
|
# Make `InputRequired` work on `FileField`. |
58
|
|
|
form_fields = request.form.copy() |
59
|
|
|
if request.files: |
60
|
|
|
form_fields.update(request.files) |
61
|
|
|
|
62
|
|
|
form = UpdateForm(form_fields) |
63
|
|
|
|
64
|
|
|
if not form.validate(): |
65
|
|
|
return update_form(form) |
66
|
|
|
|
67
|
|
|
image = request.files.get('image') |
68
|
|
|
|
69
|
|
|
_update(user.id, image) |
70
|
|
|
|
71
|
|
|
flash_success(gettext('Avatar image has been updated.'), icon='upload') |
72
|
|
|
user_avatar_signals.avatar_updated.send(None, user_id=user.id) |
73
|
|
|
|
74
|
|
|
return redirect_to('user_settings.view') |
75
|
|
|
|
76
|
|
|
|
77
|
1 |
|
def _update(user_id, image): |
78
|
|
|
if not image or not image.filename: |
79
|
|
|
abort(400, 'No file to upload has been specified.') |
80
|
|
|
|
81
|
|
|
try: |
82
|
|
|
avatar_service.update_avatar_image( |
83
|
|
|
user_id, image.stream, ALLOWED_IMAGE_TYPES |
84
|
|
|
) |
85
|
|
|
except avatar_service.ImageTypeProhibited as e: |
86
|
|
|
abort(400, str(e)) |
87
|
|
|
except FileExistsError: |
88
|
|
|
abort(409, 'File already exists, not overwriting.') |
89
|
|
|
|
90
|
|
|
|
91
|
1 |
|
@blueprint.delete('/me/avatar') |
92
|
1 |
|
@respond_no_content |
93
|
|
|
def delete(): |
94
|
|
|
"""Remove the current user's avatar image.""" |
95
|
|
|
user = _get_current_user_or_404() |
96
|
|
|
|
97
|
|
|
try: |
98
|
|
|
avatar_service.remove_avatar_image(user.id) |
99
|
|
|
except ValueError: |
100
|
|
|
# No avatar selected. |
101
|
|
|
# But that's ok, deletions should be idempotent. |
102
|
|
|
flash_notice(gettext('No avatar image is set that could be removed.')) |
103
|
|
|
else: |
104
|
|
|
flash_success(gettext('Avatar image has been removed.')) |
105
|
|
|
|
106
|
|
|
|
107
|
1 |
|
def _get_current_user_or_404(): |
108
|
|
|
user = g.user |
109
|
|
|
|
110
|
|
|
if not user.authenticated: |
111
|
|
|
abort(404) |
112
|
|
|
|
113
|
|
|
return user |
114
|
|
|
|