<reponame>xihuaxone/NewsWeb<gh_stars>0
# encoding=utf-8

from flask import Blueprint, make_response, request, current_app, jsonify, json, session
from info.utils.captcha import captcha
from info.utils.response_code import RET
from info.lib.yuntongxun.sms import CCP
from info import constants
from info.models import *
import re, random, datetime

passPort = Blueprint('passport', __name__)

@passPort.route('/get_image')
def getImage():
    from info import redis_store

    image_code_id = request.args.get('image_code_id')
    pre_image_code_id = request.args.get('pre_image_code_id')

    try:
        redis_store.delete('iamge_code_id:' + pre_image_code_id)
    except Exception as err:
        current_app.logger.error(err)
        return jsonify(errno = RET.DBERR, errmsg = '数据库操作故障')

    try:
        name, code_text, image = captcha.captcha.generate_captcha()
    except Exception as err:
        current_app.logger.error(err)
        return jsonify(errno = RET.SERVERERR, errmsg = '生成验证码失败')

    # 存储图片验证码内容和识别id；
    try:
        redis_store.setex('iamge_code_id:' + image_code_id, constants.IMAGE_CODE_REDIS_EXPIRES, code_text)
    except Exception as err:
        current_app.logger.error(err)
        return make_response(jsonify(errno =RET.DBERR, errmsg = '验证码保存失败'))

    # 给浏览器返回验证码图片；
    ret = make_response(image)
    ret.headers['content_type'] = 'image/jpg'
    return ret

@passPort.route('/get_sms', methods = ['POST'])
def getSms():
    # 获得前端的json数据，抽取出mobile、验证码、验证码id；
    data_dict = request.json
    mobile = data_dict.get('mobile')
    pic_code = data_dict.get('pic_code')
    pic_id = data_dict.get('pic_id')

    if not all([mobile, pic_code, pic_id]):
        return jsonify(errno = RET.USERERR, errmsg = '数据不完整')

    # 正则匹配mobile格式， 错误则保存到log日志，return error信息；
    if not re.match(r'1[35789][0-9]{9}', mobile):
        return jsonify(errno = RET.USERERR, errmsg = '手机号格式错误')

    # 从redis数据库查询验证码id对应的验证码内容，如果获取失败，则return 验证码过期，成功则删除redis中该条数据，
    # 并与前端获得的验证码对比，不同则return 验证码错误；

    stored_pic_id = None
    try:
        from info import redis_store
        stored_pic_id = redis_store.get('iamge_code_id:' + pic_id)
        redis_store.delete('iamge_code_id:' + pic_id)
    except Exception as err:
        current_app.logger.error(err)
        return jsonify(errno = RET.NODATA, errmsg = '验证码不存在或者已过期')

    if stored_pic_id:
        if stored_pic_id.decode('utf-8').lower() != pic_code.lower():
            redis_store.delete('iamge_code_id:' + pic_id)
            return jsonify(errno = RET.USERERR, errmsg = '验证码输入错误')
    else:
        return jsonify(errno = RET.NODATA, errmsg = '验证码已过期')

    try:
        user = User.query.filter(User.mobile == mobile).first()
    except Exception as err:
        user = None

    if user:
        return jsonify(errno = RET.DATAEXIST, errmsg = '该账号已注册过')

    # 引入6位随机数作为验证码；
    sms_code = random.randint(0,999999)
    sms_code = '%06d'%sms_code
    print(sms_code)


    # # 发送手机验证码，根据发送验证码的函数返回值判断是否成功，失败则保存log日志，return 发送验证码失败；
    # result = CCP().send_template_sms(mobile, [sms_code, constants.SMS_CODE_REDIS_EXPIRES/60], 1)
    # if result != 0:
    #     current_app.logger.error('SMS验证码第三方错误')
    #     return jsonify(errno = RET.THIRDERR, errmsg = '验证码发送失败')

    # 成功则把验证码保存到redis中，识别id为手机号，若保存到redis失败，则保存log日志，return 验证码保存失败；
    try:
        redis_store.setex('mibile:' + mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)
    except Exception as err:
        current_app.logger.error(err)
        return jsonify(errno = RET.DBERR, errmsg = '短信验证码保存失败')

    # 发送成功则return 成功发送信息；
    return jsonify(errno = RET.OK, errmsg = '发送成功', datas = {'sms_code': sms_code})

@passPort.route('/register', methods = ['POST'])
def registerAccount():
    # 从前端获得json数据，抽取出 mobile， 手机验证码， 密码；
    register_infos = request.json
    mobile = register_infos.get('mobile')
    sms_code = register_infos.get('sms_code')
    passwd = register_infos.get('passwd')

    if not all([mobile, sms_code, passwd]):
        return jsonify(errno = RET.NODATA, errmsg = '数据不全')

    # 根据mobile查询redis获得验证码， 若获取失败，则return 手机验证码过期；
    stored_code = None
    try:
        from info import redis_store
        stored_code = redis_store.get('mibile:' + mobile)
    except Exception as err:
        return jsonify(errno = RET.DBERR, errmsg = '手机验证码获取失败')

    # 若上一步获取成功，则与mobile对比，若不同则return 手机验证码输入错误；
    if stored_code:
        if stored_code.decode('utf-8') != sms_code:

            return jsonify(errno = RET.USERERR, errmsg = '验证码输入错误')
    else:
        return jsonify(errno = RET.NODATA, errmsg = '手机验证码已过期')

    # 正则校验密码格式，若错误则return 密码格式错误；
    if not re.match(r'^[0-9a-zA-Z][\w]{5,}$', passwd):
        return jsonify(errno = RET.PWDERR, errmsg = '密码格式错误')

    # 从redis删除该验证码，try newUser = User{mobile = mobile, passwd = passwd}, db.session.add(newUser), db.session.commit();
        # sql数据库更新失败则return 注册失败；
    redis_store.delete('mibile:' + mobile)

    # new_account = User(nick_name=str(mobile), password_hash=str(passwd), mobile=str(mobile))
    new_account = User()
    new_account.nick_name = mobile
    new_account.password = <PASSWORD>
    new_account.mobile = mobile
    try:
        db.session.add(new_account)
        db.session.commit()
    except Exception as err:
        db.session.rollback()
        current_app.logger.error(err)
        return jsonify(errno = RET.DBERR, errmsg = '注册账户到数据库失败')

    # 保存用户登录状态到redis（通过session，因为session已经建立session与redis的链接；）；
    session['login_user_id:'] = new_account.id

    # return 登录成功；
    return jsonify(errno = RET.OK, errmsg = '注册成功')

@passPort.route('/login', methods = ['POST'])
def login():
    # 获取前端ajax数据，抽取出 mobile， passwd， 判断是否为空；
    login_infos = request.json
    mobile = login_infos.get('mobile')
    passwd = login_infos.get('passwd')

    if not all([mobile, passwd]):
        return jsonify(errno = RET.USERERR, errmsg = '输入数据不全')

    # 正则判断mobile和passwd格式，不匹配则return 格式错误；
    if not re.match(r'1[35789][0-9]{9}', mobile):
        return jsonify(errno = RET.USERERR, errmsg = '手机号码格式错误')

    if not re.match(r'^[0-9a-zA-Z][\w]{5,}$', passwd):
        return jsonify(errno=RET.USERERR, errmsg='密码格式错误')

    # 在mysql数据库中查询mobile， 若查不到，则return 该用户尚未注册；
    try:
        login_user = User.query.filter(User.mobile == mobile).first()
    except Exception as err:
        current_app.logger.error(err)
        return jsonify(errno = RET.DBERR, errmsg = '数据库查询失败')
    if not login_user:
        return jsonify(errno = RET.NODATA, errmsg = '此账号尚未注册')

    # 获取mysql中该用户密码，与输入密码passwd对比，不一致则return 密码输入错误；
    if not login_user.check_password(passwd):
        return jsonify(errno = RET.PWDERR, errmsg = '账号或密码错误')

    try:
        login_user.last_login = datetime.datetime.now()
        db.session.commit()
    except Exception as err:
        current_app.logger.error(err)
        return jsonify(errno = RET.DBERR, errmsg = '数据库操作失败')

    # 保存用户登录状态到redis（通过session，因为session已经建立session与redis的链接；）；
    session['login_user_id:'] = login_user.id

    from info import redis_store

    # return 登录成功；
    return jsonify(errno = RET.OK, errmsg = '登录成功')

@passPort.route('/logout', methods = ['POST'])
def logOut():
    try:
        session.pop('login_user_id:', None)
    except Exception as err:
        current_app.logger.error(err)
        return jsonify(errno = RET.DBERR, errmsg = '数据库操作失败')
    return jsonify(errno = RET.OK, errmsg = '已退出登录')

# encoding=utf-8

from flask import Blueprint, make_response, request, current_app, jsonify, json, session
from info.utils.captcha import captcha
from info.utils.response_code import RET
from info.lib.yuntongxun.sms import CCP
from info import constants
from info.models import *
import re, random, datetime

passPort = Blueprint('passport', __name__)

@passPort.route('/get_image')
def getImage():
    from info import redis_store

    image_code_id = request.args.get('image_code_id')
    pre_image_code_id = request.args.get('pre_image_code_id')

    try:
        redis_store.delete('iamge_code_id:' + pre_image_code_id)
    except Exception as err:
        current_app.logger.error(err)
        return jsonify(errno = RET.DBERR, errmsg = '数据库操作故障')

    try:
        name, code_text, image = captcha.captcha.generate_captcha()
    except Exception as err:
        current_app.logger.error(err)
        return jsonify(errno = RET.SERVERERR, errmsg = '生成验证码失败')

    # 存储图片验证码内容和识别id；
    try:
        redis_store.setex('iamge_code_id:' + image_code_id, constants.IMAGE_CODE_REDIS_EXPIRES, code_text)
    except Exception as err:
        current_app.logger.error(err)
        return make_response(jsonify(errno =RET.DBERR, errmsg = '验证码保存失败'))

    # 给浏览器返回验证码图片；
    ret = make_response(image)
    ret.headers['content_type'] = 'image/jpg'
    return ret

@passPort.route('/get_sms', methods = ['POST'])
def getSms():
    # 获得前端的json数据，抽取出mobile、验证码、验证码id；
    data_dict = request.json
    mobile = data_dict.get('mobile')
    pic_code = data_dict.get('pic_code')
    pic_id = data_dict.get('pic_id')

    if not all([mobile, pic_code, pic_id]):
        return jsonify(errno = RET.USERERR, errmsg = '数据不完整')

    # 正则匹配mobile格式， 错误则保存到log日志，return error信息；
    if not re.match(r'1[35789][0-9]{9}', mobile):
        return jsonify(errno = RET.USERERR, errmsg = '手机号格式错误')

    # 从redis数据库查询验证码id对应的验证码内容，如果获取失败，则return 验证码过期，成功则删除redis中该条数据，
    # 并与前端获得的验证码对比，不同则return 验证码错误；

    stored_pic_id = None
    try:
        from info import redis_store
        stored_pic_id = redis_store.get('iamge_code_id:' + pic_id)
        redis_store.delete('iamge_code_id:' + pic_id)
    except Exception as err:
        current_app.logger.error(err)
        return jsonify(errno = RET.NODATA, errmsg = '验证码不存在或者已过期')

    if stored_pic_id:
        if stored_pic_id.decode('utf-8').lower() != pic_code.lower():
            redis_store.delete('iamge_code_id:' + pic_id)
            return jsonify(errno = RET.USERERR, errmsg = '验证码输入错误')
    else:
        return jsonify(errno = RET.NODATA, errmsg = '验证码已过期')

    try:
        user = User.query.filter(User.mobile == mobile).first()
    except Exception as err:
        user = None

    if user:
        return jsonify(errno = RET.DATAEXIST, errmsg = '该账号已注册过')

    # 引入6位随机数作为验证码；
    sms_code = random.randint(0,999999)
    sms_code = '%06d'%sms_code
    print(sms_code)


    # # 发送手机验证码，根据发送验证码的函数返回值判断是否成功，失败则保存log日志，return 发送验证码失败；
    # result = CCP().send_template_sms(mobile, [sms_code, constants.SMS_CODE_REDIS_EXPIRES/60], 1)
    # if result != 0:
    #     current_app.logger.error('SMS验证码第三方错误')
    #     return jsonify(errno = RET.THIRDERR, errmsg = '验证码发送失败')

    # 成功则把验证码保存到redis中，识别id为手机号，若保存到redis失败，则保存log日志，return 验证码保存失败；
    try:
        redis_store.setex('mibile:' + mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)
    except Exception as err:
        current_app.logger.error(err)
        return jsonify(errno = RET.DBERR, errmsg = '短信验证码保存失败')

    # 发送成功则return 成功发送信息；
    return jsonify(errno = RET.OK, errmsg = '发送成功', datas = {'sms_code': sms_code})

@passPort.route('/register', methods = ['POST'])
def registerAccount():
    # 从前端获得json数据，抽取出 mobile， 手机验证码， 密码；
    register_infos = request.json
    mobile = register_infos.get('mobile')
    sms_code = register_infos.get('sms_code')
    passwd = register_infos.get('passwd')

    if not all([mobile, sms_code, passwd]):
        return jsonify(errno = RET.NODATA, errmsg = '数据不全')

    # 根据mobile查询redis获得验证码， 若获取失败，则return 手机验证码过期；
    stored_code = None
    try:
        from info import redis_store
        stored_code = redis_store.get('mibile:' + mobile)
    except Exception as err:
        return jsonify(errno = RET.DBERR, errmsg = '手机验证码获取失败')

    # 若上一步获取成功，则与mobile对比，若不同则return 手机验证码输入错误；
    if stored_code:
        if stored_code.decode('utf-8') != sms_code:

            return jsonify(errno = RET.USERERR, errmsg = '验证码输入错误')
    else:
        return jsonify(errno = RET.NODATA, errmsg = '手机验证码已过期')

    # 正则校验密码格式，若错误则return 密码格式错误；
    if not re.match(r'^[0-9a-zA-Z][\w]{5,}$', passwd):
        return jsonify(errno = RET.PWDERR, errmsg = '密码格式错误')

    # 从redis删除该验证码，try newUser = User{mobile = mobile, passwd = passwd}, db.session.add(newUser), db.session.commit();
        # sql数据库更新失败则return 注册失败；
    redis_store.delete('mibile:' + mobile)

    # new_account = User(nick_name=str(mobile), password_hash=str(passwd), mobile=str(mobile))
    new_account = User()
    new_account.nick_name = mobile
    new_account.password = <PASSWORD>
    new_account.mobile = mobile
    try:
        db.session.add(new_account)
        db.session.commit()
    except Exception as err:
        db.session.rollback()
        current_app.logger.error(err)
        return jsonify(errno = RET.DBERR, errmsg = '注册账户到数据库失败')

    # 保存用户登录状态到redis（通过session，因为session已经建立session与redis的链接；）；
    session['login_user_id:'] = new_account.id

    # return 登录成功；
    return jsonify(errno = RET.OK, errmsg = '注册成功')

@passPort.route('/login', methods = ['POST'])
def login():
    # 获取前端ajax数据，抽取出 mobile， passwd， 判断是否为空；
    login_infos = request.json
    mobile = login_infos.get('mobile')
    passwd = login_infos.get('passwd')

    if not all([mobile, passwd]):
        return jsonify(errno = RET.USERERR, errmsg = '输入数据不全')

    # 正则判断mobile和passwd格式，不匹配则return 格式错误；
    if not re.match(r'1[35789][0-9]{9}', mobile):
        return jsonify(errno = RET.USERERR, errmsg = '手机号码格式错误')

    if not re.match(r'^[0-9a-zA-Z][\w]{5,}$', passwd):
        return jsonify(errno=RET.USERERR, errmsg='密码格式错误')

    # 在mysql数据库中查询mobile， 若查不到，则return 该用户尚未注册；
    try:
        login_user = User.query.filter(User.mobile == mobile).first()
    except Exception as err:
        current_app.logger.error(err)
        return jsonify(errno = RET.DBERR, errmsg = '数据库查询失败')
    if not login_user:
        return jsonify(errno = RET.NODATA, errmsg = '此账号尚未注册')

    # 获取mysql中该用户密码，与输入密码passwd对比，不一致则return 密码输入错误；
    if not login_user.check_password(passwd):
        return jsonify(errno = RET.PWDERR, errmsg = '账号或密码错误')

    try:
        login_user.last_login = datetime.datetime.now()
        db.session.commit()
    except Exception as err:
        current_app.logger.error(err)
        return jsonify(errno = RET.DBERR, errmsg = '数据库操作失败')

    # 保存用户登录状态到redis（通过session，因为session已经建立session与redis的链接；）；
    session['login_user_id:'] = login_user.id

    from info import redis_store

    # return 登录成功；
    return jsonify(errno = RET.OK, errmsg = '登录成功')

@passPort.route('/logout', methods = ['POST'])
def logOut():
    try:
        session.pop('login_user_id:', None)
    except Exception as err:
        current_app.logger.error(err)
        return jsonify(errno = RET.DBERR, errmsg = '数据库操作失败')
    return jsonify(errno = RET.OK, errmsg = '已退出登录')
# encoding=utf-8 # 存储图片验证码内容和识别id； # 给浏览器返回验证码图片； # 获得前端的json数据，抽取出mobile、验证码、验证码id； # 正则匹配mobile格式， 错误则保存到log日志，return error信息； # 从redis数据库查询验证码id对应的验证码内容，如果获取失败，则return 验证码过期，成功则删除redis中该条数据， # 并与前端获得的验证码对比，不同则return 验证码错误； # 引入6位随机数作为验证码； # # 发送手机验证码，根据发送验证码的函数返回值判断是否成功，失败则保存log日志，return 发送验证码失败； # result = CCP().send_template_sms(mobile, [sms_code, constants.SMS_CODE_REDIS_EXPIRES/60], 1) # if result != 0: #     current_app.logger.error('SMS验证码第三方错误') #     return jsonify(errno = RET.THIRDERR, errmsg = '验证码发送失败') # 成功则把验证码保存到redis中，识别id为手机号，若保存到redis失败，则保存log日志，return 验证码保存失败； # 发送成功则return 成功发送信息； # 从前端获得json数据，抽取出 mobile， 手机验证码， 密码； # 根据mobile查询redis获得验证码， 若获取失败，则return 手机验证码过期； # 若上一步获取成功，则与mobile对比，若不同则return 手机验证码输入错误； # 正则校验密码格式，若错误则return 密码格式错误； # 从redis删除该验证码，try newUser = User{mobile = mobile, passwd = passwd}, db.session.add(newUser), db.session.commit(); # sql数据库更新失败则return 注册失败； # new_account = User(nick_name=str(mobile), password_hash=str(passwd), mobile=str(mobile)) # 保存用户登录状态到redis（通过session，因为session已经建立session与redis的链接；）； # return 登录成功； # 获取前端ajax数据，抽取出 mobile， passwd， 判断是否为空； # 正则判断mobile和passwd格式，不匹配则return 格式错误； # 在mysql数据库中查询mobile， 若查不到，则return 该用户尚未注册； # 获取mysql中该用户密码，与输入密码passwd对比，不一致则return 密码输入错误； # 保存用户登录状态到redis（通过session，因为session已经建立session与redis的链接；）； # return 登录成功；