放一个半年前写的Python静态检查编译器

使用了wxPython、pychecker编写的python静态编译器,用于在编译器查找py脚本的错误。
开放源码,与各位pythoner共享之!

from wxPython.wx import *
import time
import sys
import pychecker.checker2
import py_compile
from compileall import compile_dir


ID_SET_WORK_DIRECTORY   = wxNewId()
ID_CLEAR                = wxNewId()
ID_EXIT                 = wxNewId()

ID_COMPILE_FILES        = wxNewId()
ID_COMPILE_ONE          = wxNewId()
ID_COMPILE_ALL          = wxNewId()
ID_COMPILE_DIRECTORY    = wxNewId()

ID_BUILD_FILES          = wxNewId()
ID_BUILD_ONE            = wxNewId()
ID_BUILD_ALL            = wxNewId()
ID_BUILD_DIRECTORY      = wxNewId()

ID_ABOUT                = wxNewId()

ID_LIST                 = wxNewId()
ID_REPORT               = wxNewId()
 
class MyFrame(wxFrame):
    def __init__(self, parent, ID, title):
        wxFrame.__init__(self, parent, ID, title, wxDefaultPosition, wxSize(640, 480))

        self.icon = wxIcon('cd2py.ico', wxBITMAP_TYPE_ICO)
        self.SetIcon(self.icon)

        self.statusbar = self.CreateStatusBar(2)
        self.statusbar.SetStatusWidths([-1, 130])
        self.statusbar.SetStatusText("Thanks for use cd2Py compiler...", 0)
        self.statusbar.SetStatusText(self.Time(), 1)
        self.CentreOnScreen()

        self.timer = wxPyTimer(self.Notify)
        self.timer.Start(1000)
        self.Notify()
       
        fmenu = wxMenu()
        fmenu.Append(ID_SET_WORK_DIRECTORY, "&Work Directory",  "Choose Tuntown2 directory")
        fmenu.Append(ID_CLEAR,              "&Clear",           "Clear the compile history")
        fmenu.AppendSeparator()
        fmenu.Append(ID_EXIT,               "E&xit",            "Terminate the program")

        cmenu = wxMenu()
        cmenu.Append(ID_COMPILE_ONE,        "Compile &one",     "Compile one selected file")
        cmenu.Append(ID_COMPILE_ALL,        "Compile &all",     "Compile all selected file(s)")
        cmenu.AppendSeparator()
        cmenu.Append(ID_COMPILE_FILES,      "&Files",           "Compile selected file(s)")
        cmenu.Append(ID_COMPILE_DIRECTORY,  "&Directory",       "Compile selected directory")

        bmenu = wxMenu()
        bmenu.Append(ID_BUILD_ONE,          "Build &one",       "Build one selected file")
        bmenu.Append(ID_BUILD_ALL,          "Build &all",       "Build all selected file(s)")
        bmenu.AppendSeparator()
        bmenu.Append(ID_BUILD_FILES,        "&Files",           "Build selected file(s)")
        bmenu.Append(ID_COMPILE_DIRECTORY,  "&Directory",       "Build selected directory")

        hmenu = wxMenu()
        hmenu.Append(ID_ABOUT,              "&About",           "More information about this program")
       
        menuBar = wxMenuBar()
        menuBar.Append(fmenu,   "&Files");
        menuBar.Append(cmenu,   "&Compile");
        menuBar.Append(bmenu,   "&Build");
        menuBar.Append(hmenu,   "&Help");
       
        self.SetMenuBar(menuBar)

        EVT_MENU(self, ID_SET_WORK_DIRECTORY,   self.OnSetWorkDirectory)
        EVT_MENU(self, ID_CLEAR,                self.OnClearHistory)
        EVT_MENU(self, ID_EXIT,                 self.OnQuit)

        EVT_MENU(self, ID_COMPILE_FILES,        self.OnCompileFiles)
        EVT_MENU(self, ID_COMPILE_ONE,          self.OnCompileOne)
        EVT_MENU(self, ID_COMPILE_ALL,          self.OnCompileAll)
        EVT_MENU(self, ID_COMPILE_DIRECTORY,    self.OnCompileDirectory)

        EVT_MENU(self, ID_BUILD_FILES,          self.OnBuildFiles)
        EVT_MENU(self, ID_BUILD_ONE,            self.OnBuildOne)
        EVT_MENU(self, ID_BUILD_ALL,            self.OnBuildAll)
        EVT_MENU(self, ID_BUILD_DIRECTORY,      self.OnBuildDirectory)

        EVT_MENU(self, ID_ABOUT,                self.OnAbout)

        EVT_SIZE(self,                          self.OnResize)
        EVT_CLOSE(self,                         self.OnClose)

        sizeClient = self.GetClientSize()

        self.List = wxComboBox(self, ID_LIST, "", wxPoint(0, 0),
                                sizeClient, [""], wxCB_DROPDOWN | wxCB_READONLY)
        sizeList = self.List.GetClientSize()
        self.Report = wxTextCtrl(self, ID_REPORT, "", wxPoint(0, sizeList.height),
                                wxSize(sizeClient.width, sizeClient.height-sizeList.height),
                                wxTE_AUTO_URL |
                                wxHSCROLL |
                                wxTE_MULTILINE |
                                wxTE_READONLY)

        self.cfg = ["\n", "\n", "\n"]
        try:
            f = open("config.cfg", "r")
            try:
                self.cfg[0] = f.readline()
                self.cfg[1] = f.readline()
                self.cfg[2] = f.readline()
            except:
                pass
            f.close()
        except IOError:
            pass

        self.save_sys_path = sys.path[:]
        curdir = self.cfg[0]
        curdir = curdir[0:len(curdir)-1]
        self.AddPath(curdir)


    def OnSetWorkDirectory(self, event):
        dlg = wxDirDialog(self, "Choose Tuntown Directory", self.cfg[0])
        if dlg.ShowModal() == wxID_OK:
            self.AddPath(dlg.GetPath())
            self.cfg[0] = dlg.GetPath()

        dlg.Destroy()


    def OnClearHistory(self, event):
        self.Report.Clear()


    def OnCompileFiles(self, event):
        dlg = wxFileDialog(self, "Open File(s) for compile", self.cfg[1],
                            "", "python script(*.py)|*.py", wxOPEN | wxMULTIPLE)
        if dlg.ShowModal() == wxID_OK:
            self.paths = dlg.GetPaths()
            self.List.Clear()
            self.Report.AppendText(self.CompileInfoHead("File(s)"))
            for path in self.paths:
                print "Compiling " + path + " ..."
                self.PyCheck(path)
                self.List.Append(path)
            self.List.Select(0)
            self.Report.AppendText("=-- Compile Finished.\n\n")
            self.cfg[1] = dlg.GetDirectory()

        dlg.Destroy()


    def OnCompileOne(self, event):
        if self.paths.count != 0:
            self.Report.AppendText(self.CompileInfoHead("File"))
            path = self.paths[self.List.GetSelection()]
            print "Compiling " + path + " ..."
            self.PyCheck(path)
            self.Report.AppendText("=-- Compile Finished.\n\n")


    def OnCompileAll(self, event):
        if self.paths.count != 0:
            self.Report.AppendText(self.CompileInfoHead("File(s)"))
            for path in self.paths:
                print "Compiling " + path + " ..."
                self.PyCheck(path)
            self.Report.AppendText("=-- Compile Finished.\n\n")


    def OnCompileDirectory(self, event):
        dlg = wxDirDialog(self, "Select a directory for compile", self.cfg[2])
        if dlg.ShowModal() == wxID_OK:
            path = dlg.GetPath()
            self.Report.AppendText(self.CompileInfoHead("Directory:", path))
            sys.path.append(path)
            self.PyCheck(path + '\\*.py')
            sys.path.pop()
            self.Report.AppendText("=-- Compile Finished.\n\n")
            self.cfg[2] = dlg.GetPath()
               
        dlg.Destroy()


    def OnBuildFiles(self, event):
        dlg = wxFileDialog(self, "Open File(s) for build", self.cfg[1],
                            "", "python script(*.py)|*.py", wxOPEN | wxMULTIPLE)
        if dlg.ShowModal() == wxID_OK:
            self.paths = dlg.GetPaths()
            self.List.Clear()
            self.Report.AppendText(self.CompileInfoHead("File(s)"))
            for path in self.paths:
                print "Building " + path + " ..."
                py_compile.compile(path, None, None)
                self.List.Append(path)
            self.List.Select(0)
            self.Report.AppendText("=-- Build Finished.\n\n")
            self.cfg[1] = dlg.GetDirectory()

        dlg.Destroy()


    def OnBuildOne(self, event):
        if self.paths.count != 0:
            self.Report.AppendText(self.CompileInfoHead("File"))
            path = self.paths[self.List.GetSelection()]
            print "Building " + path + " ..."
            try:
                py_compile.compile(path, None, None)
            except py_compile.PyCompileError, ex:
                print ex
            self.Report.AppendText("=-- Build Finished.\n\n")


    def OnBuildAll(self, event):
        if self.paths.count != 0:
            self.Report.AppendText(self.CompileInfoHead("File(s)"))
            for path in self.paths:
                print "Building " + path + " ..."
                try:
                    py_compile.compile(path, None, None)
                except py_compile.PyCompileError, ex:
                    print ex
            self.Report.AppendText("=-- Build Finished.\n\n")


    def OnBuildDirectory(self, event):
        dlg = wxDirDialog(self, "Select a directory for build", self.cfg[2])
        if dlg.ShowModal() == wxID_OK:
            path = dlg.GetPath()
            self.Report.AppendText(self.CompileInfoHead("Directory:", path))
            compile_dir(path, 10, None, 1, None)
            self.Report.AppendText("=-- Build Finished.\n\n")
            self.cfg[2] = dlg.GetPath()
               
        dlg.Destroy()
   

    def OnAbout(self, event):
        dlg = wxMessageDialog(self, "Present by Dracula 2005\n"
                                    "Build 2005.05.05\n", "About",
                                    wxOK | wxICON_INFORMATION)
        dlg.ShowModal()
        dlg.Destroy()


    def OnResize(self, event):
        sizeClient = self.GetClientSize()
        self.List.SetSize(sizeClient)
        sizeList = self.List.GetClientSize()
        self.Report.SetSize(wxSize(sizeClient.width, sizeClient.height-sizeList.height))


    def OnClose(self, event):
        try:
            f = open("config.cfg", "w")
            f.write(self.cfg[0])
            if self.cfg[0][-1] != '\n':
                f.write("\n")
            f.write(self.cfg[1])
            if self.cfg[1][-1] != '\n':
                f.write("\n")
            f.write(self.cfg[2])
            f.close()
        except IOError:
            pass

        sys.path = self.save_sys_path[:]
       
        self.timer.Stop()
        del self.timer
        del self.icon
        self.Destroy()


    def OnQuit(self, event):
        self.Close(true)


    def PyCheck(self, argv):
        argv2 = ['pychecker']
        argv2.append(argv)
        pychecker.checker2.main(argv2)
        #reload(pychecker.checker2)


    def AddPath(self, path):
        curdir = path
        system_dir = curdir + '\\data\\script'
        system_core_dir = curdir + '\\data\\script\\core'
        subsystem_dir = curdir + '\\data\\subsystem'
        subsystem_trashbin_dir = curdir + '\\data\\subsystem\\trashbin'

        sys.path = self.save_sys_path[:]
        sys.path.append(curdir)
        sys.path.append(system_dir)
        sys.path.append(system_core_dir)
        sys.path.append(subsystem_dir)
        sys.path.append(subsystem_trashbin_dir)


    def CompileInfoHead(self, str1, str2=""):
        return "=-- %s %s Compile %s %s ...\n" % (self.Date(), self.Time(), str1, str2)
   

    def Error(self, error):
        self.Report.AppendText(error)


    def Output(self, info):
        self.Report.AppendText(info)


    def Date(self):
        t = time.localtime(time.time())
        strDate = time.strftime("%Y.%m.%d", t)
        return strDate


    def Time(self):
        t = time.localtime(time.time())
        strTime = time.strftime("%I:%M:%S", t)
        return strTime


    def Notify(self):
        self.statusbar.SetStatusText(self.Date() + "   " + self.Time(), 1)


class MyApp(wxApp):
    def OnInit(self):
        self.frame = MyFrame(NULL, -1, "cd2Py Compiler")
        self.frame.Show(true)
        self.SetTopWindow(self.frame)
        return true

cd2Py = MyApp(0)


import sys

class errCatcher:
    def __init__(self):
        pass
       
    def write(self, stuff):
        cd2Py.frame.Error(stuff)


class outCatcher:
    def __init__(self):
        pass
       
    def write(self, stuff):
        cd2Py.frame.Output(stuff)

sys.stderr = errCatcher()
sys.stdout = outCatcher()

cd2Py.MainLoop()

posted @ 2005-11-24 10:03  千里马肝  阅读(1228)  评论(0编辑  收藏  举报