def rewind_swiper(uid): """ 反悔最近5分钟的操作 每天只能反悔3次 """ # 取出当前时间 now = datetime.datetime.now() # 取出反悔key的过期时间,如果没有给一个默认值 rewind_key = keys.REWIND_K % (now.date(), uid) rewind_times = rds.get(rewind_key, 0) # 检查key的反悔次数,如果超过3次则抛出错误 if rewind_times > 3: raise stat.REWIND_TIMEOUT_ERR # 从数据库中取出最近滑动记录 latest_swipe = Swiped.objects.filter(uid=uid).latest('stime') # 5分钟内可以撤销滑动,过时则抛错 pass_time = now - latest_swipe.stime if pass_time.total_seconds() > config.TIMEOUT: raise stat.REWIND_TIME_ERR # 如果是超级喜欢,那么要把自己从对方的优先推荐队列中删去,好友表记录删去 if latest_swipe.stype == 'superlike': rds.lrem(keys.FIRST_RCMD_K % latest_swipe.sid, 1, uid) Friends.break_off(latest_swipe.sid, uid) # 如果是超级喜欢和喜欢类型,那么要把好友表记录删去 elif latest_swipe.stype == 'like': Friends.break_off(latest_swipe.sid, uid) # 调整用户的积分 score = config.HOT_RANK_SCORE[latest_swipe.stype] rds.zincrby(keys.HOT_RANK_K, score, latest_swipe.sid) # 删除滑动记录 latest_swipe.delete() # 更新反悔次数 rds.set(rewind_key, rewind_times + 1, 86400)
def superlike_someone(uid, sid): '''上滑:喜欢某人''' # 添加一条滑动记录 Swiped.swipe(uid, sid, 'superlike') # 强制从自己优先队列删除 sid rds.lrem(keys.FIRST_RCMD_K % uid, 1, sid) # 为被滑动用户增加积分 rds.zincrby('HotRank', conf.SWIPE_SCORE['superlike'], sid) # 检查是否对方是否右滑或上滑过自己 if Swiped.has_liked(sid, uid): # 匹配成好友关系 Friend.make_friends(uid, sid) return True else: # 将自己的 UID 添加到对方的优先推荐队列 rds.rpush(keys.FIRST_RCMD_K % sid, uid) return False
def rewind(uid): key = keys.REWIND % uid cached_rewind_times = cache.get(key, 0) if cached_rewind_times < config.MAX_REWIND_TIMES: # 说明可以执行反悔操作. # 查找上一次操作的Swiped记录 record = Swiped.objects.latest('time') # 如果建立了好友关系,好友关系也需取消. if Friend.is_friend(uid1=uid, uid2=record.sid): Friend.delete_friend(uid1=uid, uid2=record.sid) # 更新缓存 cached_rewind_times += 1 now = datetime.datetime.now() timeout = 86400 - (3600 * now.hour + 60 * now.minute + now.second) cache.set(key, cached_rewind_times, timeout) # 处理反悔之后排行榜的分数问题 # if record.mark == 'like': # rds.zincrby(config.TOP_N, -config.LIKE_SCORE, # keys.TOP_N_KEY % record.sid) # elif record.mark == 'dislike': # rds.zincrby(config.TOP_N, -config.DISLIKE_SCORE, # keys.TOP_N_KEY % record.sid) # else: # rds.zincrby(config.TOP_N, -config.SUPERLIKE_SCORE, # keys.TOP_N_KEY % record.sid) # 使用字典做模式匹配优化以上代码 mapping = { 'like': config.LIKE_SCORE, 'dislike': config.DISLIKE_SCORE, 'superlike': config.SUPERLIKE_SCORE } rds.zincrby(config.TOP_N, -mapping.get(record.mark), keys.TOP_N_KEY % record.sid) record.delete() return True else: raise errors.ExceedMaximumRewindTimes
def superlike_someone(user_id, sid): '''超级喜欢某人''' '''添加滑动记录''' Swiped.swpied(user_id, sid, 'superlike') '''在自己的优先推荐列表里删除对方id''' rds.lrem(keys.PRIOR_RCMD_LIST % user_id, value=sid) '''超级喜欢对方,给对方的增加积分''' rds.zincrby(keys.HOT_RANK, sid, config.RANK_SCORE['superlike']) '''检查对方是否上滑(superlike)或右滑(like)过你''' liked = Swiped.is_liked(user_id, sid) if liked is True: # 对方喜欢你 '''如果对方也喜欢过你,将你们匹配为好友''' Friend.make_friends(user_id, sid) return True elif liked is False: # 对方不喜欢你 return False else: # 对方没有滑过你,将你的id给到对方的优先推荐列表 rds.rpush(keys.PRIOR_RCMD_LIST % sid, user_id) return False
def superlike_someone(uid, sid): Swiped.swipe(uid, sid, stype='superlike') # 删除滑动过的推荐 rds.lrem(keys.FIRST_RCMD_K % uid, 1, sid) liked_me = Swiped.is_liked(sid, uid) # 调整用户的积分 score = config.HOT_RANK_SCORE['superlike'] rds.zincrby(keys.HOT_RANK_K, score, sid) if liked_me: Friends.make_friends(uid, sid) return True elif liked_me == False: return False else: # 对方并没有滑动过uid,将uid添加到对方的“优先推荐队列” rds.rpush(keys.FIRST_RCMD_K % sid, uid) return False
def rewind_last_swipe(uid): ''' 反悔最后一次的滑动 - 每天允许反悔 3 次 - 反悔的记录只能是五分钟之内的 ''' # 取出当前时间 now = datetime.datetime.now() # 检查当前是否达到了 3 次 key = keys.REWIND_K % (now.date(), uid) rewind_times = rds.get(key, 0) # 取出当天的反悔次数,默认为 0 次 if rewind_times >= 3: raise stat.RewindLimited # 当天达到额定次数: 直接给用户提示 latest_swipe = Swiped.objects.filter(uid=uid).latest('stime') # 找到最后一次的滑动记录 # 对比当前时间和最后一次的滑动时间,差值是否在五分钟内 passed_time = (now - latest_swipe.stime).total_seconds() # 计算距离上一次滑动已经过去的秒数 if passed_time >= 300: raise stat.RewindTimeout # 超过 5 分钟,直接给用户提示 # 撤销滑动式可能受影响的其他相关数据 # 好友关系删掉 if latest_swipe.stype in ['like', 'superlike']: Friend.break_off(uid, latest_swipe.sid) # 优先推荐队列里的数据删掉 if latest_swipe.stype == 'superlike': rds.lrem(keys.FIRST_RCMD_K % latest_swipe.sid, 1, uid) # 撤销滑动积分 rds.zincrby(keys.RANK_K, -conf.SWIPE_SCORE[latest_swipe.stype], latest_swipe.sid) # 删除最后一次滑动记录 latest_swipe.delete() # 全部完成后,累加反悔次数 rds.set(key, rewind_times + 1, 86400 * 2) # 过期时间是为了让当天的反悔次数自然消失
def rewind_swipe(uid): ''' 反悔一次滑动 每天允许反悔 5 次,反悔的记录只能是五分钟之内的 ''' now = datetime.datetime.now() # 当前时间 # 取出当天的反悔次数 rewind_k = keys.REWIND_K % (now.date(), uid) rewind_times = rds.get(rewind_k, 0) # 当天反悔次数,取不到时默认为 0 # 检查当前反悔次数 if rewind_times >= config.REWIND_TIMES: raise stat.RewindLimit # 取出最后一次的滑动记录 latest_swipe = Swiped.objects.filter(uid=uid).latest('stime') # 检查滑动记录的时间否超是过 5 分钟 pass_time = now - latest_swipe.stime if pass_time.total_seconds() > config.REWIND_TIMEOUT: raise stat.RewindTimeout # 如果是超级喜欢,需要将自己从对方优先推荐队列删除 # 如果之前是喜欢或超级喜欢,需要撤销好友关系 if latest_swipe.stype == 'superlike': rds.lrem(keys.FIRST_RCMD_K % latest_swipe.sid, 1, uid) Friend.break_off(uid, latest_swipe.sid) elif latest_swipe.stype == 'like': Friend.break_off(uid, latest_swipe.sid) # 调整对方的滑动积分 score = config.HOT_RANK_SCORE[latest_swipe.stype] rds.zincrby(keys.HOT_RANK_K, -score, latest_swipe.sid) # 将滑动记录删除 latest_swipe.delete() # 更新反悔次数 rds.set(rewind_k, rewind_times + 1, 86400) return config.REWIND_TIMES, rds.get(rewind_k, 0)
def rewind_slide(uid): '''反悔(每天3次,5分钟内)''' now_time = datetime.datetime.now() today = now_time.date() rewind_key = keys.REWIND_K % (today, uid) # 检查是否已经3次 rewind_num = rds.get(rewind_key, 0) if rewind_num >= config.REWIND_TIMES: raise errors.RewindLimit # 检查最后一次滑动是否在5分钟内 last_slide = Slide.objects.filter(uid=uid).latest('slide_time') if now_time > last_slide.slide_time + datetime.timedelta( minutes=config.REWIND_TIMEOUT): raise errors.RewindTimeout # 将多次数据修改在事务中执行 with atomic(): # 检查是否是好友 if last_slide.slide_type in ['like', 'superlike']: Friend.broken(uid, last_slide.sid) if last_slide.slide_type == 'superlike': # 从对方的推荐列表里删除我的id rds.lrem(keys.FIRST_RCMD_Q % last_slide.sid, count=0, value=uid) # 撤回被滑动者的积分 score = config.SLIDE_SCORE[last_slide.slide_type] rds.zincrby(keys.HOT_RANK, -score, last_slide.sid) # 删除最后一次滑动 last_slide.delete() # 设置缓存,反悔次数加一 rds.set(rewind_key, rewind_num + 1, 86400)
def superlike_someone(uid, sid): '''超级喜欢''' # 1.添加滑动记录 Slide.slide(uid=uid, sid=sid, slide_type='superlike') # 2.强制删除优先推荐队列里的id rds.lrem(keys.FIRST_RCMD_Q % uid, count=0, value=sid) # 给被滑动者添加积分 rds.zincrby(keys.HOT_RANK, config.SLIDE_SCORE['superlike'], sid) # 3.检查对方是否喜欢自己,如果喜欢那么建立好友关系 is_like = Slide.is_liked(uid=sid, sid=uid) if is_like is True: Friend.make_friend(uid, sid) return True elif is_like is False: return False else: # 对方没有滑到自己,将自己添加到对方的优先推荐队列 rds.lpush(keys.FIRST_RCMD_Q % sid, uid) return False
def rewind_swiped(user): '''反悔一次滑动纪录''' # 获取今天的反悔次数 rewind_times = rds.get(keys.REWIND_KEY % user.id, 0) # 检查今天反悔是否达到限制次数 if rewind_times >= cfg.DAILY_REWIND: raise stat.RewindLimit # 找到最近一次的滑动记录 latest_swiped = Swiped.objects.filter(uid=user.id).latest('stime') # 检查反悔的记录是否是五分钟之内的 now = datetime.datetime.now() if (now - latest_swiped.stime).total_seconds() >= cfg.REWIND_TIMEOUT: raise stat.RewindTimeout # 检查上一次滑动是否有可能匹配成了好友 if latest_swiped.stype in ['like', 'superlike']: # 删除好友关系 Friend.break_off(user.id, latest_swiped.sid) # 如果上一次是超级喜欢,将自身uid从对方的优先推荐队列中删除 if latest_swiped.stype == 'superlike': rds.zrem(keys.SUPERLIKED_KEY % latest_swiped.sid, user.id) # 还原用户的滑动积分 score = -cfg.SWIPE_SCORE[latest_swiped.stype] rds.zincrby(keys.HOT_RANK_KEY, score, latest_swiped.sid) # 删除滑动记录 latest_swiped.delete() # 更新当天的滑动次数, 同时设置过期时间到下一个凌晨 next_zero = datetime.datetime(now.year, now.month, now.day) + datetime.timedelta(1) remain_seconds = (next_zero - now).total_seconds() rds.set(keys.REWIND_KEY % user.id, rewind_times + 1, int(remain_seconds))
def superlike_someone(uid, sid): '''超级喜欢某人(上滑)''' # 添加滑动记录 Swiped.swiped(uid, sid, 'superlike') # 强制删除优先推荐队列中的 sid rds.lrem(keys.FIRST_RCMD_Q + str(f'{uid}'), count=0, value=sid) # 增加对方的滑动积分 rds.zincrby(keys.HOT_RANK, config.SWIPE_SCORE['superlike'], sid) # 检查对方是否喜欢过自己 is_liked = Swiped.is_liked(sid, uid) if is_liked is True: # 将互相喜欢的两个人添加为好友 Friend.make_friends(uid, sid) return True elif is_liked is False: return False else: # 对方尚未滑动过自己,将自己优先推荐给对方 rds.rpush(keys.FIRST_RCMD_Q + str(f'{sid}'), uid) return False
def superlike_someone(uid, sid): '''超级喜欢某人''' # 添加滑动记录 Swiped.swipe(uid, sid, 'superlike') # 将 sid 从自己的优先推荐队列中删除 rds.lrem(keys.FIRST_RCMD_K % uid, 1, sid) # 调整对方的滑动积分 score = config.HOT_RANK_SCORE['superlike'] rds.zincrby(keys.HOT_RANK_K, score, sid) # 检查对方有没有右滑或者上滑过自己 liked_me = Swiped.is_liked(sid, uid) if liked_me: # 如果对方喜欢过自己,匹配成好友 Friend.make_friends(uid, sid) return True elif liked_me == False: return False else: # 对方没有滑动过自己,需要将将自己的 uid 添加到对方的 “优先推荐队列” rds.rpush(keys.FIRST_RCMD_K % sid, uid) return False
def like_someone(uid, sid): '''喜欢某人''' # 添加滑动记录 Swiped.swiper(uid, sid, 'like') # 将sid从自己的优先推荐队列中删除 rds.lrem(keys.FIRST_CRMD_K % uid, 1, sid) # 积分 score = config.HOT_RANK_SCORE['like'] print(score) # 调整被滑动者的积分 rds.zincrby(keys.HOT_RANK_K, score, sid) print(rds.zrevrange(keys.HOT_RANK_K, 0, 49, withscores=True)) # 检查对方有没有喜欢自己(右滑或上滑过自己) if Swiped.is_liked(sid, uid): # 添加好友列表 Friend.make_friends(uid, sid) return True else: return False
def rewind_swiper(uid): '''返回一次滑动''' # 取出当前时间 now = datetime.datetime.now() # 取出当天的反悔次数 rewind_k = keys.REWIND_KEY % (now.date(), uid) rewind_times = rds.get(rewind_k, 0) # 当天返回次数,取不到时默认为零 # 检查当前返回次数 if rewind_times >= config.REWIND_TIMES: raise stat.RewindLimit # 取出最后一次的滑动记录 latest_swiper = Swiped.objects.filter(uid=uid).latest('stime') # 检查滑动记录的时间是否超过5分钟 pass_time = now - latest_swiper.stime if pass_time.total_seconds() > config.REWIND_TIMEOUT: raise stat.RewindTimeout # 如果是超级喜欢,需要将自己从对方的优先推荐队列删除 if latest_swiper.stype == 'superlike': rds.lrem(keys.FIRST_CRMD_K % sid, 1, uid) Friend.break_off(uid, latest_swiper.sid) # 如果之前是喜欢或超级喜欢 需要撤销好友关系 elif latest_swiper.stype == 'like': Friend.break_off(uid, latest_swiper.sid) score = config.HOT_RANK_SCORE[latest_swiper.stype] rds.zincrby(keys.HOT_RANK_K, -score, latest_swiper.sid) # 将滑动记录删除 latest_swiper.delete() # 更新返回次数 rds.set(rewind_k, rewind_times + 1, 86400)
def superlike_someone(uid, sid): '''超级喜欢某人 (上滑)''' # 添加滑动记录 Swiped.swipe(uid, sid, 'superlike') # 强制删除优先推荐队列中的 sid rds.lrem(keys.FIRST_RCMD_Q % uid, count=0, value=sid) # 给被滑动者增加滑动积分 rds.zincrby(keys.HOT_RANK, config.SWIPE_SCORE['superlike'], sid) # 检查对方是否喜欢(右滑或上滑)过自己 liked = Swiped.is_liked(sid, uid) if liked is True: # 将互相喜欢的两人添加成好友 Friend.make_friends(uid, sid) return True elif liked is False: return False else: # 对方尚未滑到过自己,把自己推荐给对方 rds.rpush(keys.FIRST_RCMD_Q % sid, uid) return False
def like_someone(uid, sid): """ 喜欢某人函数 1.Swiped表中记录喜欢某人 2.检查Swiped表中对方是否喜欢过我 3.如果喜欢匹配成好友 :param uid: :param sid: :return: True or False or None """ Swiped.swipe(uid, sid, stype='like') # 删除滑动过的推荐 rds.lrem(keys.FIRST_RCMD_K % uid, 1, sid) # 调整用户的积分 score = config.HOT_RANK_SCORE['like'] rds.zincrby(keys.HOT_RANK_K, score, sid) if Swiped.is_liked(sid, uid): Friends.make_friends(uid, sid) return True else: return False
def rewind_last_swiped(uid): '''反悔上一次滑动 (每天允许反悔参数)''' now = datetime.datetime.now() # 检查今天是否已经反悔 3 次 rewind_key = keys.REWIND_TIMES_K + str(f'{now.date()}' + '-' + str(f'{uid}')) rewind_times = rds.get(rewind_key, 0) if rewind_times >= config.REWIND_TIMES: raise errors.RewindLimit # 找到最后一次滑动 last_swipe = Swiped.objects.filter(uid=uid).latest('stime') # 检查最后一次滑动是否在 5 分钟内 time_past = (now - last_swipe.stime).total_seconds() if time_past >= config.REWIND_TIMEOUT: raise errors.RewindTimeout with atomic(): # 将多次数据修改在事务中执行 # 如果之前是好友,删除好友关系 if last_swipe.stype in ['like', 'superlike']: Friend.breakoff(uid1=uid, uid2=last_swipe.sid) # 如果是超级喜欢,删除对方优先队列里面的数据 if last_swipe.stype == 'superlike': rds.lrem(keys.FIRST_RCMD_Q + str(f'{last_swipe}'), 0, uid) # 增加对方的滑动积分 score = config.SWIPE_SCORE[last_swipe.stype] rds.zincrby(keys.HOT_RANK, -score, last_swipe.sid) # 删除最后一次滑动 last_swipe.delete() # 今日反悔次数加一 rds.set(rewind_key, rewind_times + 1, 86460) # 设置缓存过期时间 一天零一分
def set_score(uid, stype): '''给用户设置滑动积分''' # 调整用户积分 score = cfg.SWIPE_SCORE[stype] rds.zincrby(keys.HOT_RANK_KEY, score, uid)