mini web框架完整版本 添加 :url编码解码 -- log日志
文件目录:
├── dynamic │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-37.pyc │ │ └── mini_frame.cpython-37.pyc │ └── mini_frame.py ├── new.log ├── static │ ├── css │ │ ├── bootstrap.min.css │ │ ├── main.css │ │ └── swiper.min.css │ └── js │ ├── a.js │ ├── bootstrap.min.js │ ├── jquery-1.12.4.js │ ├── jquery-1.12.4.min.js │ ├── jquery-ui.min.js │ ├── jquery.animate-colors-min.js │ ├── jquery.animate-colors.js │ ├── jquery.cookie.js │ ├── server.js │ ├── swiper.jquery.min.js │ ├── swiper.min.js │ └── zepto.min.js ├── templates │ ├── center.html │ ├── index.html │ └── update.html └── web_server.py
web服务器:
import socket import re import multiprocessing import time import dynamic.mini_frame import sys class WSGIServer(object): def __init__(self,port): # 1. 创建套接字 self.tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 2. 绑定 self.tcp_server_socket.bind(("", port)) # 3. 变为监听套接字 self.tcp_server_socket.listen(128) def service_client(self, new_socket): """为这个客户端返回数据""" # 1. 接收浏览器发送过来的请求 ,即http请求 # GET / HTTP/1.1 # ..... request = new_socket.recv(1024).decode("utf-8") # print(">>>"*50) # print(request) request_lines = request.splitlines() print("") print(">"*20) print("request_lines[0]",request_lines[0]) # GET /index.html HTTP/1.1 # get post put del file_name = "" ret = re.match(r"[^/]+(/[^ ]*)", request_lines[0]) print("ret",ret.group(1)) if ret: file_name = ret.group(1) print("ret_group",ret.group(1)) # print("*"*50, file_name) if file_name == "/": file_name = "/index.html" # 2. 返回http格式的数据,给浏览器 # 2.1 如果请求的资源不是以.py结尾,那么就认为是静态资源(html/css/js/png,jpg等) if not file_name.endswith(".html"): try: f = open("./static" + file_name, "rb") except: response = "HTTP/1.1 404 NOT FOUND\r\n" response += "\r\n" response += "------file not found-----" new_socket.send(response.encode("utf-8")) else: html_content = f.read() f.close() # 2.1 准备发送给浏览器的数据---header response = "HTTP/1.1 200 OK\r\n" response += "\r\n" # 2.2 准备发送给浏览器的数据---boy # response += "hahahhah" # 将response header发送给浏览器 new_socket.send(response.encode("utf-8")) # 将response ic.mini_frame.applicationbody发送给浏览器 new_socket.send(html_content) else: # 2.2 如果是以.py结尾,那么就认为是动态资源的请求 env = dict() # 这个字典中存放的是web服务器要传递给 web框架的数据信息 env['PATH_INFO'] = file_name print("PATH_INFO",env["PATH_INFO"]) # {"PATH_INFO": "/index.py"} body = dynamic.mini_frame.application(env, self.set_response_header) header = "HTTP/1.1 %s\r\n" % self.status for temp in self.headers: header += "%s:%s\r\n" % (temp[0], temp[1]) header += "\r\n" response = header+body # 发送response给浏览器 new_socket.send(response.encode("utf-8")) # 关闭套接 new_socket.close() def set_response_header(self, status, headers): self.status = status self.headers = [("server", "mini_web v8.8")] self.headers += headers def run_forever(self): """用来完成整体的控制""" while True: # 4. 等待新客户端的链接 new_socket, client_addr = self.tcp_server_socket.accept() # 5. 为这个客户端服务 p = multiprocessing.Process(target=self.service_client, args=(new_socket,)) p.start() new_socket.close() # 关闭监听套接字 self.tcp_server_socket.close() def main(): if len(sys.argv) == 2: port = int(sys.argv[1]) """控制整体,创建一个web 服务器对象,然后调用这个对象的run_forever方法运行""" wsgi_server = WSGIServer(port) wsgi_server.run_forever() else: print("error") if __name__ == "__main__": main()
web框架
# coding=utf-8 import re from pymysql import connect import urllib.parse import logging ROUTER_DICT = dict() def route(url): def set_func(func): ROUTER_DICT[url] = func def call_func(*args,**kwargs): return func(*args,**kwargs) return call_func return set_func @route("/index.html") def index(res): with open("./templates/index.html",encoding="utf-8") as f: content = f.read() conn = connect(host="localhost",port=3306,user="root",password="",database="stock_db",charset="utf8") cs = conn.cursor() cs.execute("select * from info") info = cs.fetchall() cs.close() conn.close() page_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> <a type="button" class="btn btn-default btn-xs" href="/add/%s.html"> <span class="glyphicon glyphicon-start" aria-hidden="true"></span>添加</a> </td> </tr>""" html = "" for i in info: html += page_template % (i[0],i[1],i[2],i[3],i[4],i[5],i[6],i[7],i[1]) content = re.sub(r"\{%content%\}", html, content) return content @route("/center.html") def center(res): with open("./templates/center.html") as f: content = f.read() # my_stock_info = "这里是从mysql查询出来的数据。。。" # content = re.sub(r"\{%content%\}", my_stock_info, content) conn = connect(host="localhost",port=3306,user="root",password="",database="stock_db",charset="utf8") cs = conn.cursor() cs.execute("select i.code,i.short,i.chg,i.turnover,i.price,i.highs,f.note_info from info as i inner join focus as f on i.id = f.info_id;") info = cs.fetchall() cs.close() conn.close() page_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-start" aria-hidden="true"></span>修改</a> </td> <td> <a type="button" class="btn btn-default btn-xs" href="/del/%s.html"> <span class="glyphicon glyphicon-start" aria-hidden="true"></span>删除</a> </td> </tr>""" # <input type="button" value="删除" id="toDel" name="toDel" systemidvaule=%s> html = "" for i in info: html += page_template % (i[0],i[1],i[2],i[3],i[4],i[5],i[6],i[0],i[0]) content = re.sub(r"\{%content%\}", html, content) return content @route(r"/add/(\d+)\.html") def add_focus(res): #获取股票代码 stock_code = res.group(1) #判断是否有这个股票 conn = connect(host="localhost",port=3306,user="root",password="",database="stock_db",charset="utf8") cs = conn.cursor() sql = "select * from info where code=%s" cs.execute(sql,(stock_code,)) if not cs.fetchone(): cs.close() conn.close() return "没有这只股票.." #判断是否已经关注 sql = "select * from info as i inner join focus as f on i.id=f.info_id where i.code=%s" cs.execute(sql,(stock_code,)) if cs.fetchone(): cs.close() conn.close() return "已经关注过了.." #添加关注 else: sql = "insert into focus (info_id) select id from info where code=%s" cs.execute(sql,(stock_code,)) conn.commit() cs.close() conn.close() return "关注成功.." @route(r"/del/(\d+)\.html") def del_focus(res): #获取股票代码 stock_code = res.group(1) #判断是否有这个股票 conn = connect(host="localhost",port=3306,user="root",password="",database="stock_db",charset="utf8") cs = conn.cursor() sql = "select * from info where code=%s" cs.execute(sql,(stock_code,)) if not cs.fetchone(): cs.close() conn.close() return "没有这只股票.." #判断是否已经关注 sql = "select * from info as i inner join focus as f on i.id=f.info_id where i.code=%s" cs.execute(sql,(stock_code,)) #如果没有关注过,表示非法请求 if not cs.fetchone(): cs.close() conn.close() return "没有关注这只股票.." #取消关注 else: sql = "delete from focus where info_id=(select id from info where code=%s);" cs.execute(sql,(stock_code,)) conn.commit() cs.close() conn.close() return "取消关注成功.." @route(r"/update/(\d+)\.html") def show_update_page(res): #备注修改页面 #打开修改模版 with open("./templates/update.html") as f: content = f.read() #股票代码 stock_code = res.group(1) #根据股票代码查询备注信息 conn = connect(host="localhost",port=3306,user="root",password="",database="stock_db",charset="utf8") cs = conn.cursor() sql = "select note_info from focus inner join info on info.id=focus.info_id where info.code=%s" cs.execute(sql,(stock_code,)) stock_info = cs.fetchone() cs.close() conn.close() content = re.sub(r"\{%note_info%\}",stock_info[0],content) content = re.sub(r"\{%code%\}",stock_code,content) return content @route(r"/update/(\d+)/(.*)\.html") def change_note(res): stock_code = res.group(1) note_info = res.group(2) print("old note_info",note_info) #URL解码后再存储 note_info = urllib.parse.unquote(note_info) print("new note_info",note_info) conn = connect(host="localhost",port=3306,user="root",password="",database="stock_db",charset="utf8") cs = conn.cursor() sql="update focus set note_info=%s where info_id=(select id from info where code=%s)" cs.execute(sql,(note_info,stock_code)) conn.commit() cs.close() conn.close() return "修改成功!" def application(env, start_response): start_response('200 OK', [('Content-Type', 'text/html;charset=utf-8')]) file_name = env['PATH_INFO'] # file_name = "/index.py" # print("app_file_name",file_name) # print("dict",ROUTER_DICT) # ROUTER_DICT = { # "r'/index.html'":index', # "r'/center.html'":center, # "r'/update/(\d*)\.html':add_focus #. "r'/del/(\d+)\.html':del_focus" # } #添加log日志 logging.basicConfig(level=logging.INFO,#控制台打印的日志级别 filename='./new.log', filemode='a',##模式,有w和a,w就是写模式,每次都会重新写日志,覆盖之前的日志 #a是追加模式,默认如果不写的话,就是追加模式 format= '%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s' #日志格式 ) #记录访问的文件 logging.info("访问的是:%s"%file_name) try: for url,func in ROUTER_DICT.items(): #字典中的键url有"/index.html"、"/center.html"和正则"/add/\(d+)\.html" res = re.match(url,file_name) if res: print("res is true",res,func) return func(res) else: #记录错误 logging.warning("没有对应的函数..") return "%s has not found..[未匹配]"%file_name except Exception as e: return "%s has not found[捕获异常]" % file_name

浙公网安备 33010602011771号