框架路由

webServer.py

import socket, sys, re, multiprocessing, time


# 定义WSGI服务器类
class WSGIServer(object):
    # 初始化服务端socket
    def __init__(self, docRoot, app):
        # 创建socket
        self.svrSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 设置地址复用
        self.svrSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        # 绑定地址
        self.svrSocket.bind(("", 80))
        # 改主动为被动
        self.svrSocket.listen(128)
        # 设定html页面根目录
        self.docRoot = docRoot
        # 把传进来的app变为对象的app
        self.app = app

    # 定义运行服务器的方法
    def runServer(self):
        # 接受客户端请求
        cltSocket, _ = self.svrSocket.accept()
        # 设定客户端超时时间
        # cltSocket.settimeout(3)
        # 开启一个新的进程,处理客户端请求
        newProcces = multiprocessing.Process(target=self.dealWithRequest, args=(cltSocket,))
        # 启动新进程
        newProcces.start()

    # 设置动态数据的请求头
    def setResponse(self, status, headers):
        # 设置一些默认请求头的数据
        responseHeaderDefault = [
            ("Data", time.ctime()),
            ("Server", "BDQN-python mini web server")
        ]
    
        # 拼接响应头部数据
        self.headers = [status, responseHeaderDefault + headers]
    
    # 定义处理客户端请求的函数
    def dealWithRequest(self, cltSocket):
        while True:
            try:
                # 接收客户端的数据
                content = cltSocket.recv(1024).decode("utf-8")
            # 异常捕获
            except Exception as ret:
                print("========>", ret)
                cltSocket.close()
                return

            # 判断客户端是不是要关闭连接
            if not content:
                # 如果没有数据,则关闭客户端
                cltSocket.close()
                return

            # 处理客户端传递的数据
            requestLines = content.splitlines()

            # 提取客户端请求的路径
            ret = re.match(r"[^/]+(/[^ ]*)", requestLines[0])

            # 判断请求的路径是什么
            if ret.group(1) == "/":
                # 如果请求的是根路径,让他获取index页面
                pathName = ret.group(1) + "index.html"
            else:
                # 如果请求的不是根路径,则把原有路径赋值
                pathName = ret.group(1)

            # 处理静态请求
            if not pathName.endswith(".html"):
                # 如果请求的是静态文件
                try:
                    f = open(self.docRoot + pathName, "r")
                # 如果读取不到,捕获异常
                except Exception as ret:
                    # 准备响应头和响应体
                    responseBody = "file not found, Please input right url"
                    responseHeader = "HTTP/1.1 404 not found\r\n"
                    responseHeader += "Content-Type: text/html; charset=utf-8\r\n"
                    responseHeader += "Content-Length: %d\r\n" % (len(responseBody))
                    responseHeader += "\r\n"

                    # 拼接异常的响应数据
                    response = responseHeader + responseBody
                # 如果没有没有异常
                else:
                    # 读取文件数据
                    content = f.read()

                    # 准备响应头和响应体
                    responseBody = content
                    responseHeader = "HTTP/1.1 200 OK\r\n"
                    responseHeader += "Content-Type: text/html; charset=utf-8\r\n"
                    responseHeader += "Content-Length: %d\r\n" % (len(responseBody))
                    responseHeader += "\r\n"

                    # 拼接响应数据
                    response = responseHeader + responseBody

                # 将响应数据发送给客户端
                cltSocket.send(response.encode('utf-8'))

            # 处理动态请求
            else:
                # 存储所有需要处理的请求的key-value
                requestDict = {"pathName": pathName}

                # 通过myWeb下的app函数处理动态请求,获取响应数据
                responseBody = self.app(requestDict, self.setResponse)

                # 设置响应头
                responseHeader = "HTTP/1.1 {status}\r\n".format(status=self.headers[0])
                responseHeader += "Content-Type: text/html; charset=utf-8\r\n"
                responseHeader += "Content-Length: %d\r\n" % (len(responseBody))

                # 设置响应头
                for tempHead in self.headers[1]:
                    responseHeader += "{0}:{1}\r\n".format(*tempHead)

                # 拼接响应数据
                response = responseHeader + "\r\n" + responseBody

                # 发送数据给客户端
                cltSocket.send(response.encode("utf-8"))



# 设置静态资源访问的路径
gStaticDocumentRoot = "./html"
# 设置动态资源访问的路径
gDynamicDocumentRoot = "./web"

# 定义服务器的入口
def main():
    # 判断程序参数符不符合要求
    if len(sys.argv) == 2:
        # 获取程序的参数,获取要执行的函数名
        webModuleAppName = sys.argv[1]
    # 如果程序参数不符合要求,中断程序
    else:
        print("Please input like 'python fileName modelName:applicationName'")
    
    # 导入程序传参模块名以及应用名
    ret = re.match(r"([^:]*):(.*)", webModuleAppName)

    # 获取模块以及应用名
    modelName = ret.group(1)
    appName = ret.group(2)

    # 添加模块路径到代码环境变量中
    sys.path.append(gDynamicDocumentRoot)

    # 导入模块名
    model = __import__(modelName)
    
    # 将模块内的app应用变成可用的对象或者函数
    app = getattr(model, appName)

    # 初始化http服务器对象
    httpServer = WSGIServer(gStaticDocumentRoot, app)
    # 运行http服务器
    httpServer.runServer()


if __name__ == "__main__":
    main()

web/myWeb.py

import time, re, pymysql

# 定义模版文件存放的位置
templateRoot = "./templates"

# 定义全局路由列表
gUrlRoute = dict()


# 定义装饰器工厂
def route(url):
    def func1(func):
        gUrlRoute[url] = func
        def func2(fileName):
            return func(fileName)
        return func2
    return func1


# 定义查看函数
@route(r"/index/(\d*).html")
def index(fileName, url):
    # 异常处理
    try:
        fileName = "/index.html"
        f = open(templateRoot + fileName)
    # 捕获异常
    except Exception as ret:
        return "%s" % ret
    # 正常返回数据
    else:
        # 保存读取的内容
        content = f.read()
        # 关闭打开的文件
        f.close()

        # 连接数据库
        conn = pymysql.connect(host='172.16.238.130', port=3306, user='root',password='123456',database='my_mysql',charset='utf8')
        # 获取游标
        cs = conn.cursor()
        # 准备查询语句
        sql = """select * from goods;"""
        # 游标执行语句
        cs.execute(sql)
        # 获取游标内的数据
        dataFromMysql = cs.fetchall()

        # 准备html格式
        html_template = """
            <tr>
                <td>%d</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>
                <br>"""

        html = ""
        
         # 准备数据
        for data in dataFromMysql:
            html += html_template % (data[0], data[1], data[2], data[3], data[4], data[1])
            
        # 进行模版数据的替换
        content = re.sub(r"\{%content%\}", html, content)
        
        # 返回数据
        return content.encode("utf-8")
        

@route(r"/center.html")
def center(fileName, url):
    # 异常处理
    try:
        f = open(templateRoot + fileName)
    # 捕获异常
    except Exception as ret:
        return "%s" % ret
    # 正常返回数据
    else:
        # 保存读取的内容
        content = f.read()
        # 关闭打开的文件
        f.close()
        # 准备替换数据
        dataFromMysql = "center no data,,,,~~~~(>_<)~~~~ \n %s" % time.ctime()
        # 进行模版数据的替换
        content = re.sub(r"\{%content%\}", dataFromMysql, content)
        # 返回数据
        return "content"


# 定义添加函数
@route(r"/add/(\d*).html")
def add(fileName, url):
    # 获取url中的数字
    ret = re.match(url, fileName)
    id = ret.group(1)

    # 连接数据库
    conn = pymysql.connect(host='172.16.238.130', port=3306, user='root',password='123456',database='my_mysql',charset='utf8')
    # 获取数据库游标
    cs = conn.cursor()

    # 定义查询sql语句
    sql = '''select * from goods where id=%s''' % id

    # 去数据库查询相应ID的数据,如果有则返回数据已存在,没有则添加
    cs.execute(sql)
    data = cs.fetchall()
    # 判断数据是否存在
    if data:
        return "already exit"
    # 数据不存在就添加数据
    else:
        # 添加sql语句
        sql = '''insert into goods
        (id, name, cname, bname, price)
        values
        (%s, "aaa", "bbb", "ccc", 1000)''' % id

        # 执行sql语句
        cs.execute(sql)
        # 提交数据
        conn.commit()
        # 关闭游标
        cs.close()
        # 关闭数据连接
        conn.close()
        # 返回提示信息
        return "success"



# 定义修改函数
@route(r"/update/(\d*).html")
def update(fileName, url):
    # 获取url中的数字
    ret = re.match(url, fileName)
    id = ret.group(1)
    # 连接数据库
    conn = pymysql.connect(host='172.16.238.130', port=3306, user='root',password='123456',database='my_mysql',charset='utf8')
    # 获取数据库游标
    cs = conn.cursor()

    #定义查找的sql语句
    sql = '''select * from goods where id=%s''' % id
    # 去数据库查询是否有相应的ID的数据, 如果有则修改,没有提示数据不存在
    cs.execute(sql)
    data = cs.fetchall()

    # 如果数据不存在
    if not data:
        return "data not txt"
    # 数据存在
    else:
        # 修改sql语句
        sql = '''update goods set name=cccc where id=%s''' % id
        # 执行sql语句
        cs.execute(sql)
        # 提交数据
        conn.commit()
        # 关闭游标
        cs.close()
        # 关闭数据库
        conn.close()
        # 提示修改成功信息
        return "success"



# 定义删除函数
@route(r"/delete/(\d*).html")
def delete(fileName, url):
    # 获取url中的数字
    ret = re.match(url, fileName)
    id = ret.group(1)
    # 连接数据库
    conn = pymysql.connect(host='172.16.238.130', port=3306, user='root',password='123456',database='my_mysql',charset='utf8')
    # 获取数据库游标
    cs = conn.cursor()

    #定义查找的sql语句
    sql = '''select * from goods where id=%s''' % id
    # 去数据库查询是否有相应的ID的数据, 如果有则删除,没有提示数据不存在
    cs.execute(sql)
    data = cs.fetchall()

    # 如果数据不存在
    if not data:
        return "data not txt"
    # 数据存在
    else:
        # 修改sql语句
        sql = '''delete from goods where id=%s''' % id
        # 执行sql语句
        cs.execute(sql)
        # 提交数据
        conn.commit()
        # 关闭游标
        cs.close()
        # 关闭数据库
        conn.close()
        # 提示修改成功信息
        return "success"



def app(requestDict, setResponse):
    # 定义状态码
    status = 200
    # 定义响应头
    responseHeader = [('Content-Type', 'text/html')]
    # 设置返回的响应头
    setResponse(status, responseHeader)

    # 获取客户端请求的路径
    pathName = requestDict["pathName"]

    # 根据客户端的请求,返回相应的页面
    try:
        # 遍历路由表,将url键和func函数值取出,做路径对比
        for url, callFunc in gUrlRoute.items():

            # 用取出的url正则表达式,匹配用户请求的路径
            ret = re.match(url, pathName)

            # 如果上面的正则获取到了结果,说明路径匹配成功
            if ret:
                # 如果匹配成功,返回函数的调用结果,也就是responseBody
                return callFunc(pathName, url)

        # 如果遍历完列表还没结果,说明路径请求错误
        else:
            return "没有访问的页面--->%s" % pathName

    except Exception as ret:
        # 没有页面返回的数据
        return str(requestDict) + '%s--->%s\n' % (ret, time.ctime())
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值