You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
256 lines
9.4 KiB
Python
256 lines
9.4 KiB
Python
from quart import request, Response, render_template, session, redirect, jsonify, abort, current_app, url_for
|
|
import aiohttp
|
|
from app import app, db
|
|
from app.models import User, Blog, Post
|
|
from nanoid import generate
|
|
from functools import wraps
|
|
import json
|
|
from quart_cors import route_cors
|
|
|
|
@app.before_first_request
|
|
def create_tables():
|
|
db.create_all()
|
|
|
|
def user_cook(f):
|
|
@wraps(f)
|
|
async def decorated_function(*args, **kwargs):
|
|
if session.get('username'):
|
|
return await current_app.ensure_async(f)(*args, **kwargs)
|
|
else:
|
|
return abort(403)
|
|
return decorated_function
|
|
|
|
@app.route('/health_check')
|
|
#@route_cors()
|
|
async def health_check():
|
|
status1, _, _, _ = await get_request(f"http://{app.config.get('REDIRECT_SERVER')}/health_check")
|
|
status2, _, _, _ = await get_request(f"http://{app.config.get('CONTENT_SERVER')}/health_check")
|
|
if status1 == 200 and status2 == 200:
|
|
return "OK"
|
|
else:
|
|
return "Not OK", 500
|
|
|
|
@app.route('/health_check2')
|
|
#@route_cors()
|
|
async def health_check2():
|
|
return "OK"
|
|
|
|
@app.route('/image/<path>')
|
|
#@route_cors()
|
|
async def get_image(path): # put application's code here
|
|
#if x.get(""): #if valid image (example 404, 405, corrupted_image)
|
|
#...
|
|
#else:
|
|
|
|
path2 = request.args.get("another") #путь до картинки (логика хранения картинки как в CDN (начало пути - начало хеша).
|
|
filename = request.args.get("filename")
|
|
content_server = app.config.get("CONTENT_SERVER")
|
|
if path2 == 'secrets' or path == 'secrets':
|
|
return abort(403)
|
|
status_code, json_data, data_data, headers = await get_request(f"http://{app.config.get('REDIRECT_SERVER')}/{path}/{content_server}?filename={filename}")
|
|
if status_code == 200:
|
|
if len(filename.split('.')) > 0 and filename.split('.')[-1] == 'png':
|
|
content_type = "Content-Type: image/png"
|
|
return Response(
|
|
response=data_data,
|
|
content_type=content_type,
|
|
status=status_code
|
|
)
|
|
else:
|
|
status_code, json_data, data_data, headers = await get_request(f"http://{app.config.get('REDIRECT_SERVER')}/{path2}/{content_server}?filename={filename}")
|
|
content_type = headers.get("Content-Type")
|
|
if len(filename.split('.')) > 0 and filename.split('.')[-1] == 'png':
|
|
content_type = "Content-Type: image/png"
|
|
return Response(
|
|
response=data_data,
|
|
content_type=content_type,
|
|
status=status_code
|
|
)
|
|
|
|
async def post_request(url, headers={}, json_inp=None, data=None, cookies=None):
|
|
async with aiohttp.ClientSession(cookies=cookies, skip_auto_headers={"User-Agent"}) as session:
|
|
async with session.post(url, headers=headers, json=json_inp, data=data) as r:
|
|
data = ""
|
|
json_data = ""
|
|
if hasattr(r, "data"):
|
|
data = await r.data
|
|
if r.content_type == 'application/json':
|
|
json_data = await r.json()
|
|
return r.status, json_data, data, r.headers
|
|
|
|
async def get_request(url, headers={}, cookies={}):
|
|
async with aiohttp.ClientSession(cookies=cookies, skip_auto_headers={"User-Agent"}) as session:
|
|
async with session.get(url, headers=headers) as r:
|
|
data = ""
|
|
json_data = ""
|
|
if r.content_type == 'application/json':
|
|
json_data = await r.json()
|
|
return r.status, json_data, data, r.headers
|
|
if hasattr(r, "data"):
|
|
data = r.data
|
|
elif hasattr(r, "content"):
|
|
data = await r.content.read()
|
|
return r.status, json_data, data, r.headers
|
|
|
|
|
|
@app.route('/file/get/<path>', methods=['GET'])
|
|
#@route_cors()
|
|
@user_cook
|
|
async def get_file(path): # put application's code here
|
|
async def check_access(username, filename):
|
|
status_code, _, _, _ = await get_request(f"http://{app.config.get('REDIRECT_SERVER')}/check_access?filename={filename}&username={username}")
|
|
if status_code == 200:
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
filename = request.args.get("filename")
|
|
content_server = app.config.get("CONTENT_SERVER")
|
|
if not await check_access(session.get("username"), filename):
|
|
return abort(403)
|
|
status_code, json_data, data_data, header = await get_request(f"http://{app.config.get('REDIRECT_SERVER')}/{path}/{content_server}?filename={filename}")
|
|
content_type = header.get("Content-Type")
|
|
if len(filename.split('.')) > 0 and filename.split('.')[-1] == 'png':
|
|
content_type = "Content-Type: image/png"
|
|
return Response(
|
|
response=data_data,
|
|
content_type=content_type,
|
|
status=status_code
|
|
)
|
|
|
|
@app.route('/file/list')
|
|
#@route_cors()
|
|
async def file_list():
|
|
content_server = app.config.get("CONTENT_SERVER")
|
|
path = request.args.get('path')
|
|
status_code, json_data, _, headers = await get_request(f"http://{app.config.get('REDIRECT_SERVER')}/file_list/{path}/{content_server}")
|
|
return Response(
|
|
response=json.dumps(json_data),
|
|
content_type=headers.get('Content-Type'),
|
|
status=status_code)
|
|
|
|
|
|
|
|
@app.route('/file/upload', methods=['POST'])
|
|
#@route_cors()
|
|
@user_cook
|
|
async def upload_image():
|
|
if request.method == 'POST':
|
|
if 'file' not in await request.files:
|
|
return abort(403)
|
|
content_server = app.config.get("CONTENT_SERVER")
|
|
path = request.args.get("path")
|
|
username = session.get("username")
|
|
form_data = aiohttp.FormData()
|
|
file_bytes = (await request.files).get('file').stream.read()
|
|
filename = (await request.files).get("file").filename
|
|
form_data.add_field(name='file', value=file_bytes , filename=filename)
|
|
form_data.add_field(name="username", value=username)
|
|
form_data.add_field(name="filename", value=filename)
|
|
status_code, json_data, data_data, headers = await post_request(f"http://{app.config.get('REDIRECT_SERVER')}/{path}/{content_server}",
|
|
data=form_data)
|
|
|
|
return Response(
|
|
response=json.dumps(json_data),
|
|
content_type=headers.get('Content-Type'),
|
|
status=status_code
|
|
)
|
|
|
|
@app.route('/api/auth/sign_up', methods=["POST"])
|
|
#@route_cors()
|
|
async def sign_up():
|
|
username = (await request.json).get("username")
|
|
password = (await request.json).get("password")
|
|
is_private = (await request.json).get("is_private")
|
|
if username and password:
|
|
url_id = generate('1234567890abcdef', 12)
|
|
user = User(username=username, blog_url=url_id)
|
|
user.set_password(password)
|
|
blog = Blog(url_id, is_private)
|
|
db.session.add(user)
|
|
db.session.add(blog)
|
|
db.session.commit()
|
|
session["username"] = user.username
|
|
return jsonify({"Status": "OK"})
|
|
else:
|
|
return abort(403)
|
|
|
|
|
|
|
|
@app.route('/api/auth/sign_in', methods=["POST"])
|
|
async def sign_in():
|
|
username = (await request.json).get("username")
|
|
password = (await request.json).get("password")
|
|
if username and password:
|
|
user = User.query.filter_by(username=username).first()
|
|
if user is None or not user.check_password(password):
|
|
return jsonify({"Result": "Bad creads"}), 400
|
|
else:
|
|
session["username"] = user.username
|
|
return jsonify({"Result": "OK"})
|
|
|
|
@app.route('/api/self_delete')
|
|
#@route_cors()
|
|
@user_cook
|
|
async def self_remove_acc():
|
|
username = session.get("username")
|
|
user = User.query.filter_by(username=username).first()
|
|
db.session.delete(user)
|
|
db.session.commit()
|
|
await get_request(f"http://{app.config.get('REDIRECT_SERVER')}/delete/{username}/{app.config.get('CONTENT_SERVER')}")
|
|
return jsonify({"result": "OK"})
|
|
|
|
@app.route('/api/blog')
|
|
#@route_cors()
|
|
@user_cook
|
|
async def get_my_blog():
|
|
user = User.query.filter_by(username=session.get("username")).first()
|
|
blog = Blog.query.filter_by(url=user.blog_url).first()
|
|
return jsonify({"url": blog.url, "is_private": blog.is_private})
|
|
|
|
@app.route('/api/blogs')
|
|
#@route_cors()
|
|
async def get_blogs():
|
|
blogs = Blog.query.with_entities(Blog.url, Blog.is_private).all()
|
|
blogs_list = [{"url": i.url, "is_private": i.is_private} for i in blogs]
|
|
return jsonify(blogs_list)
|
|
|
|
|
|
@app.route('/api/blog/<url_id>')
|
|
#@route_cors()
|
|
@user_cook
|
|
async def blog_get_posts(url_id):
|
|
blog = Blog.query.filter_by(url=url_id).first()
|
|
if blog:
|
|
if blog.posts:
|
|
return jsonify({"posts": list(map(lambda x: {"id":x.id, "title":x.title}, blog.posts))})
|
|
else:
|
|
return jsonify({"error": "?"})
|
|
else:
|
|
return jsonify({"error": "?"})
|
|
|
|
@app.route('/api/blog/<url_id>/create_post', methods=["POST"])
|
|
#@route_cors()
|
|
@user_cook
|
|
async def blog_create_post(url_id):
|
|
blog = Blog.query.filter_by(url=url_id).first()
|
|
title = (await request.json).get("title")
|
|
body = (await request.json).get("body")
|
|
post = Post(title=title, body=body, blog_url=blog.url)
|
|
db.session.add(post)
|
|
db.session.commit()
|
|
this_post = Post.query.filter_by(title=title, body=body).all()[-1]
|
|
return jsonify({"Result": "OK", "post_id": this_post.id})
|
|
|
|
|
|
@app.route('/api/blog/<url_id>/post/<int:post_id>')
|
|
#@route_cors()
|
|
@user_cook
|
|
async def blog_read_post(url_id, post_id):
|
|
post = Post.query.filter_by(blog_url=url_id, id=post_id).first()
|
|
return jsonify({"title": post.title, "body": post.body})
|
|
|
|
|
|
if __name__ == '__main__':
|
|
app.run(port=13377, host="0.0.0.0", debug=False)
|