diff --git a/404.html b/404.html index 4ee47a3..e673396 100644 --- a/404.html +++ b/404.html @@ -1,115 +1,155 @@ + + Ghink Universe - 404 - - + + + + + + - - - - - - - - + + + + + + + +
-

404

-

Page not found 页面找不到了

-
- -
+

404

+

+ Page not found 页面找不到了 +

+
+ +
+
+ + - + \ No newline at end of file diff --git a/README.md b/README.md index 65e0038..82c9067 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,9 @@ -# short_link +# Short Link -Ghink Universe Short Link Service Source Code \ No newline at end of file +Ghink Universe Short Link Service Source Code + +## Usage + +1. Install all requirements +2. Configure like example config +3. Run it! \ No newline at end of file diff --git a/index.html b/index.html deleted file mode 100644 index 0830dcb..0000000 --- a/index.html +++ /dev/null @@ -1,226 +0,0 @@ - - - - - - 极科宇视 - 短链接服务 - - - - - - - -
-
Copyright Ghink © 2014
-
浙ICP备2021025087号
- - - - - - diff --git a/main.py b/main.py index 962788d..1bea3b1 100644 --- a/main.py +++ b/main.py @@ -1,6 +1,11 @@ -import time, random, json, threading -import pymysql -from flask import Flask, request, redirect +import time +import random +import json + +from quart import Quart, request, redirect + +import aiomysql +import aiofiles with open("config.json", "r") as fb: config = json.loads(fb.read()) @@ -9,13 +14,8 @@ with open("config.json", "r") as fb: LISTEN = config["LISTEN"] DEBUG = config["DEBUG"] -app = Flask("Ghink Short Link Service") -db = pymysql.connect( - host=DB["host"], - user=DB["user"], - password=DB["password"], - database=DB["database"] -) +app = Quart("Ghink Short Link Service") +db_pool = None field_map = { 'A': 0, 'a': 1, 'B': 2, 'b': 3, @@ -33,63 +33,67 @@ field_map = { 'v': 48, 'W': 49, 'w': 50, 'X': 51, 'x': 52, '6': 53, 'Y': 54, 'y': 55, 'Z': 56, 'z': 57, '7': 58, '8': 59, - '9': 60, '0': 61} + '9': 60, '0': 61 +} +async def init_db(): + global db_pool + db_pool = await aiomysql.create_pool( + host=DB["host"], + user=DB["user"], + password=DB["password"], + db=DB["database"], + autocommit=True + ) + +@app.before_serving +async def startup(): + await init_db() + +@app.after_serving +async def shutdown(): + db_pool.close() + await db_pool.wait_closed() @app.route("/", methods=["GET"]) -def index(): - with open("index.html", "r", encoding="utf-8") as fb: - return fb.read() - +async def index(): + return redirect("https://k76u22n4gd.apifox.cn") @app.route("/", methods=["GET"]) -def route(link_id: str): - global db +async def route(link_id: str): for char in link_id: - if char not in tuple(field_map.keys()): + if char not in field_map: return redirect("https://www.ghink.net") - link_id_converted = 0 - for i in range(len(link_id)): - link_id_converted += field_map[link_id[::-1][i]] * 62 ** i - try: - db.ping() - except pymysql.err.InterfaceError: - db = pymysql.connect( - host=DB["host"], - user=DB["user"], - password=DB["password"], - database=DB["database"] - ) + link_id_converted = sum(field_map[link_id[::-1][i]] * 62 ** i for i in range(len(link_id))) - cursor = db.cursor() - cursor.execute('SELECT link, validity FROM links WHERE id=%s', link_id_converted) - db.commit() - link = cursor.fetchone() + async with db_pool.acquire() as conn: + async with conn.cursor() as cursor: + await cursor.execute('SELECT link, validity FROM links WHERE id=%s', (link_id_converted,)) + link = await cursor.fetchone() + if link is None or link[0] is None: - with open("404.html", "r", encoding="utf-8") as fb: - return fb.read(), 404 + async with aiofiles.open("404.html", "r", encoding="utf-8") as fb: + return await fb.read(), 404 if link[1] is not None and link[1] < time.time(): - remove_thread = threading.Thread(target=remove_link, args=(link_id_converted,)) - remove_thread.start() - with open("404.html", "r", encoding="utf-8") as fb: - return fb.read(), 404 + await remove_link(link_id_converted) + async with aiofiles.open("404.html", "r", encoding="utf-8") as fb: + return await fb.read(), 404 return redirect(link[0]) - @app.route("/", methods=["POST"]) -def add(): - global db - key = request.form.get("key") - link = request.form.get("link") - validity = request.form.get("validity") - # Judge whether fields are empty - if key == "" or link == "": +async def add(): + form = await request.form # Await the form to get the data + key = form.get("key") # Access the key + link = form.get("link") # Access the link + validity = form.get("validity") # Access the validity + + if not key or not link: return json.dumps({"ok": False, "message": "bad field(s)", "id": ""}) - # No access + if key not in KEYS: return json.dumps({"ok": False, "message": "forbidden", "id": ""}) - # Check validity + if validity: if validity.isdecimal() and int(validity) > time.time(): validity = int(validity) @@ -98,37 +102,25 @@ def add(): else: validity = None - # Random while True: - link_id_random = ''.join(random.sample(tuple(field_map.keys()), 6)) - link_id_converted = 0 - for i in range(len(link_id_random)): - link_id_converted += field_map[link_id_random[::-1][i]] * 62 ** i - # Get Cursor - try: - db.ping() - except pymysql.err.InterfaceError: - db = pymysql.connect( - host=DB["host"], - user=DB["user"], - password=DB["password"], - database=DB["database"] - ) - cursor = db.cursor() - cursor.execute('SELECT link FROM links WHERE id=%s', link_id_converted) - db.commit() - link_selected = cursor.fetchone() - if link_selected is None: - break - # Insert - cursor.execute("INSERT INTO `links` VALUES (%s, %s, %s)", [link_id_converted, link, validity]) - db.commit() + link_id_random = ''.join(random.sample(field_map.keys(), 6)) + link_id_converted = sum(field_map[link_id_random[::-1][i]] * 62 ** i for i in range(len(link_id_random))) + + async with db_pool.acquire() as conn: + async with conn.cursor() as cursor: + await cursor.execute('SELECT link FROM links WHERE id=%s', (link_id_converted,)) + link_selected = await cursor.fetchone() + if link_selected is None: + break + + async with db_pool.acquire() as conn: + async with conn.cursor() as cursor: + await cursor.execute("INSERT INTO `links` VALUES (%s, %s, %s)", (link_id_converted, link, validity)) return json.dumps({"ok": True, "message": "successful", "id": link_id_random}) - @app.route("/", methods=["PATCH"]) -def reload(): +async def reload(): global config, DB, KEYS, LISTEN, DEBUG with open("config.json", "r") as fb: @@ -140,24 +132,10 @@ def reload(): return json.dumps({"ok": True, "message": "successful"}) - -def remove_link(id): - global db - # Get Cursor - try: - db.ping() - except pymysql.err.InterfaceError: - db = pymysql.connect( - host=DB["host"], - user=DB["user"], - password=DB["password"], - database=DB["database"] - ) - cursor = db.cursor() - cursor.execute('DELETE FROM links WHERE id=%s', id) - db.commit() - +async def remove_link(id): + async with db_pool.acquire() as conn: + async with conn.cursor() as cursor: + await cursor.execute('DELETE FROM links WHERE id=%s', (id,)) if __name__ == "__main__": - app.run(LISTEN[0], LISTEN[1], DEBUG) - db.close() + app.run(host=LISTEN[0], port=LISTEN[1], debug=DEBUG) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..8b13386 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +aiomysql +aiofiles +quart \ No newline at end of file