class PyInstallerPanel(BaseBuilderPanel): def __init__(self, parent, projectName, creationDate): """ Default class constructor. **Parameters:** * projectName: the name of the project we are working on * creationDate: the date and time the project was created """ BaseBuilderPanel.__init__(self, parent, projectName, creationDate, name="PyInstaller") # I need this flag otherwise all the widgets start sending changed # events when I first populate the full panel self.created = False # A whole bunch of static box sizers self.pathSizer_staticbox = wx.StaticBox(self, -1, _("Path Extensions")) self.hookSizer_staticbox = wx.StaticBox(self, -1, _("Hooks Extensions")) self.commonSizer_staticbox = wx.StaticBox(self, -1, _("Common Options")) self.includesSizer_staticbox = wx.StaticBox(self, -1, _("Includes")) self.excludesSizer_staticbox = wx.StaticBox(self, -1, _("Excludes")) self.packagesSizer_staticbox = wx.StaticBox(self, -1, _("Packages (PKG)")) self.dllExcludesSizer_staticbox = wx.StaticBox(self, -1, _("DLL/Binary Excludes")) self.dllIncludesSizer_staticbox = wx.StaticBox(self, -1, _("DLL/Binary Includes")) self.datafileSizer_staticBox = wx.StaticBox(self, -1, _("Data Files")) self.otherOptionsSizer_staticbox = wx.StaticBox(self, -1, _("Other Options")) self.scriptSizer_staticbox = wx.StaticBox(self, -1, _("Scripts")) # A simple label that holds information about the project transdict = dict(projectName=projectName, creationDate=creationDate) self.label = wx.StaticText(self, -1, _("PyInstaller options for: %(projectName)s (Created: %(creationDate)s)")%transdict) # This list holds all the script files added by the user self.scriptsList = BaseListCtrl(self, columnNames=[_("Python Scripts")], name="scripts") # A list for the extension of the search path self.pathexList = BaseListCtrl(self, columnNames=[_("Paths")], name="pathex") # A list for the extension of the hooks package self.hookList = BaseListCtrl(self, columnNames=[_("Paths")], name="hookspath") # Do we want a debug build? self.debugCheck = wx.CheckBox(self, -1, _("Debug"), name="debug") # Radiobutton for the one-file build self.oneFileRadio = wx.RadioButton(self, -1, _("One File"), style=wx.RB_GROUP, name="onefile") # Name of the executable self.exeTextCtrl = wx.TextCtrl(self, -1, "", name="exename") # Whether it is a console or a windowed application self.consoleCheck = wx.CheckBox(self, -1, _("Console Application"), name="console") # Radiobutton for the one-dir build self.oneDirRadio = wx.RadioButton(self, -1, _("One Directory"), name="onedir") # A file picker for the executable icon self.iconPicker = wx.FilePickerCtrl(self, style=wx.FLP_USE_TEXTCTRL, name="icon") # Strip or no strip? self.stripCheck = wx.CheckBox(self, -1, _("Strip Executable"), name="strip") # Do we want to include encodings or not? self.asciiCheck = wx.CheckBox(self, -1, "Ascii", name="ascii") # Name of the distribution directory self.distTextCtrl = wx.TextCtrl(self, -1, "", name="dist_dir") # Compression level self.compressCombo = MultiComboBox(self, [str(i) for i in xrange(10)], wx.CB_DROPDOWN|wx.CB_READONLY, self.GetName(), "level") # Use UPX compression? self.upxCheck = wx.CheckBox(self, -1, _("UPX Compression"), name="upx") # Include Tk in the distribution? self.includeTkCheck = wx.CheckBox(self, -1, _("Include Tk"), name="includetk") # A file picker for the version file self.versionPicker = wx.FilePickerCtrl(self, style=wx.FLP_USE_TEXTCTRL, name="version") # A list control for the "includes" option, a comma separated list of # modules to include self.includeList = BaseListCtrl(self, columnNames=[_("Python Modules"), _("Path")], name="includes") # A list control for the "excludes" option, a comma separated list of # modules to exclude self.excludeList = BaseListCtrl(self, columnNames=[_("Python Modules")], name="excludes") # A list control for the "packages" option, a comma separated list of # packages to include self.packagesList = BaseListCtrl(self, columnNames=[_("Python Packages"), _("Path")], name="packages") # A couple of listctrls to hold DLL/binary includes and excludes self.dllExcludeList = BaseListCtrl(self, columnNames=[_("File Name"), _("Path")], name="dll_excludes") self.dllIncludeList = BaseListCtrl(self, columnNames=[_("File Name"), _("Path")], name="dll_includes") # A list control for the "data_files" option. "data_files" should contain # a sequence of (target-dir, files) tuples, where files is a sequence of # files to be copied self.datafileList = BaseListCtrl(self, columnNames=[_("File Name"), _("Path")], name="data_files") # Less used options self.verboseCheck = wx.CheckBox(self, -1, _("Verbose Import"), name="option1") self.warningCheck = wx.CheckBox(self, -1, _("Warning Option"), name="option2") self.forceexecCheck = wx.CheckBox(self, -1, _("Force Execpv"), name="option3") self.unbufferedCheck = wx.CheckBox(self, -1, _("Unbuffered STDIO"), name="option4") self.useSiteCheck = wx.CheckBox(self, -1, _("Use Site.py"), name="option5") self.optimizeCheck = wx.CheckBox(self, -1, _("Build Optimized"), name="option6") self.addManifest = wx.CheckBox(self, -1, _("Create Manifest File (MSW)"), name="create_manifest_file") # Hold a reference to all the list controls, to speed up things later self.listCtrls = [self.includeList, self.packagesList, self.excludeList, self.dllExcludeList, self.dllIncludeList, self.datafileList, self.scriptsList, self.pathexList, self.hookList] # Hold a reference to the most obscure PyInstaller options self.optionsCheckBoxes = [self.verboseCheck, self.warningCheck, self.forceexecCheck, self.unbufferedCheck, self.useSiteCheck, self.optimizeCheck] # Do the hard work... quite a few to layout :-D self.LayoutItems() self.SetProperties() self.BindEvents() # ========================== # # Methods called in __init__ # # ========================== # def SetProperties(self): """ Set fonts and other default properties. """ # Set a bold font for the static texts font = self.GetFont() font.SetWeight(wx.FONTWEIGHT_BOLD) for child in self.GetChildren(): if isinstance(child, wx.StaticText) or isinstance(child, wx.CheckBox) or \ isinstance(child, wx.RadioButton): child.SetFont(font) def LayoutItems(self): mainSizer = wx.BoxSizer(wx.VERTICAL) otherOptionsSizer = wx.StaticBoxSizer(self.otherOptionsSizer_staticbox, wx.HORIZONTAL) otherGridSizer = wx.FlexGridSizer(2, 4, 5, 5) dataFileSizer = wx.StaticBoxSizer(self.datafileSizer_staticBox, wx.HORIZONTAL) centerSizer2 = wx.BoxSizer(wx.HORIZONTAL) dllIncludesSizer = wx.StaticBoxSizer(self.dllIncludesSizer_staticbox, wx.HORIZONTAL) dllExcludesSizer = wx.StaticBoxSizer(self.dllExcludesSizer_staticbox, wx.HORIZONTAL) packagesSizer = wx.StaticBoxSizer(self.packagesSizer_staticbox, wx.HORIZONTAL) centerSizer1 = wx.BoxSizer(wx.HORIZONTAL) excludesSizer = wx.StaticBoxSizer(self.excludesSizer_staticbox, wx.HORIZONTAL) includesSizer = wx.StaticBoxSizer(self.includesSizer_staticbox, wx.HORIZONTAL) commonSizer = wx.StaticBoxSizer(self.commonSizer_staticbox, wx.HORIZONTAL) commonGridSizer = wx.FlexGridSizer(5, 5, 0, 5) topSizer = wx.BoxSizer(wx.HORIZONTAL) hookSizer = wx.StaticBoxSizer(self.hookSizer_staticbox, wx.HORIZONTAL) pathSizer = wx.StaticBoxSizer(self.pathSizer_staticbox, wx.HORIZONTAL) scriptSizer = wx.StaticBoxSizer(self.scriptSizer_staticbox, wx.HORIZONTAL) mainSizer.Add(self.label, 0, wx.ALL, 10) flag = wx.LEFT|wx.TOP|wx.BOTTOM|wx.EXPAND scriptSizer.Add(self.scriptsList, 1, flag, 5) scriptSizer.Add(self.scriptsList.MakeButtons(), 0, wx.EXPAND|wx.LEFT, 3) topSizer.Add(scriptSizer, 2, wx.ALL|wx.EXPAND, 5) pathSizer.Add(self.pathexList, 1, flag, 5) pathSizer.Add(self.pathexList.MakeButtons(), 0, wx.EXPAND|wx.LEFT, 3) topSizer.Add(pathSizer, 1, wx.RIGHT|wx.TOP|wx.BOTTOM|wx.EXPAND, 5) hookSizer.Add(self.hookList, 1, flag, 5) hookSizer.Add(self.hookList.MakeButtons(), 0, wx.EXPAND|wx.LEFT, 3) topSizer.Add(hookSizer, 1, wx.RIGHT|wx.TOP|wx.BOTTOM|wx.EXPAND, 5) mainSizer.Add(topSizer, 0, wx.EXPAND, 0) exename = wx.StaticText(self, -1, _("Executable Name")) commonGridSizer.Add(exename, 0, wx.LEFT|wx.ALIGN_CENTER_VERTICAL, 5) compress = wx.StaticText(self, -1, _("Compression Level")) commonGridSizer.Add(compress, 0, wx.LEFT|wx.ALIGN_CENTER_VERTICAL, 10) commonGridSizer.Add(self.debugCheck, 0, wx.LEFT|wx.ALIGN_BOTTOM, 10) commonGridSizer.Add(self.oneFileRadio, 0, wx.LEFT|wx.RIGHT|wx.ALIGN_BOTTOM, 10) icon = wx.StaticText(self, -1, _("Icon File")) commonGridSizer.Add(icon, 0, wx.ALIGN_CENTER_VERTICAL, 0) commonGridSizer.Add(self.exeTextCtrl, 0, wx.LEFT|wx.EXPAND|wx.ALIGN_CENTER_VERTICAL, 5) commonGridSizer.Add(self.compressCombo, 1, wx.EXPAND|wx.LEFT|wx.ALIGN_BOTTOM, 10) commonGridSizer.Add(self.consoleCheck, 0, wx.LEFT|wx.ALIGN_BOTTOM, 10) commonGridSizer.Add(self.oneDirRadio, 0, wx.LEFT|wx.RIGHT|wx.ALIGN_BOTTOM, 10) commonGridSizer.Add(self.iconPicker, 0, wx.RIGHT|wx.EXPAND|wx.ALIGN_CENTER_VERTICAL, 5) commonGridSizer.Add((0, 15), 0, 0, 0) commonGridSizer.Add((0, 15), 0, 0, 0) commonGridSizer.Add((0, 5), 0, 0, 0) commonGridSizer.Add((0, 15), 0, 0, 0) commonGridSizer.Add((0, 15), 0, 0, 0) distname = wx.StaticText(self, -1, _("Dist Directory Name")) commonGridSizer.Add(distname, 0, wx.LEFT|wx.ALIGN_CENTER_VERTICAL, 5) commonGridSizer.Add((0, 5), 1, 0, 0) commonGridSizer.Add(self.stripCheck, 0, wx.LEFT|wx.ALIGN_BOTTOM, 10) commonGridSizer.Add(self.asciiCheck, 0, wx.LEFT|wx.RIGHT|wx.ALIGN_BOTTOM, 10) version = wx.StaticText(self, -1, _("Version File")) commonGridSizer.Add(version, 0, wx.RIGHT|wx.ALIGN_CENTER_VERTICAL, 5) commonGridSizer.Add(self.distTextCtrl, 0, wx.LEFT|wx.EXPAND|wx.ALIGN_CENTER_VERTICAL, 5) commonGridSizer.Add((0, 5), 1, 0, 0) commonGridSizer.Add(self.upxCheck, 0, wx.LEFT|wx.ALIGN_BOTTOM, 10) commonGridSizer.Add(self.includeTkCheck, 0, wx.LEFT|wx.RIGHT|wx.ALIGN_BOTTOM, 10) commonGridSizer.Add(self.versionPicker, 0, wx.RIGHT|wx.EXPAND|wx.ALIGN_CENTER_VERTICAL, 5) commonGridSizer.AddGrowableCol(0) commonGridSizer.AddGrowableCol(4) commonSizer.Add(commonGridSizer, 1, wx.EXPAND|wx.TOP|wx.BOTTOM, 5) mainSizer.Add(commonSizer, 0, wx.ALL|wx.EXPAND, 5) # Add the list controls includesSizer.Add(self.includeList, 1, flag, 5) includesSizer.Add(self.includeList.MakeButtons(), 0, wx.EXPAND|wx.LEFT, 3) centerSizer1.Add(includesSizer, 1, wx.ALL|wx.EXPAND, 5) excludesSizer.Add(self.excludeList, 1, flag, 5) excludesSizer.Add(self.excludeList.MakeButtons(), 0, wx.EXPAND|wx.LEFT, 3) centerSizer1.Add(excludesSizer, 1, wx.RIGHT|wx.TOP|wx.BOTTOM|wx.EXPAND, 5) mainSizer.Add(centerSizer1, 0, wx.EXPAND, 0) packagesSizer.Add(self.packagesList, 1, flag, 5) packagesSizer.Add(self.packagesList.MakeButtons(), 0, wx.EXPAND|wx.LEFT, 3) centerSizer2.Add(packagesSizer, 1, wx.ALL|wx.EXPAND, 5) dllExcludesSizer.Add(self.dllExcludeList, 1, flag, 5) dllExcludesSizer.Add(self.dllExcludeList.MakeButtons(), 0, wx.EXPAND|wx.LEFT, 3) centerSizer2.Add(dllExcludesSizer, 1, wx.RIGHT|wx.TOP|wx.BOTTOM|wx.EXPAND, 5) dllIncludesSizer.Add(self.dllIncludeList, 1, flag, 5) dllIncludesSizer.Add(self.dllIncludeList.MakeButtons(), 0, wx.EXPAND|wx.LEFT, 3) centerSizer2.Add(dllIncludesSizer, 1, wx.RIGHT|wx.TOP|wx.BOTTOM|wx.EXPAND, 5) mainSizer.Add(centerSizer2, 0, wx.EXPAND, 0) dataFileSizer.Add(self.datafileList, 1, flag, 5) dataFileSizer.Add(self.datafileList.MakeButtons(), 0, wx.EXPAND|wx.LEFT, 3) mainSizer.Add(dataFileSizer, 0, wx.ALL|wx.EXPAND, 5) otherGridSizer.Add(self.verboseCheck, 0, wx.LEFT|wx.TOP|wx.ALIGN_CENTER_VERTICAL, 5) otherGridSizer.Add(self.warningCheck, 0, wx.TOP|wx.ALIGN_CENTER_VERTICAL, 5) otherGridSizer.Add(self.forceexecCheck, 0, wx.TOP|wx.ALIGN_CENTER_VERTICAL, 5) otherGridSizer.Add(self.unbufferedCheck, 0, wx.LEFT|wx.BOTTOM|wx.ALIGN_CENTER_VERTICAL, 5) otherGridSizer.Add(self.useSiteCheck, 0, wx.LEFT|wx.BOTTOM|wx.ALIGN_CENTER_VERTICAL, 5) otherGridSizer.Add(self.optimizeCheck, 0, wx.BOTTOM|wx.ALIGN_CENTER_VERTICAL, 5) otherGridSizer.Add(self.addManifest, 0, wx.BOTTOM|wx.ALIGN_CENTER_VERTICAL, 5) otherGridSizer.AddGrowableCol(0) otherGridSizer.AddGrowableCol(1) otherGridSizer.AddGrowableCol(2) otherGridSizer.AddGrowableCol(3) otherOptionsSizer.Add(otherGridSizer, 1, wx.EXPAND, 0) mainSizer.Add(otherOptionsSizer, 1, wx.ALL|wx.EXPAND, 5) self.SetSizer(mainSizer) mainSizer.Fit(self) self.SetAutoLayout(True) self.SetSizer(mainSizer) self.SetupScrolling() self.label.SetFocus() def ValidateOptions(self): """ Validates the PyInstaller input options before compiling. """ # check if the script files exist if self.scriptsList.GetItemCount() == 0: msg = _("No Python scripts have been added.") self.MainFrame.RunError(2, msg, True) return False for indx in xrange(self.scriptsList.GetItemCount()): script = self.scriptsList.GetItem(indx, 1) if not os.path.isfile(script.GetText()): transdict = dict(scriptName=script.GetText()) msg = _("Python script:\n\n%(scriptName)s\n\nIs not a valid file.")%transdict self.MainFrame.RunError(2, msg, True) return False # check if the icon/version files are not empty and if they exist iconFile = self.iconPicker.GetPath() if iconFile and not os.path.isfile(iconFile): msg = _("Icon file is not a valid file.") self.MainFrame.RunError(2, msg, True) return False versionFile = self.versionPicker.GetPath() if versionFile and not os.path.isfile(versionFile): msg = _("Version file is not a valid file.") self.MainFrame.RunError(2, msg, True) return False # Everything is ok, let's go compiling... return True def PrepareForCompile(self): """ Retrieves all the data to prepare for compilation. """ if not self.ValidateOptions(): # No way, something went wrong with the options set by the user return None # Retrieve the project stored in the parent (LabelBook) properties project = self.GetParent().GetProject() # Send a message to out fancy bottom log window transdict = dict(projectName=project.GetName()) self.MainFrame.SendMessage(0, _('Generating "%(projectName)s" setup script...')%transdict) # Get the project configuration (all the options, basically) configuration = project.GetConfiguration(self.GetName()) # Get the custom code (if any) that the user added customCode = project.GetCustomCode(self.GetName()) # Get the post-compilation code (if any) that the user added postCompile = project.GetPostCompileCode(self.GetName()) for lists in self.listCtrls: # Last update for all the list controls lists.UpdateProject(False) # Build the target script file return self.BuildTargetClass(configuration, project, None, customCode, postCompile) def BuildTargetClass(self, configuration, project, manifestFile, customCode, postCompile): """ Builds the PyInstaller compilation script file, returning it as a string. """ # A couple of dictionaries to populate the setup string setupDict, importDict = {}, {} configuration = dict(configuration) pyFile = self.scriptsList.GetItem(0, 1).GetText() buildDir = os.path.split(pyFile)[0] includeTk = self.includeTkCheck.GetValue() oneDir = self.oneDirRadio.GetValue() ascii = self.asciiCheck.GetValue() normpath = os.path.normpath useRelPath = self.MainFrame.relativePaths scriptFile = pyFile # Loop over all the keys, values of the configuration dictionary for key, item in configuration.items(): if key.startswith("option"): continue if isinstance(self.FindWindowByName(key), wx.CheckBox): item = bool(int(item)) if key == "create_manifest_file": continue if type(item) == ListType and item: # Terrible hack to setup correctly the string to be included # in the setup file if key not in ["hookspath", "scripts", "excludes", "pathex"]: tmp = [] for data in item: data = data + (_pyInstallerTOC[key],) tmp.append(data) item = tmp elif key == "pathex": if buildDir not in item: item.append(buildDir) elif key == "scripts": continue item = setupString(key, item, True, useRelPath=useRelPath, mainScript=scriptFile) if key == "exename" and not item.strip() and not oneDir: item = os.path.splitext(os.path.split(pyFile)[1])[0] + ".exe" if key == "dist_dir" and not item.strip() and oneDir: item = normpath(os.path.split(pyFile)[0] + "/dist") if key in ["icon", "version"]: if not item.strip(): item = None else: if useRelPath: item = 'r"%s"'%(relpath(item, os.path.split(scriptFile)[0])) else: item = "r'%s'"%item setupDict[key] = item # Set up the obscure options otherOptions = [] for indx, checks in enumerate(self.optionsCheckBoxes): if checks.GetValue(): otherOptions.append(_pyInstallerOptions[indx]) setupDict["options"] = otherOptions # Depending on the various choices in the interface, PyInstaller # includes/excludes some Python source file located in # PyInstaller_Path/support/ pyInstallerPath = self.MainFrame.GetPyInstallerPath() if not pyInstallerPath or pyInstallerPath == "None": msg = _("PyInstaller path has not been set.\n\nPlease set the PyInstaller" \ "path using the menu Options ==> Set PyInstaller path.") self.MainFrame.RunError(2, msg) return items = configuration["scripts"][:] pyInstallerPath += "/support/" if setupDict["level"] != "0": # Include zlib as user wants compression items.append(normpath(pyInstallerPath + "_mountzlib.py").encode()) if includeTk: # That's a bit of a mess, but PyInstaller is not exactly user-friendly... if oneDir: items.append(normpath(pyInstallerPath + "useTK.py").encode()) else: items.extend([normpath(pyInstallerPath + "unpackTK.py").encode(), normpath(pyInstallerPath + "useTK.py").encode(), normpath(pyInstallerPath + "removeTK.py").encode()]) if not ascii: # Using unicode items.append(normpath(pyInstallerPath + "useUnicode.py").encode()) items.append(items[0]) items.pop(0) setupDict["scripts"] = setupString("scripts", items, True) # Add the custom code (if any) setupDict["customcode"] = (customCode and [customCode.strip()] or ["# No custom code added"])[0] # Add the post-compilation code (if any) setupDict["postcompilecode"] = (postCompile and [postCompile.strip()] or ["# No post-compilation code added"])[0] # Include the GUI2Exe version in the setup script importDict["gui2exever"] = self.MainFrame.GetVersion() # Populate the "import" section setupScript = _pyInstaller_imports % importDict if oneDir: target = _pyInstaller_target_onedir if includeTk: setupDict["TkPKG"] = "TkTree()," else: setupDict["TkPKG"] = "" else: target = _pyInstaller_target_onefile if includeTk: setupDict["TkPKG"] = "TkPKG()," else: setupDict["TkPKG"] = "" # Populate the main section of the setup script setupScript += target % setupDict # Send a message to out fancy bottom log window transdict = dict(projectName=project.GetName()) self.MainFrame.SendMessage(0, _('Setup script for "%(projectName)s" succesfully created')%transdict) return setupScript, buildDir
class cx_FreezePanel(BaseBuilderPanel): def __init__(self, parent, projectName, creationDate): """ Default class constructor. **Parameters:** * projectName: the name of the project we are working on * creationDate: the date and time the project was created """ BaseBuilderPanel.__init__(self, parent, projectName, creationDate, name="cx_Freeze") # I need this flag otherwise all the widgets start sending changed # events when I first populate the full panel self.created = False # A whole bunch of static box sizers self.commonSizer_staticbox = wx.StaticBox(self, -1, _("Common Options")) self.pathSizer_staticbox = wx.StaticBox(self, -1, _("Path")) self.includesSizer_staticbox = wx.StaticBox(self, -1, _("Includes")) self.packagesSizer_staticbox = wx.StaticBox(self, -1, _("Packages")) self.excludesSizer_staticbox = wx.StaticBox(self, -1, _("Excludes")) self.otherOptionsSizer_staticbox = wx.StaticBox( self, -1, _("Other Options")) self.targetSizer_staticbox = wx.StaticBox(self, -1, _("Target Classes")) # A simple label that holds information about the project transdict = dict(projectName=projectName, creationDate=creationDate) self.label = wx.StaticText( self, -1, _("cx_Freeze options for: %(projectName)s (Created: %(creationDate)s)" ) % transdict) # A list control for the target classes, scripts self.multipleExe = BaseListCtrl(self, columnNames=[ _("Exe Kind"), _("Python Main Script"), _("Executable Name"), _("Version"), _("Description"), _("Author"), _("Program Name") ], name="multipleexe") # Optimization level for cx_Freeze 1 for "python -O", 2 for "python -OO", # 0 to disable self.optimizeCombo = MultiComboBox(self, ["0", "1", "2"], wx.CB_DROPDOWN | wx.CB_READONLY, self.GetName(), "optimize") # Compression level for the zipfile in cx_Freeze self.compressCombo = MultiComboBox(self, ["0", "1"], wx.CB_DROPDOWN | wx.CB_READONLY, self.GetName(), "compress") # A checkbox that enables the user to choose a different name for the # distribution directory. Default is unchecked, that means dist_dir="dist" self.distChoice = wx.CheckBox(self, -1, _("Dist Directory"), name="dist_dir_choice") # The name of the distribution directory (if enabled) self.distTextCtrl = wx.TextCtrl(self, -1, "dist", name="dist_dir") # A list control for the "includes" option, a comma separated list of # modules to include self.includeList = BaseListCtrl(self, columnNames=[_("Python Modules")], name="includes") # A list control for the "packages" option, a comma separated list of # packages to include self.packagesList = BaseListCtrl(self, columnNames=[_("Python Packages")], name="packages") # A list control for the "excludes" option, a comma separated list of # modules to exclude self.excludeList = BaseListCtrl(self, columnNames=[_("Python Modules")], name="excludes") # A list control for the "path" option, a comma separated list of # paths to search for modules self.pathList = BaseListCtrl(self, columnNames=[_("Paths")], name="path") self.copyDepFiles = wx.CheckBox(self, -1, _("Copy Dependent Files"), name="copy_dependent_files") self.appendScriptToExe = wx.CheckBox(self, -1, _("Append Script To Executable"), name="append_script_toexe") self.appendScriptToLibrary = wx.CheckBox( self, -1, _("Append Script To Library"), name="append_script_tolibrary") self.addManifest = wx.CheckBox(self, -1, _("Create Manifest File (MSW)"), name="create_manifest_file") self.icon = wx.FilePickerCtrl(self, style=wx.FLP_USE_TEXTCTRL, name="icon") self.initScriptPicker = wx.FilePickerCtrl(self, style=wx.FLP_USE_TEXTCTRL, name="initScript") # Hold a reference to all the list controls, to speed up things later self.listCtrls = [ self.pathList, self.includeList, self.packagesList, self.excludeList ] # Do the hard work... quite a few to layout :-D self.LayoutItems() self.SetProperties() self.BindEvents() # ========================== # # Methods called in __init__ # # ========================== # def SetProperties(self): """ Sets the properties fro cx_FreezePanel and its children widgets. """ # I use all the cx_Freeze default values (where applicable), and my standard # configuration or preferences otherwise. This can easily be changed later # with a user customizable default project options file (or wx.Config) # Defaults (for me), executable name = python script name self.distTextCtrl.Enable(False) # Set a bold font for the static texts font = self.GetFont() font.SetWeight(wx.FONTWEIGHT_BOLD) for child in self.GetChildren(): if isinstance(child, wx.StaticText) or isinstance( child, wx.CheckBox): child.SetFont(font) def LayoutItems(self): """ Layouts the widgets using sizers. """ # Create a whole bunch of sizers mainSizer = wx.BoxSizer(wx.VERTICAL) otherOptionsSizer = wx.StaticBoxSizer(self.otherOptionsSizer_staticbox, wx.VERTICAL) excludesSizer = wx.StaticBoxSizer(self.excludesSizer_staticbox, wx.HORIZONTAL) packagesSizer = wx.StaticBoxSizer(self.packagesSizer_staticbox, wx.HORIZONTAL) includesSizer = wx.StaticBoxSizer(self.includesSizer_staticbox, wx.HORIZONTAL) pathSizer = wx.StaticBoxSizer(self.pathSizer_staticbox, wx.HORIZONTAL) plusSizer = wx.BoxSizer(wx.HORIZONTAL) minusSizer = wx.BoxSizer(wx.HORIZONTAL) resourceSizer = wx.BoxSizer(wx.HORIZONTAL) commonSizer = wx.StaticBoxSizer(self.commonSizer_staticbox, wx.VERTICAL) # This grid bag sizer will hold all the list controls and widgets # that display cx_Freeze options commonGridSizer = wx.GridBagSizer(5, 5) commonSizer_7 = wx.BoxSizer(wx.VERTICAL) commonSizer_6 = wx.BoxSizer(wx.VERTICAL) commonSizer_5 = wx.BoxSizer(wx.VERTICAL) commonSizer_4 = wx.BoxSizer(wx.VERTICAL) commonSizer_3 = wx.BoxSizer(wx.VERTICAL) commonSizer_2 = wx.BoxSizer(wx.VERTICAL) commonSizer_1 = wx.BoxSizer(wx.VERTICAL) targetSizer = wx.StaticBoxSizer(self.targetSizer_staticbox, wx.HORIZONTAL) topGridSizer = wx.FlexGridSizer(1, 4, 5, 5) topSizer_4 = wx.BoxSizer(wx.VERTICAL) topSizer_3 = wx.BoxSizer(wx.VERTICAL) topSizer_2 = wx.BoxSizer(wx.VERTICAL) topSizer_1 = wx.BoxSizer(wx.VERTICAL) pickerSizer_1 = wx.BoxSizer(wx.VERTICAL) pickerSizer_2 = wx.BoxSizer(wx.VERTICAL) flag = wx.LEFT | wx.RIGHT | wx.EXPAND flag2 = wx.LEFT | wx.BOTTOM | wx.TOP | wx.EXPAND # Add the VersionInfo text controls mainSizer.Add(self.label, 0, wx.ALL, 10) targetSizer.Add(self.multipleExe, 1, flag2, 5) targetSizer.Add(self.multipleExe.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) mainSizer.Add(targetSizer, 0, wx.ALL | wx.EXPAND, 5) optimize = wx.StaticText(self, -1, _("Optimize")) commonSizer_1.Add(optimize, 0, wx.RIGHT | wx.BOTTOM, 2) commonSizer_1.Add(self.optimizeCombo, 0, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_1, (1, 0), (1, 1), wx.ALL | wx.EXPAND, 5) compress = wx.StaticText(self, -1, _("Compressed")) commonSizer_2.Add(compress, 0, wx.RIGHT | wx.BOTTOM, 2) commonSizer_2.Add(self.compressCombo, 0, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_2, (1, 1), (1, 1), wx.ALL | wx.EXPAND, 5) commonGridSizer.Add((0, 0), (1, 3), (1, 1), wx.EXPAND) commonSizer_5.Add(self.distChoice, 0, wx.BOTTOM, 2) commonSizer_5.Add(self.distTextCtrl, 1, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_5, (1, 5), (1, 1), wx.ALL | wx.EXPAND, 5) commonGridSizer.AddGrowableCol(3) commonGridSizer.AddGrowableCol(4) commonGridSizer.AddGrowableCol(5) ## commonGridSizer.AddGrowableCol(6) commonGridSizer.SetEmptyCellSize((0, 0)) commonSizer.Add(commonGridSizer, 1, wx.EXPAND, 0) mainSizer.Add(commonSizer, 0, wx.ALL | wx.EXPAND, 5) flag = wx.LEFT | wx.TOP | wx.BOTTOM | wx.EXPAND # Add the list controls pathSizer.Add(self.pathList, 1, flag, 5) pathSizer.Add(self.pathList.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) includesSizer.Add(self.includeList, 1, flag, 5) includesSizer.Add(self.includeList.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) packagesSizer.Add(self.packagesList, 1, flag, 5) packagesSizer.Add(self.packagesList.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) plusSizer.Add(pathSizer, 1, wx.EXPAND) plusSizer.Add(includesSizer, 1, wx.EXPAND | wx.LEFT, 5) plusSizer.Add(packagesSizer, 1, wx.EXPAND | wx.LEFT, 5) mainSizer.Add(plusSizer, 1, wx.ALL | wx.EXPAND, 5) excludesSizer.Add(self.excludeList, 1, flag, 5) excludesSizer.Add(self.excludeList.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) minusSizer.Add(excludesSizer, 1, wx.EXPAND) otherOptionsSizer.Add(self.copyDepFiles, 0, wx.LEFT | wx.TOP | wx.EXPAND, 5) otherOptionsSizer.Add((0, 2)) otherOptionsSizer.Add(self.appendScriptToExe, 0, wx.LEFT | wx.EXPAND, 5) otherOptionsSizer.Add((0, 2)) otherOptionsSizer.Add(self.appendScriptToLibrary, 0, wx.LEFT | wx.EXPAND, 5) otherOptionsSizer.Add((0, 2)) otherOptionsSizer.Add(self.addManifest, 0, wx.LEFT | wx.EXPAND, 5) otherOptionsSizer.Add((0, 10)) icon = wx.StaticText(self, -1, _("Icon File")) pickerSizer_1.Add(icon, 0, wx.BOTTOM, 2) pickerSizer_1.Add(self.icon, 0, wx.EXPAND) initScript = wx.StaticText(self, -1, _("Initialization Script")) pickerSizer_2.Add(initScript, 0, wx.BOTTOM, 2) pickerSizer_2.Add(self.initScriptPicker, 0, wx.EXPAND) otherOptionsSizer.Add(pickerSizer_1, 0, wx.LEFT | wx.EXPAND, 5) otherOptionsSizer.Add((0, 4)) otherOptionsSizer.Add(pickerSizer_2, 0, wx.LEFT | wx.EXPAND, 5) minusSizer.Add(otherOptionsSizer, 1, wx.EXPAND | wx.LEFT, 5) mainSizer.Add(minusSizer, 0, wx.ALL | wx.EXPAND, 5) # Set a bold font for the static texts font = self.GetFont() font.SetWeight(wx.FONTWEIGHT_BOLD) for child in self.GetChildren(): if isinstance(child, wx.StaticText) or isinstance( child, wx.CheckBox): child.SetFont(font) self.SetAutoLayout(True) self.SetSizer(mainSizer) self.SetupScrolling() self.label.SetFocus() def ValidateOptions(self): """ Validates the cx_Freeze input options before compiling. """ # check if the script files exist if self.multipleExe.GetItemCount() == 0: msg = _("No Python scripts have been added.") self.MainFrame.RunError(2, msg, True) return False for indx in xrange(self.multipleExe.GetItemCount()): script = self.multipleExe.GetItem(indx, 2) if not os.path.isfile(script.GetText()): msg = _("Python main script is not a valid file.") self.MainFrame.RunError(2, msg, True) return False # check if the initialization file is not empty and if it exists initScript = self.initScriptPicker.GetPath() if initScript and not os.path.isfile(initScript): msg = _("Initialization file is not a valid file.") self.MainFrame.RunError(2, msg, True) return False # check if the icon file is not empty and if it exists icon = self.icon.GetPath() if icon and not os.path.isfile(icon): msg = _("Icon file is not a valid file.") self.MainFrame.RunError(2, msg, True) return False # Everything is ok, let's go compiling... return True def PrepareForCompile(self): """ Retrieves all the data to prepare for compilation. """ if not self.ValidateOptions(): # No way, something went wrong with the options set by the user return None # Retrieve the project stored in the parent (LabelBook) properties project = self.GetParent().GetProject() # Send a message to out fancy bottom log window transdict = dict(projectName=project.GetName()) self.MainFrame.SendMessage( 0, _('Generating "%(projectName)s" setup script...') % transdict) # Get the project configuration (all the options, basically) configuration = project.GetConfiguration(self.GetName()) # Get the custom code (if any) that the user added customCode = project.GetCustomCode(self.GetName()) # Get the post-compilation code (if any) that the user added postCompile = project.GetPostCompileCode(self.GetName()) for lists in self.listCtrls: # Last update for all the list controls lists.UpdateProject(False) # Build the target script file return self.BuildTargetClass(configuration, project, customCode, postCompile) def BuildTargetClass(self, configuration, project, customCode, postCompile): """ Builds the cx_Freeze compilation script file, returning it as a string. """ # A couple of dictionaries to populate the setup string setupDict, importDict = {}, {} configuration = dict(configuration) # Delete the keys we don't need distChoice = self.distChoice.GetValue() del configuration["dist_dir_choice"] extension = "" if wx.Platform == "__WXMSW__": extension = ".exe" useRelPath = self.MainFrame.relativePaths scriptFile = self.multipleExe.GetItem(0, 2).GetText() # Loop over all the keys, values of the configuration dictionary for key, item in configuration.items(): if key == "initScript" and not item: # I don't know how often this option is used item = "" elif isinstance(self.FindWindowByName(key), wx.CheckBox): item = bool(int(item)) if key in ["create_manifest_file", "multipleexe"]: # Skip these 2 options, we'll take care of them later... continue if isinstance(item, basestring) and key != "compress": if key == "dist_dir": if not item.strip() or not distChoice: item = "dist" if distChoice: self.MainFrame.SendMessage( 1, _('Empty dist_dir option. Using default value "dist"' )) if not item.strip(): item = None else: if useRelPath and key in ["initScript", "icon"]: item = 'r"%s"' % (relpath( item, os.path.split(scriptFile)[0])) else: item = 'r"%s"' % item if type(item) == ListType: # Terrible hack to setup correctly the string to be included # in the setup file item = setupString(key, item, useRelPath=useRelPath, mainScript=scriptFile) setupDict[key] = item baseName = "GUI2Exe_Target_%d" targetclass = "" executables = "[" # Loop over all the Python scripts used for indx in xrange(self.multipleExe.GetItemCount()): # Add the target class tupleMultiple = (baseName % (indx + 1), ) scriptFile = self.multipleExe.GetItem(indx, 2).GetText() buildDir, scriptFile = os.path.split(scriptFile) # Add the Python script file tupleMultiple += (scriptFile, ) # Add the init script tupleMultiple += (setupDict["initScript"], ) consoleOrWindows = self.multipleExe.GetItem(indx, 1).GetText() # Check if it is a GUI app and if it runs on Windows if consoleOrWindows == "windows" and sys.platform == "win32": tupleMultiple += ("'Win32GUI'", ) else: tupleMultiple += (None, ) # Add the distribution directory tupleMultiple += (setupDict["dist_dir"], ) targetName = self.multipleExe.GetItem(indx, 3).GetText() if not targetName.strip(): # Missing executable name? Use the Python script file name targetName = os.path.splitext(scriptFile)[0] self.MainFrame.SendMessage( 1, _('Empty Executable Name option. Using Python script name') ) # Add the executable name tupleMultiple += (targetName + extension, ) # Add the remaining keys tupleMultiple += (bool(setupDict["compress"]), setupDict["copy_dependent_files"], setupDict["append_script_toexe"], setupDict["append_script_tolibrary"], setupDict["icon"]) # Build the target classes targetclass += _cx_Freeze_class % tupleMultiple # Save the executables in a list to be processed by cx_Freeze executables += tupleMultiple[0] + ", " keys = setupDict.keys() for key in keys: # Remove the keys we have already used if key not in ["includes", "excludes", "packages", "path"]: setupDict.pop(key) # Add the custom code (if any) setupDict["customcode"] = (customCode and [customCode.strip()] or ["# No custom code added"])[0] # Add the post-compilation code (if any) setupDict["postcompilecode"] = ( postCompile and [postCompile.strip()] or ["# No post-compilation code added"])[0] # Add the target classes and the executables list setupDict["targetclasses"] = targetclass setupDict["executables"] = executables.rstrip(", ") + "]" # Include the GUI2Exe version in the setup script importDict["gui2exever"] = self.MainFrame.GetVersion() # Populate the "import" section setupScript = _cx_Freeze_imports % importDict globalSetup = ["version", "description", "author", "name"] for col in xrange(4, self.multipleExe.GetColumnCount()): item = self.multipleExe.GetItem(indx, col).GetText() setupDict[globalSetup[col - 4]] = '"%s"' % item.strip() # Populate the main section of the setup script setupScript += _cx_Freeze_target % setupDict # Send a message to out fancy bottom log window transdict = dict(projectName=project.GetName()) self.MainFrame.SendMessage( 0, _('Setup script for "%(projectName)s" succesfully created') % transdict) return setupScript, buildDir
class bbFreezePanel(BaseBuilderPanel): def __init__(self, parent, projectName, creationDate): """ Default class constructor. **Parameters:** * projectName: the name of the project we are working on * creationDate: the date and time the project was created """ BaseBuilderPanel.__init__(self, parent, projectName, creationDate, name="bbfreeze") # I need this flag otherwise all the widgets start sending changed # events when I first populate the full panel self.created = False # A whole bunch of static box sizers self.commonSizer_staticbox = wx.StaticBox(self, -1, _("Common Options")) self.includesSizer_staticbox = wx.StaticBox(self, -1, _("Includes")) self.excludesSizer_staticbox = wx.StaticBox(self, -1, _("Excludes")) self.otherOptionsSizer_staticbox = wx.StaticBox(self, -1, _("Other Options")) self.targetSizer_staticbox = wx.StaticBox(self, -1, _("Target Classes")) transdict = dict(projectName=projectName, creationDate=creationDate) # A simple label that holds information about the project self.label = wx.StaticText(self, -1, _("bbFreeze options for: %(projectName)s (Created: %(creationDate)s)")%transdict) # A list control for the target classes, scripts self.multipleExe = BaseListCtrl(self, columnNames=[_("Exe Kind"), _("Python Main Script")], name="multipleexe") # Optimization level for bbFreeze 1 for "python -O", 2 for "python -OO", # 0 to disable self.optimizeCombo = MultiComboBox(self, ["0", "1", "2"], wx.CB_DROPDOWN|wx.CB_READONLY, self.GetName(), "optimize") # Compression level for the zipfile in bbFreeze self.compressCombo = MultiComboBox(self, ["0", "1"], wx.CB_DROPDOWN|wx.CB_READONLY, self.GetName(), "compress") # A checkbox that enables the user to choose a different name for the # distribution directory. Default is unchecked, that means dist_dir="dist" self.distChoice = wx.CheckBox(self, -1, _("Dist Directory"), name="dist_dir_choice") # The name of the distribution directory (if enabled) self.distTextCtrl = wx.TextCtrl(self, -1, "dist", name="dist_dir") # A list control for the "includes" option, a comma separated list of # modules to include self.includeList = BaseListCtrl(self, columnNames=[_("Python Modules")], name="includes") # A list control for the "excludes" option, a comma separated list of # modules to exclude self.excludeList = BaseListCtrl(self, columnNames=[_("Python Modules")], name="excludes") self.includeInterpreter = wx.CheckBox(self, -1, _("Include Python Interpreter"), name="include_py") self.addManifest = wx.CheckBox(self, -1, _("Create Manifest File (MSW)"), name="create_manifest_file") # Hold a reference to all the list controls, to speed up things later self.listCtrls = [self.includeList, self.excludeList] # Do the hard work... quite a few to layout :-D self.LayoutItems() self.SetProperties() self.BindEvents() # ========================== # # Methods called in __init__ # # ========================== # def SetProperties(self): """ Sets the properties fro bbFreezePanel and its children widgets. """ # I use all the bbFreeze default values (where applicable), and my standard # configuration or preferences otherwise. This can easily be changed later # with a user customizable default project options file (or wx.Config) self.distTextCtrl.Enable(False) # Set a bold font for the static texts font = self.GetFont() font.SetWeight(wx.FONTWEIGHT_BOLD) for child in self.GetChildren(): if isinstance(child, wx.StaticText) or isinstance(child, wx.CheckBox): child.SetFont(font) def LayoutItems(self): """ Layouts the widgets using sizers. """ # Create a whole bunch of sizers mainSizer = wx.BoxSizer(wx.VERTICAL) otherOptionsSizer = wx.StaticBoxSizer(self.otherOptionsSizer_staticbox, wx.HORIZONTAL) excludesSizer = wx.StaticBoxSizer(self.excludesSizer_staticbox, wx.HORIZONTAL) includesSizer = wx.StaticBoxSizer(self.includesSizer_staticbox, wx.HORIZONTAL) targetSizer = wx.StaticBoxSizer(self.targetSizer_staticbox, wx.HORIZONTAL) plusSizer = wx.BoxSizer(wx.HORIZONTAL) minusSizer = wx.BoxSizer(wx.HORIZONTAL) commonSizer = wx.StaticBoxSizer(self.commonSizer_staticbox, wx.VERTICAL) # This grid bag sizer will hold all the list controls and widgets # that display bbFreeze options commonGridSizer = wx.GridBagSizer(5, 5) commonSizer_7 = wx.BoxSizer(wx.VERTICAL) commonSizer_6 = wx.BoxSizer(wx.VERTICAL) commonSizer_5 = wx.BoxSizer(wx.VERTICAL) commonSizer_4 = wx.BoxSizer(wx.VERTICAL) commonSizer_3 = wx.BoxSizer(wx.VERTICAL) commonSizer_2 = wx.BoxSizer(wx.VERTICAL) commonSizer_1 = wx.BoxSizer(wx.VERTICAL) targetSizer = wx.StaticBoxSizer(self.targetSizer_staticbox, wx.HORIZONTAL) flag2 = wx.LEFT|wx.BOTTOM|wx.TOP|wx.EXPAND mainSizer.Add(self.label, 0, wx.ALL, 10) targetSizer.Add(self.multipleExe, 1, flag2, 5) targetSizer.Add(self.multipleExe.MakeButtons(), 0, wx.EXPAND|wx.LEFT, 3) mainSizer.Add(targetSizer, 0, wx.ALL|wx.EXPAND, 5) optimize = wx.StaticText(self, -1, _("Optimize")) commonSizer_1.Add(optimize, 0, wx.RIGHT|wx.BOTTOM, 2) commonSizer_1.Add(self.optimizeCombo, 0, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_1, (1, 0), (1, 1), wx.ALL|wx.EXPAND, 5) compress = wx.StaticText(self, -1, _("Compressed")) commonSizer_2.Add(compress, 0, wx.RIGHT|wx.BOTTOM, 2) commonSizer_2.Add(self.compressCombo, 0, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_2, (1, 1), (1, 1), wx.ALL|wx.EXPAND, 5) commonGridSizer.Add((0, 0), (1, 3), (1, 1), wx.EXPAND) commonSizer_5.Add(self.distChoice, 0, wx.BOTTOM, 2) commonSizer_5.Add(self.distTextCtrl, 1, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_5, (1, 5), (1, 1), wx.ALL|wx.EXPAND, 5) commonGridSizer.AddGrowableCol(3) commonGridSizer.AddGrowableCol(4) commonGridSizer.AddGrowableCol(5) ## commonGridSizer.AddGrowableCol(6) commonGridSizer.SetEmptyCellSize((0, 0)) commonSizer.Add(commonGridSizer, 1, wx.EXPAND, 0) mainSizer.Add(commonSizer, 0, wx.ALL|wx.EXPAND, 5) flag = wx.LEFT|wx.TOP|wx.BOTTOM|wx.EXPAND # Add the list controls includesSizer.Add(self.includeList, 1, flag, 5) includesSizer.Add(self.includeList.MakeButtons(), 0, wx.EXPAND|wx.LEFT, 3) excludesSizer.Add(self.excludeList, 1, flag, 5) excludesSizer.Add(self.excludeList.MakeButtons(), 0, wx.EXPAND|wx.LEFT, 3) plusSizer.Add(includesSizer, 1, wx.EXPAND) plusSizer.Add(excludesSizer, 1, wx.EXPAND|wx.LEFT, 5) mainSizer.Add(plusSizer, 0, wx.ALL|wx.EXPAND, 5) otherOptionsSizer.Add(self.includeInterpreter, 0, wx.ALL|wx.EXPAND, 5) otherOptionsSizer.Add(self.addManifest, 0, wx.ALL|wx.EXPAND, 5) minusSizer.Add(otherOptionsSizer, 1, wx.EXPAND) mainSizer.Add(minusSizer, 0, wx.ALL|wx.EXPAND, 5) self.SetAutoLayout(True) self.SetSizer(mainSizer) self.SetupScrolling() self.label.SetFocus() def ValidateOptions(self): """ Validates the bbFreeze input options before compiling. """ # check if the script files exist if self.multipleExe.GetItemCount() == 0: msg = _("No Python scripts have been added.") self.MainFrame.RunError(2, msg, True) return False for indx in xrange(self.multipleExe.GetItemCount()): script = self.multipleExe.GetItem(indx, 2) if not os.path.isfile(script.GetText()): msg = _("Python main script is not a valid file.") self.MainFrame.RunError(2, msg, True) return False # Everything is ok, let's go compiling... return True def PrepareForCompile(self): """ Retrieves all the data to prepare for compilation. """ if not self.ValidateOptions(): # No way, something went wrong with the options set by the user return None # Retrieve the project stored in the parent (LabelBook) properties project = self.GetParent().GetProject() # Send a message to out fancy bottom log window transdict = dict(projectName=project.GetName()) self.MainFrame.SendMessage(0, _('Generating "%(projectName)s" setup script...')%transdict) # Get the project configuration (all the options, basically) configuration = project.GetConfiguration(self.GetName()) # Get the custom code (if any) that the user added customCode = project.GetCustomCode(self.GetName()) # Get the post-compilation code (if any) that the user added postCompile = project.GetPostCompileCode(self.GetName()) for lists in self.listCtrls: # Last update for all the list controls lists.UpdateProject(False) # Build the target script file return self.BuildTargetClass(configuration, project, customCode, postCompile) def BuildTargetClass(self, configuration, project, customCode, postCompile): """ Builds the bbFreeze compilation script file, returning it as a string. """ # A couple of dictionaries to populate the setup string setupDict, importDict = {}, {} configuration = dict(configuration) # Delete the keys we don't need distChoice = self.distChoice.GetValue() del configuration["dist_dir_choice"] # Loop over all the keys, values of the configuration dictionary for key, item in configuration.items(): if isinstance(self.FindWindowByName(key), wx.CheckBox): item = bool(int(item)) if key in ["create_manifest_file", "multipleexe"]: # Skip these 2 options, we'll take care of them later... continue if isinstance(item, basestring) and key != "compress": if key == "dist_dir" and (item == "" or not distChoice): item = "'dist'" if distChoice: self.MainFrame.SendMessage(1, _('Empty dist_dir option. Using default value "dist"')) else: item = "r'%s'"%item if type(item) == ListType: # Terrible hack to setup correctly the string to be included # in the setup file item = setupString(key, item) setupDict[key] = item targetclass = "" for indx in xrange(self.multipleExe.GetItemCount()): # Add the target classes gui_only = self.multipleExe.GetItem(indx, 1).GetText() scriptFile = self.multipleExe.GetItem(indx, 2).GetText() gui = (gui_only == "windows" and [True] or [False])[0] targetclass += _bbFreeze_class%{"gui_only": gui, "script": 'r"%s"'%scriptFile} buildDir, scriptFile = os.path.split(scriptFile) # Add the custom code (if any) setupDict["customcode"] = (customCode and [customCode.strip()] or ["# No custom code added"])[0] # Add the post-compilation code (if any) setupDict["postcompilecode"] = (postCompile and [postCompile.strip()] or ["# No post-compilation code added"])[0] setupDict["executables"] = targetclass # Include the GUI2Exe version in the setup script importDict["gui2exever"] = self.MainFrame.GetVersion() # Populate the "import" section setupScript = _bbFreeze_imports % importDict # Populate the main section of the setup script setupScript += _bbFreeze_target % setupDict # Send a message to out fancy bottom log window transdict = dict(projectName=project.GetName()) self.MainFrame.SendMessage(0, _('Setup script for "%(projectName)s" succesfully created')%transdict) return setupScript, buildDir
class Py2ExePanel(BaseBuilderPanel): def __init__(self, parent, projectName, creationDate): """ Default class constructor. **Parameters:** * projectName: the name of the project we are working on * creationDate: the date and time the project was created """ BaseBuilderPanel.__init__(self, parent, projectName, creationDate, name="py2exe") # I need this flag otherwise all the widgets start sending changed # events when I first populate the full panel self.created = False # A whole bunch of static box sizers self.commonSizer_staticbox = wx.StaticBox(self, -1, _("Common Options")) self.includesSizer_staticbox = wx.StaticBox(self, -1, _("Includes")) self.packagesSizer_staticbox = wx.StaticBox(self, -1, _("Packages")) self.excludesSizer_staticbox = wx.StaticBox(self, -1, _("Excludes")) self.dllExcludesSizer_staticbox = wx.StaticBox(self, -1, _("DLL Excludes")) self.ignoreSizer_staticbox = wx.StaticBox(self, -1, _("Ignores")) self.datafile_staticbox = wx.StaticBox(self, -1, _("Data Files")) self.icon_staticbox = wx.StaticBox(self, -1, _("Icon Resources")) self.bitmap_staticbox = wx.StaticBox(self, -1, _("Bitmap Resources")) self.other_staticbox = wx.StaticBox(self, -1, _("Other Resources")) self.otherSizer_staticbox = wx.StaticBox(self, -1, _("Other Options")) self.targetSizer_staticbox = wx.StaticBox(self, -1, _("Target Classes")) # A simple label that holds information about the project transdict = dict(projectName=projectName, creationDate=creationDate) self.label = wx.StaticText( self, -1, _("Py2exe options for: %(projectName)s (Created: %(creationDate)s)" ) % transdict) # These text controls hold data used by VersionInfo in py2exe # A list control for the target classes, scripts self.multipleExe = BaseListCtrl(self, columnNames=[ _("Exe Kind"), _("Python Main Script"), _("Executable Name"), _("Version"), _("Company Name"), _("Copyrights"), _("Program Name") ], name="multipleexe") # Optimization level for py2exe 1 for "python -O", 2 for "python -OO", # 0 to disable self.optimizeCombo = MultiComboBox(self, ["0", "1", "2"], wx.CB_DROPDOWN | wx.CB_READONLY, self.GetName(), "optimize") # Compression level for the zipfile (if any) in py2exe self.compressCombo = MultiComboBox(self, ["0", "1", "2"], wx.CB_DROPDOWN | wx.CB_READONLY, self.GetName(), "compressed") # Bundle files option for py2exe. Specifying a level of 2 includes # the .pyd and .dll files into the zip-archive or the executable. Thus, # the dist directory will contain your exe file(s), the library.zip file # (if you haven't specified 'zipfile=None'), and the python dll. The # advantage of this scheme is that the application can still load extension # modules from the file system if you extend sys.path at runtime. # Using a level of 1 includes the .pyd and .dll files into the zip-archive # or the executable itself, and does the same for pythonXY.dll. The advantage # is that you only need to distribute one file per exe, which will however # be quite large. Another advantage is that inproc COM servers will run # completely isolated from other Python interpreters in the same exe. The # disadvantage of this scheme is that it is impossible to load other # extensions from the file system, the application will crash with a fatal # Python error if you try this. self.bundleCombo = MultiComboBox(self, ["1", "2", "3"], wx.CB_DROPDOWN | wx.CB_READONLY, self.GetName(), "bundle_files") # A checkbox that enables the user to choose a different name for the zipfile # Default is unchecked, that means zipfile=None self.zipfileChoice = wx.CheckBox(self, -1, "Zipfile", name="zipfile_choice") # The name of the zipfile (if enabled by the user) self.zipfileTextCtrl = wx.TextCtrl(self, -1, "None", name="zipfile") # A checkbox that enables the user to choose a different name for the # distribution directory. Default is unchecked, that means dist_dir="dist" self.distChoice = wx.CheckBox(self, -1, _("Dist Directory"), name="dist_dir_choice") # The name of the distribution directory (if enabled) self.distTextCtrl = wx.TextCtrl(self, -1, "dist", name="dist_dir") # Allows to skip the archive. If checked, this copies the Python bytecode files # directly into the dist directory and subdirectories - no archive is used. self.skiparchiveChoice = wx.CheckBox(self, -1, "Skip Archive", name="skip_archive") # If checked, embed the XP manifest file directly in the executable self.xpmanifestChoice = wx.CheckBox(self, -1, "XP Manifest File", name="manifest_file") # A list control for the "includes" option, a comma separated list of # modules to include self.includeList = BaseListCtrl(self, columnNames=[_("Python Modules")], name="includes") # A list control for the "packages" option, a comma separated list of # packages to include self.packagesList = BaseListCtrl(self, columnNames=[_("Python Packages")], name="packages") # A list control for the "excludes" option, a comma separated list of # modules to exclude self.excludeList = BaseListCtrl(self, columnNames=[_("Python Modules")], name="excludes") # A list control for the "dll_excludes" option, a comma separated list of # Windows dlls to include self.dllExcludeList = BaseListCtrl(self, columnNames=[_("DLL Names")], name="dll_excludes") # A list control for the "ignores" option, a comma separated list of # modules to ignores self.ignoreList = BaseListCtrl(self, columnNames=[_("Python Modules")], name="ignores") # A list control for the "data_files" option. "data_files" should contain # a sequence of (target-dir, files) tuples, where files is a sequence of # files to be copied self.datafileList = BaseListCtrl( self, columnNames=[_("Directory") + " " * 15, _("Files Path")], name="data_files") # A list control for the "icon_resources" option self.iconResourceList = BaseListCtrl( self, columnNames=[_("Id "), _("Icon Path")], name="icon_resources") # A list control for the "bitmap_resources" option self.bitmapResourceList = BaseListCtrl( self, columnNames=[_("Id "), _("Bitmap Path")], name="bitmap_resources") # A list control for the "other_resources" option self.otherResourceList = BaseListCtrl( self, columnNames=[_("Type"), _("Id "), _("Path/Value")], name="other_resources") # This command line switch instructs py2exe to create a python module cross # reference and display it in the webbrowser. This allows to answer question # why a certain module has been included, or if you can exclude a certain module # and it's dependencies. Also, the html page includes links which will even # allow to view the source code of a module in the browser, for easy inspection. self.crossRefCheck = wx.CheckBox(self, -1, "Cross-Reference", name="xref") # To prevent unicode encoding error, py2exe now by default includes the codecs # module and the encodings package. If you are sure your program never # implicitely or explicitely has to convert between unicode and ascii strings # this can be prevented by checking this checkbox self.asciiCheck = wx.CheckBox(self, -1, "Ascii", name="ascii") # The following 2 are only for service, com_server and ctypes_com_server self.createExeCheck = wx.CheckBox(self, -1, "Create EXE", name="create_exe") self.createDllCheck = wx.CheckBox(self, -1, "Create DLL", name="create_dll") # By picking a Python script here, this script can do things like installing # a customized stdout blackhole. See py2exe's boot_common.py for examples of # what can be done. The custom boot script is executed during startup of # the executable immediately after boot_common.py is executed self.customBootPicker = wx.FilePickerCtrl(self, style=wx.FLP_USE_TEXTCTRL, name="custom_boot_script") # Hold a reference to all the list controls, to speed up things later self.listCtrls = [ self.includeList, self.packagesList, self.excludeList, self.dllExcludeList, self.ignoreList, self.datafileList, self.iconResourceList, self.bitmapResourceList, self.otherResourceList ] # Do the hard work... quite a few to layout :-D self.LayoutItems() self.SetProperties() self.BindEvents() # ========================== # # Methods called in __init__ # # ========================== # def SetProperties(self): """ Sets the properties fro Py2ExePanel and its children widgets. """ # I use all the py2exe default values (where applicable), and my standard # configuration or preferences otherwise. This can easily be changed later # with a user customizable default project options file (or wx.Config) # Defaults (for me) zipfile=None self.zipfileTextCtrl.Enable(False) self.distTextCtrl.Enable(False) self.createExeCheck.SetValue(1) self.createDllCheck.SetValue(1) # Set a bold font for the static texts font = self.GetFont() font.SetWeight(wx.FONTWEIGHT_BOLD) for child in self.GetChildren(): if isinstance(child, wx.StaticText) or isinstance( child, wx.CheckBox): child.SetFont(font) def LayoutItems(self): """ Layouts the widgets using sizers. """ # Create a whole bunch of sizers mainSizer = wx.BoxSizer(wx.VERTICAL) otherSizer = wx.StaticBoxSizer(self.otherSizer_staticbox, wx.VERTICAL) otherSizer_1 = wx.BoxSizer(wx.HORIZONTAL) otherSizer_2 = wx.BoxSizer(wx.VERTICAL) ignoreSizer = wx.StaticBoxSizer(self.ignoreSizer_staticbox, wx.HORIZONTAL) dllExcludesSizer = wx.StaticBoxSizer(self.dllExcludesSizer_staticbox, wx.HORIZONTAL) excludesSizer = wx.StaticBoxSizer(self.excludesSizer_staticbox, wx.HORIZONTAL) packagesSizer = wx.StaticBoxSizer(self.packagesSizer_staticbox, wx.HORIZONTAL) includesSizer = wx.StaticBoxSizer(self.includesSizer_staticbox, wx.HORIZONTAL) datafilesSizer = wx.StaticBoxSizer(self.datafile_staticbox, wx.HORIZONTAL) iconSizer = wx.StaticBoxSizer(self.icon_staticbox, wx.HORIZONTAL) bitmapSizer = wx.StaticBoxSizer(self.bitmap_staticbox, wx.HORIZONTAL) otherResSizer = wx.StaticBoxSizer(self.other_staticbox, wx.HORIZONTAL) plusSizer = wx.BoxSizer(wx.HORIZONTAL) minusSizer = wx.BoxSizer(wx.HORIZONTAL) resourceSizer = wx.BoxSizer(wx.HORIZONTAL) commonSizer = wx.StaticBoxSizer(self.commonSizer_staticbox, wx.VERTICAL) # This grid bag sizer will hold all the list controls and widgets # that display py2exe options commonGridSizer = wx.GridBagSizer(5, 5) commonSizer_7 = wx.BoxSizer(wx.VERTICAL) commonSizer_6 = wx.BoxSizer(wx.VERTICAL) commonSizer_5 = wx.BoxSizer(wx.VERTICAL) commonSizer_4 = wx.BoxSizer(wx.VERTICAL) commonSizer_3 = wx.BoxSizer(wx.VERTICAL) commonSizer_2 = wx.BoxSizer(wx.VERTICAL) commonSizer_1 = wx.BoxSizer(wx.VERTICAL) targetSizer = wx.StaticBoxSizer(self.targetSizer_staticbox, wx.HORIZONTAL) topGridSizer = wx.FlexGridSizer(1, 4, 5, 5) topSizer_4 = wx.BoxSizer(wx.VERTICAL) topSizer_3 = wx.BoxSizer(wx.VERTICAL) topSizer_2 = wx.BoxSizer(wx.VERTICAL) topSizer_1 = wx.BoxSizer(wx.VERTICAL) flag = wx.LEFT | wx.RIGHT | wx.EXPAND flag2 = wx.LEFT | wx.BOTTOM | wx.TOP | wx.EXPAND mainSizer.Add(self.label, 0, wx.ALL, 10) targetSizer.Add(self.multipleExe, 1, flag2, 5) targetSizer.Add(self.multipleExe.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) mainSizer.Add(targetSizer, 0, wx.ALL | wx.EXPAND, 5) optimize = wx.StaticText(self, -1, _("Optimize")) commonSizer_1.Add(optimize, 0, wx.RIGHT | wx.BOTTOM, 2) commonSizer_1.Add(self.optimizeCombo, 0, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_1, (1, 0), (1, 1), flag, 5) compress = wx.StaticText(self, -1, _("Compressed")) commonSizer_2.Add(compress, 0, wx.RIGHT | wx.BOTTOM, 2) commonSizer_2.Add(self.compressCombo, 0, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_2, (1, 1), (1, 1), flag, 5) bundle = wx.StaticText(self, -1, _("Bundle Files")) commonSizer_3.Add(bundle, 0, wx.RIGHT | wx.BOTTOM, 2) commonSizer_3.Add(self.bundleCombo, 0, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_3, (1, 2), (1, 1), flag, 5) commonGridSizer.Add((0, 0), (1, 3), (1, 1), wx.EXPAND) commonSizer_4.Add(self.zipfileChoice, 0, wx.BOTTOM, 2) commonSizer_4.Add(self.zipfileTextCtrl, 1, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_4, (1, 4), (1, 1), flag, 5) commonSizer_5.Add(self.distChoice, 0, wx.BOTTOM, 2) commonSizer_5.Add(self.distTextCtrl, 1, wx.EXPAND, 0) commonGridSizer.Add(commonSizer_5, (1, 5), (1, 1), flag, 5) commonGridSizer.AddGrowableCol(3) commonGridSizer.AddGrowableCol(4) commonGridSizer.AddGrowableCol(5) ## commonGridSizer.AddGrowableCol(6) commonGridSizer.SetEmptyCellSize((0, 0)) commonSizer.Add(commonGridSizer, 1, wx.EXPAND | wx.BOTTOM, 5) mainSizer.Add(commonSizer, 0, wx.ALL | wx.EXPAND, 5) flag = wx.LEFT | wx.TOP | wx.BOTTOM | wx.EXPAND # Add the list controls includesSizer.Add(self.includeList, 1, flag, 5) includesSizer.Add(self.includeList.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) packagesSizer.Add(self.packagesList, 1, flag, 5) packagesSizer.Add(self.packagesList.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) plusSizer.Add(includesSizer, 1, wx.EXPAND) plusSizer.Add(packagesSizer, 1, wx.EXPAND | wx.LEFT, 5) mainSizer.Add(plusSizer, 1, wx.ALL | wx.EXPAND, 5) excludesSizer.Add(self.excludeList, 1, flag, 5) excludesSizer.Add(self.excludeList.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) dllExcludesSizer.Add(self.dllExcludeList, 1, flag, 5) dllExcludesSizer.Add(self.dllExcludeList.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) ignoreSizer.Add(self.ignoreList, 1, flag, 5) ignoreSizer.Add(self.ignoreList.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) minusSizer.Add(excludesSizer, 1, wx.EXPAND) minusSizer.Add(dllExcludesSizer, 1, wx.EXPAND | wx.LEFT, 5) minusSizer.Add(ignoreSizer, 1, wx.EXPAND | wx.LEFT, 5) mainSizer.Add(minusSizer, 1, wx.ALL | wx.EXPAND, 5) datafilesSizer.Add(self.datafileList, 1, flag, 5) datafilesSizer.Add(self.datafileList.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) mainSizer.Add(datafilesSizer, 1, flag, 5) iconSizer.Add(self.iconResourceList, 1, flag, 5) iconSizer.Add(self.iconResourceList.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) bitmapSizer.Add(self.bitmapResourceList, 1, flag, 5) bitmapSizer.Add(self.bitmapResourceList.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) otherResSizer.Add(self.otherResourceList, 1, flag, 5) otherResSizer.Add(self.otherResourceList.MakeButtons(), 0, wx.EXPAND | wx.LEFT, 3) resourceSizer.Add(iconSizer, 1, wx.EXPAND) resourceSizer.Add(bitmapSizer, 1, wx.EXPAND | wx.LEFT, 5) resourceSizer.Add(otherResSizer, 1, wx.EXPAND | wx.LEFT, 5) mainSizer.Add(resourceSizer, 0, wx.ALL | wx.EXPAND, 5) # Add the other options at the bottom otherSizer_1.Add(self.xpmanifestChoice, 0, wx.ALL, 5) otherSizer_1.Add((0, 0), 1) otherSizer_1.Add(self.crossRefCheck, 0, wx.ALL, 5) otherSizer_1.Add((0, 0), 1) otherSizer_1.Add(self.asciiCheck, 0, wx.ALL, 5) otherSizer_1.Add((0, 0), 1) otherSizer_1.Add(self.skiparchiveChoice, 0, wx.ALL, 5) otherSizer_1.Add((0, 0), 1) otherSizer_1.Add(self.createExeCheck, 0, wx.ALL, 5) otherSizer_1.Add((0, 0), 1) otherSizer_1.Add(self.createDllCheck, 0, wx.ALL, 5) customboot = wx.StaticText(self, -1, _("Custom Boot Script")) otherSizer_2.Add(customboot, 0, wx.BOTTOM, 2) otherSizer_2.Add(self.customBootPicker, 0, wx.EXPAND) otherSizer.Add(otherSizer_1, 0, wx.EXPAND) otherSizer.Add(otherSizer_2, 0, wx.ALL | wx.EXPAND, 5) mainSizer.Add(otherSizer, 0, wx.ALL | wx.EXPAND, 5) self.SetAutoLayout(True) self.SetSizer(mainSizer) self.SetupScrolling() self.label.SetFocus() def EnableDllAndExe(self): """ Enables or disables the create_exe and create_dll option for py2exe. These options are only available for services, com_servers and ctypes_com_servers. """ # Disable the create_exe and create_dll self.createDllCheck.Enable(False) self.createExeCheck.Enable(False) # Enable the create_exe/create_dll if a service, com_server or ctypes_com_server are there for indx in xrange(self.multipleExe.GetItemCount()): consoleOrWindows = self.multipleExe.GetItem(indx, 1).GetText() if consoleOrWindows in [ "service", "com_server", "ctypes_com_server" ]: # These things accept module *names*, not file names... self.createDllCheck.Enable(True) self.createExeCheck.Enable(True) break def ValidateOptions(self): """ Validates the py2exe input options before compiling. """ # check if the script files exist if self.multipleExe.GetItemCount() == 0: msg = _("No Python scripts have been added.") self.MainFrame.RunError(2, msg, True) return False for indx in xrange(self.multipleExe.GetItemCount()): script = self.multipleExe.GetItem(indx, 2) if not os.path.isfile(script.GetText()): msg = _("Python main script is not a valid file.") self.MainFrame.RunError(2, msg, True) return False # check if the custom boot file is not empty and if it exists customBoot = self.customBootPicker.GetPath() if customBoot and not os.path.isfile(customBoot): msg = _("Custom boot file is not a valid file.") self.MainFrame.RunError(2, msg, True) return False # Everything is ok, let's go compiling... return True def PrepareForCompile(self): """ Retrieves all the data to prepare for compilation. """ if not self.ValidateOptions(): # No way, something went wrong with the options set by the user return None # Retrieve the project stored in the parent (LabelBook) properties project = self.GetParent().GetProject() # Send a message to out fancy bottom log window transdict = dict(projectName=project.GetName()) self.MainFrame.SendMessage( 0, _('Generating "%(projectName)s" setup script...') % transdict) # Get the project configuration (all the options, basically) configuration = project.GetConfiguration(self.GetName()) # Get the custom code (if any) that the user added customCode = project.GetCustomCode(self.GetName()) # See if the user wants the manifest file embedded in the executable manifestFile = self.xpmanifestChoice.GetValue() # Get the post-compilation code (if any) that the user added postCompile = project.GetPostCompileCode(self.GetName()) for lists in self.listCtrls: # Last update for all the list controls lists.UpdateProject(False) # Build the target script file return self.BuildTargetClass(configuration, project, manifestFile, customCode, postCompile) def BuildTargetClass(self, configuration, project, manifestFile, customCode, postCompile): """ Builds the py2exe compilation script file, returning it as a string. """ # A couple of dictionaries to populate the setup string setupDict, importDict = {}, {} configuration = dict(configuration) # Delete the keys we don't need zipChoice, distChoice = self.zipfileChoice.GetValue( ), self.distChoice.GetValue() createExe, createDll = self.createExeCheck.GetValue( ), self.createDllCheck.GetValue() del configuration["zipfile_choice"], configuration["dist_dir_choice"] if "create_exe" in configuration: del configuration["create_exe"] if "create_dll" in configuration: del configuration["create_dll"] useRelPath = self.MainFrame.relativePaths scriptFile = self.multipleExe.GetItem(0, 2).GetText() # Loop over all the keys, values of the configuration dictionary for key, item in configuration.items(): if key == "custom_boot_script": # I don't know how often this option is used if not item: item = "''" else: item = "r'%s'" % item elif isinstance(self.FindWindowByName(key), wx.CheckBox): item = bool(int(item)) if type(item) == ListType and key != "multipleexe": # Terrible hack to setup correctly the string to be included # in the setup file item = setupString(key, item, useRelPath=useRelPath, mainScript=scriptFile) if key == "zipfile": if item and item.strip() and zipChoice: if (os.path.splitext(item)[1]).lower() != ".zip": self.MainFrame.SendMessage( 1, _('zipfile does not have ".zip" extension')) item = "r'%s'" % item else: item = None elif key == "dist_dir": if item and item.strip() and distChoice: item = r'%s' % item else: item = "dist" if distChoice: self.MainFrame.SendMessage( 1, _('Empty dist_dir option. Using default value "dist"' )) setupDict[key] = item targetclass = "" baseName = "GUI2Exe_Target_%d" console, windows, service, com_server, ctypes_com_server = "console = [", "windows = [", \ "service = [", "com_server = [", \ "ctypes_com_server = [" for indx in xrange(self.multipleExe.GetItemCount()): tupleMultiple = (baseName % (indx + 1), ) consoleOrWindows = self.multipleExe.GetItem(indx, 1).GetText() scriptFile = self.multipleExe.GetItem(indx, 2).GetText() buildDir, scriptFile = os.path.split(scriptFile) isSpecial = False realScript = scriptFile if consoleOrWindows in [ "service", "com_server", "ctypes_com_server" ]: # These things accept module *names*, not file names... realScript = os.path.splitext(scriptFile)[0] isSpecial = True if consoleOrWindows == "console": console += tupleMultiple[0] + ", " elif consoleOrWindows == "windows": windows += tupleMultiple[0] + ", " elif consoleOrWindows == "service": service += tupleMultiple[0] + ", " elif consoleOrWindows == "com_server": com_server += tupleMultiple[0] + ", " else: ctypes_com_server += tupleMultiple[0] + ", " tupleMultiple += (realScript, ) for col in xrange(3, self.multipleExe.GetColumnCount()): item = self.multipleExe.GetItem(indx, col) text = item.GetText() if not text.strip(): text = os.path.splitext(scriptFile)[0] self.MainFrame.SendMessage( 1, _('Empty targetName option. Using Python script name')) if col == 3: programName = text.strip() elif col == 4: versionNumber = text.strip() tupleMultiple += (text, ) extraKeywords = self.multipleExe.GetExtraKeywords(indx) if isSpecial: tupleMultiple += (extraKeywords + "\n create_exe = %s, create_dll = %s" % (bool(createExe), bool(createDll)), ) else: tupleMultiple += (extraKeywords, ) if isSpecial: # services, com_servers and ctypes_com_server require a "modules" keyword py2exe_class = _py2exe_class.replace(" script = ", " modules = ") else: py2exe_class = _py2exe_class targetclass += py2exe_class % tupleMultiple # Add the custom code (if any) setupDict["customcode"] = (customCode and [customCode.strip()] or ["# No custom code added"])[0] # Look if the user wants to remove the "build" directory removeBuild = (self.MainFrame.deleteBuild and \ ['# Remove the build folder\nshutil.rmtree("build", ignore_errors=True)\n'] or [""])[0] importDict["remove_build"] = removeBuild # Include the GUI2Exe version in the setup script importDict["gui2exever"] = self.MainFrame.GetVersion() # Add the post-compilation code (if any) setupDict["postcompilecode"] = ( postCompile and [postCompile.strip()] or ["# No post-compilation code added"])[0] # Populate the "import" section setupScript = _py2exe_imports % importDict if manifestFile: # Embed the manifest file setupDict["other_resources"] = setupDict["other_resources"] % "" setupScript += _manifest_template % dict(prog=programName) setupDict["targetclasses"] = targetclass setupDict["console"] = console.rstrip(", ") + "]" setupDict["windows"] = windows.rstrip(", ") + "]" setupDict["service"] = service.rstrip(", ") + "]" setupDict["com_server"] = com_server.rstrip(", ") + "]" setupDict["ctypes_com_server"] = ctypes_com_server.rstrip(", ") + "]" upx, inno = project.GetUseUPX("py2exe"), project.GetBuildInno("py2exe") if upx or inno: upxinno = _upx_inno % (upx, inno, programName, versionNumber) setupDict["upx_inno"] = upxinno setupDict["use_upx_inno"] = 'cmdclass = {"py2exe": Py2exe},' else: setupDict[ "upx_inno"] = "# No custom class for UPX compression or Inno Setup script" setupDict["use_upx_inno"] = "# No UPX or Inno Setup" # Populate the main section of the setup script setupScript += _py2exe_target % setupDict if manifestFile: # Substitute a dummy line with the real one setupScript = setupScript.replace("'manifest_template'", "manifest_template") # Send a message to out fancy bottom log window transdict = dict(projectName=project.GetName()) self.MainFrame.SendMessage( 0, _('Setup script for "%(projectName)s" succesfully created') % transdict) return setupScript, buildDir