def post(valid_class, parse, template):
    """
    一些固定的对象的方法模板 多用于post和put
    :param valid_class:
    :param parse:
    :param template:
    :return:
    """
    if isinstance(parse, dict):
        valid = valid_class(parse)
    elif isinstance(parse, reqparse.RequestParser):
        valid = valid_class(parse.parse_args())
    else:
        raise ValueError("parse must be dict or RequestParser")
    err_map = valid.valid_data()
    if err_map:
        response = Response()
        response.data = err_map
        response.errno = len(err_map)
        response.code = FORMAT_ERROR
        return response
    clean_data = valid.clean_data
    # for key in template.__dict__:
    #     if template.__dict__[key] is None:
    #         setattr(template, key, clean_data[key])
    for key in clean_data:
        if not key.startswith("_"):
            setattr(template, key, clean_data[key])
Exemple #2
0
 def put(self):
     """
     修改课程的接口
     :return:
     """
     response = Response()
     try:
         _id = request.json["id"]
         course = CourseTemplate()
         response = post(CourseValid, parse, course)
         if response:
             return jsonify(response.dict_data)
         ret = execute_sql(UpdateMap.update_course_by_id, [
             course.name, course.type, course.level, course.burning,
             course.id
         ])
         if ret == 0:
             raise UserDoesNotExistException("课程不存在")
         response.data = {
             "id": course.id, "name": course.name, "type": course.type,
             "level": course.level, "burning": course.burning
         }
     except KeyError as e:
         init_key_error_handler(response, e, "缺少入参:")
     except UserDoesNotExistException as e:
         init_key_error_handler(response, e)
     return jsonify(response.dict_data)
Exemple #3
0
 def get(self):
     """
     获取一个特定的挑战的接口 根据course id  请求需要携带一个参数 id 由于挑战 不用登陆也可以访问
     所以不加权,此pageviews每请求一次就会增加一次 在多线程环境下会不准确 但是没关系 问题不大
     :return:
     """
     response = Response()
     try:
         _id = request.args["id"]
         challenge = fetchone_dict(SelectMap.challenge_by_id, [_id, ], ChallengeTemplate)
         if challenge:
             ret = execute_sql(UpdateMap.update_challenge_pageviews, [challenge.id, ])
             if ret == 0:
                 raise InvalidArgumentException("数据不存在")
             response.data = {
                 "id": challenge.id, "picture": challenge.picture,
                 "content": challenge.content, "start_time": challenge.start_time,
                 "end_time": challenge.end_time, "create_time": challenge.create_time,
                 "pageviews": challenge.pageviews + 1
             }
             return jsonify(response.dict_data)
         raise InvalidArgumentException("数据不存在")
     except Exception as e:
         init_key_error_handler(response, e, "信息:")
     return jsonify(response.dict_data)
Exemple #4
0
 def post(self):
     comment = CommentTemplate()
     response = post(CommentValid, parse, comment)
     if response:
         return jsonify(response.dict_data)
     try:
         response = Response()
         now = datetime.datetime.now()
         user_id = getattr(request, "user")["id"]
         user = fetchone_dict(SelectMap.user_info_by_user_id, (user_id, ),
                              GeneralObject)
         ret = execute_sql(InsertMap.comment,
                           (comment.content, now, comment.blog_id, user_id,
                            user.nick_name), True)
         if ret == 0:
             raise InvalidArgumentException("评论失败")
         response.data = {
             "id": ret,
             "create_time": now,
             "content": comment.content,
             "blog_id": comment.blog_id,
             "user_id": user_id,
             "nick_name": user.nick_name
         }
     except Exception as e:
         init_key_error_handler(response, e, "信息:")
     return jsonify(response.dict_data)
Exemple #5
0
 def post(self):
     """
     添加挑战的接口 此接口的content是一个重点 是有格式要求的 要求就是 其中的html不能包含script标签
     也不能含有任何的注释
     添加挑战的另一个约定就是 start_time和end_time是有格式要求的 必须是2019-11-03这种格式 无法配置
     :return:
     """
     challenge = ChallengeTemplate()
     response = post(ChallengeValid, parse, challenge)
     if response is None:
         response = Response()
         try:
             number = generate_number(20)
             ret = execute_sql(InsertMap.challenge, [
                 challenge.picture, challenge.content, challenge.start_time,
                 challenge.end_time, datetime.datetime.now(), challenge.pageviews,
                 number
             ])
             if ret == 0:
                 raise InvalidArgumentException("数据写入失败")
             challenge = fetchone_dict(SelectMap.challenge_by_number, [number, ], ChallengeTemplate)
             response.data = {
                 "id": challenge.id, "picture": challenge.picture,
                 "content": challenge.content, "start_time": challenge.start_time,
                 "end_time": challenge.end_time, "create_time": challenge.create_time,
                 "pageviews": challenge.pageviews
             }
         except Exception as e:
             init_key_error_handler(response, e, "信息:")
     return jsonify(response.dict_data)
Exemple #6
0
 def get(self):
     args = request.args
     course_id = args.get("id", 0)
     response = Response()
     offset = request.args.get("offset", current_app.config["PAGE_OFFSET"])
     offset = int(offset)
     default_url = os.path.join(current_app.config["MEDIA_URL"], "default_course.jpg")
     try:
         user_id = getattr(request, "user", {}).get("id")
         ret_list = fetchall_dict(SelectMap.course_list_by_page, (course_id, offset), GeneralObject)
         ret_json = []
         if user_id:
             for course in ret_list:
                 collect = fetchone_dict(SelectMap.collect_by_course_id, (course.id, user_id),
                                         GeneralObject)
                 course.is_collect = True if collect else False
                 course.collect_id = collect.id if collect else None
                 action = fetchone_dict(SelectMap.action_list_by_course_id, (course.id,), GeneralObject)
                 course.picture = action.picture if action else default_url
                 ret_json.append(course.data)
         else:
             for course in ret_list:
                 course.is_collect = False
                 course.collect_id = None
                 ret_json.append(course.data)
         response.data = {
             "course_list": ret_json, "count": len(ret_json),
             "query_id": ret_list[-1].id,
             "last_query_id": course_id, "page_offset": offset
         }
         return jsonify(response.dict_data)
     except Exception as e:
         init_key_error_handler(response, e, "错误:")
         return jsonify(response.dict_data)
Exemple #7
0
 def post(self):
     """
     添加帖子的接口 帖子的添加需要携带 user_id content title picture 等键值对
     图片需要先上传 content需要不存在注释以及script标签
     :return:
     """
     response = Response()
     blog = BlogTemplate()
     resp = post(BlogValid, parser, blog)
     if resp is not None:
         return resp
     try:
         from datetime import datetime
         now = datetime.now()
         row_id = execute_sql(
             InsertMap.blog,
             (blog.user_id, blog.content, blog.title, blog.picture, now))
         if row_id == 0:
             raise InvalidArgumentException("插入记录失败")
         response.data = {
             "id": row_id,
             "user_id": blog.user_id,
             "content": blog.content,
             "title": blog.title,
             "picture": blog.picture,
             "create_time": now
         }
     except Exception as e:
         init_key_error_handler(response, e, "信息:")
     return jsonify(response.dict_data)
Exemple #8
0
 def inner(*args, **kwargs):
     response = Response()
     user_permission = getattr(g, "user", {}).get("permission", 0)
     if permission & user_permission == permission:
         return func(*args, **kwargs)
     else:
         response.code = PERMISSION_ERROR
         response.errno = 1
         response.data = {"msg": "权限不足"}
         return jsonify(response.dict_data)
Exemple #9
0
 def inner(*args, **kwargs):
     response = Response()
     ip = request.remote_addr
     if ip not in ip_map:
         ip_map[ip] = _IpStack(times, seconds)
     ret = ip_map[ip].append(time.time())
     if ret:
         return func(*args, **kwargs)
     else:
         response.errno = 1
         response.code = THROTTLE_ERROR
         response.data = {"msg": "请求过于频繁,稍后再试"}
         return jsonify(response.dict_data)
Exemple #10
0
 def delete(self):
     """
     删除课程接口 但是并不会删除action
     :return:
     """
     response = Response()
     try:
         _id = request.json["id"]
         course_num = execute_sql(DeleteMap.course_by_id, [_id, ])
         response.data = {"msg": "ok", "count": course_num}
     except KeyError as e:
         init_key_error_handler(response, e)
     return jsonify(response.dict_data)
Exemple #11
0
 def delete(self):
     upper = UpperTemplate()
     response = post(UpperValid, parse, upper)
     if response:
         return jsonify(response)
     try:
         user_id = getattr(request, "user")["id"]
         response = Response()
         ret = execute_sql(DeleteMap.upper_by_id, (upper.blog_id, user_id))
         if ret == 0:
             raise InvalidArgumentException("取消失败")
         execute_sql(UpdateMap.blog_upper_dev, (upper.blog_id, ))
         response.data = {"msg": "ok"}
     except Exception as e:
         init_key_error_handler(response, e, "信息:")
     return jsonify(response.dict_data)
Exemple #12
0
 def delete(self):
     response = Response()
     try:
         _id = request.json["id"]
         comment_count = execute_sql(DeleteMap.comment_by_id, (_id, ))
         if comment_count == 0:
             raise InvalidArgumentException("删除失败!")
         reply_count = execute_sql(DeleteMap.reply_by_comment_id, (_id, ))
         response.data = {
             "comment_count": comment_count,
             "reply_count": reply_count,
             "msg": "ok"
         }
     except Exception as e:
         init_key_error_handler(response, e, "信息:")
     return jsonify(response.dict_data)
 def inner(*args, **kwargs):
     response = Response()
     content = f"{request.url}:{request.remote_addr}"
     md5 = hashlib.md5(current_app.config["SALT"].encode(
         current_app.config["DB_CHARSET"]))
     md5.update(content.encode(current_app.config["DB_CHARSET"]))
     val = md5.hexdigest()
     if val in content_set:
         response.code = THROTTLE_ERROR
         response.errno = 1
         response.data = {"msg": "请求正在处理中"}
         return jsonify(response.dict_data)
     content_set.add(val)
     ret = func(*args, **kwargs)
     content_set.remove(val)
     return ret
Exemple #14
0
 def delete(self):
     response = Response()
     try:
         _id = request.json["id"]
         b = fetchone_dict(SelectMap.blog_by_id, (_id, ), GeneralObject)
         permission = getattr(request, "user")["permission"]
         if getattr(
                 request,
                 "user")["id"] != b.user_id and permission & ADMIN != ADMIN:
             raise InvalidArgumentException("权限不足")
         ret = execute_sql(DeleteMap.blog_by_id, (_id, ))
         if ret == 0:
             raise InvalidArgumentException("删除失败")
         response.data = {"msg": "ok"}
     except Exception as e:
         init_key_error_handler(response, e, "信息:")
     return jsonify(response.dict_data)
Exemple #15
0
 def delete(self):
     response = Response()
     try:
         _id = request.json["id"]
         ret = execute_sql(DeleteMap.challenge_by_id, (_id, ))
         if ret == 0:
             raise UserDoesNotExistException("挑战不存在")
     except Exception as e:
         init_key_error_handler(response, e, "信息")
     return jsonify(response.dict_data)
Exemple #16
0
 def put(self):
     """
     修改,修改用户信息使用此方法  tag代表了你想要的动作 有3个选项
     all 全部的  avatar 头像 description 描述信息
     当你传all 的时候 需要同时传所有的信息 包括未被修改的部分
     :return:
     """
     response = Response()
     connection = pool.connection()
     try:
         tag = request.json.get("tag", "all")
         user_id = request.json.get("id") or getattr(g, "user")["id"]
         getattr(self, "_update_" + tag)(connection, user_id)
         response.data = {"msg": "ok"}
     except (KeyError, AttributeError, InvalidArgumentException) as e:
         init_key_error_handler(response, e)
     finally:
         connection.close()
     return jsonify(response.dict_data)
Exemple #17
0
 def get(self):
     response = Response()
     try:
         tag = request.args.get("tag", "back")
         func = getattr(self, f"_{tag}_list")
         func(response)
     except Exception as e:
         init_key_error_handler(response, e, "信息:")
         import traceback
         traceback.print_exc()
     return jsonify(response.dict_data)
Exemple #18
0
 def post(self):
     """
     文件上传的接口,可以上传多个文件
     :return:
     """
     files = request.files.getlist(current_app.config["UPLOAD_FILE_KEY"])
     response = Response()
     media_url = current_app.config["MEDIA_URL"]
     media_dir = current_app.config["MEDIA_DIR"]
     err_list = []
     suffix_list = []
     for f in files:
         if is_safe(f.filename):
             suffix_list.append(get_suffix(f.filename))
             continue
         err_list.append(f.filename)
     if err_list:
         response.errno = len(err_list)
         response.code = FORMAT_ERROR
         response.data = {"msg": "错误的文件类型:" + ",".join(err_list)}
         return jsonify(response.dict_data)
     file_url = []
     for index, f in enumerate(files):
         file_name = generate_filename() + "." + suffix_list[index]
         path = os.path.join(media_dir, file_name)
         file_name = self._save(f, path, file_name)
         file_url.append({
             "url": os.path.join(media_url, file_name),
             "filename": file_name
         })
     response.data = {"msg": file_url}
     return jsonify(response.dict_data)
Exemple #19
0
 def _delete_user(self, user_id, connection):
     """
     删除一个用户的具体逻辑,包括判断用户是否存在等,此方法如果用户不存在会
     抛出异常
     :param user_id: 想要删除的用户的id
     :param connection: 数据库连接的conn对象
     :return: 抛出异常或者返回response对象
     """
     cursor = connection.cursor()
     user = get_one(cursor, SelectMap.user_valid_by_id, user_id)
     response = Response()
     if user:
         try:
             ret1 = delete_sql_execute(cursor, DeleteMap.user_by_id,
                                       user_id)
             ret2 = delete_sql_execute(cursor,
                                       DeleteMap.user_info_by_user_id,
                                       user_id)
             connection.commit()
             response.data = {"msg": ret1 + ret2}
         except Exception as e:
             connection.rollback()
             connection.commit()
             response.code = 500
             response.errno = 1
             response.data = {"msg": "内部错误:" + str(e)}
         finally:
             cursor.close()
             connection.close()
             return response
     raise UserDoesNotExistException("用户不存在")
Exemple #20
0
 def post(self):
     """
     此方法用来添加一个对应课程的动作 但是此方法不会校验sequence(动作编号),所以请谨慎调用
     :return:
     """
     template = ActionTemplate()
     ret = post(ActionValid, parse, template)
     response = Response()
     if ret:
         return jsonify(ret.dict_data)
     try:
         count = execute_sql(InsertMap.action, [
             template.id, template.content, template.picture, template.sequence
         ])
         response.data = {
             "course_id": template.id, "content": template.content,
             "picture": template.picture, "sequence": template.sequence,
             "count": count
         }
     except Exception as e:
         init_key_error_handler(response, e)
     return jsonify(response.dict_data)
Exemple #21
0
 def delete(self):
     response = Response()
     try:
         user_id = request.json["id"]
         connection = pool.connection()
         response = self._delete_user(user_id, connection)
     except UserDoesNotExistException as e:
         response.code = 405
         response.errno = 1
         response.data = {"msg": str(e)}
     except KeyError:
         response.code = 405
         response.errno = 1
         response.data = {"msg": "你必须传一个id"}
     return jsonify(response.dict_data)
Exemple #22
0
 def get(self):
     response = Response()
     try:
         _id = request.args["id"]
         blog = fetchone_dict(SelectMap.blog_by_id, (_id, ), BlogTemplate)
         if blog is None:
             raise InvalidArgumentException("数据不存在")
         user = fetchone_dict(SelectMap.user_info_by_user_id,
                              (blog.user_id, ), GeneralObject)
         response.data = blog.__dict__
         response.data.update({
             "nick_name": user.nick_name,
             "gender": user.gender,
             "email": user.email,
             "avatar": user.avatar,
             "permission": user.permission
         })
         req = fetchone_dict(SelectMap.comment_and_reply_count_by_blog,
                             (_id, ), GeneralObject)
         response.data.update({"comment_count": req.count})
     except Exception as e:
         init_key_error_handler(response, e, "信息:")
     return jsonify(response.dict_data)
Exemple #23
0
 def put(self):
     """
     修改挑战的接口 和post接口相比 需要多传一个id的key 如果id不存在 则无法执行
     :return:
     """
     challenge = ChallengeTemplate()
     response = post(ChallengeValid, parse, template=challenge)
     if response is None:
         response = Response()
         try:
             _id = challenge.id
             ret = execute_sql(UpdateMap.update_challenge_by_id, [
                 challenge.picture, challenge.content, challenge.start_time,
                 challenge.end_time, _id
             ])
             if ret == 0:
                 raise InvalidArgumentException("数据不存在")
         except InvalidArgumentException as e:
             response.errno = 1
             response.code = 403
             response.data = {"msg": str(e)}
         except Exception as e:
             init_key_error_handler(response, e, "信息:")
     return jsonify(response.dict_data)
Exemple #24
0
 def get(self):
     """
     带分页的 get方法获取所有的用户 用于在后台管理显示
     缺点为,我不会关心你这个id的合法性,假如每页要显示的数量为10个 但是 你给了我一个10个中的1个id 对于这种情况我不会进行校验
     此方法不会包含你传过来的id对应的用户,只会传过来以你传过来的id为头但是不含此id的LIMIT个用户,并将此结果集的最后一个用户的id单独返回
     用来作为下次请求的参数,如果你是首次请求,则默认选择的起始id为0
     :return:
     """
     response = Response()
     try:
         tag = request.args.get("tag", "back")
         func = getattr(self, f"_{tag}_list")
         func(response)
     except (KeyError, UserDoesNotExistException) as e:
         init_key_error_handler(response, e)
     return jsonify(response.dict_data)
Exemple #25
0
 def inner(*args, **kwargs):
     response = Response()
     key = current_app.config["AUTH_CODE_SESSION_KEY"]
     try:
         auth_code = session[key].lower()
         code = request.args.get(key).lower()
         if code != auth_code:
             raise InvalidArgumentException()
         ret = func(*args, **kwargs)
         session.clear()
         return ret
     except (KeyError, AttributeError):
         response.code = FORMAT_ERROR
         response.errno = 1
         response.data = {"msg": "验证码已失效 重新输入"}
     except InvalidArgumentException:
         response.code = FORMAT_ERROR
         response.errno = 1
         response.data = {"msg": "验证码校验错误"}
     return jsonify(response.dict_data)
Exemple #26
0
 def _rollback(self, upper):
     response = Response()
     user_id = getattr(request, "user")["id"]
     ret = execute_sql(UpdateMap.update_upper_by_user_and_blog,
                       (upper.blog_id, user_id))
     if ret == 0:
         response.code = FORMAT_ERROR
         response.errno = 1
         response.data = {"msg": "点赞失败"}
         return response
     response.data = {
         "user_id": upper.user_id,
         "blog_id": upper.blog_id,
         "create_time": upper.create_time
     }
     return response
Exemple #27
0
 def _real_insert(self, upper):
     response = Response()
     now = datetime.datetime.now()
     user_id = getattr(request, "user")["id"]
     ret = execute_sql(InsertMap.upper, (upper.blog_id, user_id, now), True)
     if ret == 0:
         response.code = FORMAT_ERROR
         response.errno = 1
         response.data = {"msg": "点赞失败"}
         return response
     response.data = {
         "id": ret,
         "user_id": upper.user_id,
         "blog_id": upper.blog_id,
         "create_time": now
     }
     return response
Exemple #28
0
 def get(self):
     """
     get方法的接口,获取单个的用户,通过账号密码,如果用户存在,则返回用户信息和token
     :return:
     """
     account = request.args["account"]
     password = md5(request.args["password"])
     response = Response()
     connection = pool.connection()
     cursor = connection.cursor()
     try:
         if account == "" or password == "":
             raise InvalidArgumentException("账号或密码不可为空")
         ret = get_one(cursor, SelectMap.user_info_with_login,
                       [account, password])
         if ret is None:
             raise UserDoesNotExistException("错误的用户名或密码")
         response.data = {
             "id": ret[0],
             "account": ret[1],
             "permission": ret[2],
             "phone": ret[3],
             "email": ret[4],
             "gender": ret[5],
             "avatar": ret[6],
             "description": ret[7],
             "nick_name": ret[10],
             "create_time": ret[9],
             "age": ret[11],
             "token": self._make_jwt(ret)
         }
     except UserDoesNotExistException as e:
         init_key_error_handler(response, e, "提示:")
     except Exception as e:
         response.code = 500
         response.errno = 1
         response.data = {"msg": "获取用户失败:" + str(e)}
     finally:
         cursor.close()
         connection.close()
     return jsonify(response.dict_data)
Exemple #29
0
 def post(self):
     valid = CourseValid(parse.parse_args())
     err_map = valid.valid_data()
     response = Response()
     if err_map:
         response.data = err_map
         response.errno = len(err_map)
         response.code = FORMAT_ERROR
         return jsonify(response.dict_data)
     try:
         data = valid.clean_data
         execute_sql(InsertMap.course, [
             data["type"], data["name"], datetime.datetime.now(),
             data["level"], data["burning"]
         ])
         ret = execute_query_sql(SelectMap.course_by_create, [data["name"], ], lambda c: c.fetchone())
         response.data = {
             "id": ret[0], "type": ret[1], "name": ret[2], "create_time": ret[3],
             "level": ret[4], "burning": ret[5]
         }
     except Exception as e:
         init_key_error_handler(response, e, "插入数据失败:")
     return jsonify(response.dict_data)
def jwt_handler():
    """
    json web token的处理函数,如果携带了token 则处理 否则略
    :return:
    """
    if request.is_json:
        token = request.json.get("token")
    elif request.method != "GET":
        token = request.form.get("token")
    else:
        token = request.args.get("token")
    if token is not None:
        response = Response()
        try:
            header, payload, signature = token.split(".")
            header = decode_base64(header)
            payload = decode_base64(payload)
            payload_handler(payload)
            alg = header_handler(header)
            signature_handler(header, payload, signature, alg)
        except TokenTimeOutException as e:
            response.code = PERMISSION_ERROR
            response.errno = 1
            response.data = {"msg": str(e)}
        except (KeyError, IndexError, IllegalTokenException) as e:
            response.code = FORMAT_ERROR
            response.errno = 1
            response.data = {"msg": "错误的token:" + str(e)}
        except ValueError:
            response.code = FORMAT_ERROR
            response.errno = 1
            response.data = {"msg": "token格式错误"}
        except Exception as e:
            response.code = SERVER_ERROR
            response.errno = 1
            response.data = {"msg": "服务端错误:" + str(e)}
        finally:
            if response.errno > 0:
                if hasattr(request, "user"):
                    delattr(request, "user")
                return jsonify(response.dict_data)