Skip to content

Commit fb9f056

Browse files
bhaveshAnKreijstal
authored andcommitted
Fixes fossasia#5205 feat: Load local image default_system_image.png for default system image (fossasia#5312)
1 parent 29ddb66 commit fb9f056

File tree

8 files changed

+138
-11
lines changed

8 files changed

+138
-11
lines changed

app/api/event_topics.py

+65-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
from flask_rest_jsonapi import ResourceDetail, ResourceList, ResourceRelationship
2+
import urllib.error
23

34
from app.api.bootstrap import api
45
from app.api.helpers.db import safe_query
6+
from app.api.helpers.exceptions import UnprocessableEntity
57
from app.api.schema.event_topics import EventTopicSchema
68
from app.models import db
9+
from app.api.helpers.files import create_system_image
710
from app.models.event import Event
811
from app.models.event_sub_topic import EventSubTopic
912
from app.models.event_topic import EventTopic
@@ -14,10 +17,41 @@ class EventTopicList(ResourceList):
1417
"""
1518
List and create event topics
1619
"""
20+
def after_create_object(self, event_topic, data, view_kwargs):
21+
"""
22+
after create method to save roles for users and add the user as an accepted role(organizer)
23+
:param event_topic:
24+
:param data:
25+
:param view_kwargs:
26+
:return:
27+
"""
28+
if data.get('system_image_url'):
29+
try:
30+
uploaded_image = create_system_image(data['system_image_url'], unique_identifier=event_topic.id)
31+
except (urllib.error.HTTPError, urllib.error.URLError):
32+
raise UnprocessableEntity(
33+
{'source': 'attributes/system-image-url'}, 'Invalid Image URL'
34+
)
35+
except IOError:
36+
raise UnprocessableEntity(
37+
{'source': 'attributes/system-image-url'}, 'Image is absent at URL'
38+
)
39+
else:
40+
try:
41+
uploaded_image = create_system_image(unique_identifier=event_topic.id)
42+
except IOError:
43+
raise UnprocessableEntity(
44+
{'source': ''}, 'Default Image is absent in server'
45+
)
46+
47+
self.session.query(EventTopic).filter_by(id=event_topic.id).update(uploaded_image)
48+
self.session.commit()
49+
1750
decorators = (api.has_permission('is_admin', methods="POST"),)
1851
schema = EventTopicSchema
1952
data_layer = {'session': db.session,
20-
'model': EventTopic}
53+
'model': EventTopic,
54+
'methods': {'after_create_object': after_create_object}}
2155

2256

2357
class EventTopicDetail(ResourceDetail):
@@ -49,11 +83,41 @@ def before_get_object(self, view_kwargs):
4983
else:
5084
view_kwargs['id'] = None
5185

86+
def before_update_object(self, event_topic, data, view_kwargs):
87+
"""
88+
method to save image urls before updating event object
89+
:param event_topic:
90+
:param data:
91+
:param view_kwargs:
92+
:return:
93+
"""
94+
if data.get('system_image_url'):
95+
try:
96+
uploaded_image = create_system_image(data['system_image_url'], unique_identifier=event_topic.id)
97+
except (urllib.error.HTTPError, urllib.error.URLError):
98+
raise UnprocessableEntity(
99+
{'source': 'attributes/system-image-url'}, 'Invalid Image URL'
100+
)
101+
except IOError:
102+
raise UnprocessableEntity(
103+
{'source': 'attributes/system-image-url'}, 'Image is absent at URL'
104+
)
105+
else:
106+
try:
107+
uploaded_image = create_system_image(unique_identifier=event_topic.id)
108+
except IOError:
109+
raise UnprocessableEntity(
110+
{'source': ''}, 'Default Image is absent in server'
111+
)
112+
113+
data['system_image_url'] = uploaded_image['system_image_url']
114+
52115
decorators = (api.has_permission('is_admin', methods="PATCH,DELETE"),)
53116
schema = EventTopicSchema
54117
data_layer = {'session': db.session,
55118
'model': EventTopic,
56119
'methods': {
120+
'before_update_object': before_update_object,
57121
'before_get_object': before_get_object
58122
}}
59123

app/api/helpers/files.py

+50
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,56 @@ def create_save_image_sizes(image_file, image_sizes_type, unique_identifier=None
196196
return new_images
197197

198198

199+
def create_system_image(image_file=None, upload_path=None, unique_identifier=None,
200+
ext='jpg'):
201+
"""
202+
Create System Images for Event Topics
203+
:param upload_path:
204+
:param ext:
205+
:param remove_after_upload:
206+
:param image_file:
207+
:return:
208+
"""
209+
# Get an unique identifier from uuid if not provided
210+
filename = '{filename}.{ext}'.format(filename=get_file_name(), ext=ext)
211+
if image_file:
212+
with urllib.request.urlopen(image_file) as img_data:
213+
image_file = io.BytesIO(img_data.read())
214+
else:
215+
file_relative_path = 'static/default_system_image.png'
216+
image_file = app.config['BASE_DIR'] + '/' + file_relative_path
217+
try:
218+
im = Image.open(image_file)
219+
except IOError:
220+
raise IOError("Corrupt/Invalid Image")
221+
222+
# Convert to jpeg for lower file size.
223+
if im.format is not 'JPEG':
224+
img = im.convert('RGB')
225+
else:
226+
img = im
227+
228+
temp_file_relative_path = 'static/media/temp/' + generate_hash(str(image_file)) + get_file_name() + '.jpg'
229+
temp_file_path = app.config['BASE_DIR'] + '/' + temp_file_relative_path
230+
dir_path = temp_file_path.rsplit('/', 1)[0]
231+
232+
# create dirs if not present
233+
if not os.path.isdir(dir_path):
234+
os.makedirs(dir_path)
235+
236+
img.save(temp_file_path)
237+
upfile = UploadedFile(file_path=temp_file_path, filename=filename)
238+
239+
if not upload_path:
240+
upload_path = UPLOAD_PATHS['event_topic']['system_image'].format(event_topic_id=unique_identifier)
241+
242+
uploaded_url = upload(upfile, upload_path)
243+
os.remove(temp_file_path)
244+
245+
image = {'system_image_url': uploaded_url}
246+
return image
247+
248+
199249
def make_frontend_url(path, parameters=None):
200250
"""
201251
Create URL for frontend

app/api/helpers/storage.py

+3
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@
7575
'large': 'custom-placeholders/{identifier}/large',
7676
'icon': 'custom-placeholders/{identifier}/icon'
7777
},
78+
'event_topic': {
79+
'system_image': 'event_topic/{event_topic_id}/system_image'
80+
},
7881
'pdf': {
7982
'ticket_attendee': 'attendees/tickets/pdf/{identifier}'
8083
}

app/api/schema/event_topics.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class Meta:
2121

2222
id = fields.Str(dump_only=True)
2323
name = fields.Str(required=True)
24-
system_image_url = fields.Url(dump_only=True)
24+
system_image_url = fields.Url()
2525
slug = fields.Str(dump_only=True)
2626
events = Relationship(attribute='event',
2727
many=True,

app/factories/event_topic.py

+1
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ class Meta:
1111

1212
name = common.string_
1313
slug = common.slug_
14+
system_image_url = common.imageUrl_

docs/api/api_blueprint.apib

+17-8
Original file line numberDiff line numberDiff line change
@@ -1818,6 +1818,7 @@ Event Topics for Events. Can only be edited and entered by admins.
18181818
|:----------|-------------|------|----------|
18191819
| `name` | Name of the event topic | string | - |
18201820
| `slug` | Slug of the event topic | string | - |
1821+
| `system-image-url` | Url of system image of event topic | string | - |
18211822

18221823

18231824
## Event Topics Collection [/v1/event-topics{?page%5bsize%5d,page%5bnumber%5d,sort}]
@@ -1861,7 +1862,8 @@ Get a list of Event Topics.
18611862
},
18621863
"attributes": {
18631864
"name": "Travel & Outdoor",
1864-
"slug": "travel-outdoor"
1865+
"slug": "travel-outdoor",
1866+
"system-image-url": "https://www.w3schools.com/html/pic_mountain.jpg"
18651867
},
18661868
"type": "event-topic",
18671869
"id": "1",
@@ -1893,7 +1895,8 @@ Create a new event topic with name.
18931895
{
18941896
"data": {
18951897
"attributes": {
1896-
"name": "Travel & Outdoor"
1898+
"name": "Travel & Outdoor",
1899+
"system-image-url": "https://www.w3schools.com/html/pic_mountain.jpg"
18971900
},
18981901
"type": "event-topic"
18991902
}
@@ -1919,7 +1922,8 @@ Create a new event topic with name.
19191922
},
19201923
"attributes": {
19211924
"name": "Travel & Outdoor",
1922-
"slug": "travel-outdoor"
1925+
"slug": "travel-outdoor",
1926+
"system-image-url": "https://www.w3schools.com/html/pic_mountain.jpg"
19231927
},
19241928
"type": "event-topic",
19251929
"id": "1",
@@ -1970,7 +1974,8 @@ Get a single event topic.
19701974
},
19711975
"attributes": {
19721976
"name": "Travel & Outdoor",
1973-
"slug": "travel-outdoor"
1977+
"slug": "travel-outdoor",
1978+
"system-image-url": "https://www.w3schools.com/html/pic_mountain.jpg"
19741979
},
19751980
"type": "event-topic",
19761981
"id": "1",
@@ -2005,7 +2010,8 @@ Authorized user must be admin.
20052010
{
20062011
"data": {
20072012
"attributes": {
2008-
"name": "Travel & Outdoor"
2013+
"name": "Travel & Outdoor",
2014+
"system-image-url": "https://www.w3schools.com/html/pic_mountain.jpg"
20092015
},
20102016
"type": "event-topic",
20112017
"id": "1"
@@ -2032,7 +2038,8 @@ Authorized user must be admin.
20322038
},
20332039
"attributes": {
20342040
"name": "Travel & Outdoor",
2035-
"slug": "travel-outdoor"
2041+
"slug": "travel-outdoor",
2042+
"system-image-url": "https://www.w3schools.com/html/pic_mountain.jpg"
20362043
},
20372044
"type": "event-type",
20382045
"id": "1",
@@ -2106,7 +2113,8 @@ Delete a single event topic.
21062113
},
21072114
"attributes": {
21082115
"slug": "travel-outdoor",
2109-
"name": "Travel & Outdoor"
2116+
"name": "Travel & Outdoor",
2117+
"system-image-url": "https://www.w3schools.com/html/pic_mountain.jpg"
21102118
},
21112119
"type": "event-topic",
21122120
"id": "1",
@@ -2158,7 +2166,8 @@ Delete a single event topic.
21582166
},
21592167
"attributes": {
21602168
"slug": "travel-outdoor",
2161-
"name": "Travel & Outdoor"
2169+
"name": "Travel & Outdoor",
2170+
"system-image-url": "https://www.w3schools.com/html/pic_mountain.jpg"
21622171
},
21632172
"type": "event-topic",
21642173
"id": "1",

static/.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
*
22
*/
33
!.gitignore
4-
!header.png
4+
!default_system_image.png
File renamed without changes.

0 commit comments

Comments
 (0)