This repository has been archived by the owner on Apr 29, 2022. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
131 lines (103 loc) · 3.54 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import quart
import orjson
import urllib3
import io
import os
import random
import time
import ulid
from minio import Minio
from dotenv import load_dotenv
from werkzeug.utils import secure_filename
from werkzeug.datastructures import FileStorage
from cdn.errors import BadData, Unauthorized, Err, NotFound
load_dotenv()
# the secret the Rest API should use.
secret = os.getenv('secret')
try:
import uvloop # type: ignore
uvloop.install()
except:
pass
class ORJSONDecoder:
def __init__(self, **kwargs):
self.options = kwargs
def decode(self, obj):
return orjson.loads(obj)
class ORJSONEncoder:
def __init__(self, **kwargs):
self.options = kwargs
def encode(self, obj):
return orjson.dumps(obj).decode('utf-8')
app = quart.Quart(__name__)
# only accept 10mb or less files.
app.config['MAX_CONTENT_LENGTH'] = 10 * 1000 * 1000
app.json_encoder = ORJSONEncoder
app.json_decoder = ORJSONDecoder
client = Minio(
endpoint=os.getenv('host'),
access_key=os.getenv('access_key', ''),
secret_key=os.getenv('secret_key', ''),
secure=False
)
@app.route('/admin/upload/<bucket_id>', methods=['PUT', 'POST'])
async def upload(bucket_id: str):
if quart.request.headers.get('Authorization') != secret:
raise Unauthorized()
if not client.bucket_exists(bucket_id):
client.make_bucket(bucket_id)
imgs = await quart.request.files
for _, fp in imgs.items():
assert isinstance(fp, FileStorage)
if fp.filename == '':
raise BadData()
ending = '.' + fp.mimetype.split('/')[1]
fp.filename = secure_filename(fp.filename)
try:
name = str(ulid.new())
name += ending
client.put_object(
bucket_name=bucket_id,
object_name=str(name),
data=fp,
length=-1,
content_type=fp.mimetype,
part_size=app.config['MAX_CONTENT_LENGTH']
)
except Exception as exc:
print(repr(exc))
raise BadData()
return quart.jsonify({'id': str(name)})
# TODO: This currently downloads the file, but i just want this to show the file
def get_obj_by_id(bucket_id: str, obj_id: str):
try:
resp: urllib3.HTTPResponse = client.get_object(bucket_id, obj_id)
except:
raise NotFound()
bytesio = io.BytesIO(resp.read(decode_content=False, cache_content=False))
return quart.send_file(bytesio, resp.getheader('content-type').split(';')[0])
@app.route('/users/avatars/<avatar_id>')
async def get_user_avatar(avatar_id):
return await get_obj_by_id('user-avatars', avatar_id)
@app.route('/users/banners/<banner_id>')
async def get_user_banner(banner_id):
return await get_obj_by_id('user-banners', banner_id)
@app.route('/guilds/avatars/<avatar_id>')
async def get_guild_avatar(avatar_id):
return await get_obj_by_id('guild-avatars', avatar_id)
@app.route('/guilds/banners/<banner_id>')
async def get_guild_banner(banner_id):
return await get_obj_by_id('guild-banners', banner_id)
@app.route('/guilds/users/avatars/<avatar_id>')
async def get_guild_user_avatar(avatar_id):
return await get_obj_by_id('guild-user-avatars', avatar_id)
@app.route('/guilds/users/banners/<banner_id>')
async def get_guild_user_banner(banner_id):
return await get_obj_by_id('guild-user-banners', banner_id)
@app.errorhandler(Err)
async def handle_err(err: Err):
resp = err._to_json()
resp.mimetype = 'application/json'
return resp
if __name__ == '__main__':
app.run(debug=True)