web服务器2
web服务端主要实现在浏览器调用动态页面,并根据页面点击事件对数据库数据做相应操作
1.web服务端
import socket
import re
import sys
from threading import Thread
# 设置静态文件根目录
from Four.web import mini_framework
HTML_ROOT_DIR = "./static"
WSGI_PYTHON_DIR = "./wsgipython"
class HTTPServer(object):
def __init__(self):
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
server_socket.bind(('', 6500))
server_socket.listen(128)
self.server_socket = server_socket
def start(self):
while True:
client_socket, client_address = self.server_socket.accept()
print("[%s, %s]用户连接上了" % client_address)
handle_client_thread = Thread(target=self.handle_client, args=(client_socket,))
handle_client_thread.start()
handle_client_thread.join()
client_socket.close()
def handle_client(self, client_socket):
"""处理客户端请求"""
# 获取客户端请求数据
request_data = client_socket.recv(4096)
# 提取用户请求的文件名
request = request_data.decode("utf-8")
file_name = re.search("/\S*", request)
if not file_name:
client_socket.close()
print('file_name is None')
return
file_path = file_name.group()
if "/" == file_path:
file_path = "/index.html"
if file_path.endswith('.html'):
# 请求动态资源 # 构造响应数据
response_start_line = "HTTP/1.1 200 OK\r\n"
response_headers = "Server: My server\r\n"
response_body = mini_framework.application(file_path)
response = (response_start_line + response_headers + "\r\n" + response_body).encode('gbk')
# 向客户端返回响应数据
client_socket.send(response)
else:# 请求静态资源
# 打开文件,读取内容
try:
with open(HTML_ROOT_DIR + file_path, 'rb') as file:
print('file_path', file_path)
file_data = file.read()
except IOError:
# 请求的文件不存在
response_start_line = "HTTP/1.1 404 Not Found\r\n"
response_headers = "Server: My server\r\n"
response_body = "<h1>The file is not found!</h1>".encode("utf-8")
response = (response_start_line + response_headers + "\r\n").encode('utf-8') + response_body
client_socket.send(response)
else:
# 请求的文件存在
# 构造响应数据
response_start_line = "HTTP/1.1 200 OK\r\n"
response_headers = "Server: My server\r\n"
response_body = file_data
response = (response_start_line + response_headers + "\r\n").encode('utf-8') + response_body
# 向客户端返回响应数据
client_socket.send(response)
# 关闭客户端连接
client_socket.close()
def start_response(self, status, headers):
response_headers = "HTTP/1.1 " + status + "\r\n"
for header in headers:
response_headers += "%s: %s\r\n" % header
self.response_headers = response_headers
def main():
sys.path.insert(1, WSGI_PYTHON_DIR)
http_server = HTTPServer()
http_server.start()
if __name__ == "__main__":
main()
2.mini_framework.py
import pymysql
import re
def conn_db():
db = pymysql.connect(host='localhost', user='user1', password="123456",
database='mydata', port=3306, charset='utf8')
cur = db.cursor()
return cur, db
g_path_func = {}
def route(path):
def set_func(func):
# 将访问路径作为key 将被装饰的函数做为value, 完成key value的对应关系
# 这种对应关系在web_server导入mini_framework的时候就已经建立好了
g_path_func[path] = func
def call_func(*args, **kwargs):
return func(*args, **kwargs)
return call_func
return set_func
# 处理不同的动态页面对应的动态数据
@route('/index.html')
def index(*args, **kwargs):
""" 处理首页动态页面的数据 """
with open('./templates/index.html', ) as f:
content = f.read()
html_str = ''
cur, db = conn_db()
select_sql = 'select * from infos'
cur.execute(select_sql)
ret = cur.fetchall()
html_template = """<tr>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>
<input type="button" value="添加" id="toAdd" name="toAdd" systemidvaule="%s">
</td>
</tr>"""
for item in ret:
html_str += (html_template % (item[0], item[1], item[2], item[3], item[4], item[5], item[6], item[7], item[1]))
# 关闭
cur.close()
db.close()
# 将数据库中的数据拼接到模板中
content = re.sub(r"\{%content%\}", html_str, content)
return content
@route('/center.html')
def center(*args, **kwargs):
""" 处理首页动态页面的数据 """
with open('./templates/center.html', ) as f:
content = f.read()
html_str = ''
cur, db = conn_db()
select_sql = '''SELECT i.cood, i.simpleName, i.appreciate, i.reware, i.latest, i.prophase, f.beizhu
from infos as i INNER JOIN focus as f ON i.id = f.info_id'''
cur.execute(select_sql)
ret = cur.fetchall()
html_template = """<tr>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>
<a type="button" class="btn btn-default btn-xs" href="/update/%s.html"> <span class="glyphicon glyphicon-star" aria-hidden="true"></span> 修改 </a>
</td>
<td>
<input type="button" value="删除" id="toDel" name="toDel" systemidvaule="%s">
</td>
</tr>"""
for item in ret:
html_str += (html_template % (item[0], item[1], item[2], item[3], item[4], item[5], item[6], item[0], item[0]))
# 关闭
cur.close()
db.close()
# 将数据库中的数据拼接到模板中
content = re.sub(r"\{%content%\}", html_str, content)
return content
@route('/update.html')
def update(*args, **kwargs):
""" 处理首页动态页面的数据 """
with open('./templates/update.html', ) as f:
content = f.read()
return content
@route(r"/add/([a-zA-z0-9]{6})\.html")
def add(*args, **kwargs):
""" 添加关注某只股票到到focus表中 在访问路径中提取股票代码,需要根据股票代码获取股票的id """
request_path = args[0]
pattern = args[1]
# 通过正则表达式提取股票代码
ret = re.match(r"/add/([a-zA-z0-9]{6})\.html", request_path)
code = ret.group(1)
print('-'*10, code)
cur, db = conn_db()
sql = 'select * from focus where info_id = (select id from infos where cood = %s)'
ret = cur.execute(sql, [code])
if ret > 0:
# 查询到结果, 关注的股票已经存在, 就不能够关注
cur.close()
db.close()
return "111抱歉, 您已近关注人家啦哟...."
else:
# 将查询的结果插入到表中 insert ... select
sql = "insert into focus (info_id) select id from infos where cood = %s"
try:
cur.execute(sql, [code])
# 如果是数据更新 需要commit提交
db.commit
()
except:
print('添加失败')
db.rollback()
finally:
cur.close()
db.close()
return '222关注%s股票' % code
@route(r"/del/([a-zA-z0-9]{6})\.html")
def delete(*args, **kwargs):
""" 根据股票代码在focus表中删除对应的股票信息 """
request_path = args[0]
pattern = args[1]
# 通过正则表达式提取股票代码
ret = re.match(r"/del/([a-zA-z0-9]{6})\.html", request_path)
code = ret.group(1)
print('-' * 10, code)
cur, db = conn_db()
sql = "delete from focus where info_id = (select id from infos where cood = %s)"
try:
cur.execute(sql, [code])
db.commit
()
except Exception:
print('取消关注失败')
db.rollback()
else:
print('取消关注成功')
finally:
cur.close()
db.close()
return '333取消关注%s股票' % code
def application(file_path):
print(file_path)
for pattern, func in g_path_func.items():
ret = re.match(pattern, file_path)
if ret:
return func(file_path, pattern)
else:
return 'sorry, 你访问的动态页面暂未实现'