mirror of
https://github.com/Lost-MSth/Arcaea-server.git
synced 2025-12-14 08:06:23 +08:00
Add a register api
- Add a register api - Change requirements, which flask version should be over 2.0
This commit is contained in:
@@ -1,19 +1,34 @@
|
||||
from flask import jsonify
|
||||
|
||||
|
||||
def code_get_msg(code):
|
||||
# api接口code获取msg,返回字符串
|
||||
msg = {
|
||||
'0': '',
|
||||
'-1': 'See status code',
|
||||
'-2': 'No data',
|
||||
'-3': 'No data or user',
|
||||
'-4': 'No user_id',
|
||||
'-100': 'Wrong post data',
|
||||
'-101': 'Wrong data type',
|
||||
'-102': 'Wrong query parameter',
|
||||
'-103': 'Wrong sort parameter',
|
||||
'-104': 'Wrong sort order parameter',
|
||||
'-201': 'Wrong username or password',
|
||||
'-202': 'User is banned',
|
||||
'-999': 'Unknown error'
|
||||
0: '',
|
||||
-1: 'See status code',
|
||||
-2: 'No data',
|
||||
-3: 'No data or user',
|
||||
-4: 'No user_id',
|
||||
-100: 'Wrong post data',
|
||||
-101: 'Wrong data type',
|
||||
-102: 'Wrong query parameter',
|
||||
-103: 'Wrong sort parameter',
|
||||
-104: 'Wrong sort order parameter',
|
||||
-201: 'Wrong username or password',
|
||||
-202: 'User is banned',
|
||||
-203: 'Username exists',
|
||||
-204: 'Email address exists',
|
||||
-999: 'Unknown error'
|
||||
}
|
||||
|
||||
return msg[str(code)]
|
||||
return msg[code]
|
||||
|
||||
|
||||
def return_encode(code: int = 0, data: dict = {}, status: int = 200, msg: str = ''):
|
||||
# 构造返回,返回jsonify处理过后的response_class
|
||||
if msg == '':
|
||||
msg = code_get_msg(code)
|
||||
if code < 0:
|
||||
return jsonify({'status': status, 'code': code, 'data': {}, 'msg': msg})
|
||||
else:
|
||||
return jsonify({'status': status, 'code': code, 'data': data, 'msg': msg})
|
||||
|
||||
@@ -3,12 +3,13 @@ from flask import (
|
||||
)
|
||||
import functools
|
||||
import api.api_auth
|
||||
import api.users
|
||||
from . import users
|
||||
import api.songs
|
||||
from api.api_code import code_get_msg
|
||||
from .api_code import code_get_msg, return_encode
|
||||
|
||||
|
||||
bp = Blueprint('api', __name__, url_prefix='/api/v1')
|
||||
bp.register_blueprint(users.bp)
|
||||
|
||||
|
||||
class Query():
|
||||
@@ -62,16 +63,6 @@ def get_query_parameter(request, query_able=[], sort_able=[]):
|
||||
return decorator
|
||||
|
||||
|
||||
def return_encode(code: int = 0, data: dict = {}, status: int = 200, msg: str = ''):
|
||||
# 构造返回,返回jsonify处理过后的response_class
|
||||
if msg == '':
|
||||
msg = code_get_msg(code)
|
||||
if code < 0:
|
||||
return jsonify({'status': status, 'code': code, 'data': {}, 'msg': msg})
|
||||
else:
|
||||
return jsonify({'status': status, 'code': code, 'data': data, 'msg': msg})
|
||||
|
||||
|
||||
@bp.route('/')
|
||||
def ping():
|
||||
return return_encode()
|
||||
@@ -111,7 +102,7 @@ def token_delete(user):
|
||||
def users_get(query, user):
|
||||
# 查询全用户信息
|
||||
|
||||
data = api.users.get_users(query)
|
||||
data = users.get_users(query)
|
||||
|
||||
if not data:
|
||||
return return_encode(-2)
|
||||
@@ -133,7 +124,7 @@ def users_user_get(user, user_id):
|
||||
if user_id != user.user_id and not 'select' in user.power and user.user_id != 0: # 查别人需要select权限
|
||||
return return_encode(-1, {}, 403, 'No permission')
|
||||
|
||||
data = api.users.get_user_info(user_id)
|
||||
data = users.get_user_info(user_id)
|
||||
|
||||
if not data:
|
||||
return return_encode(-3)
|
||||
@@ -152,7 +143,7 @@ def users_user_b30_get(user, user_id):
|
||||
if user_id != user.user_id and not 'select' in user.power and user.user_id != 0: # 查别人需要select权限
|
||||
return return_encode(-1, {}, 403, 'No permission')
|
||||
|
||||
data = api.users.get_user_b30(user_id)
|
||||
data = users.get_user_b30(user_id)
|
||||
|
||||
if data['data'] == []:
|
||||
return return_encode(-3)
|
||||
@@ -173,7 +164,7 @@ def users_user_best_get(query, user, user_id):
|
||||
if user_id != user.user_id and not 'select' in user.power and user.user_id != 0: # 查别人需要select权限
|
||||
return return_encode(-1, {}, 403, 'No permission')
|
||||
|
||||
data = api.users.get_user_best(user_id, query)
|
||||
data = users.get_user_best(user_id, query)
|
||||
|
||||
if data['data'] == []:
|
||||
return return_encode(-3)
|
||||
@@ -192,7 +183,7 @@ def users_user_r30_get(user, user_id):
|
||||
if user_id != user.user_id and not 'select' in user.power and user.user_id != 0: # 查别人需要select权限
|
||||
return return_encode(-1, {}, 403, 'No permission')
|
||||
|
||||
data = api.users.get_user_r30(user_id)
|
||||
data = users.get_user_r30(user_id)
|
||||
|
||||
if data['data'] == []:
|
||||
return return_encode(-3)
|
||||
|
||||
@@ -1,9 +1,48 @@
|
||||
from flask import (
|
||||
Blueprint, request, jsonify
|
||||
)
|
||||
|
||||
from .api_code import code_get_msg, return_encode
|
||||
from .api_auth import role_required
|
||||
from core.user import RegisterUser
|
||||
from core.error import ArcError, PostError
|
||||
from server.sql import Connect
|
||||
from server.sql import Sql
|
||||
import time
|
||||
import web.webscore
|
||||
import server.info
|
||||
|
||||
bp = Blueprint('users', __name__, url_prefix='/users')
|
||||
|
||||
|
||||
@bp.route('', methods=['POST'])
|
||||
@role_required(request, ['change'])
|
||||
def users_post(user):
|
||||
# 注册用户
|
||||
with Connect() as c:
|
||||
new_user = RegisterUser(c)
|
||||
try:
|
||||
if 'name' in request.json:
|
||||
new_user.set_name(request.json['name'])
|
||||
else:
|
||||
raise PostError('No name provided.')
|
||||
|
||||
if 'password' in request.json:
|
||||
new_user.set_password(request.json['password'])
|
||||
else:
|
||||
raise PostError('No password provided.')
|
||||
|
||||
if 'email' in request.json:
|
||||
new_user.set_email(request.json['email'])
|
||||
else:
|
||||
raise PostError('No email provided.')
|
||||
|
||||
new_user.register()
|
||||
except ArcError as e:
|
||||
return return_encode(e.api_error_code)
|
||||
|
||||
return return_encode(0, {'user_id': new_user.user_id, 'user_code': new_user.user_code})
|
||||
|
||||
|
||||
def get_users(query=None):
|
||||
# 获取全用户信息,返回字典列表
|
||||
|
||||
0
latest version/core/__init__.py
Normal file
0
latest version/core/__init__.py
Normal file
28
latest version/core/error.py
Normal file
28
latest version/core/error.py
Normal file
@@ -0,0 +1,28 @@
|
||||
class ArcError(Exception):
|
||||
api_error_code = -999
|
||||
error_code = 108
|
||||
message = None
|
||||
|
||||
def __init__(self, message=None, error_code=None, api_error_code=None) -> None:
|
||||
self.message = message
|
||||
if error_code:
|
||||
self.error_code = error_code
|
||||
if api_error_code:
|
||||
self.api_error_code = api_error_code
|
||||
|
||||
def __str__(self) -> str:
|
||||
return repr(self.message)
|
||||
|
||||
|
||||
class InputError(ArcError):
|
||||
def __init__(self, message=None, error_code=None, api_error_code=-100) -> None:
|
||||
super().__init__(message, error_code, api_error_code)
|
||||
|
||||
|
||||
class DataExist(ArcError):
|
||||
pass
|
||||
|
||||
|
||||
class PostError(ArcError):
|
||||
def __init__(self, message=None, error_code=None, api_error_code=-100) -> None:
|
||||
super().__init__(message, error_code, api_error_code)
|
||||
83
latest version/core/sql.py
Normal file
83
latest version/core/sql.py
Normal file
@@ -0,0 +1,83 @@
|
||||
import sqlite3
|
||||
from flask import current_app
|
||||
import traceback
|
||||
|
||||
|
||||
class Connect():
|
||||
# 数据库连接类,上下文管理
|
||||
|
||||
def __init__(self, file_path='./database/arcaea_database.db'):
|
||||
"""
|
||||
数据库连接,默认连接arcaea_database.db
|
||||
接受:文件路径
|
||||
返回:sqlite3连接操作对象
|
||||
"""
|
||||
self.file_path = file_path
|
||||
|
||||
def __enter__(self):
|
||||
self.conn = sqlite3.connect(self.file_path)
|
||||
self.c = self.conn.cursor()
|
||||
return self.c
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
if self.conn:
|
||||
self.conn.commit()
|
||||
self.conn.close()
|
||||
|
||||
if exc_type is not None:
|
||||
current_app.logger.error(
|
||||
traceback.format_exception(exc_type, exc_val, exc_tb))
|
||||
|
||||
return True
|
||||
|
||||
|
||||
class Sql():
|
||||
|
||||
@staticmethod
|
||||
def select(c, table_name, target_column=[], query=None):
|
||||
# 执行查询单句sql语句,返回fetchall数据
|
||||
# 使用准确查询,且在单表内
|
||||
|
||||
sql = 'select '
|
||||
sql_dict = {}
|
||||
if len(target_column) >= 2:
|
||||
sql += target_column[0]
|
||||
for i in range(1, len(target_column)):
|
||||
sql += ',' + target_column[i]
|
||||
sql += ' from ' + table_name
|
||||
elif len(target_column) == 1:
|
||||
sql += target_column[0] + ' from ' + table_name
|
||||
else:
|
||||
sql += '* from ' + table_name
|
||||
|
||||
where_field = []
|
||||
where_value = []
|
||||
if query:
|
||||
for i in query.query:
|
||||
where_field.append(i)
|
||||
where_value.append(query.query[i])
|
||||
|
||||
if where_field and where_value:
|
||||
sql += ' where '
|
||||
sql += where_field[0] + '=:' + where_field[0]
|
||||
sql_dict[where_field[0]] = where_value[0]
|
||||
if len(where_field) >= 2:
|
||||
for i in range(1, len(where_field)):
|
||||
sql_dict[where_field[i]] = where_value[i]
|
||||
sql += ' and ' + where_field[i] + '=:' + where_field[i]
|
||||
|
||||
if query and query.sort:
|
||||
sql += ' order by ' + \
|
||||
query.sort[0]['column'] + ' ' + query.sort[0]['order']
|
||||
for i in range(1, len(query.sort)):
|
||||
sql += ', ' + query.sort[i]['column'] + \
|
||||
' ' + query.sort[i]['order']
|
||||
|
||||
if query and query.limit >= 0:
|
||||
sql += ' limit :limit offset :offset'
|
||||
sql_dict['limit'] = query.limit
|
||||
sql_dict['offset'] = query.offset
|
||||
|
||||
c.execute(sql, sql_dict)
|
||||
|
||||
return c.fetchall()
|
||||
106
latest version/core/user.py
Normal file
106
latest version/core/user.py
Normal file
@@ -0,0 +1,106 @@
|
||||
from .error import ArcError, InputError, DataExist
|
||||
from setting import Config
|
||||
import hashlib
|
||||
import time
|
||||
|
||||
|
||||
class User:
|
||||
name = None
|
||||
email = None
|
||||
password = None
|
||||
user_id = None
|
||||
user_code = None
|
||||
|
||||
def __init__(self) -> None:
|
||||
pass
|
||||
|
||||
|
||||
class RegisterUser(User):
|
||||
def __init__(self, c) -> None:
|
||||
super().__init__()
|
||||
self.c = c
|
||||
|
||||
def set_name(self, name: str):
|
||||
if 3 <= len(name) <= 16:
|
||||
self.c.execute(
|
||||
'''select exists(select * from user where name = :name)''', {'name': name})
|
||||
if self.c.fetchone() == (0,):
|
||||
self.name = name
|
||||
else:
|
||||
raise DataExist('Username exists.', 101, -203)
|
||||
|
||||
else:
|
||||
raise InputError('Username is invalid.')
|
||||
|
||||
def set_password(self, password: str):
|
||||
if 8 <= len(password) <= 32:
|
||||
self.password = password
|
||||
self.hash_pwd = hashlib.sha256(password.encode("utf8")).hexdigest()
|
||||
else:
|
||||
raise InputError('Password is invalid.')
|
||||
|
||||
def set_email(self, email: str):
|
||||
# 邮箱格式懒得多判断
|
||||
if 4 <= len(email) <= 32 and '@' in email and '.' in email:
|
||||
self.c.execute(
|
||||
'''select exists(select * from user where email = :email)''', {'email': email})
|
||||
if self.c.fetchone() == (0,):
|
||||
self.email = email
|
||||
else:
|
||||
raise DataExist('Email address exists.', 102, -204)
|
||||
else:
|
||||
raise InputError('Email address is invalid.')
|
||||
|
||||
def _build_user_code(self):
|
||||
from random import randint
|
||||
random_times = 0
|
||||
|
||||
while random_times <= 1000:
|
||||
random_times += 1
|
||||
user_code = ''.join([str(randint(0, 9)) for _ in range(9)])
|
||||
self.c.execute('''select exists(select * from user where user_code = :user_code)''',
|
||||
{'user_code': user_code})
|
||||
if self.c.fetchone() == (0,):
|
||||
break
|
||||
|
||||
if random_times <= 1000:
|
||||
self.user_code = user_code
|
||||
else:
|
||||
raise ArcError('No available user code.')
|
||||
|
||||
def _build_user_id(self):
|
||||
# 生成user_id,往后加1
|
||||
self.c.execute('''select max(user_id) from user''')
|
||||
x = self.c.fetchone()
|
||||
if x[0] is not None:
|
||||
self.user_id = x[0] + 1
|
||||
else:
|
||||
self.user_id = 2000001
|
||||
|
||||
def _insert_user_char(self):
|
||||
# 为用户添加初始角色
|
||||
self.c.execute('''insert into user_char values(?,?,?,?,?,?)''',
|
||||
(self.user_id, 0, 1, 0, 0, 0))
|
||||
self.c.execute('''insert into user_char values(?,?,?,?,?,?)''',
|
||||
(self.user_id, 1, 1, 0, 0, 0))
|
||||
self.c.execute(
|
||||
'''select character_id, max_level, is_uncapped from character''')
|
||||
x = self.c.fetchall()
|
||||
if x:
|
||||
for i in x:
|
||||
exp = 25000 if i[1] == 30 else 10000
|
||||
self.c.execute('''insert into user_char_full values(?,?,?,?,?,?)''',
|
||||
(self.user_id, i[0], i[1], exp, i[2], 0))
|
||||
|
||||
def register(self):
|
||||
now = int(time.time() * 1000)
|
||||
self._build_user_code()
|
||||
self._build_user_id()
|
||||
self._insert_user_char()
|
||||
|
||||
self.c.execute('''insert into user(user_id, name, password, join_date, user_code, rating_ptt,
|
||||
character_id, is_skill_sealed, is_char_uncapped, is_char_uncapped_override, is_hide_rating, favorite_character, max_stamina_notification_enabled, current_map, ticket, prog_boost, email)
|
||||
values(:user_id, :name, :password, :join_date, :user_code, 0, 0, 0, 0, 0, 0, -1, 0, '', :memories, 0, :email)
|
||||
''', {'user_code': self.user_code, 'user_id': self.user_id, 'join_date': now, 'name': self.name, 'password': self.hash_pwd, 'memories': Config.DEFAULT_MEMORIES, 'email': self.email})
|
||||
self.c.execute('''insert into recent30(user_id) values(:user_id)''', {
|
||||
'user_id': self.user_id})
|
||||
@@ -1,2 +1,2 @@
|
||||
flask
|
||||
flask==2.0.2
|
||||
cryptography
|
||||
|
||||
Reference in New Issue
Block a user