tornado热加载框架

收藏的一个tornado热加载框架
程序代码 程序代码

# coding:utf-8
#mvc框架总入口
import sys
import os
import time
import re
import tornado.gen
import tornado.web
import traceback
import mvcroot
import mvcroot.conf
import ujson as json

if(sys.version[0:2]=="2."):
    pass
else:
    from importlib import reload

pymodule_cache_dict={}  #用来缓存加载到内存的控制器类
class MVCMainHandler(tornado.web.RequestHandler):
    @tornado.gen.coroutine
    def httprequest_handler(self,requestpath):
        requestpath=requestpath.strip()
        requestpath.replace("//","/")
        if(requestpath[-1:]=="/"):
            requestpath=requestpath[:-1]
        #==============================检查静态资源文件Begin====================================
        extsz=os.path.splitext(requestpath)
        extname=extsz[1].lower()
        if(extname!=""): #如果请求的为静态资源
            if(extname in [".txt",".css",".jpg",".gif",".png",".doc",".docx",".xls",".xlsx",""]):
                if(extname in mvcroot.conf.mimetype):
                    self.set_header("Content-Type",mvcroot.conf.mimetype.get(extname,""))
                    #print(mvcroot.conf.mimetype.get(extname,""))
                yield self.static_resource_handler(requestpath,extname)
                return
        #==============================检查静态资源文件End====================================
        #==============================检测路由表中的所有url是否匹配,如果有匹配的,执行匹配的路由指向的类的page_load函数Begin==================
        isfindinroutemap=False  #在路由表中是否找到匹配的
        routerallclassname="" #匹配的路由中指向的类的完整名称
        routerclassname=""    #匹配的路由中指向的类的名称
        routermodulename=""   #匹配的路由中指向的类所在的模块名称(不包含这个文件里面的某个class类),用来__import__加载用
        isurlcontainsargs=False
        for myroutetuple in mvcroot.conf.routemap:
            url = requestpath     #这是url源文本
            p1 = myroutetuple[0]  #这是我们写的正则表达式
            pattern1 = re.compile(p1)#同样是编译
            matcher1 = re.findall(pattern1,url)#同样是查询
            if(len(matcher1)>0):
                if(p1.find("(")>-1):
                    isurlcontainsargs=True
                isfindinroutemap=True
                routerallclassname=str(myroutetuple[1])[8:-2]
                rfindindex=routerallclassname.rfind(".") #右边第一个.出现的位置
                routermodulename=routerallclassname[0:rfindindex]
                routerclassname=routerallclassname[rfindindex+1:]
                print("routerclassname:{0},routermodulename:{1}".format(routerclassname,routermodulename))
                page_args=matcher1[0]
                if(type(page_args)!=tuple):
                    page_args=[page_args]
                print("page_args:{0}".format(page_args))
                break
        if(isfindinroutemap==True): #如果在路由表匹配到符合的url,则执行路由处理函数
            mypageclass=__import__(routermodulename,fromlist=True)
            #print("mypageclass:{0}".format(mypageclass))
            if(mvcroot.conf.debug):
                reload(mypageclass)
            mypage= getattr(mypageclass,routerclassname)()
            mypage.request=self.request
            mypage.tornadowebinstance=self
            errmsg=""
            try:
                yield mypage.prepare()
            except Exception as ex:
                traceback.print_exc()
                mypage.isend=True
                self.write(traceback.format_exc().replace("\n","<br>"))
            if(mypage.isend==True):  #如果控制器确定要终止执行,则到这里就停止
                return
            try:
                if(isurlcontainsargs):
                    yield mypage.page_load(*page_args)
                else:
                    yield mypage.page_load()
            except Exception as ex:
                traceback.print_exc()
                self.write(traceback.format_exc().replace("\n","<br>"))
            return
        #=============================================路由处理结束================================
        #======================================检查请求的html文件Begin=================================
        #========================如果路由没有检测到html页面的路由,则检查真正的静态文件 Begin======================
        if(extname in [".htm",".html"]):
            self.set_header("Content-Type","text/html")
            yield self.static_resource_handler(requestpath,extname)
            return
        #===============================检查请求的html文件End=================

        #=============================按照url路径寻找并加载控制器Begin===========================
        #print("requestpath:"+requestpath)
        patharray=requestpath.split("/")
        patharraylen=len(patharray)
        #print(patharray)
        controllerandmethodname=""
        controllername=""
        methodname=""
        if(patharraylen>1):
            modulepre=requestpath[0:requestpath.rfind("/")].replace("/",".")
            controllerandmethodname=patharray[patharraylen-1]
        else:
            modulepre=""
            controllerandmethodname=patharray[0]
        if(controllerandmethodname.find("!")>-1):
            sz=controllerandmethodname.split("!")
            controllername=sz[0]
            methodname=sz[1]
        else:
            controllername=controllerandmethodname
        #print("controllername:{0},methodname:{1},modulepre:{2}".format(controllername,methodname,modulepre))
        if(controllername==""):
            controllername="index"
            #print("url中的控制器为空,将控制器名字设置为index")
            # self.write("必须提供控制器名称")
            # return
        if(controllername=="mvcrootdoor" or controllername=="conf"):
            self.write("you can't use this controller name")
            return
        pymoduleload="" #需要调用__import__加载的类名
        if(modulepre!=""):
            pymoduleload="mvcroot."+modulepre+"."+controllername
        else:
            pymoduleload="mvcroot."+controllername
        #print("pymoduleload:"+pymoduleload)
        try:
            # 加载性能测试,80万次每秒的加载速度,如果是开发模式热更新的话,4000次每秒
            # t1=time.time()
            # for i in range(0,1000):
            #     mypageclass=__import__(pymoduleload,fromlist=True)
            #     reload(mypageclass)
            # t2=time.time()
            # print(t2-t1)
            if(pymoduleload not in pymodule_cache_dict):
                mypageclass=__import__(pymoduleload,fromlist=True)
                pymodule_cache_dict[pymoduleload]=mypageclass
            if(mvcroot.conf.debug==True):
                mypageclass=__import__(pymoduleload,fromlist=True)
                reload(mypageclass)
                pymodule_cache_dict[pymoduleload]=mypageclass
                #print("isdebug:{0},reload controller".format(mvcroot.conf.debug))
            else:
                #print("isdebug:{0},load controller from cache".format(mvcroot.conf.debug))
                mypageclass=pymodule_cache_dict[pymoduleload]
                pass
        except Exception as ex:
            self.write(traceback.format_exc().replace("\n","<br>"))
            return
        #self.redirect()

        #print(mypageclass)
        #print(dir(self.request))
        # print("arguments:{0}".format(self.request.arguments))
        # print("query_arguments:{0}".format(self.request.query_arguments))
        # print("body:{0}".format(self.request.body))
        # print("body_arguments:{0}".format(self.request.body_arguments))
        mypage=mypageclass.page()
        mypage.request=self.request
        mypage.tornadowebinstance=self
        errmsg=""
        try:
            yield mypage.prepare()
        except Exception as ex:
            errmsg=traceback.format_exc()
            traceback.print_exc()
        if(mypage.isend==True):  #如果控制器确定要终止执行,则到这里就停止
            return
        if(methodname==""):
            try:
                r=yield mypage.page_load()
            except Exception as ex:
                errmsg=traceback.format_exc()
                traceback.print_exc()
        else:
            try:
                methodnamerun=getattr(mypage,methodname)
                r=yield methodnamerun()
            except Exception as ex:
                errmsg=traceback.format_exc()
                traceback.print_exc()
        if(errmsg!=""):
            print(errmsg)
            self.write(errmsg.replace("\n","<br>"))
            return
        #print("执行结果:"+str(r))
        rtype=type(r)
        #print("r type:{0}".format(rtype.__name__))
        if(rtype==mvcroot.ViewReturn):
            viewname=r.Get()
            print("viewname:"+viewname)
            realviewfilepath=""
        elif(rtype==mvcroot.TextReturn):
            txt=r.Get()
            self.write(txt)
        elif(rtype==mvcroot.JsonReturn):
            jsonresult=r.Get()
            if(jsonresult!=None):
                sendtext=json.dumps(jsonresult)
                self.write(sendtext)
        elif(rtype==str):
            self.write(r)
        elif(rtype.__name__ in ["int","long","float","bool"]):
            self.write(str(r))
        elif(rtype.__name__=="unicode"):
            self.write(r.encode("utf8"))
        elif(rtype==list or rtype==dict):
            self.write(json.dumps(r))
        elif(r==None):
            #print("返回值为空值")
            pass
        else:
            if(hasattr(r,"__dict__")):
                self.write(json.dumps(r.__dict__))
        mypage.request=None
        mypage.tornadowebinstance=None
        #r=self.render_string("page1.html")
        pass

    @tornado.gen.coroutine
    def static_resource_handler(self,requestpath,extname):
        realfilepath=mvcroot.rootpath+"/"+requestpath
        #print("realfilepath:"+realfilepath)
        #self.write(realfilepath)
        if(os.path.exists(realfilepath)):
            f=open(realfilepath,"rb")
            filecontent=f.read()
            f.close()
            self.write(filecontent)
        else:
            self.write("Static File:["+realfilepath+"] Not Exists")
        pass

    @tornado.gen.coroutine
    def routeHandler(self):

        pass
    @tornado.gen.coroutine
    def get(self,requestpath):
        yield self.httprequest_handler(requestpath)

        pass
    @tornado.gen.coroutine
    def post(self,requestpath):
        yield self.httprequest_handler(requestpath)
        pass
    @tornado.gen.coroutine
    def put(self,requestpath):
        yield self.httprequest_handler(requestpath)

        pass
    @tornado.gen.coroutine
    def delete(self, requestpath):
        yield self.httprequest_handler(requestpath)
        pass





除非申明,文章均为一号门原创,转载请注明本文地址,谢谢!
文章来自: 本站原创
引用通告: 查看所有引用 | 我要引用此文章
Tags: tornado
相关日志:
评论: 0 | 引用: 0 | 查看次数: -
发表评论
昵 称:
密 码: 游客发言不需要密码.
内 容:
验证码: 验证码
选 项:
虽然发表评论不用注册,但是为了保护您的发言权,建议您注册帐号.