利用redis的bitmap实现用户签到功能

import datetime
import redis


class RedisSignIn():

def __init__(self):
# 连接redis数据库
self.redis_store = redis.Redis(
host="127.0.0.1",
port='6379',
db="1"
)

@staticmethod
def GetDaliySignKey(time=datetime.datetime.now()):
# 拼接redis的key
bitmap_key_daily_sign = "daily_sign_{date}" # daily_sign_2019-09-16
return bitmap_key_daily_sign.format(date=time.date())

def UserDailySign(self, user_id):
# 今日签到并获取本周签到记录
sing_status = self.UserDaliySignByUserId(user_id)
if not sing_status:
return "今日已签到"
# 获取本周签到记录
rec,l = self.GetSignRecordByUserId(user_id, 7)
print(rec)
print(l)
return l,rec

# 获取指定时间段的签到记录
def GetSignRecordByUserId(self, user_id, days=30):
# 开启管道模拟事务
with self.redis_store.pipeline(True) as p:
for i in range(days):
# 获取key对应值的二进制表示中的某位的值
p = p.getbit(self.GetDaliySignKey(datetime.datetime.now() - datetime.timedelta(days=i)), user_id)
# execute返回命令执行结果列表
res = p.execute()
# res是一个[1,0,0,0...]的列表
print('res',res)
# 转成字符串的二进制
print(sum(res))
return ''.join([str(x) for x in res]),sum(res)

# 通过user_id用户做每日签到
def UserDaliySignByUserId(self, user_id):
if self.GetDailySignByUserId(user_id):
print( "今天您已签到")
return False
# 今日签到
key = self.GetDaliySignKey()
# key就是签到日期,将该user_id在key对应的位置上设置为1,表示签到了
self.redis_store.setbit(key, user_id, 1)
# 设置key的过期时间
self.redis_store.expire(key, 60 * 60 * 24 * 30)
return True

# 通过user_id获取用户每日签到信息
def GetDailySignByUserId(self, user_id):
return self.redis_store.getbit(self.GetDaliySignKey(), user_id)


if __name__ == '__main__':
user_id=1003
sign=RedisSignIn()
sign.UserDailySign(user_id)
# sign.GetSignRecordByUserId(user_id)








# 以user_id作为key的优化
import datetime
import redis

import time


class RedisSignIn():

# 连接redis数据库
def __init__(self):
self.redis_store = redis.Redis(
host="127.0.0.1",
port='6379',
db="9"
)

# 获取偏移量和有效时间
@staticmethod
def GetDaliySignTime():
now_week = datetime.date.today().weekday() # 当前周几
sunday = datetime.date.today()
one_day = datetime.timedelta(days=1)
while sunday.weekday() != 6:
sunday += one_day
dateC = datetime.datetime(sunday.year, sunday.month, sunday.day + 1, 0, 0, 0) # 本周结束时间
suntime = int((time.mktime(dateC.timetuple())))
_time = suntime - int(time.time())
return 3, _time

# 今日签到并获取本周签到记录
def UserDailySign(self, user_id):
sing_status = self.UserDaliySignByUserId(user_id)
if not sing_status:
return "今日已签到"
# 获取本周签到记录
rec,l = self.GetSignRecordByUserId(user_id, 7)
print(rec)
print(l)
print("签到成功")
return l,rec

# 获取指定时间段的签到记录
def GetSignRecordByUserId(self, user_id, days=7):
# 开启管道模拟事务
with self.redis_store.pipeline(True) as p:
for i in range(days):
# 获取key对应值的二进制表示中的某位的值
p = p.getbit(user_id,i)
# execute返回命令执行结果列表
res = p.execute()
# res是一个[1,0,0,0...]的列表
# print('res',res)
# # 转成字符串的二进制
# print(sum(res))
return ''.join([str(x) for x in res if x]),sum(res)

# 通过user_id用户做每日签到
def UserDaliySignByUserId(self, user_id):
now_week ,_time = self.GetDaliySignTime()
if self.GetDailySignByUserId(user_id,now_week):
print( "今天您已签到")
return False
# 今日签到
key = user_id
# key就是签到日期,将该user_id在key对应的位置上设置为1,表示签到了
self.redis_store.setbit(user_id, now_week, 1)
# 设置key的过期时间
self.redis_store.expire(key, _time)
return True

# 通过user_id获取用户每日签到信息
def GetDailySignByUserId(self, user_id, now_week):
return self.redis_store.getbit(user_id,now_week)


if __name__ == '__main__':
user_id=1003
sign=RedisSignIn()
sign.UserDailySign(user_id)
sig_str,l=sign.GetSignRecordByUserId(user_id,7)
for i in range(1,8):
sig_str_status = sig_str[i-1:i] or 0
print( sig_str[i-1:i] or 0,end=" ")
print(l)

# 签到奖品列表
# for i in reword_data:
# d = {
# "name": i.name,
# "reword_id": i.id,
# "images": get_sign_images(i.type, i.count),
# "status": sig_str[i-1:i] or 0
# }
# reword_list.append(d)
posted @ 2019-09-16 11:47  wxl106  阅读(1043)  评论(0编辑  收藏  举报