def bing_phone(request): """ 绑定新手机,作为登录凭证而存在 业务流程: 输入新手机号-检查手机是否存在-获取验证码-更换手机号凭证 此验证码只作为绑定手机业务使用 手机号要检查是否和当前手机号一致,再检查是否和其他账号的登录凭证冲突 param phone captcha """ # 验证手机号是否和验证码一致,验证码是否有效,密码字符集判断处理,重设密码 phone = request.POST.get('phone', None) captcha = request.POST.get('captcha', None) cache_key = hashlib.md5(SMS_TYPE_BIND_PHONE + phone).hexdigest() cache_value = cache.get(cache_key) if not cache_value: return json_params_error(message=u'验证码错误') if not cache_value.has_key('code') or cache_value['code'] != captcha: return json_params_error(message=u'验证码错误') user = FrontUserModel.objects.filter(pk=request.front_user.id).first() user.update_phone(phone) cache.delete(cache_key) return json_result(message=u'手机绑定成功')
def comment_time_period(create_time): if create_time: now = datetime.datetime.now() # 转换成秒数计算相差 seconds = (now - create_time).total_seconds() # 如果秒数小于10分钟,则返回刚刚 if seconds: if seconds <= 60 * 10: return u'刚刚' elif seconds > 60 * 10 and seconds <= 60 * 60: minute = seconds / 60 return u'%s分钟前' % int(minute) elif seconds > 60 * 60 and seconds <= 60 * 60 * 24: hours = seconds / (60 * 60) return u'%s小时之前' % int(hours) elif seconds > 60 * 60 * 24 and seconds <= 60 * 60 * 24 * 30: day = seconds / (60 * 60 * 24) return u'%s天前' % int(day) # elif seconds > 60 * 60 * 24 * 30 and seconds <= 60 * 60 * 24 * 365: # month = seconds / (60 * 60 * 24 * 30) # return u'%s月前' % int(month) else: #year = seconds / (60 * 60 * 24 * 365) #return u'%s年前' % int(year) # str_time =time.strptime(create_time, "%Y-%m-%d %H:%M:%S") # 转换为其他字符串格式: return create_time.strftime("%Y-%m-%d") else: return json_params_error(message=u'时间格式错误!') else: return json_params_error(message=u'时间格式错误!')
def phone_forget_pwd(request): if request.method == 'GET': return render(request, 'phone_forget_pwd.html') # 验证手机号是否和验证码一致,验证码是否有效,密码字符集判断处理,重设密码 phone = request.POST.get('phone', None) captcha = request.POST.get('captcha', None) password = request.POST.get('password', None) cache_key = hashlib.md5(SMS_TYPE_FORGET_PWD + phone).hexdigest() cache_value = cache.get(cache_key) if not password: return json_params_error(data={'password': u'密码不能为空!'}) if len(password) < 4 or len(password) > 16: return json_params_error(data={'password': u'请输入4-16位长度的密码!'}) if not cache_value: return json_params_error(data={'captcha': u'验证码错误'}) if not cache_value.has_key('code') or cache_value['code'] != captcha: return json_params_error(data={'captcha': u'验证码错误'}) try: user = FrontUserModel.objects.get(phone=phone) except FrontUserModel.DoesNotExist: return json_params_error(message=u'该账号不存在') user.update_password(password) login_by_specific_backend(request, user) cache.delete(cache_key) return json_result(message=u'密码重设成功')
def send_phone_login_code(request): ''' 发送手机登陆时的验证码 ''' phone = request.POST.get('phone', None) if not phone: return json_params_error(data={'phone': u'手机号不能为空'}) if not re.match(configs.PHONE_REGX, phone): return json_params_error(data={'phone': u'手机号格式错误'}) cache_key = hashlib.md5(SMS_TYPE_LOGIN + phone).hexdigest() return _send_sms_code(cache_key, phone)
def user_praise(request, id=0, type_id=0): try: Id = int(id) except: pass model_type = configs.model_type if not Id: return json_params_error(message=u'这是一片未知的荒原!') if not type_id: return json_params_error(message=u'请选择点赞类型!') if model_type[type_id]: typeId = int(type_id) if typeId == 1: praiseModel = MethodArticleInfoModel.objects.filter( status__in=[1, 2], pk=Id).first() if not praiseModel: return json_params_error(message=u'你尝试查看一篇不存在的文章!') elif typeId == 2: praiseModel = NewsModel.objects.filter(status__in=[1, 2], pk=Id).first() if not praiseModel: return json_params_error(message=u'你尝试查看一篇不存在的新闻!') elif typeId == 3: praiseModel = VideoModel.objects.filter(status=1, pk=Id).first() if not praiseModel: return json_params_error(message=u'你尝试查看一节不存在的课程!') elif typeId == 6: praiseModel = VideoCommentModel.objects.filter(pk=Id).first() if not praiseModel: return json_params_error(message=u'你尝试查看一条不存在的评论!') else: return json_params_error(message=u'请更新模型!') #判断用户是否已点赞 userPraiseModel = UserPraiseModel.objects.filter( username=request.front_user) if userPraiseModel: for u in userPraiseModel: if praiseModel == u.content_object: u.delete() context = { 'is_praise': 0, } return json_result(message=u'已取消赞点!', data=context) addPraiseModel = UserPraiseModel(username=request.front_user, content_object=praiseModel) addPraiseModel.save() context = { 'is_praise': 1, } return json_result(message=u'已点赞!', data=context) else: return json_params_error(message=u'你尝试点赞一个不存在的类型!')
def _send_email_code(cache_key, email, exipre_second=600): stored_value = cache.get(cache_key) if stored_value: if (timezone.now() - stored_value['send_time']).seconds < 60: return json_params_error(data={'email': u'60秒内只能获取一次验证码'}, message=u'60秒内只能获取一次验证码') code = '' for i in range(6): ch = chr(random.randrange(ord('0'), ord('9') + 1)) code += ch value = dict(code=code, send_time=timezone.now()) cache.set(cache_key, value, exipre_second) subject = u'[医咖会]-邮箱验证' message = u'您好! 您在{}申请了邮箱验证\n' \ u'请填写如下6位验证码:\n' \ u'{}\n' \ u'验证码在10分钟内有效,10分钟后需要重新发送\n\n' \ u'此邮件为系统邮件,请勿回复,如您想了解更多内容,欢迎访问我们的网站获取信息' time_formated = time.strftime("%Y年%m月%d日 %H:%M:%S", time.localtime()) from_email = settings.EMAIL_HOST_USER recipinet_list = [email] if mail.send_mail(subject, message.format(time_formated, code), from_email, recipinet_list): # request.session['email'] = email # 将邮箱存入缓存 return Response(200, code=200, message='验证码已发送到你的邮箱') else: return Response(400, code=400, message='邮件发送失败,请稍后重试')
def bind_email(request): email = request.POST.get('email', None) captcha = request.POST.get('captcha', None) cache_key = hashlib.md5(CODE_TYPE_BIND_EMAIL + email).hexdigest() cache_value = cache.get(cache_key) if not cache_value: return json_params_error(message=u'验证码错误') if not cache_value.has_key('code') or cache_value['code'] != captcha: return json_params_error(message=u'验证码错误') user = FrontUserModel.objects.filter(pk=request.front_user.id).first() user.update_email(email) cache.delete(cache_key) return json_result(message=u'邮箱绑定成功')
def send_code_email(email, sub_subject=None, message=None, code=None, key_head=EMAIL_TYPE_VALIDATE): ''' 生成激活码,发送账户激活邮件 如果存在上一个激活码,那么重新发送,如果不存在,那么发送新激活邮件 cache_key_validate是为了方便查找到上次的激活码 TODO 应该限制单位时间内发送的邮件次数 ''' email = None if email == None else email.strip() cache_key = hashlib.md5(key_head + email).hexdigest() stored_value = cache.get(cache_key) if stored_value: if (timezone.now() - stored_value['send_time']).seconds < 60: return json_params_error(message='60秒内只能获取一次验证码', data={'email': u'60秒内只能获取一次验证码'}) value = dict(code=code, send_time=timezone.now()) cache.set(cache_key, value, 600) # 发送邮件到email邮箱 subject = u'[医咖会]-' + sub_subject from_mail = settings.EMAIL_HOST_USER recipinet_list = [email] try: if mail.send_mail(subject, message, from_mail, recipinet_list): print('saved-key', cache_key, 'value=', value) return json_result(message='验证码邮件已发送成功') else: return json_result(message='验证码邮件已发送失败') except Exception: raise
def send_phone_forget_pwd_code(request): ''' 发送手机登陆时的验证码 ''' phone = request.POST.get('phone', None) if not phone: return json_params_error(data={'phone': u'手机号不能为空'}) if not re.match(configs.PHONE_REGX, phone): return json_params_error(data={'phone': u'手机号格式错误'}) try: user = FrontUserModel.objects.get(phone=phone) except FrontUserModel.DoesNotExist: return json_params_error(data={'phone': u'该手机号未注册'}) cache_key = hashlib.md5(SMS_TYPE_FORGET_PWD + phone).hexdigest() return _send_sms_code(cache_key, phone)
def send_phone_register_code(request): ''' 发送手机注册时的验证码,cache存储的key有特定格式,防止串用验证码 TODO type定义为reigister/forget_pwd/,这样保证一个验证码只能在一个业务流里使用 ''' phone = request.POST.get('phone', None) if not phone: return json_params_error(data={'phone': u'手机号不能为空'}) if not re.match(configs.PHONE_REGX, phone): return json_params_error(data={'phone': u'手机号格式错误'}) try: user = FrontUserModel.objects.get(phone=phone) if user: return json_params_error(data={'phone': u'该手机号已注册'}) except FrontUserModel.DoesNotExist: pass cache_key = hashlib.md5(SMS_TYPE_REGISTER + phone).hexdigest() return _send_sms_code(cache_key, phone)
def send_bind_phone_code(request): ''' 发送手机绑定时的验证码 ''' phone = request.POST.get('phone', None) if not phone: return json_params_error(message=u'手机号不能为空') if not re.match(configs.PHONE_REGX, phone): return json_params_error(message=u'手机号格式错误') if phone == request.front_user.phone: return json_params_error(message=u'请绑定新手机号') try: user = FrontUserModel.objects.get(phone=phone) if user: return json_params_error(message=u'手机号已经被使用') except FrontUserModel.DoesNotExist: pass cache_key = hashlib.md5(SMS_TYPE_BIND_PHONE + phone).hexdigest() return _send_sms_code(cache_key, phone)
def send_bind_email_code(request): ''' 发送邮箱绑定时的验证码 ''' email = request.POST.get('email', None) if not email: return json_params_error(message=u'邮箱不能为空') if not re.match(configs.EMAIL_REGX, email): return json_params_error(message=u'邮箱格式错误') if email == request.front_user.email: return json_params_error(message=u'请绑定新邮箱') try: user = FrontUserModel.objects.get(email=email) if user: return json_params_error(message=u'邮箱已经被使用') except FrontUserModel.DoesNotExist: pass cache_key = hashlib.md5(CODE_TYPE_BIND_EMAIL + email).hexdigest() return _send_email_code(cache_key, email)
def upload_file(request, file_path): if request.method == 'POST': fileInfo = request.FILES.get('file_info') if fileInfo: filePath = os.path.join(settings.BASE_DIR, 'media/%s/%s').replace( "\\", "/") % (file_path, fileInfo.name) with open(filePath, 'wb') as f: for chunk in fileInfo.chunks(): f.write(chunk) return json_result(data=fileInfo.name) else: return json_params_error(message=u'请添加需要上传的文件!')
def phone_login(request): if request.method == 'GET': return render(request, 'phone_login.html') # post短信登录 phone = request.POST.get('phone', None) captcha = request.POST.get('captcha', None) cache_key = hashlib.md5(SMS_TYPE_LOGIN + phone).hexdigest() if not cache.get(cache_key): return json_params_error(data={'captcha': u'验证码错误'}) code = cache.get(cache_key)['code'] # TODO 需要检查一下cache过期是直接删除还是会返回过期的属性,否则无法判断验证码过期还是没有验证码 if not code: return json_params_error(data={'captcha': u'验证码错误'}) if code != captcha: return json_params_error(data={'captcha': u'验证码错误'}) user = authenticate(phone=phone) if not user: return json_params_error(data={'phone': u'账号或密码错误'}) # TODO 检查账号是否是用邮箱注册、且没有点击验证链接,这种情况下, # 跳转到页面提示用户完成激活 # if not user.activated: # return redirect(...) if not user.is_active: return json_params_error(message=u'此用户已被锁定,请联系管理员!') login(request, user) # 如果有 next,则跳转到 next 页面,否则返回 json 信息 nexturl = request.GET.get('next') if nexturl: return redirect(nexturl) else: context = dict(id=user.id, username=user.username, avatar=user.avatar) return json_result(message=u'登录成功!', data=context)
def _send_sms_code(cache_key, phone, exipre_second=600): # TODO 需要记录单位时间内同一个手机发送的短信次数,现在先由阿里云直接支持,一个小时一个手机号最多5次 # TODO 暂时只支持同一种短信类型60秒只能获取一次验证码,是否应该支持全局的同一手机号60秒只能获取一次验证码 stored_value = cache.get(cache_key) if stored_value: if (timezone.now() - stored_value['send_time']).seconds < 60: return json_params_error(data={'phone': u'60秒内只能获取一次验证码'}, message=u'60秒内只能获取一次验证码') code = alisms.send_verify_code(phone) value = dict(code=code, send_time=timezone.now()) cache.set(cache_key, value, exipre_second) if alisms.DRYRUN: return Response(200, code=200, message='短信已发送,测试模式:' + code) else: return Response(200, code=200, message='短信已发送')
def image_storage(request, img_path): if request.method == 'POST': imgFile = request.FILES.get('imgFile') logger.info({'imgFile': imgFile}) if imgFile: file_name = hashlib.md5(str(time.time()) + imgFile.name).hexdigest() file_path = os.path.join( settings.BASE_DIR, 'images/%s/%s', ).replace("\\", "/") % (img_path, file_name) with open(file_path, 'wb') as f: for chunk in imgFile.chunks(): f.write(chunk) return json_result(data=file_name) else: return json_params_error(message=u'图片不能为空!')
def resend_active_mail(request): """ 重新发送激活邮件,支持两种情况: 登陆的未激活账号重新发送激活邮件:使用request.front_user对象获取邮箱地址 注册流程中重新发送激活邮件:从post中获取邮箱地址 """ if hasattr(request, 'front_user'): # 检查cache是否有邮箱激活链接,有则发送cache已有链接,无则发送新的激活链接 email = request.front_user.email else: email = request.POST.get('email') if not email: return json_params_error(message=u'邮箱地址不为空') # 查找是否发送过邮箱激活链接,有则重新发送,没有则检查是否有这个账号但是未激活,有则发送激活链接,无则提示未注册。 # cache里面key是code=md5(time+email),无法直接通过email查询是否有过邮箱激活链接,所以在 # cache里面增加一个action+email的缓存,关联到上面code,这样能实现通过email查询当前有无邮件激活链接 if send_email.send_email_active_mail(request, email): return json_result(message=u'激活邮件已发送') else: return json_method_error(message=u'激活邮件发送失败')
def register_email(request): if request.method == 'GET': return render(request, 'register_email.html') # POST phone = request.POST.get('phone', None) captcha = request.POST.get('captcha', None) password = request.POST.get('password', None) if phone is None: return json_params_error(data={'phone': u'手机号不能为空'}) if not password: return json_params_error(data={'password': u'密码不能为空!'}) if len(password) < 4 or len(password) > 16: return json_params_error(data={'password': u'请输入4-16位长度的密码!'}) cache_key = hashlib.md5(SMS_TYPE_REGISTER + phone).hexdigest() if not cache.get(cache_key): return json_params_error(data={'captcha': u'验证码错误'}) if not captcha: return json_params_error(data={'captcha': u'验证码不能为空'}) # 验证码验证部分 code = cache.get(cache_key)['code'] # TODO 需要检查一下cache过期是直接删除还是会返回过期的属性,否则无法判断验证码过期还是没有验证码 if not code: return json_params_error(data={'captcha': u'验证码错误'}) if code != captcha: return json_params_error(data={'captcha': u'验证码错误'}) try: emailModel = FrontUserModel.objects.get(phone=phone) return json_params_error(data={'phone': u'此手机已被注册!'}) except FrontUserModel.DoesNotExist: pass # 用户名现在不由用户注册时输入,默认生成一个。 user = FrontUserModel(phone=phone, password=password) user.create_user_by_phone() login_by_specific_backend(request, user) return Response(200, code=200, message='注册成功,请登录')
def favorites(request, id=0, collect_category_id=0, type_id=0): try: Id = int(id) collectCategoryId = int(collect_category_id) except: pass typeId = type_id model_type = configs.model_type if not Id: return json_params_error(message=u'这是一片未知的荒原!') if not typeId: return json_params_error(message=u'请选择收藏类型!') collectCategoryModel = None # 判断收藏分类是否存在 if collectCategoryId: userCollectCategoryModel = UserCollectCategoryModel.objects.filter( author=request.front_user, pk=collectCategoryId).first() if userCollectCategoryModel: collectCategoryModel = userCollectCategoryModel # 判断此类型是否存在 if model_type[typeId]: typeId = int(typeId) if typeId == 1: favoritesModel = MethodArticleInfoModel.objects.filter( status__in=[1, 2], pk=Id).first() if not favoritesModel: return json_params_error(message=u'你尝试查看一篇不存在的文章!') elif typeId == 2: favoritesModel = NewsModel.objects.filter(status__in=[1, 2], pk=Id).first() if not favoritesModel: return json_params_error(message=u'你尝试查看一篇不存在的新闻!') elif typeId == 3: favoritesModel = VideoModel.objects.filter(status=1, pk=Id).first() if not favoritesModel: return json_params_error(message=u'你尝试查看一节不存在的课程!') else: return json_params_error(message=u'请更新模型!') # 判断用户收藏列表中是否存在此收藏 userFavoritesModel = UserFavoritesModel.objects.filter( username=request.front_user, favorite_category=collectCategoryModel).all() if userFavoritesModel: for u in userFavoritesModel: if u.content_object == favoritesModel: u.delete() context = { 'is_collect': 0, } return json_result(message=u'已取消收藏!', data=context) userFavoritesModel = UserFavoritesModel( username=request.front_user, favorite_category=collectCategoryModel, content_object=favoritesModel) userFavoritesModel.save() context = { 'is_collect': 1, } return json_result(message=u'收藏成功!', data=context) else: return json_params_error(message=u'你尝试收藏一个不存在的类型!')
def add_answer(request): if request.method == 'GET': return json_result(message=u'这是问答发表评论页面!') else: questionId = request.POST.get('question_id', 0) relevanceAnswer = request.POST.get('relevance_answer', 0) relayTo = request.POST.get('relay_to', 0) comment = request.POST.get('comment', None) try: comment = str(comment).strip() relevanceAnswer = int(relevanceAnswer) relayTo = int(relayTo) except: pass logger.info({ 'question_id': questionId, 'relevance_answer': relevanceAnswer, 'relay_to': relayTo, 'comment': comment }) if questionId: questionModel = QuestionsModel.objects.filter( pk=questionId, is_removed=0).first() if questionModel: if comment: if relevanceAnswer: #如果关联的回答id为真,则为2级评论 answerModel = AnswersModel.objects.filter( pk=relevanceAnswer, questions=questionModel, is_removed=0).first() if answerModel: #2级评论还需要区分:对父评论回复时,不需要显示 回复者 if relayTo: frontUserModel = FrontUserModel.objects.filter( pk=relayTo, is_active=1).first() if frontUserModel: # 若修改userid,导致不是当前问题下的用户,需要特殊处理 tmpAnswerUserModel = AnswersModel.objects.filter( author=frontUserModel, questions=questionModel, is_removed=0).first() if tmpAnswerUserModel: relevanceAnswerModel = AnswersModel( author=request.front_user, questions=questionModel, comment=comment, relevance_answer=answerModel, relay_to=frontUserModel) relevanceAnswerModel.save() # 更新问题模型中的最后评论时间 questionModel.last_answer_time = datetime.datetime.now( ) questionModel.save( update_fields=['last_answer_time']) #给回复者发通知 return json_result(message=u'回复评论成功!') else: return json_params_error( message=u'你回复的回答不存在或已删除!') else: return json_params_error( message=u'不能回复给不存在的人!') else: tmpChildAnswerModel = AnswersModel( author=request.front_user, questions=questionModel, comment=comment, relevance_answer=answerModel) tmpChildAnswerModel.save() questionModel.last_answer_time = datetime.datetime.now( ) questionModel.save( update_fields=['last_answer_time']) return json_result(message=u'回复评论成功!') else: return json_params_error(message=u'你尝试回复一个不存在的评论!') else: parentAnswerModel = AnswersModel( author=request.front_user, questions=questionModel, comment=comment) parentAnswerModel.save() questionModel.last_answer_time = datetime.datetime.now( ) questionModel.save(update_fields=['last_answer_time']) #20171212 当问题有1级回复时,给发表问题者发送通知 myMessagesModel = MyMessagesModel( replay_name=request.front_user, replay_answer=parentAnswerModel, question=questionModel) myMessagesModel.save() return json_result(message=u'回复评论成功!') else: return json_params_error(message=u'评论内容不能为空!') else: return json_params_error(message=u'你尝试回答一个不存在的问题!') else: return json_params_error(message=u'你尝试访问一个不存在的问题!')