云计算:基于Redis的文章投票系统(Python完整版)
| Redis的安装不懂的可前往 https://www.zeker.top/posts/9d3a5b2a/
网上搜到的代码很多,但大多都有点小毛病(方法不可用,逻辑错误等)
自己基于网上找到的代码进行修改补缺,基本符合投票系统的用户运行,只需改下面即可运行。
redis.ConnectionPool(host="ip地址", port=6379, password='', db=0)
- 改ip为服务器地址,本地就localhost;
- 有密码就填充密码,没有则忽略;
- redis默认有16个数据库,想在哪个数据库存储就设置一下数字(数据库以 0 起始)
直接贴代码
# -*- coding: utf-8 -*-
# @Time : 2022/5/17 14:30
# @Author : Ztop
# @Email : top.zeker@gmail.com
# @Link: https://www.zeker.top
import redis
import time
try:
ONE_WEEK_IN_SECONDS = 604800
VOTE_SCORE = 240.00
pool = redis.ConnectionPool(host="ip地址", port=6379, password='', db=0)
redis = redis.Redis(connection_pool=pool)
except Exception as err:
print(err)
# 发布文章
def post(articleData, redis=redis):
articleId = str(redis.incr('article:')) # 自增文章id
# try:
"""保存文章"""
article = 'article:' + articleId
"""hmset 新版本不维护"""
# redis.hmset(article, articleData) # redis.hmset('xx', {'k1':'v1', 'k2': 'v2'})
for k, v in articleData.items():
redis.hset(article, k, v)
'#将文章与发布时间通过一个有序集合进行关联'
post_time = time.time()
# redis.zadd('time', dict(article=articleData['time'])) # r.zadd('xset1',{'m1':10,'m2':20})
redis.zadd('time', {article: post_time})
print("即将为自己投初始票!", articleData['poster'])
'#为自己投初始票'
vote(article, articleData['poster'], True)
'修改文章评分'
score(article, redis)
return article
# except Exception as err:
# print(err)
# return False
# 为文章投票
def vote(article, user, posting, redis=redis):
global ONE_WEEK_IN_SECONDS
'#投票,和用户绑定'
voted = 'voted:' + article.partition(':')[-1]
articleData = redis.hgetall(article)
if not bool(articleData):
print("%s该id无对应文章!!!%s\n" % (red, end))
return False
postTime = redis.zscore('time', article)
# print(postTime)
# 一周之前的文章不能投票
tempTime = time.time() - ONE_WEEK_IN_SECONDS
if postTime and postTime <= tempTime:
print("%s一周之前的文章不能投票!!!%s\n" % (red, end))
return False
# 一个用户只能投一票,判断用户是否已经投过
if (redis.sismember(voted, user)):
print("%s你已投票过该文章!!!%s\n" % (red, end))
return False
# print(articleData)
if posting:
redis.sadd(voted, articleData[b'poster'])
else:
redis.sadd(voted, user)
score(article)
print("%s已成功为 %s 投票!%s\n" % (green, voted, end))
redis.expire(voted, ONE_WEEK_IN_SECONDS) # 设置超时时间
# 更新章的评分
def score(article, redis=redis):
global VOTE_SCORE
'#将文章与评分通过一个有序集合进行关联'
redis.zincrby('score', VOTE_SCORE, article)
redis.hincrby(article, 'votes', 1)
aScore = redis.zscore('score', article)
print("%s已成功为 %s 加分!当前分为 %s%s\n" % (green, article, int(aScore), end))
# 按特定的方式(发布时间,评分)降序取出文章
def get_articles(order, page=1, limit=25, redis=redis):
start = (page - 1) * limit
end = start + limit - 1
articleIds = redis.zrange(order, start, end, desc=True)
articleList = {};
for id in articleIds:
articleData = redis.hgetall(id)
articleData['id'] = id
articleList[id] = articleData
return articleList
# 设置,移除文章分组
def add_remove_group(article, add=[], remove=[], redis=redis):
if len(add) != 0:
for group in add:
groupKey = 'group:' + group
redis.sadd(groupKey, article)
print("%s已将该文章加入分组(%s)%s" % (green, add, end))
else:
for group in remove:
groupKey = 'group:' + group
redis.srem(groupKey, article)
print("%s已将该文章移除分组(%s)%s" % (green, remove, end))
# 按评分或时间排名取出分组下的文章
def get_group_articles(group, order, page=25, limit=25, redis=redis):
key = order + group
if (not redis.exists(key)):
redis.zinterstore(key, ['group:' + group, order], aggregate='max')
redis.expire(key, 5)
return get_articles(key, page, limit)
# 删除文章
def deleteArticle(article, redis=redis):
id = article.partition(':')[-1]
# 文章是hash
if redis.exists(article):
redis.delete(article)
else:
print("%s对应文章不存在%s" % (red, end))
# 删除对应投票, voted 是 set 类型
voted = "voted:" + id
if redis.exists(voted):
redis.delete(voted)
else:
print("%s对应投票不存在%s" % (red, end))
# 删除对应时间,time 是 zset 类型
redis.zrem("time", article)
# 删除对应文章分数, zset
redis.zrem("score", article)
if redis.dbsize() == 1:
redis.flushdb()
print("%s已删除文章%s%s\n" % (green, article, end))
if __name__ == '__main__':
global red, green, end
red = '\033[1m\033[31m'
green = '\033[1m\033[32m'
end = "\033[0m"
statement = "原文地址: https://www.cnblogs.com/xiangdongsheng/p/13455921.html"
menu = """\033[1m\033[35m------------ redis简易文章投票系统(完善版 by Ztop)---------------
1. 发布文章 6. 查看指定文章分数
2. 查看指定文章 7. 文章添加、移除从指定分组
3. 以发布时间,评分获取文章 8. 按评分或时间排名取出分组下的文章
4. 为文章投票 9. 删除指定文章
5. 为指定文章加分 10.删库
0. 退出
--------------------------------------------------------------------\033[0m"""
print(statement)
while True:
print(menu)
choice = int(input(">>"))
if choice == 1:
poster = input("发布人id(例001):")
title = input("标题:")
content = input("内容:")
articleData = dict(poster="user:" + poster, title=title, content=content)
print(articleData, type(articleData))
# articleData 是字典
article = post(articleData)
if article:
print('%s文章发布成功!%s\n' % (green, end))
else:
print('%s文章发布失败%s\n' % (red, end))
# articleId = article.partition(':')[-1]
# add_remove_group(article, add=['redis'])
elif choice == 2:
articleId = input("文章id(例1):")
article = "article:" + articleId
articleData = redis.hgetall(article)
if not bool(articleData):
print("%s该id无对应文章%s\n" % (red, end))
else:
print(articleData, "\n")
elif choice == 3: # 以发布时间,评分获取文章
print("发布时间1 | 评分2")
choice = int(input('>>'))
if choice == 1:
print(get_articles(order='time'))
elif choice == 2:
print(get_articles(order='score'))
elif choice == 4: # 为文章投票
article = "article:" + input("文章id(例87):")
userid = "user:" + input("你的id(例: 001):")
vote(article, userid, False)
elif choice == 5: # 更新文章评分
article = "article:" + input("文章id(例87):")
score(article)
elif choice == 6: # 查看指定文章分数
article = "article:" + input("文章id(例87):")
aScore = redis.zscore('score', article)
if score:
print("%s文章 %s 的当前分数为 %s \n%s" % (green, article, int(aScore), end))
else:
print("%s无该文章信息,请检查是否正确!\n%s" % (red, end))
elif choice == 7: # 文章添加、移除从指定分组
print("添加1 | 移除2")
choice = int(input('>>'))
if subChoice == 1:
article = "article:" + input("文章id(例87):")
group = input("分组名:")
add_remove_group(article, add=[group])
elif subChoice == 2:
article = "article:" + input("文章id(例87):")
group = input("分组名:")
add_remove_group(article, remove=[group])
elif choice == 8: # 按评分或时间排名取出分组下的文章
print("发布时间1 | 评分2")
subChoice = int(input('>>'))
group = input("分组名:")
if subChoice == 1:
get_group_articles(group=group, order='time')
elif subChoice == 2:
get_group_articles(group=group, order='score')
elif choice == 9:
article = "article:" + input("文章id(例87):")
deleteArticle(article)
elif choice == 10:
print("%s是否进行删库跑路? 是y/否n%s"% (red, end), end=" ")
subChoice = input().lower()
if subChoice == 'y':
redis.flushall()
print("%s删库成功,祝君平安%s\n" % (green, end))
else:
print("%s已取消删库%s\n" % (green, end))
continue
else:
exit()