Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
DCP project
DCPv4
Commits
833f80f6
Commit
833f80f6
authored
Apr 27, 2022
by
Elizabeth Myers
💬
Browse files
Implement emoji upload
parent
3391ccdd
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
112 additions
and
17 deletions
+112
-17
adminscripts/init.py
adminscripts/init.py
+1
-0
dcp/webserver/media.py
dcp/webserver/media.py
+111
-17
No files found.
adminscripts/init.py
View file @
833f80f6
...
...
@@ -15,6 +15,7 @@ async def init():
Path
(
base_media_path
,
'avatar'
).
mkdir
(
parents
=
True
,
exist_ok
=
True
)
Path
(
base_media_path
,
'media'
).
mkdir
(
exist_ok
=
True
)
Path
(
base
.
media_path
,
'file'
).
mkdir
(
exist_ok
=
True
)
Path
(
base
.
media_path
,
'emoji'
).
mkdir
(
exist_ok
=
True
)
asyncio
.
run
(
init
())
dcp/webserver/media.py
View file @
833f80f6
...
...
@@ -85,26 +85,37 @@ class FileUploader(ABC):
self
.
size
=
0
self
.
temp_file
=
NamedTemporaryFile
(
delete
=
False
,
suffix
=
dest_suffix
)
with
self
.
temp_file
.
file
as
f
:
while
True
:
chunk
=
await
field
.
read_chunk
()
if
not
chunk
:
break
self
.
size
+=
len
(
chunk
)
if
self
.
size
>
self
.
max_file_size
:
Path
(
f
.
name
).
unlink
()
raise
web
.
HTTPRequestEntityTooLarge
(
text
=
'{"reason": "File too large"}'
,
content_type
=
'application/json'
)
try
:
with
self
.
temp_file
.
file
as
f
:
while
True
:
chunk
=
await
field
.
read_chunk
()
if
not
chunk
:
break
self
.
size
+=
len
(
chunk
)
if
self
.
size
>
self
.
max_file_size
:
Path
(
f
.
name
).
unlink
()
raise
web
.
HTTPRequestEntityTooLarge
(
text
=
'{"reason": "File too large"}'
,
content_type
=
'application/json'
)
f
.
write
(
chunk
)
f
.
write
(
chunk
)
except
:
Path
(
self
.
temp_file
.
name
).
unlink
()
raise
# This is a relative path into the media directory
await
self
.
process_file
()
Path
(
self
.
temp_file
.
name
).
unlink
()
await
self
.
update_db
()
try
:
await
self
.
process_file
()
finally
:
Path
(
self
.
temp_file
.
name
).
unlink
()
try
:
await
self
.
update_db
()
except
:
Path
(
self
.
storage_path
,
self
.
filename
).
unlink
()
raise
return
self
.
url
...
...
@@ -184,6 +195,79 @@ class MediaFileUploader(FileUploader):
pathname
=
relative_file_path
)
)
await
session
.
execute
(
stmt
)
await
session
.
commit
()
class
EmojiFileUploader
(
MediaFileUploader
):
def
__init__
(
self
,
user
,
request
,
short_code
):
super
().
__init__
(
user
,
request
)
self
.
short_code
=
short_code
@
property
def
relative_storage_path
(
self
):
return
Path
(
'emoji'
)
@
property
def
url
(
self
):
if
conf
.
media_base_url
.
endswith
(
'/'
):
media_base_url
=
conf
.
media_base_url
[:
-
1
]
else
:
media_base_url
=
conf
.
media_base_url
return
'/'
.
join
((
media_base_url
,
'emoji'
,
self
.
filename
))
async
def
process_image
(
self
,
image
):
if
image
.
height
!=
image
.
width
:
raise
web
.
HTTPBadRequest
(
text
=
'{"reason": "File must be square"}'
,
content_type
=
'application/json'
)
if
image
.
height
>
128
:
image
=
(
await
asyncio
.
to_thread
(
image
.
resize
,
(
128
,
128
))
)
return
(
await
super
().
process_image
(
image
))
async
def
update_db
(
self
):
async
with
async_session
()
as
session
:
async
with
session
.
begin
():
# Find the user
stmt
=
(
select
(
StorageUser
).
where
(
StorageUser
.
username
==
self
.
user
)
)
result
=
await
session
.
execute
(
stmt
)
try
:
storage_src
=
result
.
one
()[
0
]
except
(
NoResultFound
,
IndexError
):
# Shouldn't happen
return
web
.
json_response
({
'reason'
:
'Server error'
},
status
=
500
)
relative_file_path
=
str
(
Path
(
self
.
relative_storage_path
,
self
.
filename
))
stmt
=
(
insert
(
StorageUserUpload
).
values
(
user_id
=
storage_src
.
id
,
pathname
=
relative_file_path
)
)
await
session
.
execute
(
stmt
)
# Get ID of upload
stmt
=
(
select
(
StorageUserUpload
.
id
).
where
(
StorageUserUpload
.
id
==
storage_src
.
id
).
where
(
pathname
==
relative_file_path
)
)
result
=
await
session
.
execute
(
stmt
)
upload_id
=
result
.
scalar_one
()
# Add emoji entry
stmt
=
(
insert
(
StorageEmoji
).
values
(
upload_id
=
upload_id
,
short_code
=
self
.
short_code
)
)
await
session
.
execute
(
stmt
)
await
session
.
commit
()
class
AvatarFileUploader
(
MediaFileUploader
):
...
...
@@ -265,6 +349,7 @@ class AvatarFileUploader(MediaFileUploader):
pathname
=
relative_file_path
)
)
await
session
.
execute
(
stmt
)
await
session
.
commit
()
@
routes
.
delete
(
'/avatar/{filename}'
)
...
...
@@ -365,6 +450,15 @@ async def avatar_handler(request):
return
web
.
json_response
({
'url'
:
url
})
@
routes
.
post
(
'/upload/avatar/{short_code}/{user}'
)
async
def
emoji_handler
(
request
):
short_code
=
request
.
match_info
[
'short_code'
]
user
=
request
.
match_info
[
'user'
]
uploader
=
EmojiFileUploader
(
user
,
request
,
short_code
)
url
=
await
uploader
.
get_file
()
return
web
.
json_response
({
'url'
:
url
})
@
routes
.
post
(
'/upload/media/{user}'
)
async
def
media_handler
(
request
):
user
=
request
.
match_info
[
'user'
]
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment