WSGI服务器

WSGI服务器

  1 import re
  2 from pymysql import connect
  3 import urllib.parse
  4 import logging
  5 
  6 
  7 URL_FUNC_DICT = dict()
  8 
  9 def open_mysql():
 10     # 创建connect连接
 11     conn = connect(host='localhost',port=3306,user='root',password='m',database='stock',charset='utf8')
 12     # 获得cursor对象
 13     cs = conn.cursor()
 14     return conn, cs
 15 
 16 def close_mysql(conn, cs):
 17     # 关闭连接、对象
 18     cs.close()
 19     conn.close()
 20 
 21 def route(path_info):
 22     '''装饰器:添加方法-路径到字典'''
 23     def set_func(func):
 24         URL_FUNC_DICT[path_info] = func
 25         def call_func(*args, **kwargs):
 26             return func(*args, **kwargs)
 27         return call_func
 28     return set_func
 29 
 30 @route(r"/index.html")
 31 def index(ret):
 32     # 打开、读取网页
 33     with open("./templates/index.html", encoding="utf-8") as f:
 34         content = f.read()
 35     # 打开数据库
 36     conn, cs = open_mysql()
 37     # 执行sql语句
 38     cs.execute("select * from info;")
 39     # 读取数据库数据
 40     stock_infos = cs.fetchall()
 41     # 关闭数据库
 42     close_mysql(conn, cs)
 43     # 数据库数据替换模板数据
 44     tr_template = """<tr>
 45         <td>%s</td>
 46         <td>%s</td>
 47         <td>%s</td>
 48         <td>%s</td>
 49         <td>%s</td>
 50         <td>%s</td>
 51         <td>%s</td>
 52         <td>%s</td>
 53         <td>
 54             <input type="button" value="添加" id="toAdd" name="toAdd" systemidvaule="%s">
 55         </td>
 56         </tr>
 57     """
 58     html = ""
 59     for line_info in stock_infos:
 60         html += tr_template % (line_info[0],line_info[1],line_info[2],line_info[3],line_info[4],line_info[5],line_info[6],line_info[7], line_info[1])
 61     return re.sub(r"\{%content%\}", html, content)
 62 
 63 @route(r"/center.html")
 64 def center(ret):
 65     # 打开读取网页
 66     with open("./templates/center.html", encoding="utf-8") as f:
 67         content = f.read()
 68     # 打开数据库
 69     conn, cs = open_mysql()
 70     # 执行sql语句
 71     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;")
 72     # 读取sql语句结果
 73     stock_infos = cs.fetchall()
 74     # 关闭数据库
 75     close_mysql(conn, cs)
 76     tr_template = """
 77         <tr>
 78             <td>%s</td>
 79             <td>%s</td>
 80             <td>%s</td>
 81             <td>%s</td>
 82             <td>%s</td>
 83             <td>%s</td>
 84             <td>%s</td>
 85             <td>
 86                 <a type="button" class="btn btn-default btn-xs" href="/update/%s.html"> <span class="glyphicon glyphicon-star" aria-hidden="true"></span> 修改 </a>
 87             </td>
 88             <td>
 89                 <input type="button" value="删除" id="toDel" name="toDel" systemidvaule="%s">
 90             </td>
 91         </tr>
 92     """
 93     # 用数据库内容替换模板数据
 94     html = ""
 95     for stock_info in stock_infos:
 96         html += tr_template % (stock_info[0], stock_info[1], stock_info[2], stock_info[3],stock_info[4], stock_info[5], stock_info[6], stock_info[0], stock_info[0])
 97     return re.sub(r"\{%content%\}", html, content)
 98 
 99 @route(r"^/add/(\d+)\.html$")
100 def add_focus(ret):
101     '''添加股票'''
102     # 获取股票代码
103     stock_code = ret.group(1)
104     # 打开数据库,查询股票代码
105     conn, cs = open_mysql()
106     sql = "select * from info where code = %s;"
107     cs.execute(sql, (stock_code,))
108     # 股票代码不在数据库中
109     if not cs.fetchall():
110         # 返回提示
111         close_mysql(conn, cs)
112         return "没有这只股票代码,请收下留情。。"
113     # 判断股票代码是否已存在于focus表数据库中
114     sql = "select * from info as i inner join focus as f on i.id = f.info_id where i.code = %s"
115     cs.execute(sql, (stock_code,))
116     # 已存在于focus表
117     if cs.fetchall():
118         close_mysql(conn, cs)
119         return "已成功关注,请勿重复关注。。"
120     # 不存在于focu表
121     # 执行sql语句添加股票代码到focus表
122     sql = "insert into focus(info_id) select id from info where code = %s;"
123     cs.execute(sql, (stock_code))
124     conn.commit()
125     # 关闭数据库
126     close_mysql(conn, cs)
127     return "关注成功。。"
128 
129 @route(r"^/del/(\d+)\.html$")
130 def del_focus(ret):
131     '''取消关注股票'''
132     stock_code = ret.group(1)
133     print(stock_code)
134     conn, cs = open_mysql()
135     sql = "select * from focus as f inner join info as i on i.id = f.info_id where i.code = %s;"
136     cs.execute(sql, (stock_code,))
137     # 股票代码不存在于focus表
138     if not cs.fetchall():
139         close_mysql(conn, cs)
140         return "未曾关注,谈何取消。。"
141     sql = "delete from focus where info_id = (select id from info where code = %s);"
142     cs.execute(sql, (stock_code,))
143     conn.commit()
144     close_mysql(conn, cs)
145     return "已成功取关注。。"
146 
147 @route(r"/update/(\d+)\.html")
148 def update_info(ret):
149     '''更新数据'''
150     # 获取股票代码
151     stock_code = ret.group(1)
152     # 打开数据库,查询股票代码
153     conn, cs = open_mysql()
154     sql = "select * from info where code = %s;"
155     cs.execute(sql, (stock_code,))
156     # 股票代码不在数据库中
157     if not cs.fetchall():
158         # 返回提示
159         close_mysql(conn, cs)
160         return "没有这只股票代码,请收下留情。。"
161     # 判断股票代码是否已存在于focus表数据库中
162     sql = "select * from info as i inner join focus as f on i.id = f.info_id where i.code = %s"
163     cs.execute(sql, (stock_code,))
164     # 已存在于focus表
165     if not cs.fetchall():
166         close_mysql(conn, cs)
167         return "没有关注,请勿输入备注。。"
168     # 打开网页
169     with open("./templates/update.html", encoding="utf-8") as f:
170         content = f.read()
171     # 替换模板,回传数据
172     content = re.sub(r"\{%note_info%\}","请输入修改内容", content)
173     return re.sub(r"\{%code%\}", stock_code, content)
174     # return "更新数据成功。。"
175 
176 @route(r"/update/(\d+)/(.*)\.html")
177 def save_update(ret):
178     stock_code = ret.group(1)
179     new_info = ret.group(2)
180     new_info = urllib.parse.unquote(new_info)
181     # 打开数据库,查询股票代码
182     conn, cs = open_mysql()
183     sql = "select * from info where code = %s;"
184     cs.execute(sql, (stock_code,))
185     # 股票代码不在数据库中
186     if not cs.fetchall():
187         # 返回提示
188         close_mysql(conn, cs)
189         return "没有这只股票代码,请收下留情。。"
190     # 判断股票代码是否已存在于focus表数据库中
191     sql = "select * from info as i inner join focus as f on i.id = f.info_id where i.code = %s"
192     cs.execute(sql, (stock_code,))
193     # 不存在于focu表
194     if not cs.fetchall():
195         close_mysql(conn, cs)
196         return "未曾关注,请勿修改。。"
197     # 已存在于focus表
198     # 执行sql语句添加股票代码到focus表
199     sql = "update focus set note_info=%s where info_id = (select id from info where code=%s);"
200     cs.execute(sql, (new_info, stock_code))
201     conn.commit()
202     # 关闭数据库
203     close_mysql(conn, cs)
204     return "修改成功。。"
205 
206 def application(env, start_header):
207     start_header("200 OK", [("Content-type", "text/html;charset=utf-8")])
208     # 获取请求文件信息
209     file_name = env["PATH_INFO"]
210     file_name = urllib.parse.unquote(file_name)
211     # 日志设定
212     # 创建logger
213     logger = logging.getLogger()
214     logger.setLevel(logging.DEBUG)
215     # 创建一个handler,用于写入文件
216     logfile = "./log.txt"
217     fh = logging.FileHandler(logfile,mode='a')
218     fh.setLevel(logging.INFO)
219     # 创建一个handler,用于输出控制台
220     ch = logging.StreamHandler()
221     ch.setLevel(logging.WARNING)
222     # 定义日志输出格式
223     formatter = logging.Formatter("%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s")
224     fh.setFormatter(formatter)
225     ch.setFormatter(formatter)
226     # 将logger添加到handler中
227     logger.addHandler(fh)
228     logger.addHandler(ch)
229     logger.info("客户访问:%s" % file_name)
230     try:
231         for url, func in URL_FUNC_DICT.items():
232             ret = re.match(url, file_name)
233             if ret:
234                 return func(ret)
235         else:
236             logger.warning("请求错误。file(%s) not found" % file_name)
237             return "请求错误。file(%s) not found" % file_name
238     except Exception as e:
239         logger.warning("程序异常。错误信息:%s" % e)
240         return "请求错误。logger错误信息:%s" % e

  1 import sys
  2 import re
  3 import socket
  4 import multiprocessing
  5 
  6 class WSGIServer(object):
  7     '''服务器运行对象'''
  8     def __init__(self, port, app, static_path):
  9         '''对象初始化'''
 10         # 创建套接字
 11         self.tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 12         self.tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 13         # 绑定端口 IP
 14         self.tcp_server_socket.bind(("", port))
 15         # 设置监听套接字
 16         self.tcp_server_socket.listen(128)
 17         # web框架调用方法
 18         self.application = app
 19         # 静态网页存放地址
 20         self.static_path = static_path
 21 
 22     def client_serve(self, client_socket):
 23         '''为浏览器实现具体服务'''
 24         # 获取浏览器请求
 25         request = client_socket.recv(1024).decode("utf-8")
 26         request_lines = request.splitlines()
 27         # 解析浏览器请求
 28         ret = re.match(r"[^/]+(/[^ ]*)", request_lines[0])
 29         file_name = ""
 30         if ret:
 31             file_name = ret.group(1)
 32             if file_name == "/":
 33                 file_name = "/index.html"
 34         # print("file_nema:", file_name)
 35         # 如果为静态页面请求(非html请求)
 36         if not file_name.endswith(".html"):
 37             # 打开请求页面
 38             try:
 39                 with open(self.static_path + file_name, "rb") as f:
 40                     response_body = f.read()
 41             # 打开页面失败
 42             except:
 43                 response_body = "file not found"
 44                 response_header = "HTTP/1.1 404 FILE NOT FOUND\r\n"
 45                 response_header += "\r\n"
 46                 response = response_header + response_body
 47                 client_socket.send(response.encode("utf-8"))
 48             # 打开页面成功
 49             else:
 50                 response_header = "HTTP/1.1 200 OK\r\n"
 51                 response_header += "\r\n"
 52                 response = response_header.encode("utf-8") + response_body
 53                 client_socket.send(response)
 54         # 如果为动态页面请求
 55         else:
 56             env = dict()
 57             env["PATH_INFO"] = file_name
 58             # print(file_name)
 59             # 调用web框架方法,处理页面
 60             response_body = self.application(env, self.set_headers)
 61 
 62             response_header = "HTTP/1.1 %s \r\n" % self.status
 63             for header in self.header_list:
 64                 response_header += "%s:%s\r\n" %(header[0],header[1])
 65             response_header += "\r\n"
 66 
 67             response = response_header + response_body
 68             client_socket.send(response.encode("utf-8"))
 69         # 关闭套接字
 70         client_socket.close()
 71 
 72     def set_headers(self, status, header_list):
 73         '''存放web框架请求头信息'''
 74         self.status = status
 75         self.header_list = header_list
 76 
 77     def fun_forever(self):
 78         '''服务器对象流程控制'''
 79         while True:
 80             # print("等待浏览器连接")
 81             client_socket, client_addr = self.tcp_server_socket.accept()
 82             # 利用多进程实现多任务操作
 83             # print("创建子线程")
 84             p = multiprocessing.Process(target=self.client_serve, args=(client_socket,))
 85             p.start()
 86             client_socket.close()
 87 
 88 def error_msg():
 89     print("服务器开启失败,请按以下方式输入")
 90     print("python xxx.py 8080 mini_frame:application")
 91 
 92 def main():
 93     '''实现主体流程控制'''
 94     # # 获取服务器端口、web_frame框架地址、方法名
 95     # # 如果程序调用参数为3,输入正确
 96     # if len(sys.argv) == 3:
 97     #     # 参数输入方式正确
 98     #     try:
 99     #         port = int(sys.argv[1])
100     #         frame_app_name = sys.argv[2]
101     #     # 参数输入方式错误
102     #     except:
103     #         error_msg()
104     # # 如果不为3,调用方法错误,输出提示
105     # else:
106     #     error_msg()
107     port = 8080
108     frame_app_name = "mini_frame:application"
109     # 打开配置文件,获取静态、动态文件夹地址
110     with open("web_server.conf") as f:
111         conf_info = eval(f.read())
112     dynamic_path = conf_info["dynamic_path"]
113     sys.path.append(dynamic_path)
114     # 获取框架名、方法名
115     ret = re.match(r"([^:]+):(.*)", frame_app_name)
116     if ret:
117         frame_name = ret.group(1)
118         app_name = ret.group(2)
119         # print("app",app_name)
120     else:
121         error_msg()
122     # 导入web_frame框架
123     frame = __import__(frame_name)
124     # 导入app方法
125     app = getattr(frame, app_name)
126     # print("创建WSGI对象")
127     # 创建WSGI对象
128     wsgi_server = WSGIServer(port, app, conf_info["static_path"])
129     # 调用其run_forever方法,使流程不断运行
130     wsgi_server.fun_forever()
131 
132 if __name__ == "__main__":
133     main()

 

转载于:https://www.cnblogs.com/sure-feng/p/10427603.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/101101.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Okio—— 更加高效易用的IO库

    Okio—— 更加高效易用的IO库在OkHttp的源码中经常能看到Okio的身影,所以单独拿出来分析一下,作为作为OkHttp的低层IO库,Okio确实比传统的java输入输出流读写更加方便高效。

  • sd/tf卡槽是什么_usb电源线接法图解

    sd/tf卡槽是什么_usb电源线接法图解SDIO接线作为SD的4-bit传输模式下的接法,在RK3399上的应用,实现双TF卡无法识别闪迪卡解决办法1.硬件接线图如上图是SDIO接口接为TF接口的电路实现双TF卡功能,模式是4-bit,注意22R电阻要加上,尽量靠近3399摆放,但是调试的时候遇到一个问题,其他类型卡都可以识别,唯独闪迪卡无法识别,找了很久,最后发现TF卡电源VDD需要接3V0才可以解决。2,查看了资料,发现VDD关系到读卡的电压问题,如下图,闪迪卡在插入的时候会告知系统是否需要切换1.8…

  • 锐捷交换机配置保存到计算机,锐捷交换机常用配置命令汇总「建议收藏」

    锐捷交换机配置保存到计算机,锐捷交换机常用配置命令汇总「建议收藏」前面我们给大家汇总了华为、华三交换机的配置命令,都是非常适合小项目的,当然碰到大型的网络工程,还是需要厂家的专业人才来做。今天再给大家分享一下锐捷交换机的配置命令,这样国内三大家就全部都有了,学习一些基础网络知识还是不错的,尤其在视频监控系统中应用一下,还是可以的。正文:一、连接及远程登录用一台计算机作为控制台和网络设备相连接,通过计算机对网络设备进行配置。1、硬件连接把Console线一端连接在…

  • 万能激活成功教程器修改器_激活成功教程软件

    万能激活成功教程器修改器_激活成功教程软件神呐原谅我吧为了省$35啊删掉注册表[HKEY_CURRENT_USER\Software\Classes\CLSID\{B1159E65-821C3-21C5-CE21-34A484D54444}\4FF78130]该项下的所有内容

  • python阶乘算法

    python阶乘算法阶乘算法推导原理阶乘:n!=123*…n-1n(过于简单,不做过多描述)代码如下:num=input(“请输入一个数:”)ifnum.isdigit():#天然要求输入的是>=0的自然数num=int(num)result=1#定义结果初值为1(由于0的阶乘为1,所以无需考虑)foriinrange(1,num…

  • uniapp中使用jsencrypt进行RSA加密,解决密文作为参数传输到后台时+号变成空格的问题「建议收藏」

    uniapp中使用jsencrypt进行RSA加密,解决密文作为参数传输到后台时+号变成空格的问题「建议收藏」解决密文作为参数传输到后台时+号变成空格的问题用encrypt.encrypt()加密后生成的密文字符串中带有加号,如下Q3Q+ZijLMjcKyC1whAzxtfVpy7G+N1kpCGQJYO8dISQ1UyEzczC6vdqbwG18K6ylTv2fXujogOFwzgZlNuVTKEDVeHqjnsYjDcOUJqvE8t8Mxug+vVMnAOsJfzL0eZqYREoq7YoDJ150q7xZB/8XZEfzwnc/4MwKJLHshj+UFCc=密文作为参数传输到后端时+号变成了空格,

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号