Commit 833f80f6 authored by Elizabeth Myers's avatar Elizabeth Myers 💬
Browse files

Implement emoji upload

parent 3391ccdd
......@@ -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())
......@@ -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']
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment