def downloadFile(self, url, workshopName): logging.debug("initiating download with progress spinner dialog") try: spinnerDialog = SpinnerDialog(self, "Preparing to download workshop...") self.session.downloadWorkshop(url, workshopName, spinnerDialog) spinnerDialog.destroy() return True except: WarningDialog(self, "Could not download workshop file. Check your network connection.") return False
def download(self, menuItem): logging.debug("beginning new workshop download") if (self.downloadIndex == None): if not self.getDownloadIndex(None): return downloadDialog = DownloadDialog(self, "Select a workshop to download.", self.downloadIndex) downloadText = None while not downloadDialog.status: if downloadDialog.status is False: downloadDialog.destroy() return downloadDialog.run() downloadText = downloadDialog.xmlString downloadDialog.destroy() if downloadText is None: return elif self.session.isWorkshop(downloadDialog.entryText): WarningDialog(self, "Workshop already exists.") return if not self.downloadFile( self.session.getDownloadLink(downloadText, downloadDialog.entryText), downloadDialog.entryText): return zipPath = str(self.session.downloadedZip) if not os.path.isfile(zipPath): WarningDialog(self, "Error Downloading File, please retry") return # First we need to unzip the import file to a temp folder spinnerDialog = SpinnerDialog(self, "Preparing to unzip files") self.session.unzip(zipPath, spinnerDialog) spinnerDialog.destroy() spinnerDialog = SpinnerDialog(self, "Preparing to import files") self.session.importParseWithSpinner( os.path.join(WORKSHOP_TMP_DIRECTORY, downloadDialog.entryText), spinnerDialog) spinnerDialog.destroy() # # reload all xml files and create a new display self.workshopTree.clearTreeStore() self.session.loadXMLFiles(WORKSHOP_CONFIG_DIRECTORY) self.workshopTree.populateTreeStore(self.session.workshopList) shutil.rmtree(WORKSHOP_TMP_DIRECTORY, ignore_errors=True) os.remove(zipPath) dialog = Gtk.MessageDialog(self, 0, Gtk.MessageType.INFO, Gtk.ButtonsType.OK, "Workshop download complete.") dialog.run() dialog.destroy() self.superMenu.refreshActionEvent(self.session.workshopList)
def exportWorkshopActionEvent(self, menuItem): logging.debug("exportWorkshopActionEvent() initiated: " + str(menuItem)) matchFound = self.session.getAvailableVMs() if not matchFound: dialog = Gtk.MessageDialog( self, 0, Gtk.MessageType.WARNING, Gtk.ButtonsType.OK, "Not all VM's for this workshop are registered.") dialog.run() dialog.destroy() return dialog = Gtk.FileChooserDialog( "Please choose a folder.", self, Gtk.FileChooserAction.SELECT_FOLDER, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) response = dialog.run() folderPath = None if response != Gtk.ResponseType.OK: dialog.destroy() return else: # response == Gtk.ResponseType.OK # Save before export otherwise xml file will not contain materials! self.session.hardSave() folderPath = os.path.join(dialog.get_filename(), self.session.currentWorkshop.filename) dialog.destroy() # TODO: Transform the spinner into the ProcessOutput Window # Following this protocol: any functions to which this spinner dialog can call run, but must call hide (not destroy!) # when finished. These will likely be functions that start threads. # TODO: need to make the spinnerDialog take a thread and start it after the dialog is shown, otherwise, this could lead to an undestroyable dialog spinnerDialog = SpinnerDialog( self, "Exporting to EBX archive, this may take a few minutes...") GLib.idle_add(spinnerDialog.set_title, "Exporting...") self.session.exportWorkshop(folderPath, spinnerDialog) spinnerDialog.run() # this destroy will happen only after any hides; hides be called after the destroy spinnerDialog.destroy() dialog = Gtk.MessageDialog( self, 0, Gtk.MessageType.INFO, Gtk.ButtonsType.OK, self.session.currentWorkshop.filename + " export complete\r\nFile created in: " + str(folderPath)) dialog.run() dialog.destroy()
def importActionEvent(self, menuItem): logging.debug("importVMActionEvent() initiated") dialog = Gtk.FileChooserDialog( "Please select a EBX archive to import.", self, Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) response = dialog.run() if response == Gtk.ResponseType.OK: zipPath = dialog.get_filename() # get path for temporary directory to hold uncompressed files tempPath = os.path.join( os.path.dirname(zipPath), "creatorImportTemp", os.path.splitext(os.path.basename(zipPath))[0]) baseTempPath = os.path.join(os.path.dirname(zipPath), "creatorImportTemp") dialog.destroy() # First we need to unzip the import file to a temp folder # Following this protocol: any functions to which this spinner dialog can call run, but must call hide (not destroy!) # when finished. These will likely be functions that start threads. # TODO: need to make the spinnerDialog take a thread and start it after the dialog is shown, otherwise, this could lead to an undestroyable dialog spinnerDialog = SpinnerDialog( self, "Preparing to decompress EBX archive") self.session.importUnzip(zipPath, spinnerDialog) spinnerDialog.show() ovaList = [] xmlList = [] materialList = [] rdpList = [] # Get all files that end with .ova if os.path.exists(tempPath): baseFiles = os.listdir(tempPath) for filename in baseFiles: if filename.endswith(".ova"): ovaList.append(filename) elif filename.endswith(".xml"): xmlList.append(filename) materialsPath = os.path.join(tempPath, "Materials") logging.debug("importActionEvent(): Materials folder to search: " + str(materialsPath)) if os.path.exists(materialsPath): materialsFiles = os.listdir(materialsPath) logging.debug("importActionEvent(): Materials to import: " + str(materialsFiles)) for filename in materialsFiles: logging.debug( "importActionEvent(): Adding material to workshop: " + str(filename)) materialList.append(filename) rdpPath = os.path.join(tempPath, "RDP") if os.path.exists(rdpPath): rdpFiles = os.listdir(rdpPath) for filename in rdpFiles: rdpList.append(filename) vmNum = 1 for ova in ovaList: prog = float(float(vmNum) / len(ovaList)) logging.debug("importActionEvent(): Importing " + str(ova) + " into VirtualBox...") GLib.idle_add(spinnerDialog.setTitleVal, "Importing VMs") GLib.idle_add( spinnerDialog.setLabelVal, "Importing VM " + str(vmNum) + " of " + str(len(ovaList))) GLib.idle_add(spinnerDialog.setProgressVal, prog) #HERE is where pd = ProcessDialog(VBOXMANAGE_DIRECTORY + " import " + os.path.join(tempPath, ova) + " --options keepallmacs", granularity="char", capture="stderr") pd.run() vmNum = vmNum + 1 spinnerDialog.destroy() for xml in xmlList: # here we need to parse the file in order to obtain the groupBaseName logging.debug("importActionEvent(): Found XML file: " + xml) shutil.copy2(os.path.join(tempPath, xml), WORKSHOP_CONFIG_DIRECTORY) self.filename = os.path.join(tempPath, xmlList[0]) logging.debug( "importActionEvent(): Loading config file XML data: " + self.filename) tree = ET.parse(self.filename) root = tree.getroot() vmset = root.find('testbed-setup').find('vm-set') currXMLWorkshopGroupName = vmset.find('base-groupname').text logging.debug( "importActionEvent(): using workshop group name for directory creation: " + currXMLWorkshopGroupName) holdMatPath = os.path.join(WORKSHOP_MATERIAL_DIRECTORY, currXMLWorkshopGroupName) if not os.path.exists(holdMatPath): os.makedirs(holdMatPath) for material in materialList: logging.debug("importActionEvent(): Processing file " + str(material)) logging.debug("importActionEvent(): Checking for " + os.path.join(holdMatPath, material)) if not os.path.exists(os.path.join(holdMatPath, material)): logging.debug( "importActionEvent(): copying file " + str(os.path.join(tempPath, "Materials", material)) + " to " + str(material)) shutil.copy2(os.path.join(tempPath, "Materials", material), holdMatPath) holdRDPPath = os.path.join(WORKSHOP_RDP_DIRECTORY, currXMLWorkshopGroupName) if not os.path.exists(holdRDPPath): os.makedirs(holdRDPPath) for rdp in rdpList: if not os.path.exists(holdRDPPath + rdp): shutil.copy2(os.path.join(tempPath, "RDP", rdp), holdRDPPath) dialog = Gtk.MessageDialog(self, 0, Gtk.MessageType.INFO, Gtk.ButtonsType.OK, "Workshop import complete.") dialog.run() dialog.destroy() # reload all xml files and create a new display self.workshopTree.clearTreeStore() self.session.loadXMLFiles(WORKSHOP_CONFIG_DIRECTORY) self.workshopTree.populateTreeStore(self.session.workshopList) shutil.rmtree(baseTempPath, ignore_errors=True) self.superMenu.refreshActionEvent(self.session.workshopList) elif response == Gtk.ResponseType.CANCEL: dialog.destroy()