python小项目我的博客

我的博客小项目

又花了一阵时间重新组织了一下我的博客这个小项目,将原来的单文件编程扩展到了多文件编程,将逻辑层、显示层、数据层、进行了分离,同时加入了日志功能,数据写入文件。待完善(文章写入文件,后续会改造项目使用面对对象封装数据,将用户和文章分别封装,然后使用网络构造服务器,数据存入mysql数据库)。

本系统主要包括了用户模块和文章模块,用户模块包含了用户注册、用户登陆、维护个人信息、修改密码等几个小模块,文章模块包含了两个小模块,查看所有用户的文章,维护自己的文章。

系统涉及知识点:字典、元组、列表、字符串的使用,用字典封装跳转菜单,数据、视图与逻辑的分离,面向过程编程。

部分调试截图

用户登陆选择界面

用户登陆选择界面

博客主页

博客主页

我的文章管理

维护个人资料

查看个人信息

修改个人信息

 

系统源码:

blog模块

"""我的博客
author:
version:v1.0.0
"""
import menu
import service


def engin():
    """程序引擎"""
    # 展示登陆界面
    menu.show_login()


# 处理流程
def main():
    """程序入口"""
    service.record("程序启动\n")
    engin()


# 主程序入口
if __name__ == "__main__":
    main()

 

data模块

"""数据存储"""
import os
import json


# 获取用户列表
def get_users():
    """连接数据库,获取用户列表"""

    # 若文件存在打开文件
    if os.path.isfile("files/users.json"):
        with open("files/users.json", "r", encoding="utf-8") as f:
            users = json.loads(f.read())
            return users
    else:
        return False


# 更新用户列表
def update_users():
    # 将用户列表写入文件
    if os.path.isfile("files/users.json"):
        with open("files/users.json", "w", encoding="utf-8") as f:
            f.write(json.dumps(users, ensure_ascii=False))
            return True
    else:
        return False


# 更新在线用户列表
def update_online_users():
    # 将用户列表写入文件

    if os.path.isfile("files/online_users.json"):
        with open("files/online_users.json", "w", encoding="utf-8") as f:
            f.write(json.dumps(online_users, ensure_ascii=False))
            return True
    else:
        return False


# 所有用户字典
users = get_users()
# 所有在线用户字典
online_users = get_users()
# 所有的文章字典
all_articles = dict()



def main():
    """程序入口"""
    users = get_users()
    # 测试将用户账号为1的密码改为"2"
    # users.get("1")["password"] = "2"
    update_users(users)


if __name__ == '__main__':
    main()

 

menu模块

"""
菜单界面跳转
author:
version:v1.0.0
"""
import os
import sys
import time
import service


# 用户登陆选择界面
def show_login():
    """用户登陆选择界面"""
    os.system("cls")
    print("","*"*45, "\n\t\t我的博客登陆界面\n", "*"*45)
    print("\t\t1. 用户登陆\n\t\t2. 用户注册\n\t\t3. 退出系统\n", "*"*45)

    # 程序进入用户登陆界面
    service.record("用户进入登陆选择界面")

    # 用户选择跳转
    choice = input("请输入您的选择:")
    service.record("用户输入选择%s" % choice)

    return login_menu_dict.get(choice)() if choice in login_menu_dict else show_login()


# 用户登陆界面
def login():
    """用户登陆界面"""
    os.system("cls")
    print("","\n\t\t欢迎您的登陆\n", "*"*45)
    service.record("用户进入用户登陆界面")
    # 验证成功,展示主页
    if service.login():
        service.record("验证成功进入主页")
        show_index()
    # 验证失败,返回登陆界面
    else:
        service.record("验证失败")
        show_login()


# 用户注册界面
def register():
    """用户注册界面"""
    os.system("cls")
    print("","\n\t\t欢迎您前来注册\n", "*"*45)
    service.record("用户进入注册界面")
    # 调用注册
    service.register()
    # 展示登陆界面
    show_login()


# 我的博客主页
def show_index():
    """我的博客主页"""
    os.system("cls")
    print("","*"*45, "\n\t\t我的博客主页\n","*"*45)
    print("\t\t1. 查看所有文章\n\t\t2. 我的文章管理\n\t\t3. 维护个人资料")
    print("\t\t4. 返回上一级\n\t\t5. 退出系统\n", "*"*45)
    service.record("用户进入我的主页界面")
    # 用户选择跳转
    choice = input("请输入您的选择:")
    service.record("用户输入%s" % choice)
    # 执行跳转菜单
    return index_menu_dict.get(choice)() if choice in index_menu_dict else show_index()


# 查看所有文章
def look_all_articles():
    """查看所有文章"""
    service.record("用户进入查看所有文章界面")
    os.system("cls")
    print("", "\n\t\t查看所有文章\n", "*" * 45)

    # 显示所有未删除的文章
    print("编号\t标题\t\t作者\t浏览次数\t\t发布时间")
    for article in service.my_articles:
        # 若文章为删除
        if not article.get("is_del"):
            # 构建显示文章
            show_article = (article.get("no"), article.get("title"), article.get("author").get("username"),
                            article.get("read_count"), article.get("time"))
            print("%s\t%s\t\t%s\t%s\t\t%s" % show_article)

    # 用户输入选择
    print("\n1.查看文章 2.返回上一级 3.退出系统")
    choice = input("请输入您的选择:")
    service.record("用户输入选择%s" % choice)

    # 跳转菜单
    return look_all_articles_menu_dict.get(choice)() if choice in look_all_articles_menu_dict else look_all_articles()


# 我的文章管理
def show_manager_my_articles():
    """我的文章管理"""
    os.system("cls")
    print("", "*"*45, "\n\t\t管理我的文章\n", "*"*45)
    print("\t\t1. 查看我的所有文章\n\t\t2. 发表文章\n\t\t3. 回收站\n\t\t4. 返回上一级\n\t\t5. 退出系统\n", "*"*45)
    service.record("用户进入我的文章管理界面")
    # 用户选择跳转
    choice = input("请输入您的选择:")
    service.record("用户输入选择%s" % choice)
    # 跳转菜单
    return manager_my_articles_menu_dict.get(choice)() if choice in manager_my_articles_menu_dict else show_manager_my_articles()


# 查看我的所有文章
def look_my_articles():
    """查看我的所有文章"""
    service.record("用户进入查看我的所有文章界面")
    os.system("cls")
    print("", "\n\t\t查看我的所有文章\n", "*" * 45)

    # 显示我的文章
    print("编号\t标题\t\t作者\t浏览次数\t\t发布时间")
    for article in service.my_articles:
        # 若为自己的文章
        if article.get("author") == service.user and not article.get("is_del"):
            # 构建显示文章
            show_article = (article.get("no"), article.get("title"), article.get("author").get("username"),
                            article.get("read_count"), article.get("time"))
            print("%s\t%s\t\t%s\t%s\t\t%s" % show_article)

    # 用户输入选择
    print("\n1.查看文章 2.删除文章 3.返回上一级 4.退出系统")
    choice = input("请输入您的选择:")
    service.record("用户输入%s" % choice)

    # 跳转菜单
    return look_my_articles_menu_dict.get(choice)() if choice in look_my_articles_menu_dict else look_my_articles()


# 发表文章
def publish_article():
    """发表文章"""
    service.record("用户进入发表文章界面")
    os.system("cls")
    print("", "\n\t\t发表文章\n", "*" * 45)
    service.publish_article()


# 查看我的一篇文章
def look_article():
    """查看我的一篇文章"""
    service.record("用户查看我的文章界面")
    os.system("cls")
    print("", "*"*40,"\n文章内容\n","*"*40)
    service.look_article()


# 删除文章
def del_article():
    """删除我的文章"""
    service.record("用户删除文章界面")
    os.system("cls")
    print("", "\n\t\t删除我的文章\n", "*" * 45)
    service.del_article()


# 回收站
def recycle():
    """回收站"""
    service.record("用户进入回收站界面")
    os.system("cls")
    print("", "\n\t\t回收站\n", "*" * 45)

    # 显示我的文章
    print("编号\t标题\t\t作者\t\t浏览次数\t发布时间")
    for article in service.my_articles:
        # 若为自己的文章
        if article.get("is_del"):
            # 构建显示文章
            show_article = (article.get("no"), article.get("title"), article.get("content"),
                            article.get("read_count"), article.get("time"))
            print("%s\t%s\t\t%s\t%s\t%s" % show_article)

    choice = input("\n输入文章编号恢复文章,其他任意键返回")
    service.record("用户输入恢复文章的编号%s" % choice)
    for article in service.my_articles:

        if choice == str(article.get("no")) and article.get("is_del"):
            article["is_del"] = False
            service.record("恢复文章%s成功"% choice)
            input("恢复成功,按任意键继续!")
            return recycle()
    else:
        service.record("返回")
        input("文章不存在,按任意键继续!")
        return show_manager_my_articles()


# 维护个人信息
def show_manager_my_info():
    """维护个人信息"""
    service.record("用户进入维护个人信息界面")
    os.system("cls")
    print("","*"*45, "\n\t\t维护个人信息\n", "*"*45)
    print("\t\t1. 查看个人信息\n\t\t2. 修改个人信息\n\t\t3. 修改密码")
    print("\t\t4. 返回上一级\n\t\t5. 退出系统\n", "*"*45)

    # 用户选择跳转
    choice = input("请输入您的选择:")
    service.record("用户输入选择%s菜单跳转" % choice)

    # 跳转菜单
    return manager_my_info_menu_dict.get(choice)() if choice in manager_my_info_menu_dict else show_manager_my_info()


# 查看个人信息
def look_my_info():
    """查看个人信息"""
    service.record("用户进入查看个人信息界面")
    os.system("cls")
    print("", "\n\t\t查看我的信息界面\n", "*" * 45)
    show_info = (service.user.get("account"),service.user.get("username"), service.user.get("email"),
                 service.user.get("sex"), service.user.get("age"), service.user.get("phone"),
                 service.user.get("address"))
    print("\t\t账号:%s\n\t\t昵称:%s\n\t\t邮箱:%s\n\t\t性别:%s\n\t\t年龄:%s\n\t\t手机号码:%s\n\t\t地址:%s" % show_info)
    choice = input("\n按R键返回,其他任意键修改个人信息")
    service.record("用户输入%s" % choice)
    if choice.upper() =='R':
        service.record("返回上一级")
        return show_manager_my_info()
    else:
        service.record("修改个人信息")
        return update_my_info()


# 修改个人信息
def update_my_info():
    """修改个人信息"""
    service.record("用户进入修改个人信息界面")
    os.system("cls")
    print("", "\n\t\t修改个人信息界面\n", "*" * 45)
    print("\t1.修改昵称\n\t2.修改性别\n\t3.修改年龄\n\t4.修改手机号码\n\t5.修改地址\n\t6.返回上一级\n\t7.退出系统")

    choice = input("\n请输入您的选择:")
    service.record("用户输入%s跳转菜单" % choice)

    if choice in ["1", "2", "3", "4", "5"]:
        return service.update_my_info(choice)
    else:
        return update_my_info_menu_dict.get(choice)() if choice in update_my_info_menu_dict else update_my_info()


# 修改密码
def update_password():
    """修改密码"""
    service.record("用户进入修改密码界面")
    os.system("cls")
    print("", "\n\t\t修改密码界面\n", "*" * 45)
    return service.update_password()


def exit_system():
    """退出系统"""
    service.record("用户正常退出系统")
    for i in range(0,3):
        print("系统将在{}秒后退出".format(3-i))
        time.sleep(1)

    sys.exit(1)


# 用户登陆界面菜单,1登陆博客2.注册账号3.退出系统
login_menu_dict = {"1": login, "2": register, "3": exit_system}

# 主页菜单,1查看所有文章2.管理我的文章3.维护个人信息4.返回上一级5退出系统
index_menu_dict = {"1": look_all_articles, "2": show_manager_my_articles, "3": show_manager_my_info,
                   "4": show_login, "5": exit_system}

# 查看所有文章菜单,1.查看文章 2.返回上一级 3.退出系统
look_all_articles_menu_dict = {"1": look_article, "2": show_index, "3": exit_system}

# 管理我的文章菜单,1.查看我的所有文章,2.发表文章3.删除文章4。回收站5.返回上一级6.退出系统
manager_my_articles_menu_dict = {"1": look_my_articles, "2": publish_article, "3": recycle,
                                 "4": show_index, "5": exit_system}

# 维护个人信息菜单,1查看个人信息2.修改个人信息3.修改密码4.返回上一级5.退出系统
manager_my_info_menu_dict = {"1": look_my_info, "2": update_my_info, "3": update_password,
                             "4": show_index, "5": exit_system}

# 查看我的所有文章菜单,1查看文章 2.删除文章 3.返回上一级 4.退出系统
look_my_articles_menu_dict = {"1": look_article, "2": del_article, "3": show_manager_my_articles, "4": exit_system}

# 修改个人信息菜单
update_my_info_menu_dict = {"6": show_manager_my_info, "7": exit_system}



# 处理流程
def main():
    """程序入口"""
    show_login()
    # look_my_articles()


# 主程序入口
if __name__ == "__main__":
    main()

service模块

"""业务逻辑的处理"""
import data
import random
import menu
import datetime


# 用户登陆
def login():
    """用户登陆验证"""
    # 连接数据库获取用户列表
    users = data.get_users()
    in_account = input("请输入您的账号或邮箱:")
    record("用户输入账号或邮箱%s" % in_account)
    in_password = input("请输入您的密码:")
    record("用户输入密码%s" % in_password)

    # 遍历用户列表,获取用户字典
    for sql_user in users.values():
        # 用户输入的账号或email正在且密码正在,验证成功
        if (in_account == sql_user.get("account") or in_account == sql_user.get("email")) \
                and (in_password == sql_user.get("password")):

            # 如果在线用户不为空,将当前用户加入字典中
            if data.online_users:
                data.online_users[in_account] = data.users.get(in_account)
            # 在线用户为空,将在线用户指向当前用户(因为在线用户为空则不是字典,为布尔值)
            else:
                data.online_users = data.users.get(in_account)
            record("用户登陆成功")
            # 添加当前在线用户,将当前在线用户添加到在线用户列表
            global user
            user = data.users.get(in_account)
            data.update_online_users()
            return True
    else:
        record("用户登陆失败,账号或密码错误")
        return False


# 用户注册
def register():
    """用户注册函数"""
    # 获取数据库用户字典
    record("用户注册账号")
    users = data.users
    # 用户输入昵称密码
    username = input("请输入您的昵称(按R返回上一级):")
    record("用户输入用户昵称%s(R放弃注册)" % username)
    # 用户放弃注册,返回上一级
    if username.upper() == "R":
        record("用户放弃注册")
        return menu.show_login()

    # 用户输入密码
    in_password = input("请输入您的密码:")
    record("用户输入密码%s" % in_password)
    in_confirm = input("请确认您的密码:")
    record("用户输入确认密码%s" % in_confirm)

    # 判断用户密码是否包含特殊字符
    if not in_password.isalnum():
        input("密码只能是字母和数字,按任意键继续!")
        return register()

    # 用户密码长度只能是6~20位
    if not (6 <= len(in_password) <= 20):
        input("密码长度必须为6~20位,按任意键继续!")
        return register()

    # 前后密码一致
    if in_password == in_confirm:
        # 随机生成9位数账号
        account = ""
        count = 9
        while True:
            while count:
                account += str(random.randint(0,9))
                count -= 1
            # 若账号存在重新生成,不存在退出循环
            if account in users:
                continue
            else:
                break

        # 将用户添加到数据库
        user = {"account": account, "password": in_password, "username": username, "email": account+"@bk.com"}
        data.users[account] = user
        data.update_users()
        record("注册成功,获得账号:%s邮箱:%s" % (account,account+"@bk.com"))
        print("恭喜您注册成功,您的账号为:%s邮箱为:%s\n请牢记您的账号!" % (account, account+"@bk.com"))
        input("按任意键继续")

    # 前后密码不一致
    else:
        record("注册失败" )
        input("前后密码输入不一致,按任意键继续!")
        return register()


# 发表文章
def publish_article():
    """发表文章"""
    record("用户发表文章")
    title = input("请输入文章的标题:")
    record("用户输入标题%s" % title)
    content = input("请输入文章的内容:")
    record("用户输入文章内容%s" % content)
    article = {"no": len(my_articles) + 1, "title": title, "content": content, "author": user,
               "time": get_current_time(), "read_count": 0, "is_del": False}
    # 将当前文章添加到我的所有文章列表中
    my_articles.append(article)
    data.all_articles[user.get("account")] = my_articles
    input("发布成功,按任意键继续!")
    return menu.show_manager_my_articles()


# 查看一篇文章
def look_article():
    """查看我的一篇文章"""
    no = input("请输入要查看的文章编号:")
    record("用户输入文章编号%s" % no)
    for article in my_articles:
        if no == str(article.get("no")) and not article.get("is_del"):
            print(article.get("content"))
            article["read_count"] += 1
            break
    else:
        record("文章不存在")
        input("文章不存在,按任意键返回!")
        return menu.show_index()
    record("查看成功")
    # 查看成功
    input("按任意键返回")
    return menu.show_index()


# 删除文章
def del_article():
    """删除文章"""
    no = input("输入要删除文章的编号(按R返回):")
    record("用户输入要删除的文章编号%s或返回上一级" % no)
    # 按R返回
    if no.upper() == "R":
        record("返回上一级")
        return menu.look_my_articles()

    for article in my_articles:
        if no == str(article.get("no")) and not article.get("is_del"):
            article["is_del"] = True
            break

    else:
        record("文章不存在,删除失败")
        input("文章不存在,按任意键返回!")
        return menu.look_my_articles()

    record("成功删除文章编号为%s" % no)
    # 成功删除
    input("文章以删除,按任意键返回")
    return menu.look_my_articles()


# 完善个人信息
def update_my_info(choice):
    """完善个人信息"""
    # 用户输入修改的信息为
    new_info = input("\n请输入您的新信息:")
    record("用户输入新信息%s" % new_info)
    info_list = ["username", "sex", "age", "phone", "address"]
    user[info_list[int(choice)-1]] = new_info
    data.users[user.get("account")] = user
    data.update_users()
    record("修改信息成功")
    input("修改成功,按任意键继续!")
    return menu.look_my_info()


# 修改密码
def update_password():
    """修改密码"""
    old_password = input("请输入您的原密码(按R放弃修改):")
    record("用户输入原密码%s(R返回上一级)" % old_password)
    if old_password.upper() == "R":
        record("返回上一级")
        return menu.show_manager_my_info()

    # 密码验证成功
    if old_password == user.get("password"):
        new_password = input("请输入您的新密码:")
        record("原密码正确,用户输入新密码%s" % new_password)
        confirm_password = input("请确认您的新密码:")
        record("用户输入确认新密码为%s" % confirm_password)
        # 新密码与原密码相同
        if old_password == new_password:
            record("前后密码不一致")
            input("新密码不能与原密码相同,按任意键继续!")
            return menu.update_password()

        # 判断用户密码是否包含特殊字符
        if not new_password.isalnum():
            record("密码中包含特殊字符")
            input("密码只能是字母和数字,按任意键继续!")
            return menu.update_password()

        # 用户密码长度只能是6~20位
        if not (6 <= len(new_password) <= 20):
            record("密码长度不在6~20位之间")
            input("密码长度必须为6~20位,按任意键继续!")
            return menu.update_password()

        # 前后密码不一致
        if not new_password == confirm_password:
            record("前后密码不一致")
            input("前后密码不一致,按任意键继续!")
            return menu.update_password()

        # 修改成功
        else:
            record("修改成功,新密码为%s" % new_password)
            user["password"] = new_password
            # 更新用户字典,并将其写入数据库
            data.users[user.get("account")] = user
            data.update_users()
            input("修改密码成功,请牢记您的密码!按任意键返回")
            return menu.show_manager_my_info()

    # 验证失败
    else:
        record("修改失败")
        input("密码不正确,按任意键继续")
        return menu.update_password()


# 日志函数
def record(msg):
    """记录日志函数"""
    with open("files/blog.log", "a", encoding="utf-8") as f:
        f.write(get_current_time()+":"+msg+"\n")


# 定义当前时间函数
def get_current_time():
    """获取当前时间"""
    t = datetime.datetime.now()
    return "%s年%s月%s日 %s:%s:%s" % (t.year, t.month, t.day, t.hour, t.minute, t.second)


# 当前在线的用户
user = dict()
# 当前用户文章列表
my_articles = list()


# 主程序入口
def main():
    """程序入口"""
    login()
    # publish_article()




if __name__ == '__main__':
    main()

 

数据文件(文件在files目录下)

有序不知道怎么导入文件,用文字说明数据存储,文件的目录结构为:
----blog---项目目录
----------blog.py----
----------data.py----
----------menu.py----
----------service.py----
----------__init__.py---
----------files-----数据文件夹
---------------------online_user.json----在线用户json数据
---------------------users.json----所有用户json数据
---------------------blog.log-----系统日志文件

用户数据结构如下{"1": {"account": "1", "password": "1", "username": "lisa", "email": "1@bk.com"}}

 

结语:由于初学python,本项目为练习项目有很多待完善的地方,在后续的学习中会继续完善本项目。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值