云计算:基于Redis的文章投票系统(Python完整版)

| Redis的安装不懂的可前往 https://www.zeker.top/posts/9d3a5b2a/

网上搜到的代码很多,但大多都有点小毛病(方法不可用,逻辑错误等)

自己基于网上找到的代码进行修改补缺,基本符合投票系统的用户运行,只需改下面即可运行。

redis.ConnectionPool(host="ip地址", port=6379, password='', db=0)
  1. 改ip为服务器地址,本地就localhost;
  2. 有密码就填充密码,没有则忽略;
  3. 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()
posted @ 2022-05-30 23:43  ztop  阅读(91)  评论(0编辑  收藏  举报