小说阅读器

启动模块bin/start.py
1 import os
2 import sys
3
4 BASE_PATH=os.path.dirname(os.path.dirname(__file__))
5 sys.path.append(BASE_PATH)
6
7
8 from core import src
9
10 if __name__== \'__main__\':
11 src.run()
核心代码模块core/src.py
1 from db import db_handler as db
2 from lib import common
3
4
5 login_user = None
6
7
8
9
10 def register():
11 \'\'\'
12 注册功能
13 :return:
14 \'\'\'
15 while True:
16 inp_name = input(\'输入用户名\').strip()
17 name, psd, remind = db.getinfo(inp_name)
18 if inp_name in name:
19 print(\'用户已存在\')
20 password = input(\'输入密码\')
21 re_psd = input(\'再次输入密码\')
22 if password == re_psd:
23 db.save_reg(inp_name, password)
24 print(\'注册成功\')
25 break
26 else:
27 print(\'两次密码不一致,请重新输入\')
28
29
30
31 def login():
32 \'\'\'
33 登录功能
34 :return:
35 \'\'\'
36 while True:
37 inp_name = input(\'输入用户名\')
38 name, psd, remind = db.getinfo(inp_name)
39 if inp_name not in name:
40 print(\'用户名不存在,请先注册\')
41 continue
42 password = input(\'输入密码\').strip()
43 if password == psd:
44 global login_user
45 login_user = inp_name
46 print(\'登录成功,亲爱的{}用户\'.format(login_user))
47 break
48 else:
49 print(\'账号密码错误\')
50
51
52
53 @common.log
54 @common.auth
55 def add_credit():
56 \'\'\'
57 充值功能
58 :return:
59 \'\'\'
60 print(\'欢迎使用充值功能,亲爱的{}用户\'.format(login_user))
61 while True:
62 amount = input(\'输入充值金额\')
63 if not amount.isdigit():
64 print(\'请输入数字\')
65 continue
66 comf = input(\'确定要充值{}元吗,按Y/y确认,按R/r\'.format(amount))
67 if comf == \'R\' or comf == \'r\':
68 continue
69 if comf == \'Y\' or comf == \'y\':
70 name, psd, remind = db.getinfo(login_user)
71 remind=int(remind)
72 old_data = \'{}:{}:{}\'.format(name, psd, remind)
73 remind += int(amount)
74 new_data = \'{}:{}:{}\'.format(name, psd, remind)
75 db.update(old_data, new_data)
76 print(\'已成功充值{}\'.format(amount))
77 break
78 return amount
79
80
81 @common.log
82 @common.auth
83 def reader():
84 \'\'\'
85 小说功能
86 :return:
87 \'\'\'
88 book_dic=db.get_book()
89 if not book_dic:
90 print(\'库存没有小说了\')
91 return
92 while True:
93 print(\'\'\'
94 === 欢迎来到阅读小说功能主页 ===
95 0 玄幻武侠
96 1 都市爱情
97 2 高效养猪36技
98 ============ end ============
99 \'\'\')
100 cmd=input(\'输入你想阅读的小说种类编号\').strip()
101 if cmd not in book_dic:
102 print(\'请正确输入编号\')
103 second_dic =book_dic[cmd]
104 for num,booklist in second_dic.item():
105 name,price=booklist
106 print(\'小说编号[{}],小说名《{}》,小说价格[{}]\'.format(num,name,price))
107 while True:
108 cmd = input(\'输入你想购买的小说编号\')
109 if cmd not in second_dic:
110 print(\'请正确输入编号\')
111 continue
112 if cmd in second_dic:
113 name=second_dic[cmd][0]
114 price=second_dic[cmd][1]
115 cmd = input(\'当前选择的小说名为: 《{name}》,商品单价为: [{price}], 请输入Y/y购买:\'.format(name,price)).strip()
116 if cmd == \'Y\' or cmd==\'y\':
117 name,psd,remind = db.getinfo(login_user)
118 remind=int(remind)
119 if remind<int(price):
120 price(\'余额不足,请先充值\')
121 break
122 old_data = \'{}:{}:{}\'.format(name, psd, remind)
123 remind -= int(price)
124 new_data = \'{}:{}:{}\'.format(name, psd, remind)
125 db.update(old_data, new_data)
126 print(\'购买成功,请欣赏内容\')
127 fictiondata=db.show(name)
128 print(\'\'\'
129 -------开始阅读--------
130 {}
131 \'\'\'.format(fictiondata))
132
133
134
135 def logout():
136 \'\'\'
137 登出功能
138 :return:
139 \'\'\'
140 global login_user
141 login_user=None
142
143
144 #运行菜单
145 func_dic={
146 \'0\':[\'注册\',register],
147 \'1\':[\'登录\',login],
148 \'2\':[\'充值\',add_credit],
149 \'3\':[\'小说\',reader],
150 \'4\':[\'登出\',logout],
151 }
152
153 def run():
154 while True:
155 print(\'\'\'
156 ~~~~~~~欢迎来到小说世界~~~~~~~
157 0 账号注册
158 1 账号登录
159 2 充值功能
160 3 阅读小说
161 4 登出
162 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
163 \'\'\')
164 cmd= input(\'请输入功能编号,按4退出\').strip()
165 if cmd ==\'4\':
166 logout()
167 break
168 if cmd not in func_dic:
169 print(\'请正确输入功能编号\')
170 continue
171 func_dic[cmd][1]()
172
173 run()
数据库操作模块db/db_handler.py
1 from conf import settings
2 import os
3
4
5 def getinfo(username):
6 \'\'\'
7 取出文件中用户的数据
8 :param username:
9 :return:
10 \'\'\'
11 with open(settings.DB_TXT_PATH, \'rt\', encoding=\'utf-8\')as f:
12 for line in f:
13 if username in line:
14 name, psd, remind = line.strip().split(\':\')
15 return name, psd, remind
16
17
18 def save_reg(name, psd, balance=0):
19 \'\'\'
20 存注册用户的数据
21 :param name:
22 :param psd:
23 :param balance:
24 :return:
25 \'\'\'
26 with open(settings.DB_TXT_PATH, \'at\', encoding=\'utf-8\')as f:
27 f.write(\'{}:{}:{}\'.format(name, psd, balance))
28
29
30
31 def update(old_data, new_data):
32 \'\'\'
33 更新用户数据
34 :param old_data:
35 :param new_data:
36 :return:
37 \'\'\'
38 with open(settings.DB_TXT_PATH, \'rt\', encoding=\'utf-8\')as rf:
39 alldata = rf.read()
40 alldata = alldata.replace(old_data, new_data)
41 with open(\'db.txt.swap\', \'wt\', encoding=\'utf-8\')as wf:
42 wf.write(alldata)
43 os.rename(\'db.txt.swap\', settings.DB_TXT_PATH)
44
45
46 def get_book():
47 \'\'\'
48 获取小说数据
49 :return:
50 \'\'\'
51 with open(settings.STORY_PATH,\'rt\',encoding=\'utf-8\')as f:
52 book_dic=eval(f.read())
53 return book_dic
54
55
56 def show(bookname):
57 \'\'\'
58 查看小说
59 :param bookname:
60 :return:
61 \'\'\'
62 book_path = os.path.join(settings.BOOK_DIR, bookname)
63 with open(book_path,\'rt\',encoding=\'utf-8\')as f:
64 data=f.read()
65 return data
公共模块(装饰器)lib/common.py
1 from conf import settings
2 import time
3 from core.src import login_user
4 from core.src import login
5
6 def auth(func):
7 \'\'\'
8 认证装饰器
9 :param func:
10 :return:
11 \'\'\'
12 def wrapper(*args, **kwargs):
13 if login_user:
14 res = func(*args, **kwargs)
15 return res
16 else:
17 print(\'请先登录再使用功能\')
18 login()
19
20 return wrapper
21
22
23
24 def log(func):
25 \'\'\'
26 记录日志装饰器
27 :param func:
28 :return:
29 \'\'\'
30 def wrapper(*args, **kwargs):
31 res = func(*args, **kwargs)
32 now_time = time.strftime(\'%Y-%m-%d %X\')
33 log_data = \'{} {} {} {}\'.format(now_time, login_user, func.__name__, res)
34 with open(\'time.log\', \'ab\')as logf:
35 logf.write(log_data.encode(\'utf-8\'))
36
37 return res
38
39 return wrapper
配置模块conf/settings.py
import os
# 获取项目根目录reader_sys根目录
BASE_PATH = os.path.dirname(os.path.dirname(__file__))
# 获取db目录路径
DB_PATH = os.path.join(BASE_PATH, \'db\')
# 获取db.txt的根目录
DB_TXT_PATH = os.path.join(DB_PATH, \'db.txt\')
# story_class.txt文件目录路径
STORY_PATH = os.path.join(DB_PATH, \'story_class.txt\')
# 小说存放目录
BOOK_DIR = os.path.join(DB_PATH, \'book\')
# 日志文件的路径
LOG_PATH = os.path.join(BASE_PATH, \'log\', \'user.log\')
面条形式的一个文件下的小说阅读程序实现
1.更新了小说阅读模块
2.重写了用户存取数据的方式:将字典模式改为函数功能,方便之后规范化放入数据库操作模块中
3.独立了登录模块,将认证功能装饰器简化
import os
import time
login_user = None
# common模块
# 认证装饰器
def auth(func):
def wrapper(*args, **kwargs):
if login_user:
res = func(*args, **kwargs)
return res
else:
print(\'请先登录再使用功能\')
login()
return wrapper
# 记录日志装饰器
def log(func):
def wrapper(*args, **kwargs):
res = func(*args, **kwargs)
now_time = time.strftime(\'%Y-%m-%d %X\')
log_data = \'{} {} {} {}\'.format(now_time, login_user, func.__name__, res)
with open(\'time.log\', \'ab\')as logf:
logf.write(log_data.encode(\'utf-8\'))
return res
return wrapper
# 数据库模块
# 取数据
def getinfo(username):
with open(\'db.txt\', \'rt\', encoding=\'utf-8\')as f:
for line in f:
if username in line:
name, psd, remind = line.strip().split(\':\')
return name, psd, remind
# 存注册数据
def save_reg(name, psd, balance=0):
with open(\'db.txt\', \'at\', encoding=\'utf-8\')as f:
f.write(\'{}:{}:{}\'.format(name, psd, balance))
# 更新数据
def update(old_data, new_data):
with open(\'db.txt\', \'rt\', encoding=\'utf-8\')as rf:
alldata = rf.read()
alldata = alldata.replace(old_data, new_data)
with open(\'db.txt.swap\', \'wt\', encoding=\'utf-8\')as wf:
wf.write(alldata)
os.rename(\'db.txt.swap\', \'db.txt\')
# 注册功能
def register():
while True:
inp_name = input(\'输入用户名\').strip()
name, psd, remind = getinfo(inp_name)
if inp_name in name:
print(\'用户已存在\')
password = input(\'输入密码\')
re_psd = input(\'再次输入密码\')
if password == re_psd:
save_reg(inp_name, password)
print(\'注册成功\')
break
else:
print(\'两次密码不一致,请重新输入\')
# 登录功能
def login():
while True:
inp_name = input(\'输入用户名\')
name, psd, remind = getinfo(inp_name)
if inp_name not in name:
print(\'用户名不存在,请先注册\')
continue
password = input(\'输入密码\').strip()
if password == psd:
global login_user
login_user = inp_name
print(\'登录成功,亲爱的{}用户\'.format(login_user))
break
else:
print(\'账号密码错误\')
# 充值功能
@log
@auth
def add_credit():
print(\'欢迎使用充值功能,亲爱的{}用户\'.format(login_user))
while True:
amount = input(\'输入充值金额\')
if not amount.isdigit():
print(\'请输入数字\')
continue
comf = input(\'确定要充值{}元吗,按Y/y确认,按R/r\'.format(amount))
if comf == \'R\' or comf == \'r\':
continue
if comf == \'Y\' or comf == \'y\':
name, psd, remind = getinfo(login_user)
remind=int(remind)
old_data = \'{}:{}:{}\'.format(name, psd, remind)
remind += int(amount)
new_data = \'{}:{}:{}\'.format(name, psd, remind)
update(old_data, new_data)
print(\'已成功充值{}\'.format(amount))
break
return amount
#获取小说数据
def get_book():
with open(\'story_class.txt\',\'rt\',encoding=\'utf-8\')as f:
book_dic=eval(f.read())
return story_dic
#查看小说
def show(bookname):
with open(\'\',\'rt\',encoding=\'utf-8\')as f:
data=f.read()
return data
# 小说功能
@log
@auth
def reader():
book_dic=get_book()
if not book_dic:
print(\'库存没有小说了\')
return
while True:
print(\'\'\'
=== 欢迎来到阅读小说功能主页 ===
0 玄幻武侠
1 都市爱情
2 高效养猪36技
============ end ============
\'\'\')
cmd=input(\'输入你想阅读的小说种类编号\').strip()
if cmd not in book_dic:
print(\'请正确输入编号\')
second_dic =book_dic[cmd]
for num,booklist in second_dic.item():
name,price=booklist
print(\'小说编号[{}],小说名《{}》,小说价格[{}]\'.format(num,name,price))
while True:
cmd = input(\'输入你想购买的小说编号\')
if cmd not in second_dic:
print(\'请正确输入编号\')
continue
if cmd in second_dic:
name=second_dic[cmd][0]
price=second_dic[cmd][1]
cmd = input(\'当前选择的小说名为: 《{name}》,商品单价为: [{price}], 请输入Y/y购买:\'.format(name,price)).strip()
if cmd == \'Y\' or cmd==\'y\':
name,psd,remind = getinfo(login_user)
remind=int(remind)
if remind<int(price):
price(\'余额不足,请先充值\')
break
old_data = \'{}:{}:{}\'.format(name, psd, remind)
remind -= int(price)
new_data = \'{}:{}:{}\'.format(name, psd, remind)
update(old_data, new_data)
print(\'购买成功,请欣赏内容\')
fictiondata=show(name)
print(\'\'\'
-------开始阅读--------
{}
\'\'\'.format(fictiondata))
#登出功能
def logout():
global login_user
login_user=None
#运行菜单
func_dic={
\'0\':[\'注册\',register],
\'1\':[\'登录\',login],
\'2\':[\'充值\',add_credit],
\'3\':[\'小说\',reader],
\'4\':[\'登出\',logout],
}
def run():
while True:
print(\'\'\'
~~~~~~~欢迎来到小说世界~~~~~~~
0 账号注册
1 账号登录
2 充值功能
3 阅读小说
4 登出
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\'\'\')
cmd= input(\'请输入功能编号,按4退出\').strip()
if cmd ==\'4\':
logout()
break
if cmd not in func_dic:
print(\'请正确输入功能编号\')
continue
func_dic[cmd][1]()
run()
# 编写小说阅读程序实现下属功能
# # 一:程序运行开始时显示
# 0 账号注册
# 1 充值功能
# 2 阅读小说
#
#
# # 二: 针对文件db.txt,内容格式为:"用户名:密码:金额",完成下述功能
# 2.1、账号注册
# 2.2、充值功能
#
# # 三:文件story_class.txt存放类别与小说文件路径,如下,读出来后可用eval反解出字典
# {"0":{"0":["倚天屠狗记.txt",3],"1":["沙雕英雄转.txt",10]},"1":{"0":["令人羞耻的爱.txt",6],"1":["二狗的妻子与大草原的故事.txt",5]},}
#
# 3.1、用户登录成功后显示如下内容,根据用户选择,显示对应品类的小说编号、小说名字、以及小说的价格
# """
# 0 玄幻武侠
# 1 都市爱情
# 2 高效养猪36技
# """
#
# 3.2、用户输入具体的小说编号,提示是否付费,用户输入y确定后,扣费并显示小说内容,如果余额不足则提示余额不足
#
# # 四:为功能2.2、3.1、3.2编写认证功能装饰器,要求必须登录后才能执行操作
#
# # 五:为功能2.2、3.2编写记录日志的装饰器,日志格式为:"时间 用户名 操作(充值or消费) 金额"
#
#
#
# # 附加:
# # 可以拓展作者模块,作者可以上传自己的作品
#
#
import time
userstatus = {\'username\': None}
def auth(func):
\'\'\'
认证功能装饰器
:return:
\'\'\'
def wrapper(*args, **kwargs):
if userstatus[\'username\'] is None:
inp_name = input(\'输入用户名\')
inp_psd = input(\'输入密码\')
with open(\'db.txt\', \'rt\', encoding=\'utf-8\')as rf:
userinfo = {}
for line in rf:
name, psd, remind = line.strip().split(\':\')
userinfo[name] = [psd, int(remind)]
if inp_name not in userinfo:
print(\'用户不存在\')
return
if inp_name in userinfo and userinfo[inp_name][0]==inp_psd:
print(\'登录成功,亲爱的{}用户\'.format(inp_name))
userstatus[\'username\']=inp_name
res=func(*args, **kwargs)
return res
else:
print(\'账号密码错误\')
return
else:
res = func(*args, **kwargs)
return res
return wrapper
def record_log(func):
\'\'\'
日志记录功能装饰器
:return:
\'\'\'
def wrapper(*args, **kwargs):
res = func(*args, **kwargs)
with open(\'record.log\', \'ab\')as log_f:
op_time = time.time()
amount = func.amount
log_f.write(\'{} {} {} {}\n\'.format(op_time, userstatus[\'username\'], func.__name__, amount).encode(\'utf-8\'))
return res
return wrapper
def register():
\'\'\'
注册功能
:return:
\'\'\'
with open(\'db.txt\', \'rt\', encoding=\'utf-8\')as rf:
userinfo = {}
for line in rf:
name, psd, remind = line.strip().split(\':\')
userinfo[name] = [psd, int(remind)]
inp_name = input(\'输入注册名\')
inp_psd = input(\'输入密码\')
if inp_name in userinfo:
print(\'用户名已存在\')
return
re_psd = input(\'再次输入密码\')
if inp_psd == re_psd:
print(\'注册成功\')
with open(\'db.txt\', \'at\', encoding=\'utf-8\')as af:
af.write(\'{}:{}:0\n\'.format(inp_name, inp_psd))
else:
print(\'两次密码不一致\')
return
@record_log
@auth
def add_credit():
\'\'\'
充值功能
:return:
\'\'\'
print(\'欢迎使用充值功能,亲爱的{}\'.format(userstatus[\'username\']))
with open(\'db.txt\', \'rt\', encoding=\'utf-8\')as rf:
userinfo = {}
for line in rf:
name, psd, remind = line.strip().split(\':\')
userinfo[name] = [psd, int(remind)]
while True:
amount = input(\'请输入充值的金额\').strip()
conf = input(\'确定要向{}用户充值{}吗,确定输入Y/y,退出N/n\'.format(userstatus[\'username\'], amount))
if conf == \'Y\' or conf == \'y\':
print(\'充值成功,已为您充值{}元\'.format(amount))
userinfo[userstatus[\'username\']][1] += int(amount)
break
elif conf == \'N\' or conf == \'n\':
break
with open(\'db.txt\', \'wt\', encoding=\'utf-8\')as wf:
for name in userinfo:
wf.write(\'{}:{}:{}\n\'.format(userinfo[name], userinfo[name][0], userinfo[name][1]))
@record_log
@auth
def read():
\'\'\'
阅读小说功能
:return:
\'\'\'
pass
def logout():
\'\'\'
登出
:return:
\'\'\'
userstatus[\'username\'] = None
return
def menu():
fuc_dic = {
\'0\': (\'注册功能\', register),
\'1\': (\'充值功能\', add_credit),
\'2\': (\'阅读小说\', read),
\'3\': (\'登出\',logout)
}
tag= True
while tag:
cmd = input(\'\'\'
0 账号注册
1 充值功能
2 阅读小说
3 登出
\'\'\')
int(cmd)
if not cmd.isdigit():
print(\'请输入数字\')
if cmd.isdigit():
fuc_dic[cmd][1]()
if cmd == 3:
tag=False
menu()