def on_ok(self): exiting = npyscreen.notify_yes_no("Are you sure you want to quit?","Quit?", editw=1) if exiting: npyscreen.notify_confirm("Goodbye!", editw=1) self.parentApp.switchForm(None) else: pass
def exit_form(self): exiting = npyscreen.notify_yes_no("Are you sure you want to quit?","Quit?", editw=1) if exiting: npyscreen.notify_confirm("Goodbye!", editw=1) exit() else: pass
def delete_button(*args): # get index of the currently selected email selected_msg_index = self.cursor_pos # get the uid of the mail num_msgs = len(self.parentApp.mail.inbox_messages) # ensure the last message is not deleted. if num_msgs == 1: npyscreen.notify_ok_cancel("Can't delete last message in box") return msg_uid = self.parentApp.mail.inbox_messages[selected_msg_index].uid # call server to delete the msg with the specified id rv = self.parentApp.mail.delete_msg(msg_uid) if rv == 'OK': del self.parentApp.mail.email_hdr_lst[selected_msg_index] del self.parentApp.mail.inbox_messages[selected_msg_index] del self.msg_headers.msg_unread[selected_msg_index] # upate the indexes of the read and unread emails. self.msg_headers.update() # update the message body being displayed # if we delete the last message show the one above # otherwise show the one below if num_msgs == selected_msg_index + 1: self.parentApp.INBOX_MSG_TXT = self.parentApp.mail.inbox_messages[selected_msg_index - 2].body else: self.parentApp.INBOX_MSG_TXT = self.parentApp.mail.inbox_messages[selected_msg_index].body # update the display self.msg_body.value = self.parentApp.INBOX_MSG_TXT self.msg_body.update() else: npyscreen.notify_confirm("Failed to delete")
def build(self, userlist, order): with self.parent.lock: if not self.parent.chat in order: npyscreen.notify_confirm("No such order: %s" % self.parent.chat) return 0 for akey in range(0, self.maxheight-1): self.widgets[akey] = self.parent.add(userListText, name="%s-%s" % (self.parent.chat, akey), relx=self.relx, rely=self.rely+akey, value="", max_height=1, begin_entry_at=0, max_width=self.width, width=self.width, editable=0) self.widgets[akey].hookparent(self) self.widgets[akey].add_handlers({curses.ascii.NL: self.widgets[akey].selected}) for key in order[self.parent.chat]: auser = self.parent.librewired.getUserByID(key) if not auser: continue acctype = 0 if auser.login: if auser.login.upper() != "GUEST": acctype = 1 if int(auser.admin): acctype = 2 self.users.append(UserListItem(self, int(auser.userid), decode(auser.nick), auser.status, int(auser.idle), acctype)) self.updateList() return 1
def on_cancel(self): exit = npyscreen.notify_yes_no("Are you sure you want to cancel") if exit: npyscreen.notify_confirm("Thank you for using PyMp3. GoodBye!", "Cancel!") self.parentApp.setNextForm(None) else: npyscreen.notify_confirm("You may continue listening", "Okay")
def on_ok(self): # required field validation if self.wgColumnName.value == '': npyscreen.notify_confirm("Column name is a required field.", editw=1) return if self.wgNullable.value == [1] and self.wgDefault.value == '': npyscreen.notify_confirm("You must set a default value when adding NOT NULL columns.", editw=1) return # get new values from the form - we need to be able to compare with # old values to determine what has changed self.new_values = {} self.new_values['colname'] = self.wgColumnName.value self.new_values['datatype'] = self.wgDataType.values[self.wgDataType.value[0]] self.new_values['nullable'] = self.wgNullable.value self.new_values['default'] = self.wgDefault.value self.new_values['unique'] = self.wgUnique.value self.new_values['pk'] = self.wgPrimaryKey.value if self.action == 'add': self.parentApp.sql.add_column(self.table_name, self.new_values) if self.action == 'edit': self.parentApp.sql.edit_column(self.table_name, self.old_values, self.new_values) self.parentApp.switchForm('STRUCTURE')
def on_ok(self): exiting = npyscreen.notify_yes_no("Are you sure you want to quit?","Cancel?", editw=1) if exiting: npyscreen.notify_confirm("Goodbye!", editw=1) self.parentApp.setNextForm(None) else: npyscreen.notify_confirm("Please enter login information.", "Back to it!", editw=1)
def create(self): #Keep it from crashing when terminal size changes self.ALLOW_RESIZE = False self.OK_BUTTON_TEXT = "Next" self.CANCEL_BUTTON_TEXT = "Exit" self._widget_list = [] #Add a keybind to skip to the next form self.add_handlers({"^F": self.skipForm}) #Intro message message="""Welcome to AXIOME\nTo navigate through the UI, use arrow keys or TAB. \nENTER will select an option, and SPACE will deselect an option. \nIf you get stuck in the UI, TAB will move you to the next UI element. \nCRTL-F will skip to the forward one page, and CTRL-D will skip back one page. \nBefore we begin, you require: \n\t- File mapping in tab-separated spreadsheet format (.tsv) \n\t- Metadata mapping in tab-separated spreadsheet format (.tsv, same as required by QIIME) \n\tTemplates of these files can be generated with `axiome utility mapping_template`""" nps.notify_confirm(message=message, title="Message", form_color='STANDOUT', wrap=True, wide=True, editw=1) self.name = "Select Workflow" #Get the possible workflows from the master.xml file workflow_list = getWorkflowList() if self.parentApp.ax_file: self.parentApp.AxAnal = AxiomeAnalysis(self.parentApp.ax_file) value = workflow_list.index(self.parentApp.AxAnal.getWorkflow()) else: try: value = workflow_list.index("Default") except: value = 0 self.add_widget_intelligent(nps.TitleSelectOne, name="Select Workflow", w_id="select_workflow", values=workflow_list, value=value, max_height=len(workflow_list)+2, scroll_exit=True)
def system_commands(self, action): """ Perform system commands """ if action == "reset": okay = npyscreen.notify_ok_cancel( "This factory reset will remove ALL of Vent's user data, " "containers, and images. Are you sure?", title="Confirm system command") if okay: d_cli = docker.from_env() # remove containers list = d_cli.containers.list(filters={'label':'vent'}, all=True) for c in list: c.remove(force=True) # remove images list = d_cli.images.list(filters={'label':'vent'}, all=True) for i in list: d_cli.images.remove(image=i.id, force=True) # remove .vent folder try: shutil.rmtree(os.path.join(os.path.expanduser('~'),'.vent')) except Exception as e: # pragma: no cover npyscreen.notify_confirm("Error deleting Vent data: "+repr(e)) else: npyscreen.notify_confirm("Vent reset complete. " "Press OK to exit Vent Manager console.") self.exit() pass elif action == "upgrade": # !! TODO pass return
def del_entry(self): delete = npyscreen.notify_yes_no("Are you sure you want to delete this entry?", "Delete?", editw=1) if delete: db.remove(self.value) npyscreen.notify_confirm("Entry was deleted successfully!", editw=1) self.parentApp.switchForm("LISTENTRIES")
def whenPressed(self): # set the global variables global dbhost global dbport global dbname global dbuser global dbpass # fill in the fields dbhost = self.parent.get_widget('DbHost').value dbport = self.parent.get_widget('DbPort').value dbname = self.parent.get_widget('DbName').value dbuser = self.parent.get_widget('DbUser').value dbpass = self.parent.get_widget('DbPass').value try: # declare and modify the global con global con con = psycopg2.connect(database=dbname, user=dbuser, password=dbpass, host=dbhost, port=dbport) except psycopg2.DatabaseError, e: npyscreen.notify_confirm("Could not connect to database! Please try again!") return
def notify_not_logged_in(self): # Called when the user tries to access a form when not logged in. npyscreen.notify_confirm("Please log in to Oracle Database first!", title="No Database Connection", form_color='STANDOUT', wrap=True, wide=False, editw=1) self.parentApp.switchForm("MAIN")
def autoconnect(self, bookmarkname): if not self.config.has_section(bookmarkname): return 0 server = self.config.get(bookmarkname, 'server') port = self.config.get(bookmarkname, 'port') user = self.config.get(bookmarkname, 'user') password = self.config.get(bookmarkname, 'password') autoreconnect = int(self.config.get(bookmarkname, 'autoreconnect')) conID = self.parent.conID self.parent.conID += 1 self.parent.servers[conID] = rewiredInstance.rewiredInstance(self.parent, conID, server, port, user, password, autoreconnect, bookmarkname) if self.parent.servers[conID].fail: if self.parent.servers[conID].fail == 1: npyscreen.notify_confirm("Failed to connect to %s" % server, "Failed to connect") if self.parent.servers[conID].fail == 2: npyscreen.notify_confirm("Login Failed", "Login Failed") self.parent.servers[conID].librewired.keepalive = 0 del(self.parent.servers[conID]) return 0 form = "%s-CHAT1" % (conID) self.parent.servers[conID].forms.append(form) self.parent.registerForm(form, self.parent.servers[conID].chats[1]) return form
def buildPdf(self): to_pdffile = self._takeoff() ap_pdffile = self._airplane() ck_pdffile = self._checklist() output = PdfFileWriter() self.addAllPages(output, PdfFileReader(file(ck_pdffile, "rb"))) self.addAllPages(output, PdfFileReader(file(to_pdffile, "rb"))) self.addAllPages(output, PdfFileReader(file(ap_pdffile, "rb"))) # Add AD Info Charts files = dict() for pdf in self.getExternalPdf(self.eVfrPath, self.__fligthplan.performance_takeoff.aerodrome.code): files[pdf] = file(pdf, "rb") files["%s_" % pdf] = PdfFileReader(files[pdf]) if files["%s_" % pdf].getIsEncrypted(): pdfCracked = PdfCracker().crack(pdf) files[pdf] = file(pdfCracked, "rb") files["%s_" % pdf] = PdfFileReader(files[pdf]) self.addAllPages(output=output, input=files["%s_" % pdf]) # write out the merged file outputPdf = os.path.join(self.outputdir, 'flightplan %s.pdf' % self.__fligthplan.title) outputStream = file(outputPdf, "wb") output.write(outputStream) outputStream.close() npyscreen.notify_confirm( message="Your pretty Fligthplan has been created at\n\n%s" % outputPdf )
def to_plain_text(self): utils.WriteFile.toText(db.view(self.value)[1], db.view(self.value)[2], db.view(self.value)[3]) msg = "Saved as {}".format(utils.USER_HOME+"/"+db.view(self.value)[2]+" - "+db.view (self.value)[1]+".txt") npyscreen.notify_confirm(msg, editw=1)
def process_query(self): if not self.user_query.value: npyscreen.notify_confirm("Please enter a vehicle serial no.", editw=1, title='Error') return # Build query for when user picks "Search by vehicle serial no" query = """ SELECT h.serial_no AS Serial_No, COUNT(DISTINCT transaction_id) AS Number_of_Sales, AVG(price) AS Average_Price, COUNT(DISTINCT t.ticket_no) AS Number_of_Tickets FROM vehicle h, auto_sale a, ticket t WHERE t.vehicle_id (+)= h.serial_no AND a.vehicle_id (+)= h.serial_no AND UPPER(:serial_no) = UPPER(h.serial_no) GROUP BY h.serial_no """ results = self.parentApp.db.query( {"serial_no":self.user_query.value.ljust(15, ' ')}, query) # If we get an empty list as a query result notify the user if not results: npyscreen.notify_confirm( "No results were found for your query. " "Vehicle Serial No does not exist in database", editw=1, title='Error') return # begin the resuls with a new line self.results.values = ['\n'] joined = dict() # get column names for printing column_name = self.parentApp.db.cursor.description # iterate through each record and fill in details for record in results: record_no = record[0] # iterate through each column in the record joined[record_no] = list() for column_no in range(len(record)): if record[column_no] != None: # format column name c_name = \ column_name[column_no][0].replace("_", " ").lower().capitalize()+':' if column_no == 2: joined[record_no].append("{0: <20} ${1}\n".format( c_name, str(round(record[column_no], 2)))) else: joined[record_no].append( "{0: <20} {1}\n".format(c_name, str(record[column_no]))) else: c_name = \ column_name[column_no][0].replace("_", " ").lower().capitalize()+':' joined[record_no].append("{0: <20} {1}\n".format(c_name, "N/A")) joined[record_no].append('\n') # Append the result to the form self.results.values.extend(joined[record_no])
def send_button_press(): # regex courtesy of http://www.webmonkey.com #/2008/08/four_regular_expressions_to_check_email_addresses/ # parse the address out of the "To" field parsed_to = re.search('.+\@.+\..+', self.to.value) try: to = parsed_to.group().strip(' <>') except Exception as e: npyscreen.notify_confirm(str(e), title="Mail error", form_color='STANDOUT', wrap=True, wide=False, editw=1) return subj = self.subject.value body = self.message.value #replace '\n' with '\r\n' to match content-type: text/plain #for sending and recieving emails body = re.sub('\n','\r\n',body) self.parentApp.mail.send(to, subj, body) npyscreen.notify_confirm("Mail sent", title="Send Confirmation", form_color='STANDOUT', wrap=True, wide=False, editw=1) self.parentApp.switchForm("INBOX")
def beforeEditing(self): try: self.parentApp.rows_per_page = int(self.parentApp.results_per_page.value) if self.parentApp.rows_per_page < 1: self.parentApp.rows_per_page = 1 elif self.parentApp.rows_per_page > 15: self.parentApp.rows_per_page = 15 except Exception as e: npyscreen.notify_confirm("Error: You may only display 1-15 results per page." + str(e), editw=1) self.parentApp.switchForm('CHOOSE') self.name = "Browsing table %s" % self.value self.SQL_display.value = None try: # sql stmt execution self.colnames, self.results = self.parentApp.sql.browse_table(self.value) col_names = ' ' * 3 for x in range(0, len(self.colnames)): col_names += " | " + self.colnames[x] self.col_display.value = col_names # pagination self.page = 0 self.total_pages = int(ceil(len(self.results) / float(self.parentApp.rows_per_page))) self.displayResultsGrid(self.page) except Exception, e: npyscreen.notify_confirm("e: %s" % e, editw=1)
def on_ok(self): try: rangoTemperatura = magnitudes.Rango( magnitudes.TemperaturaEnCelsius(float(self._wTemperaturaMin.value)), magnitudes.TemperaturaEnCelsius(float(self._wTemperaturaMax.value)), ) rangoHumedad = magnitudes.Rango( magnitudes.HumedadRelativa(magnitudes.Porcentaje(float(self._wHumedadMin.value))), magnitudes.HumedadRelativa(magnitudes.Porcentaje(float(self._wHumedadMax.value))), ) rangoAcidez = magnitudes.Rango( magnitudes.AcidezEnPH(float(self._wAcidezMin.value)), magnitudes.AcidezEnPH(float(self._wAcidezMax.value)), ) estadio = plan_maestro.CicloDeVida.estadios()[self._wEstadio.value] nuevoUmbral = plan_maestro.UmbralOptimoDeCultivo(estadio, rangoTemperatura, rangoHumedad, rangoAcidez) self._planMaestro[estadio] = nuevoUmbral except Exception as err: npyscreen.notify_confirm("Error: {0}".format(err)) else: self.parentApp.setNextForm("MAIN")
def popup(original, orig_type, thr, title): """ Start the thread and display a popup of info until the thread is finished """ thr.start() info_str = '' while thr.is_alive(): if orig_type == 'containers': info = diff(Containers(), original) elif orig_type == 'images': info = diff(Images(), original) if info: info_str = '' for entry in info: info_str = entry[0] + ': ' + entry[1] + '\n' + info_str if self.action['action_name'] != 'configure': npyscreen.notify_wait(info_str, title=title) time.sleep(1) thr.join() try: result = self.api_action.queue.get(False) if isinstance(result, tuple) and isinstance(result[1], tuple): running, failed = result[1] r_str = '' for container in running: r_str += container + ': successful\n' for container in failed: r_str += container + ': failed\n' npyscreen.notify_confirm(r_str) except Exception as e: # pragma: no cover pass return
def run_sql(self, query, return_flag): if query: try: c = self.conn.cursor() c.execute(query) if query[:6].upper() in ['INSERT','UPDATE','DELETE']: row_count = c.rowcount npyscreen.notify_confirm("Successful " + query[0:6] + " on %s rows" % row_count) if return_flag: # http://stackoverflow.com/questions/10252247/how-do-i-get-a-list-of-column-names-from-a-psycopg2-cursor colnames = [desc[0] for desc in c.description] results = c.fetchall() return colnames, results else: return except Exception, e: # psql transactions posted after a failed transaction # on the same cxn will fail if the original transaction # is not rolled back first # http://stackoverflow.com/questions/10399727/psqlexception-current-transaction-is-aborted-commands-ignored-until-end-of-tra npyscreen.notify_confirm("e: %s" % e) c.execute("ROLLBACK;") finally:
def table_structure(self, table_name): try: c = self.conn.cursor() # http://www.postgresql.org/docs/9.1/static/information-schema.html # http://dba.stackexchange.com/questions/32975/error-could-not-find-array-type-for-datatype-information-schema-sql-identifier # retreive column and key column usage metadata query_string = 'SELECT c.column_name, c.data_type, c.is_nullable, \ c.column_default, array_agg(cc.constraint_type::text) AS constraints\ FROM information_schema.columns c\ LEFT JOIN ( \ SELECT tc.constraint_type, kcu.column_name \ FROM information_schema.table_constraints tc \ JOIN information_schema.key_column_usage kcu \ ON tc.constraint_catalog = kcu.constraint_catalog \ AND tc.constraint_schema = kcu.constraint_schema \ AND tc.constraint_name = kcu.constraint_name \ WHERE tc.constraint_type = \'PRIMARY KEY\' \ OR tc.constraint_type = \'UNIQUE\' \ ) AS cc \ ON c.column_name = cc.column_name \ WHERE c.table_name = \'%s\' \ GROUP BY c.column_name, c.data_type, \ c.is_nullable, c.column_default;' % table_name c.execute(query_string) colnames = [desc[0] for desc in c.description] results = c.fetchall() npyscreen.notify_confirm('%s' % results) return colnames, results except Exception, e: npyscreen.notify_confirm("e: %s" % e) c.execute("ROLLBACK;")
def on_ok(self): try: quick_setup(self.theHost.value,int(self.thePort.value),self.theRootPassword.value,self.theTmpDir.value,self.theRootDir.value,self.theFileName.value,int(self.theWebPort.value),self.theLogLevel.value,self.theStaticDir.value,self.theAssetDir.value,self.theUsername.value,self.thePassword.value) self.parentApp.setNextForm(None) except ARMException as e: np.notify_confirm(str(e), title = 'Error') except SQLAlchemyError as e: np.notify_confirm('Error adding CAIRIS user: '******'Error')
def viewAllHeaders(self,): s_header_list = [] for headers in list(self.this_email.keys()): these_headers = self.this_email.get_all(headers) if these_headers: for h in these_headers: s_header_list.append(str(headers).capitalize() + ": " + h.strip()) npyscreen.notify_confirm(s_header_list, wide=True, wrap=True)
def on_cancel(self): try: self.parentApp.sql = PostgreSQL(self.dbname.value, self.dbuser.value, self.dbpass.value, self.dbhost.value, self.dbport.value) npyscreen.notify_confirm("Successfully connected to the database!","Connected", editw=1) self.parentApp.setNextForm('MAINMENU') except: npyscreen.notify_confirm("Error: Could not connect to database. If you are unsure, do not alter the Host or Port values.", editw=1) self.parentApp.setNextForm('MAIN')
def viewShortHeaders(self,): s_header_list = [] for headers in self.SHORT_HEADER_LIST: these_headers = self.this_email.get_all(headers) if these_headers: for h in these_headers: s_header_list.append(str(headers).capitalize() + ": " + h.strip()) npyscreen.notify_confirm(s_header_list, wide=True, wrap=False)
def get_help(self, *args, **keywords): npyscreen.notify_confirm( title="Help", message = "q: Quit and mark read\n" + "w: Leave unread\n" + "i: Show feed information\n" + "a: Add to pocket" )
def on_ok(self): opt = self.menu_option.get_selected_objects() if not opt: error("Please select an option to continue or select 'Cancel' to exit the application ",ERROR_MSGS[0]) elif opt[0] == self.menu_options[0]: self.parentApp.change_form('CONFIG') elif opt[0] == self.menu_options[1]: _nps.notify_confirm("This feature will be implemented in a future update", title="Invalid Option", form_color='STANDOUT', wrap=True, wide=False) pass
def on_tweet(self): post = self.tweet.value if len(post) == 0: notify_confirm('You can\'t post an empty tweet') elif len(post) > 140: notify_confirm('Your tweet is too long!', title='Error') elif notify_yes_no('Are you sure you want to post:\n' + post, title='Post'): self.post_tweet(post) self.tweet.value = ''
def executeSQL(_sqlq): # to safeguard against dropped connections global cursor try: cursor.execute(_sqlq) except: npyscreen.notify_confirm("Need to reconnect to datahase") cursor = connectDatabase(dbHost) cursor.execute(_sqlq)
def quit(self, *args, **kargs): """ Quit without making any changes to the tool """ npyscreen.notify_confirm('No changes made to instance(s)', title='Instance confiugration cancelled') self.change_screens()
def restore(self): try: if os.path.isfile( str(settings.STATICFILES_DIRS[0] + '/' + 'config.aron.factory.prx')): load_f = gzip.open( str(settings.STATICFILES_DIRS[0] + '/' + 'config.aron.factory.prx'), 'rb') ctx = decrypt(load_f.read()) with transaction.atomic(): cursor.execute(ctx) load_f.close() mac_file = open(settings.FIREHOL_DIR + 'mac_allow', 'w') sql_ctx = 'SELECT mac from aron.Network_management;' _db = MySQLdb.connect( settings.DATABASES.values()[0]['HOST'], settings.DATABASES.values()[0]['USER'], settings.DATABASES.values()[0]['PASSWORD'], settings.DATABASES.values()[0]['NAME']) cur = _db.cursor() cur.execute(sql_ctx) manager = cur.fetchall() mac_file.write(str(manager[0][0] + '\n')) mac_file.close() call(["sudo", "firehol", "restart"]) proxy_conf = open(settings.SQUID_CONF, 'w') squid_conf = 'http_port 3128 intercept\n' \ 'acl localnet src 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8\n' \ 'acl localnet src fc00::/7\n' \ 'acl localnet src fe80::/10\n' \ 'acl SSL_ports port 443\n' \ 'acl Safe_ports port 80\n' \ 'acl Safe_ports port 21\n' \ 'acl Safe_ports port 443\n' \ 'acl Safe_ports port 70\n' \ 'acl Safe_ports port 210\n' \ 'acl Safe_ports port 1025-65535\n' \ 'acl Safe_ports port 280\n' \ 'acl Safe_ports port 488\n' \ 'acl Safe_ports port 591\n' \ 'acl Safe_ports port 777\n' \ 'acl CONNECT method CONNECT\n' \ 'http_access allow localnet\n' \ 'http_access deny all\n' \ 'negative_ttl 5 minutes\n' \ 'positive_dns_ttl 15 hours\n' \ 'negative_dns_ttl 1 minutes\n' \ 'shutdown_lifetime 1\n' \ 'cache_mgr [email protected]\n' \ 'visible_hostname Aron-Proxy\n' \ 'dns_nameservers 8.8.8.8 8.8.4.4\n' \ 'access_log none\n' proxy_conf.write(squid_conf) proxy_conf.close() call(["sudo", "/etc/init.d/squid", "restart"]) call(["sudo", "/etc/init.d/apache2", "restart"]) call(["sudo", "chmod", "666", "/etc/squid/squid.conf"]) npyscreen.notify_confirm( "Ripristino di configurazione per default.") else: npyscreen.notify_confirm( "Il file non essiste perche ancora non e' stata attivata la licenza." ) except: npyscreen.notify_confirm( "E' stato riscontrato un errore nella importazione del file.")
def exit_form(self): npyscreen.notify_confirm("You have decided to exit the Menu", "Item 1", editw=1) self.parentApp.switchForm(None)
def validate_forms(self): query = """SELECT COUNT(licence_no) FROM drive_licence WHERE licence_no = :lic""" if self.parentApp.db.query( {'lic': self.licence_no.value.ljust(15, ' ')}, query)[0][0] != 0: npyscreen.notify_confirm( "Licence number already in use. Choose another.", title="Error", form_color='STANDOUT', wrap=True, wide=False, editw=1) return False # Ensure sin is not left blank if self.sin.value == '': npyscreen.notify_confirm("Please enter a SIN", title="Error", form_color='STANDOUT', wrap=True, wide=False, editw=1) return False # Ensure sin exists in people table query = "SELECT COUNT(sin) FROM people WHERE sin = :sin" if self.parentApp.db.query({'sin': self.sin.value.ljust(15, ' ')}, query)[0][0] == 0: npyscreen.notify_confirm("Invalid SIN. Person does not exist", title="Error", form_color='STANDOUT', wrap=True, wide=False, editw=1) return False # Ensure sin is not already in the drive_licence table query = "SELECT COUNT(sin) FROM drive_licence WHERE sin = :sin" if self.parentApp.db.query({'sin': self.sin.value.ljust(15, ' ')}, query)[0][0] != 0: npyscreen.notify_confirm("Person with sin: " + self.sin.value + " is already licenced", title="Error", form_color='STANDOUT', wrap=True, wide=False, editw=1) return False # Ensure file path for image is valid if self.photo.value: if not os.path.isfile(self.photo.value): npyscreen.notify_confirm("You must select a valid image path", title="Bad image path", form_color='STANDOUT', wrap=True, wide=False, editw=1) return False # Make sure we don't try to date format an empty string. if self.issuing_date.value: self.issuing_date.value = \ self.issuing_date.value.strftime("%d-%b-%y") if self.expiring_date.value: self.expiring_date.value = \ self.expiring_date.value.strftime("%d-%b-%y") return True
def per_page_pause(locNextPg, locTotPgs): """Displays a 'Press Key to Scan Next Page' box after each page scan is complete.""" locMsg = 'Press OK to scan page ' + str(locNextPg) + ' of ' + str( locTotPgs) npyscreen.notify_confirm(locMsg, title='Message', editw=1)
def whenPressed(self): output_text = self.parent.get_widget('CommandTextBox').values try: # declare the global con global con # get current database connection cur = con.cursor() # execute it for value in output_text: cur.execute(value) con.commit() testCommandString = cur.query testFirstStringInCommand = testCommandString.partition(' ')[0] if (testFirstStringInCommand == 'SELECT'): rows = cur.fetchall() outputList = [] # convert the row objects returned into individual strings for row in rows: outputList.append(str(row)) # add strings to the ResultTextBox self.parent.get_widget('ResultTextBox').values = outputList # now display the values that were added self.parent.get_widget('ResultTextBox').display() elif (testFirstStringInCommand == 'DROP'): npyscreen.notify_confirm("Table Dropped!") else: # add testCommandString to the ResultTextBox outputList = [] outputList.append(testCommandString) self.parent.get_widget('ResultTextBox').values = outputList # now display the values that were added self.parent.get_widget('ResultTextBox').display() except psycopg2.DatabaseError, e: # clear the current transaction to free up the con if con: con.rollback() npyscreen.notify_confirm("Command did not work! Please try again!") return
def validate_entries(self): # Ensure we can convert the user data to the appropriate data types # check type_id and year separately, but not if they're left # blank (to allow NULL values). try: if not self.year.value == '': int(self.year.value) except ValueError: npyscreen.notify_confirm("Year must be an integer.", title="Error", form_color='STANDOUT', wrap=True, wide=False, editw=1) return False try: if not self.type_id.value == '': int(self.type_id.value) except ValueError: npyscreen.notify_confirm("Type ID must be an integer.", title="Error", form_color='STANDOUT', wrap=True, wide=False, editw=1) return False # Check if serial_no is in existing database query = """SELECT count(SERIAL_NO) FROM vehicle where SERIAL_NO = :serial_no""" if self.parentApp.db.query( {'serial_no': self.serial_no.value.ljust(15, ' ')}, query)[0][0]: npyscreen.notify_confirm("Serial no already exists in database.", title="Serial no error", form_color='STANDOUT', wrap=True, wide=False, editw=1) return False # Ensure that the provided vehicle type id exists in the database if not self.type_id.value == '': query = """SELECT count(type_id) FROM vehicle_type where type_id = :type_id""" if self.parentApp.db.query({'type_id': int(self.type_id.value)}, query)[0][0] == 0: npyscreen.notify_confirm( "Vehicle Type ID %s does not exist in database." % (self.type_id.value), title="Type ID Error", form_color='STANDOUT', wrap=True, wide=False, editw=1) return False # Notify user that the first owner must be primary if self.p_owner.values[0] == '': npyscreen.notify_confirm("Please enter a primary owner.", title="Error", form_color='STANDOUT', wrap=True, wide=False, editw=1) return False # If we pass all of our conditions return True to the caller to indicate # it can proceed with database entry. return True
def valid_input(val): """ Ensure the input the user gave is of a valid format """ # looks for 3 nums followed by a dot 3 times and then ending with # 3 nums, can be proceeded by any number of spaces ip_value = re.compile(r'(\d{1,3}\.){3}\d{1,3}$') # looks for only numbers and commas (because priorities can have commas # between them), can be proceeded by any number of spaces all_num = re.compile(r'(\d,?\ *)+$') sections_comments = re.compile( r""" \ *\#.* # comments (any number of whitespace, then # # followed by anything) | \[[\w-]+\]$ # section headers (any combination of chars, nums, # underscores, and dashes between brackets) """, re.VERBOSE) # can't can be a comment on option side and value side can't have # [, ], {, or } otherwise it is turned over to literal_eval for # checkout options_values = re.compile(r'[^# ]+\ *=[^[\]{}]*$') line_num = 0 warning_str = '' error_str = '' trimmed_val = [] for entry in val.split('\n'): line_num += 1 # get rid of any extraneous commas at the end of a dict and remove # extra whitespace from input trimmed_val.append(re.sub(r',\ *}', '}', entry).strip()) # empty line if entry.strip() == '': continue # look at regular (non dictionary or list) option-value pairs if options_values.match(entry): value = entry.split('=', 1)[1] # deal with potentially more equals signs for val in value.split('='): val = val.strip() # empty val means malformed equals signs if val == '': error_str += '-You have a misplaced equals sign on' \ ' line ' + str(line_num) + '\n' # starts with a num; look for bad ip input or warn user # about having extraneous characters in number input if re.match('\ *\d', val): # bad ip syntax if val.find('.') >= 0 and not ip_value.match(val): error_str += '-You have an incorrectly' \ ' formatted ip address (bad syntax) at' \ ' line ' + str(line_num) + '\n' # possibly malformed numbers elif val.find('.') < 0 and not all_num.match(val): warning_str += '-Line starting with a number has' \ ' characters mixed in at line ' + \ str(line_num) + '\n' # bad ip values elif val.find('.') >= 0: for num in val.strip().split('.'): num = int(num) if num > 255 or num < 0: error_str += '-You have an incorrectly' \ ' formatted ip address (values' \ ' exceeding 255 or below 0) at' \ ' line ' + str(line_num) + '\n' # ensure no lines end with a comma (most likely extraneous # commas from groups or priorities) if re.search(',$', val): error_str += '-You have an incorrect comma at the' \ ' end of line ' + str(line_num) + '\n' # see if input is a header or comment, otherwise try to # literal_eval it to ensure correct structure elif not sections_comments.match(entry): lit_val = '' try: opt_val = entry.split('=', 1) if opt_val[0].strip() == '': error_str += '-You have nothing preceeding an' \ ' equals sign at line ' + str(line_num) + '\n' else: lit_val = opt_val[1].strip() except IndexError: lit_val = '' error_str += '-You have an incorrectly formatted' \ ' section header at line ' + str(line_num) + '\n' if lit_val: try: ast.literal_eval(lit_val) except SyntaxError: error_str += '-You have an incorrectly formatted' \ ' list/dictionary at line ' + str(line_num) + \ '\n' if error_str: npyscreen.notify_confirm('You have the following error(s) and' " can't proceed until they are fixed:" + '\n' + '-' * 50 + '\n' + error_str, title='Error in input') return (False, '') elif warning_str: res = npyscreen.notify_yes_no( 'You have may have some error(s)' ' that you want to check before' ' proceeding:' + '\n' + '-' * 50 + '\n' + warning_str + '\n' + '-' * 50 + '\n' + 'Do you want to continue?', title='Double check') return (res, '\n'.join(trimmed_val)) return (True, '\n'.join(trimmed_val))
def whenDisplayText(self, argument): npyscreen.notify_confirm(argument)
def __displayConfirmation(self, error, title): npyscreen.notify_confirm(error, title=title) self.display()
def on_ok(self): remote_hosts = "".join(self.add_hosts_ip_addresses.value.split()).split(',') if not remote_hosts: npyscreen.notify_confirm( f"No values detected in Hosts Field", title="Information Missing/Incorrect", wide=True, editw=1) return if not self.add_hosts_username.hidden and not self.add_hosts_username.value: npyscreen.notify_confirm( f"Missing Value for Username", title="Information Missing/Incorrect", wide=True, editw=1) return if not self.add_hosts_password.hidden and not self.add_hosts_password.value: npyscreen.notify_confirm( f"Missing Value for Password", title="Information Missing/Incorrect", wide=True, editw=1) return if not self.select_hosts_method.hidden and not self.select_hosts_method.value: npyscreen.notify_confirm( f"Missing Value for Remoting Method", title="Information Missing/Incorrect", wide=True, editw=1) return args = None if self.add_hosts_args.get_values(): import json import ast try: args = ast.literal_eval(''.join(self.add_hosts_args.get_values())) except SyntaxError: try: args = json.loads(''.join(self.add_hosts_args.get_values())) except json.JSONDecodeError: npyscreen.notify_confirm( f"Failed to load additional arguments. Ensure the formatting is correct", title="Information Missing/Incorrect", wide=True, editw=1) return for address in [x for x in remote_hosts if x]: if not (self.is_valid_hostname(address) or self.is_valid_ip_address(address)): npyscreen.notify_confirm( f"Following entry: {address} is not a valid hostname or IP address", title="Information Missing/Incorrect", wide=True, editw=1) return if sv.HOSTS_CONFIG.get(address): if not npyscreen.notify_yes_no( f"Host {address} already exists, would you like to override?", title="Already Exists", editw=1): return #TODO switch to ini format with configparser sv.CHANGES_PENDING = True for address in remote_hosts: if address: sv.HOSTS_CONFIG[address] = {} sv.HOSTS_CONFIG[address]['method'] = self.select_hosts_method.get_selected_objects()[0] if not self.add_hosts_username.hidden: sv.HOSTS_CONFIG[address]['user'] = self.add_hosts_username.value sv.HOSTS_CONFIG[address]['password'] = self.add_hosts_password.value if args: for key, value in args.items(): sv.HOSTS_CONFIG[address][key] = value self.parentApp.getForm('MAIN').reload_screen() self.parentApp.switchFormPrevious()
def usage(self, *args): message = ' < or >: collapse/expand node\n { or }: collapse/expand tree\n /: set search filter\n f: set datatype filter\n r: reset all filters\n n: move next filtered\n p: move prev filtered\n q: quit application' npyscreen.notify_confirm(message, title='Usage Help')
def add_to_lbu(): npyscreen.notify_confirm("Not implemented yet :/")
def on_cancel(self): npyscreen.notify_confirm("good bye!", editw=1)
def handle_del(self, *args, **kwargs): npyscreen.notify_confirm("DEL %s %s %s" % (self.name, self.get_action_form(), kwargs))
def on_ok(self): """ Save changes made to vent.template """ # ensure user didn't have any syntactical errors input_is_good, trimmed_input = self.valid_input(self.edit_space.value) if not input_is_good: return self.edit_space.value = trimmed_input # get the number of instances and ensure user didn't malform that if re.search(r'instances\ *=', self.edit_space.value): try: # split out spaces instances_val = re.split(r'instances\ *=\ *', self.edit_space.value)[1] instances_val = instances_val.split('\n')[0] new_instances = int(re.match(r'\d+$', instances_val).group()) except AttributeError: npyscreen.notify_confirm( "You didn't specify a valid number" ' for instances.', title='Invalid' ' instance number') return # user can't change instances when configuring new instnaces if (self.instance_cfg and self.settings['new_instances'] != new_instances): npyscreen.notify_confirm( "You can't change the number of" ' instnaces while configuring new' ' instances!', title='Illegal change') return # get old number of instances try: if 'old_instances' in self.settings: old_instances = self.settings['old_instances'] else: settings_dict = json.loads( self.manifest.option(self.section, 'settings')[1]) old_instances = int(settings_dict['instances']) except Exception: old_instances = 1 else: new_instances = 1 old_instances = 1 # save changes and update manifest we're looking at with changes if self.vent_cfg: save_args = {'main_cfg': True, 'config_val': self.edit_space.value} self.manifest = self.settings['save_configure'](**save_args)[1] else: save_args = copy.deepcopy(self.tool_identifier) save_args.update({'config_val': self.edit_space.value}) if self.registry_tool: save_args.update({'from_registry': True}) if self.instance_cfg: save_args.update({'instances': new_instances}) self.manifest = self.settings['save_configure'](**save_args)[1] # restart tools, if necessary if not self.just_downloaded and not self.instance_cfg: restart_kargs = { 'main_cfg': self.vent_cfg, 'old_val': self.config_val, 'new_val': self.edit_space.value } if self.vent_cfg: wait_str = 'Restarting tools affected by changes...' else: wait_str = 'Restarting this tool with new settings...' restart_kargs.update(self.tool_identifier) npyscreen.notify_wait(wait_str, title='Restarting with changes') self.settings['restart_tools'](**restart_kargs) # start new instances if user wanted to if self.instance_cfg and self.settings['start_new']: npyscreen.notify_wait('Starting new instances...', title='Start') tool_d = {} for i in range(self.settings['old_instances'] + 1, self.settings['new_instances'] + 1): # create section by scrubbing instance number out of names # and adding new instance number i_section = self.section.rsplit(':', 2) i_section[0] = re.sub(r'[0-9]', '', i_section[0]) + str(i) i_section = ':'.join(i_section) t_name = self.manifest.option(i_section, 'name')[1] t_id = {'name': t_name} tool_d.update(self.settings['prep_start'](**t_id)[1]) if tool_d: self.settings['start_tools'](tool_d) # prompt user for instance changes, as necessary if not self.instance_cfg and not self.vent_cfg: if new_instances > old_instances: try: diff = str(new_instances - old_instances) res = npyscreen.notify_yes_no('You will be creating ' + diff + ' additional' ' instance(s) is that okay?', title='Confirm new' ' instance(s)') if res: if self.manifest.option(self.section, 'built')[1] == 'yes': run = npyscreen.notify_yes_no( 'Do you want to' ' start these new' ' tools upon' ' creation?', title='Run new' ' instance(s)') else: run = False # get clean name (no instance numbers in it) new_name = self.settings['tool_name'] new_name = re.sub(r'[0-9]+$', '', new_name) self.settings['tool_name'] = new_name npyscreen.notify_wait( 'Pulling up default settings' ' for ' + self.settings['tool_name'] + '...', title='Gathering settings') Repository(System().manifest)._clone( self.settings['repo']) self.settings['new_instances'] = new_instances self.settings['old_instances'] = old_instances self.settings['start_new'] = run self.settings['new_instance'] = True self.settings['name'] = 'Configure new instance(s)' + \ ' for ' + self.settings['tool_name'] self.parentApp.addForm( 'INSTANCEEDITOR' + self.settings['tool_name'], EditorForm, **self.settings) self.parentApp.change_form('INSTANCEEDITOR' + self.settings['tool_name']) else: return except Exception: npyscreen.notify_confirm( 'Trouble finding tools to add,' ' exiting', title='Error') self.on_cancel() elif new_instances < old_instances: try: diff = str(old_instances - new_instances) res = npyscreen.notify_yes_no('You will be deleting ' + diff + ' instance(s), is' ' that okay?', title='Confirm delete' ' instance(s)') if res: form_name = 'Delete instances for ' + \ re.sub(r'\d+$', '', self.settings['tool_name']) + '\t'*8 + \ '^E to exit configuration process' clean_section = self.section.rsplit(':', 2) clean_section[0] = re.sub(r'\d+$', '', clean_section[0]) clean_section = ':'.join(clean_section) d_args = { 'name': form_name, 'new_instances': new_instances, 'old_instances': old_instances, 'next_tool': self.settings['next_tool'], 'manifest': self.manifest, 'section': clean_section, 'clean': self.settings['clean'], 'prep_start': self.settings['prep_start'], 'start_tools': self.settings['start_tools'] } self.parentApp.addForm( 'DELETER' + self.settings['tool_name'], DeleteForm, **d_args) self.parentApp.change_form('DELETER' + self.settings['tool_name']) except Exception: npyscreen.notify_confirm( 'Trouble finding instances to' ' delete, exiting', title='Error') self.on_cancel() if (new_instances == old_instances or self.instance_cfg or self.vent_cfg): npyscreen.notify_confirm('Done configuring ' + self.settings['tool_name'], title='Configurations saved') self.change_screens()
def on_ok(self): # Ensure the user specifies a serial number if not self.serial_no.value: npyscreen.notify_confirm("Please fill in a Serial no.", title="Error", form_color='STANDOUT', wrap=True, wide=False, editw=1) self.editing = True return # Call data validation method if not self.validate_entries(): self.editing = True return # Attempt to make the database entry catch any errors that occur and # redirect the user back to the form. entry_dict = self.process_data() insert = self.prepare_statement() error = self.parentApp.db.insert(entry_dict, insert) if error: # Handle error, then return to form. self.editing = True npyscreen.notify_confirm(str(error), title="Status", form_color='STANDOUT', wrap=True, wide=False, editw=1) return # Send primary owner data to db values = { "owner_id": self.p_owner.values[0], "vehicle_id": self.serial_no.value, "is_primary_owner": 'y' } prepare = """INSERT INTO owner VALUES (:owner_id, :vehicle_id, :is_primary_owner)""" error = self.parentApp.db.insert(values, prepare) if error: # Handle error avoid main menu return self.editing = True npyscreen.notify_confirm(str(error), title="Error", form_color='STANDOUT', wrap=True, wide=False, editw=1) return # Send each secondary owner data to db for owner in self.o_owners.values: values = { "owner_id": owner, "vehicle_id": self.serial_no.value, "is_primary_owner": 'n' } prepare = """INSERT INTO owner VALUES (:owner_id, :vehicle_id, :is_primary_owner)""" error = self.parentApp.db.insert(values, prepare) if error: # Handle error avoid main menu return self.editing = True npyscreen.notify_confirm(str(error), title="Error", form_color='STANDOUT', wrap=True, wide=False, editw=1) return # Notify user that entry was successful npyscreen.notify_confirm("Success!", title="Status", form_color='STANDOUT', wrap=True, wide=False, editw=1) self.serial_no.value = '' self.maker.value = '' self.model.value = '' self.year.value = '' self.color.value = '' self.type_id.value = '' self.parentApp.NVR_primary_owner = [''] self.parentApp.NVR_other_owners = [] self.o_owners.values = self.parentApp.NVR_other_owners self.p_owner.values = self.parentApp.NVR_primary_owner
def on_cancel(self): """ Don't save changes made to vent.template """ npyscreen.notify_confirm('No changes made to ' + self.settings['tool_name'], title='Configurations not saved') self.change_screens()
def _display_popup(self, attr): widget = getattr(self, attr) row, column = widget.edit_cell msg = widget.values[row][column].as_popup() npyscreen.notify_confirm(msg, wide=True)
def prompt(self): state = self.parentApp.state self.parentApp.setNextForm('LINK') npyscreen.notify_confirm("Couldn't open your signal config file for:\nPhone: {}\nConfig dir: {}".format(state.phone, state.configDir) + "\nDo you want to link a new device right now? Hit enter twice to select the OK button. To cancel, press Ctrl+C", title="No signal-cli config")
def on_ok(self): # Deal with sin entered not being in db. If not we need to prompt the # user to enter the person into the people table. We will open this form # as a popup. query = "SELECT COUNT(sin) FROM people WHERE sin = :sin" if self.parentApp.db.query({'sin': self.sin.value.ljust(15, ' ')}, query)[0][0] == 0: # prompt to add a new person. response = npyscreen.notify_ok_cancel( "This person does not exist.\n" "Enter a person with this SIN into the database?", title="Alert", form_color='STANDOUT', wrap=True, editw=1) # If user selected ok forward them to the add person form. if response: # Set the next form to be the people form. # set vehicle_id to match the specified value before switching self.parentApp.AP_default = self.sin.value self.parentApp.switchForm('ADDPERSON') else: return return False # validate the form. if not self.validate_forms(): self.editing = True return # attempt to open the image file if self.photo.value: try: image_file = open(self.photo.value, 'rb') except IOError as exc: error, = exc.args npyscreen.notify_confirm(error.message, editw=1, title='Image Load failure') self.editing = True return # If we are successful in opening, prep image for db entry. if self.photo.value: image = image_file.read() self.parentApp.db.cursor.setinputsizes(photo=cx_Oracle.BLOB) if self.photo.value: image_file.close() else: # Should be null value. image = '' # prep and send db statement insert = """INSERT INTO drive_licence (licence_no, sin, class, photo, issuing_date, expiring_date) VALUES (:licence_no, :sin, :class, :photo, :issuing_date, :expiring_date)""" entry_dict = { 'licence_no': str(self.licence_no.value), 'sin': str(self.sin.value), 'class': str(self.licence_class.value), 'photo': image, 'issuing_date': self.issuing_date.value, 'expiring_date': self.expiring_date.value } error = self.parentApp.db.insert(entry_dict, insert) if error: self.editing = True # don't return to main menu # print error to screen npyscreen.notify_confirm(str(error), title="Status", form_color='STANDOUT', wrap=True, wide=False, editw=1) return # If we get here we have a successful entry. Notify the user. npyscreen.notify_confirm("Success!", title="Status", form_color='STANDOUT', wrap=True, wide=False, editw=1) # Clear the form for the next entry self.licence_no.value = '' self.sin.value = '' self.licence_class.value = '' self.photo.value = '' self.issuing_date.value = '' self.expiring_date.value = ''
def on_ok(): npyscreen.notify_confirm("OK Button Pressed!")
def press_2(self): npyscreen.notify_confirm("You pressed Item 2", "Item 1", editw=1)
def on_ok(self): npyscreen.notify_confirm("Use ^X to go explore!")
def on_ok(self): npyscreen.notify_confirm("Ok button was pressed", "Saved!!", editw=1) self.parentApp.setNextForm(None)
def while_waiting(self): if RDBOBJECT.processStartTime != 0: self.time_widget.hidden = False self.timeR_widget.hidden = False self.time_pb.hidden = False self.grid_db.hidden = False self.grid2.hidden = False self.time_widget.display() self.timeR_widget.display() self.time_pb.display() elapsSec = 0.0 while (not RDBOBJECT.Pfinished): #process not terminated elapsSec = int(time.time() - RDBOBJECT.processStartTime) elapsTimeStr = str(timedelta(seconds=elapsSec)) #elapsTimeStr= "{:.2f} min".format(elapsSec/60) if elapsSec >= 60.0 else "{:.2f} sec".format(elapsSec) #remTimeStr= "{:.2f} min".format(RDBOBJECT.estSecs - elapsSec/60) if RDBOBJECT.estSecs - elapsSec >= 60.0 else "{:.2f} sec".format(RDBOBJECT.estSecs - elapsSec) remTimeStr = str( timedelta(seconds=RDBOBJECT.estSecs - elapsSec)) self.time_widget.value = elapsTimeStr self.timeR_widget.value = remTimeStr self.time_pb.value = elapsSec / RDBOBJECT.estSecs * 100 if elapsSec / RDBOBJECT.estSecs * 100 <= 100 else 99.99 self.time_widget.display() self.timeR_widget.display() self.time_pb.display() time.sleep(1) RDBOBJECT.memThread.join() if elapsSec < 60: npyscreen.notify_confirm( "Elapsed time: {:.2f} sec.\nResult saved in \'mem_report.txt\'." .format(float(elapsSec)), title='Info', editw=1) else: npyscreen.notify_confirm( "Elapsed time: {:.2f} min.\nResult saved in \'mem_report.txt\'." .format(float(elapsSec) / 60.0), title='Info', editw=1) self.time_widget.hidden = True self.timeR_widget.hidden = True self.time_pb.hidden = True rdbInfo = RDBOBJECT.get_rdb_infos() self.grid.values = rdbInfo[1] rdbInfoDB = RDBOBJECT.get_rdb_DB_infos() self.grid_db.col_titles = rdbInfoDB[0] self.grid_db.values = rdbInfoDB[1] rdbInfo = RDBOBJECT.get_rdb_key_infos() self.grid2.values = rdbInfo[1] self.chosenDb.values = RDBOBJECT.get_activeDB() self.chosenDb.value = [x for x in range(len(self.chosenDb.values))] self.display() RDBOBJECT.processStartTime = 0
def on_ok(self): """ Delete the instances that the user chose to delete """ npyscreen.notify_wait('Deleting instances given...', title='In progress') # keep track of number for shifting instances down for alignment shift_num = 1 to_update = [] for i, val in enumerate(self.del_instances.values): # clean all tools for renmaing and relabeling purposes t = val.split(':') section = self.display_to_section[val] prev_running = self.manifest.option(section, 'running') run = prev_running[0] and prev_running[1] == 'yes' if i in self.del_instances.value: if run: # grab dependencies of tools that linked to previous one if i == 0: dependent_tools = [ self.manifest.option(section, 'link_name')[1] ] for dependency in Dependencies(dependent_tools): self.clean(**dependency) to_update.append(dependency) self.clean(name=t[0], branch=t[1], version=t[2]) self.manifest.del_section(section) else: try: # update instances for tools remaining section = self.display_to_section[val] settings_dict = json.loads( self.manifest.option(section, 'settings')[1]) settings_dict['instances'] = self.new_instances self.manifest.set_option(section, 'settings', json.dumps(settings_dict)) # check if tool name doesn't need to be shifted because # it's already correct identifier = str(shift_num) if shift_num != 1 else '' new_section = section.rsplit(':', 2) new_section[0] = re.sub(r'\d+$', identifier, new_section[0]) new_section = ':'.join(new_section) if section != new_section: # clean tool so that we can rename its container and # labels with new information self.clean(name=t[0], branch=t[1], version=t[2]) prev_name = self.manifest.option(section, 'name')[1] new_name = re.split(r'[0-9]', prev_name)[0] + \ identifier self.manifest.set_option(section, 'name', new_name) # copy new contents into shifted version self.manifest.add_section(new_section) for val_pair in self.manifest.section(section)[1]: self.manifest.set_option(new_section, val_pair[0], val_pair[1]) self.manifest.del_section(section) if run: to_update.append({ 'name': new_name, 'branch': t[1], 'version': t[2] }) shift_num += 1 except Exception as e: npyscreen.notify_confirm('Trouble deleting tools' ' because ' + str(e)) self.manifest.write_config() tool_d = {} for tool in to_update: tool_d.update(self.prep_start(**tool)[1]) if tool_d: self.start_tools(tool_d) npyscreen.notify_confirm('Done deleting instances.', title='Finished') self.change_screens()
def handle_del_entity(self, *args, **kwargs): npyscreen.notify_confirm("DEL %s %s" % (self.name, pprint(args), kwargs))
def handle_add(self, *args, **kwargs): npyscreen.notify_confirm("ADD %s %s %s" % (self.name, self.get_action_form(), kwargs)) self.parent.parentApp.change_form(self.get_action_form())
def popup(page): info_str = "" if page == 'Menu': info_str = """ Menu interactions are simple! Here is a quick guide to get you familiar. Navigation of a page: Up, Down, Left, Right, or TAB. Note that SHIFT+TAB can be used to reverse cycle! Editing a page: Simply navigating to an editable field and typing should be enough to edit most pages. ENTER can you be used to select or deselect options, or to open drop down menus. CTRL+T: Will toggle between two pages. CTRL+Q: Will take you back to main. Or from main, will exit the application. CTRL+X: Can be used to open up menus on certain pages. """ elif page == 'Plugins': info_str = """ Plugins are user created software hosted on GitHub that Vent can install and run. Plugins are developed following a hybrid of requirements specified both by Docker and Vent. Vent uses Docker to run all plugins so all plugins should be designed to run as a system of containers. Knowledge of linking docker containers may be necessary for more complex tasks that require creating multiple containers for your plugin. For Help on building Plugins, check out the Working with Plugins section in our Help Menu.""" elif page == 'Tools': info_str = """ Tools are the individual building blocks of a Plugin. Each tool should follow S.R.P, and over the entirety of the Plugin should be able accomplish any task desired! For Help on building Tools, check out the Working with Plugins section in our Help Menu.""" elif page == 'Filetypes': info_str = """ The filetypes Vent can support are entirely based on the installed Plugins. Each plugin is ultimately responsible for doing some form of processing.""" elif page == 'Core': info_str = """ Core Tools are tools that Vent comes with out of the box. """ elif page == 'Status': info_str = """ You'll notice Vent offers several status types amongst tools/plugins. Built means that each tool has a Docker image successfully built based off the provided specs for that tool/plugin. Enabled/Disabled correspond to user defined settings to enable or disable a tool or set of tools (plugin). Installed means simply that the plugin has been cloned from GitHub and installed to the Vent filesystem. No Docker image has been created yet. Running means that a Docker container has successfully been created from the corresponding Docker image for a specific tool in a Plugin.""" elif page == 'Plugin Adding': info_str = """ To add a plugin that you've created, simply open up the Menu from the main page using ^X. After, press "p" to open up the Plugin menu and then "a" to drop down into our Plugin installation screen. To add a Plugin, we require a valid GitHub repository. If your repository is private, you will need to enter a username and password. Once you have finished that, select OK. If we are successfully able to connect, you should see your repositories branches listed in our Plugin options menu. From here, press TAB to cycle between the options, and ENTER to select different branches to install and build from. You can even choose a specific commit if you like! Once you've selected those tools and selected OK, Vent will notify you about all tools it has detected. For more information about how Vent detects tools, see our "Building a Plugin" section. You may select or deselect the tools you wish to install as part of your Plugin. When you are done, select OK. If everything works you should get a successful Add. Select OK, to be returned to the main screen!""" elif page == 'Plugin Building': # !! TODO info_str = """Stay tuned!""" npyscreen.notify_confirm(info_str, title='About Vent ' + page, wide=True)