window.title('Utilitaires TMA') window.resizable(False, False) # Personnalisation Style style = Style(window) original_font = font.nametofont(style.lookup("TLabel", "font")) f = font.Font(**original_font.configure()) f.configure(weight='bold', underline=0, size=9) style.configure('H1.TLabel', font=f) original_font = font.nametofont(style.lookup("TButton", "font")) f2 = font.Font(**original_font.configure()) f2.configure(weight='bold', size=9) style.configure('H1.TButton', font=f2) window.grid_columnconfigure(0, weight=1) window.grid_rowconfigure(0, weight=1) window.minsize(MIN_WIDTH, MIN_HEIGHT) # FRAME Principale frame_principale = Frame(window) frame_principale.grid_columnconfigure(0, weight=1) frame_principale.grid_rowconfigure(0, weight=1) frame_principale.grid(sticky='NSEW') label_fonct = Label(frame_principale, text='Fonctionnel', style='H1.TLabel') bouton_lancer = Button(frame_principale, text="Incrémenter dates XML", command=ouvrir_incrementeur_date) bouton_dl_visualiseur = Button(frame_principale, text="installation visualiseur d'offres", command=installer_visualiseur) label_java = Label(frame_principale, text='Code Java', style='H1.TLabel') bouton_lancer_traque = Button(frame_principale, text="Vérifier clés messages", command=ouvrir_traque_mes_cles) label_version = Label(frame_principale, text="v" + __version__, font=('Arial', 8), anchor='se')
slideshow.stopSlideshow() else: root = ThemedTk() root.title("Wallpaper Changer") if (hasattr(sys, "frozen") and getattr(sys, "frozen")): img = tk.PhotoImage(file=dirname(sys.executable) + "/icon.png") else: img = tk.PhotoImage(file=dirname(realpath(__file__)) + "/icon.png") root.tk.call("wm", "iconphoto", root._w, img) root.set_theme("arc") root.grid_columnconfigure(0, weight=1) app = UI(root) app.pack() if app.slideshow.isCompatible(): app.drawUI() else: messagebox.showerror( "Wallpaper Slideshow", "Not compatible with your X_SERVER \n Contact BDeliers on gitHub if you want to add it !" ) exit() app.mainloop()
def main(): print("Scanner App Started...") # UI Updating Method def update_left_header_label(value): """UI Updating Method :param value: value to be set in left header """ if value is None: # if the provided value is none, then update to the default header host_count = DataShare.get_hosts_total() host_count_text = f"({host_count}) Hosts Scanned".format() left_frame_header_label_var.set(host_count_text) else: # else left_frame_header_label_var.set(value) def update_left_header_label_random_waiting_msg(): """Update waiting header randomly""" random_waiting_responses = [ "This may take a while...", "I'm sorry this will be a while...", "Scanning...", "Scanning in Process..." ] update_left_header_label(random.choice(random_waiting_responses)) def reset_left_header_label(): """Update left header with number of hosts scanned""" host_count = DataShare.get_hosts_total() host_count_text = f"({host_count}) Hosts Scanned".format() left_frame_header_label_var.set(host_count_text) def reload_hosts_tableview(): """Update hosts box with scanned hosts""" # hosts_listbox.delete(0, tk.END) sorted_scanned_hosts = None # Sort according to the Host Sort Setting reverse_sort = False if System.Settings.get_host_sort_type() == System.SortType.alphaDESC: reverse_sort = True if DataShare.get_hosts(): sorted_scanned_hosts = sorted(DataShare.get_hosts(), key=lambda x: (x.get_display_name()), reverse=reverse_sort) if sorted_scanned_hosts is None: return # Update hosts to the sorted version to ensure details on select are correct DataShare.set_hosts(sorted_scanned_hosts) reset_left_header_label() data = list( map( lambda host: (host.get_ip(), host.get_display_name(), host.get_vendor()), sorted_scanned_hosts)) # We need to reverse the data shown here because the table view will display the data in the reversed order # this is needed so that clicking the tableview will result in the correct host being selected: Task189 hosts_table_view.reload_data(data[::-1]) def scan_thread_completion(): """Scan given inputs, update associated ui, and save scan data""" scan_start_date = datetime.datetime.now() update_left_header_label("Scan in process...") scan_button.config(state="disabled") waiting_scanner1 = STimer.do_after( update_left_header_label_random_waiting_msg, 15) waiting_scanner2 = STimer.do_after( update_left_header_label_random_waiting_msg, 30) waiting_scanner3 = STimer.do_after( update_left_header_label_random_waiting_msg, 45) ports = f'{port_start_entry_var.get()}-{port_end_entry_var.get()}' hosts = scan_host_entry_var.get() scanner = Scanner(hosts, ports) set_host(scanner.get_scan_details(System.Settings.get_scan_type())) set_cpes_vulns(scanner.get_cpes()) scan_button.config(state="normal") scan_details_view.check_vulnerabilities_button.config(state="normal") scan_end_date = datetime.datetime.now() timedelta = scan_end_date - scan_start_date timedelta.total_seconds() last_row_id = df.DBFunctions.save_scan(scan_start_date, timedelta.total_seconds()) for host in get_hosts(): df.DBFunctions.save_host(host, last_row_id) query = "SELECT * FROM Hosts WHERE ScanID = ?" host_tuple = df.DBFunctions.get_all_where(query, (last_row_id, )) hosts_with_ID = [] for id_host in host_tuple: temp = Host(id_host[0], id_host[1], "Old Host", id_host[5], id_host[3], id_host[4], id_host[6], id_host[2]) hosts_with_ID.append(temp) set_host(hosts_with_ID) ip_list = [*DataShare.get_cpes()] cpe_list = DataShare.get_cpes() for ip in ip_list: for item in hosts_with_ID: if item.get_ip() == ip: cpe_list[item.get_id()] = cpe_list.pop(ip) DataShare.set_cpes(cpe_list) cves_with_host = df.DBFunctions.query_cves(cpe_list) for i in cves_with_host: for j in i: df.DBFunctions.save_cve_by_host(i, j) update_left_header_label(f"Scan finished in {timedelta} seconds") STimer.do_after(reset_left_header_label, 2) waiting_scanner1.cancel() waiting_scanner2.cancel() waiting_scanner3.cancel() def set_host(h): """Set scanned hosts for ui :param h: hosts found """ if h: DataShare.set_hosts(h) reload_hosts_tableview() def get_hosts(): """Get scanned hosts""" return DataShare.get_hosts() def set_cpes_vulns(c): """Set vulnerabilities from cps""" print("Main 172 set_cpes_vulns cpes:\n") print(c) DataShare.set_cpes(c) # Sort according to the Vulnerability Sort Setting reverse_sort = False if System.Settings.get_vuln_sort_type() == System.SortType.alphaDESC: reverse_sort = True sorted_vulns = sorted(df.DBFunctions.query_cves(c), reverse=reverse_sort) print('From Main 184, sorted_vulns: ', sorted_vulns) DataShare.set_vulns(sorted_vulns) # reload ui # Click Handlers def on_scan(): """Click handler for scan btn to start scanner thread""" # MAKE SURE TO VALIDATE INPUT scan_thread = SThread(0, "SCAN_THREAD_1", 5, scan_thread_completion) scan_thread.start() def on_select_scan(id): query = "SELECT * FROM Hosts WHERE ScanID = ?" params = (id, ) data = df.DBFunctions.get_all_where(query, params) test = df.DBFunctions.retrieve_scanID_data(id) print('\n\n\n\nGetting Data\n') print(data) print('\n') print(test) # these need to be set, but not sure if the cpes and vulns are differentiate # by scans like hosts are # todo: set cpes and vulns in DataShare print('\n\n\n\nCPES') #todo this changes depending on if a scan has been run print(DataShare.get_cpes()) print('\n\nVULNS') #todo these are 2.2 cpes... print(DataShare.get_vulns()) print('\n\n\n\n') curr_hosts = [] # for each host scanned for host_raw in data: host_id = host_raw[0] ip = host_raw[1] state = "Old Host" mac = host_raw[2] os_gen = host_raw[3] os_family = host_raw[4] name = host_raw[5] vendor = host_raw[6] curr_hosts.append( Host(host_id, ip, state, name, os_family, os_gen, vendor, mac)) set_host(curr_hosts) def find_exploit(cve): if cve: if exploit_view: exploit_view.update_cve(cve) else: print('No CVE selected') def update_exploit_tab(cve): main_note_book.select(2) exploit_view.cve_var.set(cve) exploit_view.on_search() def on_host_tableview_select(event): """Click handler to update right ui when user clicks on a host in left box""" index = hosts_table_view.get_selected_index() hosts = DataShare.get_hosts() scan_details_view.host_name_entry_var.set( hosts[index].get_display_name()) scan_details_view.mac_address_entry_var.set( hosts[index].get_mac_address()) scan_details_view.port_number_entry_var.set(hosts[index].get_ip()) def donothing(): filewin = Toplevel(root) button = Button(filewin, text="Do nothing button") button.pack() def update_import(): # Only takes json currently. path = askopenfilename(title='Select Database file to import...', # defaultextension='.db', filetypes=(("database files", "*.db"),("datafeeds", "*.json"),("all files", "*.*"))) path = askopenfilename(title='Select Database file to import...', filetypes=[('Json', '*.json')]) # ntpath for os compatibility with differing separators # head and tail if path ends in backslash head, tail = ntpath.split(path) fname = tail or ntpath.basename(head) if fname.endswith('.json'): # for use to support multiple file types # elif json_fp.endswith(('.json', '.db', '.xml'): df.DBFunctions.import_NVD_JSON(fname) else: tk.messagebox.showerror("Error", "File must be of type: json") # Set up tree columns to display IP and Device Names after a completed scan class TreeColumns(enum.Enum): name = 0 mac_address = 1 @staticmethod def display_name_for_column(col): display_names = { 0: "IP", 1: "Name", } return display_names[col] @staticmethod def all_cases(): cases = [] for col in TreeColumns: cases.append(TreeColumns.display_name_for_column(col.value)) return cases # Setup root ui root = ThemedTk() root.ttkStyle = ThemedStyle() theme = System.Settings.get_theme() root.ttkStyle.set_theme(theme) root.title("AnyScan") root.grid_rowconfigure(0, weight=1) root.grid_columnconfigure(1, weight=1) ################# # Setup LeftFrame ################# left_frame = ttk.Frame(root) left_frame.grid(row=0, column=0, sticky="nsew") left_frame.grid_rowconfigure(1, weight=1) left_frame.grid_columnconfigure(1, weight=1) # Setup Left Frame header Label left_frame_header_label_var = tk.StringVar() update_left_header_label(None) left_frame_header_label = ttk.Label( left_frame, textvariable=left_frame_header_label_var) left_frame_header_label.grid(row=0, column=0) # Setup Left Frame Host TableView sections_tuple = TreeColumns.all_cases() data = [] hosts_table_view = TableView(left_frame, 1, sections_tuple, data) hosts_table_view.bind_method('<ButtonRelease-1>', on_host_tableview_select) reload_hosts_tableview() # Setup scan host frame scan_host_frame = ttk.Frame(left_frame) scan_host_frame.grid(row=2, column=0) # Setup scan host label scan_host_label = ttk.Label(scan_host_frame, text="Hosts:") scan_host_label.grid(row=0, column=0) # Setup scan host entry scan_host_entry_var = tk.StringVar() scan_host_entry_var.set("192.168.1.0/28") scan_host_entry = ttk.Entry(scan_host_frame, textvariable=scan_host_entry_var) scan_host_entry.grid(row=0, column=1) # Setup scan port label frame scan_port_label_frame = ttk.Frame(left_frame) scan_port_label_frame.grid(row=3, column=0) # Setup scan port label port_start_label = ttk.Label(scan_port_label_frame, text="Start Port") port_start_label.grid(row=0, column=0, padx=(0, 8)) port_end_label = ttk.Label(scan_port_label_frame, text="End Port") port_end_label.grid(row=0, column=1, padx=(8, 0)) # Setup scan port frame scan_port_frame = ttk.Frame(left_frame) scan_port_frame.grid(row=4, column=0) # Setup scan port entries port_start_entry_var = tk.StringVar() port_start_entry_var.set("21") port_start_entry = ttk.Entry(scan_port_frame, width=4, textvariable=port_start_entry_var) port_start_entry.grid(row=0, column=0, padx=(0, 16)) port_end_entry_var = tk.StringVar() port_end_entry_var.set("30") port_end_entry = ttk.Entry(scan_port_frame, width=4, textvariable=port_end_entry_var) port_end_entry.grid(row=0, column=1, padx=(16, 0)) scan_button_frame = ttk.Frame(left_frame) scan_button_frame.grid(row=5, column=0) # Setup Left frame scan button scan_button = ttk.Button(scan_button_frame, text="Scan", command=on_scan) scan_button.grid(row=0, column=0, pady=(8, 8)) ################# # Setup RightFrame ################# # Setup Notebook for right frame rows = 0 while rows < 50: root.columnconfigure(rows + 1, weight=1) rows += 1 # Setup Root Notebook main_note_book = ttk.Notebook(root) main_note_book.grid(row=0, column=1, columnspan=50, rowspan=49, sticky="NESW") # Setup Scan Details Tab scan_details_view = ScanDetailsView() scan_details_tab = scan_details_view.get_view(main_note_book) main_note_book.add(scan_details_tab, text="Scan Details") # Setup Vulnerabilities Tab vulnerabilities_view = VulnerabilitiesView() vulnerabilities_tab = vulnerabilities_view.get_view(main_note_book) main_note_book.add(vulnerabilities_tab, text="Vulnerabilities") vulnerabilities_view.on_selected_cve = find_exploit vulnerabilities_view.move_to_exploit = update_exploit_tab # Setup Exploits Tab exploit_view = ExploitView() exploit_tab = exploit_view.get_view(main_note_book) main_note_book.add(exploit_tab, text='Exploits') # Setup Scan History Tab scan_history_view = ScanHistoryView() scan_history_tab = scan_history_view.get_view(main_note_book) main_note_book.add(scan_history_tab, text="Scan History") scan_history_view.on_selected_scan_completion = on_select_scan # File Menu Bar menubar = Menu(root) # create menu bar filemenu = Menu(menubar, tearoff=0) # create a menu to add some stuff too # Save Vulnerability in file menu bar savemenu = Menu(menubar, tearoff=0) savemenu.add_command(label="Save Vulnerability", command=VulnPopup.new_popup) filemenu.add_cascade(label='Save', menu=savemenu) # DB import in file menu bar importmenu = Menu(menubar, tearoff=0) importmenu.add_command(label="Database", command=update_import) filemenu.add_cascade(label="Import", menu=importmenu) filemenu.add_separator() # more prettiness # Scan settings in file menu bar settingsmenu = Menu(menubar, tearoff=0) settingsmenu.add_command(label="Scan Settings", command=scan_details_view.on_settings) filemenu.add_cascade(label='Settings', menu=settingsmenu) filemenu.add_separator() # pretty # Helper method to change application themes def change_theme(theme): root.ttkStyle.set_theme(theme) System.Settings.set_theme(theme) # Added the ability for the user to change themes from the cascading file menu themes_menu = Menu(menubar, tearoff=0) themes_menu.add_command(label="Alt", command=lambda: change_theme("alt")) themes_menu.add_command(label="Aqua", command=lambda: change_theme("aqua")) themes_menu.add_command(label="Clam", command=lambda: change_theme("clam")) themes_menu.add_command(label="Classic", command=lambda: change_theme("classic")) themes_menu.add_command(label="Default", command=lambda: change_theme("default")) themes_menu.add_command(label="Equilux", command=lambda: change_theme("equilux")) themes_menu.add_separator() themes_menu.add_command(label="Scidblue", command=lambda: change_theme("scidblue")) themes_menu.add_command(label="Scidgreen", command=lambda: change_theme("scidgreen")) themes_menu.add_command(label="Scidgrey", command=lambda: change_theme("scidgrey")) themes_menu.add_command(label="Scidmint", command=lambda: change_theme("scidmint")) themes_menu.add_command(label="Scidpink", command=lambda: change_theme("scidpink")) themes_menu.add_command(label="Scidpurple", command=lambda: change_theme("scidpurple")) themes_menu.add_command(label="Scidsand", command=lambda: change_theme("scidsand")) filemenu.add_cascade(label='Change Theme', menu=themes_menu) filemenu.add_separator() filemenu.add_command(label="Exit", command=root.quit) editmenu = Menu(menubar, tearoff=0) # create another menu to add some stuff too editmenu.add_command(label="Undo", command=donothing) menubar.add_cascade(label="File", menu=filemenu) # add file to menu bar # On macOS there are some default things added to this menu, but are not added to the same menu # under File. menubar.add_cascade(label='Edit', menu=editmenu) # add edit to menu bar too, for fun # Run the program with UI root.config(menu=menubar) root.geometry("1600x1000") root.minsize(800, 500) # add this to ensure app comes to front on start up root.lift() root.attributes('-topmost', True) root.after_idle(root.attributes, '-topmost', False) # start GUI root.mainloop()
class CredGui(): def __init__(self): self.master = ThemedTk(theme='equilux', background=True) #self.master.config(background = True) self.master.title('3ncryp710n T00lz') #self.style.set_theme('scidgrey') self.statuslabel = tk.StringVar() self.width = 800 self.height = 530 screen_width = self.master.winfo_screenwidth() screen_height = self.master.winfo_screenheight() x = (screen_width // 2) - (self.width // 2) y = (screen_height // 2) - (self.height // 2) self.master.geometry(f'{self.width}x{self.height}+{x}+{y}') ttk.Label(self.master, text="Data File").grid(row=0) ttk.Label(self.master, text="Decryption Key <C-k>").grid(row=1) self.filepath = ttk.Entry(self.master) self.keyentry = ttk.Entry(self.master) self.filepath.grid(row=0, column=1, sticky=tk.W) self.keyentry.grid(row=1, column=1, sticky=tk.W) ttk.Button(self.master, text='Open <C-o>', command=self.opendatafile).grid(row=0, column=2, sticky=tk.W) ttk.Button(self.master, text='New <C-n>', command=self.newfile).grid(row=0, column=2, sticky=tk.E) self.status = ttk.Label(self.master, textvariable=self.statuslabel) self.status.grid(row=2, column=1, sticky=tk.W) ttk.Label(self.master, text='Search <Ctr+f>').grid(row=3) self.searchvar = tk.StringVar() self.searchentry = ttk.Entry(self.master, width=40, textvariable=self.searchvar) self.searchentry.grid(row=3, column=1, sticky=tk.W, columnspan=2) self.searchvar.trace('w', self.search) self.myscroll = ttk.Scrollbar(self.master) self.myscroll.grid(row=4, column=3, sticky='nws') self.mylist = tk.Listbox(self.master, yscrollcommand=self.myscroll.set, width=50, bg='#414141', fg='#A3A3A3') #self.mylist = ttk.Combobox(self.master, width = 50, height = 50) self.mylist.grid(row=4, column=1, columnspan=2, sticky=tk.W) self.myscroll.config(command=self.mylist.yview) ttk.Button(self.master, text='Encrypt <C-e>', command=self.enc).grid(row=10, column=1, sticky=tk.W, pady=4) ttk.Button(self.master, text='Decrypt <C-d>', command=self.dec).grid(row=10, column=2, sticky=tk.W, pady=4) self.master.grid_columnconfigure(5, weight=2) self.master.grid_columnconfigure(4, weight=2) ttk.Separator(self.master).grid(row=14, sticky='ew', columnspan=6) ttk.Label(self.master, text="Credential").grid(row=15, pady=4) ttk.Label(self.master, text="Section <C-s>").grid(row=16, column=1, sticky=tk.W) ttk.Label(self.master, text="Username <C-u>").grid(row=16, column=2, sticky=tk.W) self.secentry = ttk.Entry(self.master) self.userentry = ttk.Entry(self.master) self.secentry.grid(row=17, column=1, sticky=tk.W) self.userentry.grid(row=17, column=2, sticky=tk.W) ttk.Button(self.master, text='Copy Password <C-c>', command=self.copy_passwd).grid(row=18, column=4, sticky=tk.E, pady=4) self.passlabel = ttk.Label(self.master, text="Password <C-p>") self.passlabel.grid(row=18, pady=4) #, column = 0, sticky=tk.W) self.passvar = tk.StringVar() self.passentry = ttk.Entry(self.master, width=40, textvariable=self.passvar) self.passentry.grid(row=18, column=1, sticky='ew', columnspan=2, pady=4) self.passvar.trace('w', self.check_passwd_strength) self.pbval = tk.IntVar(value=0) self.passcheckphrase = tk.StringVar() self.passcheckl = ttk.Label(self.master, textvariable=self.passcheckphrase) self.passcheckl.grid(row=19, column=0) self.pb = ttk.Progressbar(self.master, orient=tk.HORIZONTAL, variable=self.pbval, maximum=8, mode='determinate', length=360) self.pb.grid(row=19, column=1, sticky='ew', columnspan=2) ttk.Label(self.master, text="Password Lengt <C-h>").grid(row=20, column=1, sticky=tk.W) ttk.Label(self.master, text="Password Exclude <C-x>").grid(row=20, column=2, sticky=tk.W) ttk.Button(self.master, text='Encrypt and Quit <C-q>', command=self.encrypt_and_quit).grid(row=20, column=4, sticky=tk.E, pady=4) self.passlene = ttk.Entry(self.master) self.passexe = ttk.Entry(self.master) self.passlene.grid(row=21, column=1, sticky=tk.W) self.passexe.grid(row=21, column=2, sticky=tk.W) self.passlene.insert(tk.END, '32') self.passexe.insert(tk.END, r'%\()|{}[]:";' + "'" + '<>,./?') ttk.Button(self.master, text='Generate Password <C-g>', command=self.new_password).grid(row=22, column=1, sticky=tk.W, pady=4) ttk.Button(self.master, text='Add Password <C-a>', command=self.add_cred).grid(row=22, column=2, sticky=tk.W, pady=4) self.master.bind('<Control-o>', lambda event: self.opendatafile()) self.master.bind('<Control-n>', lambda event: self.newfile()) self.master.bind('<Control-e>', lambda event: self.enc()) self.master.bind('<Control-d>', lambda event: self.dec()) self.keyentry.bind('<Return>', lambda event: self.dec()) self.master.bind('<Control-c>', lambda event: self.copy_passwd()) self.master.bind('<Control-v>', lambda event: self.paste_passwd()) self.master.bind('<Control-g>', lambda event: self.new_password()) self.master.bind('<Control-a>', lambda event: self.add_cred()) self.master.bind('<Control-q>', lambda event: self.encrypt_and_quit()) self.master.bind('<Control-l>', lambda event: self.clear()) self.master.bind('<Control-r>', lambda event: self.del_cred()) self.master.bind('<Control-f>', lambda event: self.searchentry.focus_set()) self.master.bind('<Control-p>', lambda event: self.passentry.focus_set()) self.master.bind('<Control-s>', lambda event: self.secentry.focus_set()) self.master.bind('<Control-u>', lambda event: self.userentry.focus_set()) self.master.bind('<Control-k>', lambda event: self.keyentry.focus_set()) self.master.bind('<Control-x>', lambda event: self.passexe.focus_set()) self.master.bind('<Control-h>', lambda event: self.passlene.focus_set()) #self.searchentry.bind('<Key>', self.search) #self.searchentry.bind('<FocusIn>', self.search) self.master.bind('<<ListboxSelect>>', self.lbselect) self.mylist.bind('<Up>', self.lbselect) self.mylist.bind('<Down>', self.lbselect) self.master.mainloop() def encrypt_and_quit(self): self.enc() self.master.quit() def new_password(self): passlen = self.passlene.get() if passlen == '': passlen = 16 else: passlen = int(passlen) passexclude = self.passexe.get() password = generate_password(passlen, passexclude) self.passentry.delete(0, tk.END) self.passentry.insert(tk.END, password) def check_passwd_strength(self, *args): password = self.passentry.get() if isinstance(password, bytes): password = password.decode('utf-8') if password == '': self.pbval.set(0) self.passcheckphrase.set('') self.passlabel.config(background=None) #self.passlabel.config(background = 'grey') else: passstr = get_pass_strength(password) outputphrase = [ 'bad', 'very weak', 'weak', 'slightly weak', 'slightly strong', 'strong', 'very strong', 'excellent' ] outputcol = [ 'red', 'orange', 'yellow', 'pale green', 'green', 'deep sky blue', 'blue', 'purple' ] self.pbval.set(passstr + 1) self.passcheckphrase.set(outputphrase[passstr]) self.passlabel.config(background=outputcol[passstr]) def add_cred(self): section = self.secentry.get() username = self.userentry.get() password = self.passentry.get() fabspath = self.filepath.get() config = configparser.ConfigParser() config.read(fabspath) if not section in config.sections(): config.add_section(section) if username == '': self.statuslabel.set('Username empty, please fillin.') self.status.config(background='red') else: config[section][username] = password with open(fabspath, 'w') as f: config.write(f) self.statuslabel.set('Credential added') self.status.config(background='green') self._readfile(fabspath) self.userentry.delete(0, tk.END) self.passentry.delete(0, tk.END) self.search(None) def lbselect(self, event): def _bytes_to_str(b): if isinstance(b, bytes): b = b.decode('utf-8') return b idx_t = self.mylist.curselection() if len(idx_t) > 0: idx = idx_t[0] kv = self.mylist.get(idx_t) kv = _bytes_to_str(kv) self.secentry.delete(0, tk.END) self.userentry.delete(0, tk.END) self.passentry.delete(0, tk.END) if kv != '': if kv[0] == '[': self.secentry.insert(tk.END, kv[1:-1]) else: kv_l = kv.split('=', 1) key = kv_l[0].replace(' ', '') val = kv_l[1].replace(' ', '') while True: idx -= 1 s = self.mylist.get((idx, )) s = _bytes_to_str(s) if s[0] == '[': self.secentry.insert(tk.END, s[1:-1]) self.userentry.insert(tk.END, key) self.passentry.insert(tk.END, val) break def del_cred(self): section = self.secentry.get() username = self.userentry.get() fabspath = self.filepath.get() config = configparser.ConfigParser() config.read(fabspath) if not section in config.sections(): self.statuslabel.set('No Credential Found') self.status.config(background='red') else: if username == '': config.remove_section(section) else: config.remove_option(section, username) with open(fabspath, 'w') as f: config.write(f) self.statuslabel.set('Credential Removed') self.status.config(background='green') self._readfile(fabspath) self.secentry.delete(0, tk.END) self.userentry.delete(0, tk.END) self.passentry.delete(0, tk.END) self.search(None) def clear(self): focus = self.master.focus_get() if isinstance(focus, ttk.Entry): focus.delete(0, tk.END) def search(self, *args): config = configparser.ConfigParser() fabspath = self.filepath.get() try: config.read(fabspath) except: self.statuslabel.set('File not in searchable format.') self.status.config(background='red') else: self.mylist.delete(0, tk.END) buf = io.StringIO() searchkey = self.searchentry.get() p = re.compile(searchkey) searchres = configparser.ConfigParser() for section in config.sections(): res = p.search(section) if res is not None: if not section in searchres.sections(): searchres.add_section(section) for k, v in config.items(section): searchres[section][k] = v else: for k, v in config.items(section): res = p.search(k) if res is not None: if not section in searchres.sections(): searchres.add_section(section) searchres[section][k] = v searchres.write(buf) c = buf.getvalue() self.mylist.insert(tk.END, *c.splitlines()) buf.close() def paste_passwd(self): passwd = pyperclip.paste() self.passentry.delete(0, tk.END) self.passentry.insert(tk.END, passwd) self.status.config(background='green') self.statuslabel.set('Password Pasted From Clipboard') def copy_passwd(self): password = self.passentry.get() pyperclip.copy(password) self.status.config(background='green') self.statuslabel.set('Password Copied to Clipboard') def opendatafile(self): self.filepath.delete(0, tk.END) fabspath = fd.askopenfilename(title='Please choose Data File') if fabspath != '': self._readfile(fabspath) self.filepath.insert(tk.END, fabspath) self.keyentry.focus_set() def newfile(self): self.filepath.delete(0, tk.END) f = fd.asksaveasfile('wb') self.filepath.insert(tk.END, f.name) fabspath = self.filepath.get() self._readfile(fabspath) self.keyentry.focus_set() def _readfile(self, fabspath): self.mylist.delete(0, tk.END) f = open(fabspath, 'rb') c = f.read() f.close() self.mylist.insert(tk.END, *c.splitlines()) #filecontent.set(c) def enc(self): fabspath = self.filepath.get() if fabspath != '': key = self.keyentry.get() self.statuslabel.set('Encrypting File') self.status.config(background='red') encryptfile(key, fabspath, fabspath) self.statuslabel.set('Encrypted!') self.status.config(background='green') self._readfile(fabspath) #self.filepath.delete(0, tk.END) def dec(self): key = self.keyentry.get() fabspath = self.filepath.get() self.statuslabel.set('Decrypting File...') self.status.config(background='red') try: decryptfile(key, fabspath, fabspath) self.statuslabel.set('Decrypted!') self.status.config(background='green') self._readfile(fabspath) except: self.statuslabel.set('Wrong Key!') self.status.config(background='Red')
class GUI: """ The GUI class """ def __init__(self): """ Creates the main window and sets themes, style, and size """ self._root = ThemedTk(theme="arc") self._root.title("MemeMoney") self._root.iconbitmap("iconimg\mememoney.ico") self._root.configure(bg="#f5f6f7") self._root.grid_columnconfigure(0, weight=1) self._root.geometry("800x600") def create_welcome_frame(self): """ Creates the frame in which the title, subtitle, keyword request, and data will be displayed. """ # sets font welcome_font = tk.font.Font(size=24, weight="bold") welcome_desc_font = tk.font.Font(size=12) sub_welcome_font = tk.font.Font(size=10) sub_welcome_font_bold = tk.font.Font(size=10, weight="bold", underline=True) # creates the frame w/ style, size, position welcome_frame = ttk.Frame(self._root) welcome_frame.grid(column=0, row=0, padx=20, pady=5, sticky="ew") welcome_frame.grid_columnconfigure(0, weight=1) # title and subtitle text welcome = ttk.Label(welcome_frame, text="MemeMoney", font=welcome_font, foreground="#000000") welcome.grid(column=0) welcome_desc = ttk.Label(welcome_frame, text="Providing you with hyped stock data.", font=welcome_desc_font) welcome_desc.grid(column=0, pady=10) # instruction text instr = ttk.Label(welcome_frame, text="Instructions:", font=sub_welcome_font_bold, wraplength=600, anchor="w") instr.grid(column=0, sticky="w", padx=86) instr_desc = "Enter a stock symbol and the program will display a table with " \ "the number of Reddit and Twitter mentions, the stock's closing price, " \ "and the price differential from one day to the next, for the previous " \ "three days, excluding weekends." instructions = ttk.Label(welcome_frame, text=instr_desc, font=sub_welcome_font, wraplength=600) instructions.grid(column=0, pady=5) # gets user input for keyword search for stock symbol input_request = ttk.Label( welcome_frame, text="Please enter a stock symbol (letters only):", font=welcome_desc_font) input_request.grid(column=0, pady=10) # creates entry field for user to type in input stock_entry = ttk.Entry(welcome_frame, width=30, font=welcome_desc_font) stock_entry.grid(column=0, pady=10) def get_entry(): """ Inner function that retrieves the user entered term to provide keyword to search """ attempted_keyword = stock_entry.get() # checks to see if term is valid, based on US stock exchanges # only letters and less than 5 letters if attempted_keyword.isalpha() and len(attempted_keyword) <= 5: keyword = "$" + str(attempted_keyword.upper()) return keyword # else messagebox pops up and provides an error else: messagebox.showinfo("Invalid Entry", "You did not enter a valid search term.") stock_entry.delete( 0, "end") # clears the entry box if invalid entry def get_data(platform): ''' Inner function that gets the data from Reddit, Twitter, and Stock API's. Takes the platform as a parameter and returns a list of the data. ''' keyword = get_entry() data_source = None # determines which function to call if platform == "twitter": data_source = twitter_scrape(keyword) if platform == "reddit": data_source = reddit_scrape(keyword) if platform == "stock_price": keyword = get_entry().strip("$") data_source = get_stock_prices(keyword) # if stock does not exist return nothing if data_source == "no such ticker": messagebox.showinfo("Invalid Entry", "Stock does not exist.") stock_entry.delete( 0, "end") # clears the entry box if invalid entry return day_delta = datetime.timedelta(days=1) today = datetime.date.today() data_list = [] # creates list of [dates, mentions] for things in range(7): the_day = today - (things * day_delta) if the_day.isoweekday() != 6 and the_day.isoweekday( ) != 7 and the_day != today: the_date = the_day mentions = data_source[the_date] data_list.append([the_date, mentions]) return data_list def create_table(): """ Creates display table for twitter and reddit mentions, and stock price """ # calls functions to get data to display twitter_data = get_data("twitter") reddit_data = get_data("reddit") stock_price_data = get_data("stock_price") # if stock does not exist return nothing if stock_price_data is None: return # creates table frame table_frame = ttk.Frame(self._root) table_frame.grid(column=0, row=1, padx=20, pady=5, sticky="ew") table_frame.grid_columnconfigure(0, weight=1) # creates table foundation - tkinter treeview table = ttk.Treeview(table_frame) style = ttk.Style() style.configure('Treeview', rowheight=20) table['columns'] = ('Date', 'Close Price', 'Reddit Mentions', 'Twitter Mentions', 'Total Mentions', 'Price Diff from Prev Day', 'Mention Diff from Prev Day') table.column('#0', width=0, stretch=NO) table.column('Date', anchor=CENTER, width=75) table.column('Close Price', anchor=CENTER, width=75) table.column('Reddit Mentions', anchor=CENTER, width=100) table.column('Twitter Mentions', anchor=CENTER, width=100) table.column('Total Mentions', anchor=CENTER, width=100) table.column('Price Diff from Prev Day', anchor=CENTER, width=150) table.column('Mention Diff from Prev Day', anchor=CENTER, width=150) table.heading('#0', text='', anchor=W) table.heading('Date', text='Date', anchor=CENTER) table.heading('Close Price', text='Close Price', anchor=CENTER) table.heading('Reddit Mentions', text='Reddit Mentions', anchor=CENTER) table.heading('Twitter Mentions', text='Twitter Mentions', anchor=CENTER) table.heading('Total Mentions', text='Total Mentions', anchor=CENTER) table.heading('Price Diff from Prev Day', text='Price Diff from Prev Day', anchor=CENTER) table.heading('Mention Diff from Prev Day', text='Mention Diff from Prev Day', anchor=CENTER) # creates the table id = 0 first_index = 0 for items in range(3): # makes sure the dates are all the same one if twitter_data[first_index][0] == reddit_data[first_index][0] and \ twitter_data[first_index][0] == stock_price_data[first_index][0] and \ reddit_data[first_index][0] == stock_price_data[first_index][0]: total = reddit_data[first_index][1] + twitter_data[ first_index][1] # calculates mention and price differentials try: prev_total = reddit_data[ first_index + 1][1] + twitter_data[first_index + 1][1] prev_price = float(stock_price_data[first_index + 1][1]) if first_index < 2: mention_diff = total - prev_total price_diff = round( float(stock_price_data[first_index][1]) - prev_price, 3) else: mention_diff = "N/A" price_diff = "N/A" except IndexError: mention_diff = "N/A" price_diff = "N/A" # creates the data rows for the table table.insert(parent='', index='end', iid=id, text='', values=(twitter_data[first_index][0], stock_price_data[first_index][1], reddit_data[first_index][1], twitter_data[first_index][1], total, price_diff, mention_diff)) id += 1 first_index += 1 table.pack(pady=20) # button that when pushed retrieves the user entered keyword search_button = ttk.Button(welcome_frame, text="Get Results", command=lambda: [create_table()]) search_button.grid(column=0, pady=5) def end(self): """ Closes out the root for the GUI """ return self._root.mainloop()
class StereoVisionCalculator(object): def __init__(self): """ Class constructor of StereoVisionCalculator. This method initalizes the tkinter GUI and the object variables to store the user input and calculation results. """ # Focal length calculator parameters self.sensor_size = None self.img_width = None self.img_height = None self.focal_fov = None # Design limits self.perf_depth = None self.perf_depth_error = None self.perf_disp_max = None self.perf_disp = None self.perf_disp_calibration_error = None # Baseline calculator results self._min_depth = None self._baseline = None self._focal_length = None # Initialize the complete GUI self._initializeGUI() Row = namedtuple('Row', ['var_name', 'name', 'io', 'activate', 'units']) class RowElement(object): def __init__(self): self.name = None self.io = None self.activate = None self.units = None def setrow(self, row): if self.name: self.name.grid(row=row) if self.io: self.io.grid(row=row) if self.activate: self.activate.grid(row=row) if self.units: self.units.grid(row=row) def _rowPropertiesToGUI(self, master, row_prop): """ Method to convert row_prop of type Row() into a GUI element :param: master (The master of tk element) :param: row_prop (An instance of Row()) :return: An instance of RowElement """ row = StereoVisionCalculator.RowElement() # Create the name label row.name = ttk.Label(master, text=row_prop.name) row.name.grid(column=0, sticky="W", pady=5) # Create io Entry var if row_prop.io: row.io = ttk.Entry(master) else: row.io = ttk.Label(master, text="0.0") row.io.grid(column=1, sticky="W") if row_prop.activate: row.activate = ttk.Checkbutton(master) row.activate.grid(column=1, sticky="E") # Create units Label/OptionMenu var if row_prop.units: if isinstance(row_prop.units, list): row.units = ttk.OptionMenu( master, tk.StringVar(master, row_prop.units[1]), *row_prop.units) else: row.units = tk.Label(master, text=row_prop.units) row.units.grid(column=2, sticky="W") return row def _initializeGUI(self): """ Method to setup the StereoVision Calculator GUI using tkinter """ self.root = ThemedTk(theme="arc") self.root.tk_setPalette(background='#f5f6f7') self.root.title("StereoVision Calculator") self.root.resizable(0, 0) # Don't allow resize sensor_size_units = ['', 'mm', 'in'] fov_type = ['', 'Horizontal', 'Vertical', 'Diagonal'] depth_units = ['', 'mm', 'cm', 'm', 'in', 'ft'] row_properties = [ StereoVisionCalculator.Row('ui_sensor_size', 'Sensor size', True, False, sensor_size_units), StereoVisionCalculator.Row('ui_img_width', 'Image width', True, False, 'px'), StereoVisionCalculator.Row('ui_img_height', 'Image height', True, False, 'px'), StereoVisionCalculator.Row('ui_focal_fov', 'Focal FoV', True, False, fov_type), StereoVisionCalculator.Row('ui_perf_depth', 'Performance depth', True, False, depth_units), StereoVisionCalculator.Row('ui_perf_depth_error', 'Performance depth error', True, False, depth_units), StereoVisionCalculator.Row('ui_perf_disp', 'Performance disparity', True, True, 'px'), StereoVisionCalculator.Row('ui_disp_max', 'Max disparity', True, False, 'px'), StereoVisionCalculator.Row('ui_disp_cal_error', 'Calibration disparity error', True, False, 'px'), StereoVisionCalculator.Row('ui_focal_length', 'Focal length', False, False, 'mm'), StereoVisionCalculator.Row('ui_baseline', 'Baseline', False, False, 'mm'), StereoVisionCalculator.Row('ui_depth_min', 'Min depth', False, False, 'mm'), # StereoVisionCalculator.Row('ui_depth_max', 'Max depth', False, False, 'm'), StereoVisionCalculator.Row('ui_depth_res', 'Depth resolution', False, False, 'px'), StereoVisionCalculator.Row('ui_depth_fov', 'Depth FoV', False, False, 'deg') ] for row_num, rp in enumerate(row_properties, start=1): row_element = self._rowPropertiesToGUI(self.root, rp) row_element.setrow(row_num) self.__setattr__(rp.var_name, row_element) self.ui_perf_disp.io["state"] = tk.DISABLED self.ui_perf_disp.io["width"] = 14 self.ui_perf_disp.activate["command"] = self._disp self.ui_depth_res.io["text"] = "0 x 0" self.ui_depth_fov.io["text"] = "0° x 0°" # Buttons self.ui_auto_calculate = ttk.Checkbutton(self.root, text="Auto calculate", command=self._callback) self.ui_auto_calculate.grid(row=0, sticky="W", pady=5) self.ui_capture = ttk.Button(self.root, text="Capture", width=12, command=self._capture) self.ui_capture.grid(row=0, column=2, sticky="W") self.ui_calculate = ttk.Button(self.root, text="Calculate", width=12, command=self._callback) self.ui_calculate.grid(row=16, sticky="W") self.ui_plot = ttk.Button(self.root, text="Plot", width=12, command=self._plot) self.ui_plot.grid(row=16, column=2, sticky="W") col_count, row_count = self.root.grid_size() for col in range(col_count): self.root.grid_columnconfigure(col, pad=2) def mainloop(self): self.root.mainloop() def calculateToMeter(self, variable, conversion_from): result = 0 if conversion_from is "mm": result = variable / 1000 elif conversion_from is "cm": result = variable / 100 elif conversion_from is "m": result = variable elif conversion_from is "in": result = variable * 0.0254 elif conversion_from is "ft": result = variable * 0.3048 return result def _focalLengthCalculator(self, size, fov_type): """ Function to calculate the focal length of the imaging sensor given: :param: sensor_size: The diagonal sensor size :param: size: The measurement system of the sensor (metric/imperial) :param: img_width: The amount of pixels in width :param: img_height: The amount of pixels in height :param: focal_fov: The field of view of the lens :param: fov_type: Horizontal, vertical or diagonal FoV """ if size == 'inch': self.sensor_size = self.sensor_size * 25.4 else: self.sensor_size = self.sensor_size ratio = self.img_height / self.img_width sensor_width_mm = math.sqrt(self.sensor_size**2 / (1.0 + ratio**2)) sensor_height_mm = math.sqrt(self.sensor_size**2 / (1.0 + 1.0 / (ratio**2))) roi_width_mm = sensor_width_mm # * roi_width / img_width roi_height_mm = sensor_height_mm # * roi_height / img_height roi_diagonal_mm = math.sqrt(roi_height_mm * roi_height_mm + roi_width_mm * roi_width_mm) fov = self.focal_fov / 180 * math.pi atanInner = math.tan(fov * 0.5) try: if fov_type == 'Horizontal': f_mm = roi_width_mm / (2 * atanInner) elif fov_type == 'Vertical': f_mm = roi_height_mm / (2 * atanInner) elif fov_type == 'Diagonal': f_mm = roi_diagonal_mm / (2 * atanInner) pixel_size_mm = roi_width_mm / self.img_width self._focal_length = f_mm / pixel_size_mm except ZeroDivisionError: f_mm = 0 self._focal_length = 0 return f_mm, roi_width_mm, roi_height_mm def _baselineCalculator(self): """ Function to calculate the baseline and min depth of the stereo camera given: 1. Focal length of the lens 2. Performace depth 3. Performance depth error 4. Disparity at performance depth 5. Calibration disparity error """ disparity = self.perf_disp + self.perf_disp_calibration_error depth = self.perf_depth - self.perf_depth_error self._baseline = baselineCalculator(self._focal_length, disparity, depth) self._min_depth = disparityToDepth(self._baseline, self._focal_length, self.perf_disp_max) def _depthErrorCalculator(self, depth): """ Method to calculate the max_depth_error for a given depth for pre-determined baseline and focal length :param: depth :return: max_depth_error """ disparity_real = depthToDisparity(self._baseline, self._focal_length, depth) disparity_measured = disparity_real + self.perf_disp_calibration_error depth_measured = disparityToDepth(self._baseline, self._focal_length, disparity_measured) return abs(depth_measured - depth) def _depthCalculator(self, roi_width, roi_height, roi_width_mm, roi_height_mm, img_width, d_max, f_mm): roi_full_pixel = str(roi_width - d_max) + ' x ' + str(roi_height) h_full_angle = 2 * math.atan( (1 * roi_width_mm * (img_width - d_max) / img_width) / (2 * f_mm)) v_angle = 2 * math.atan(roi_height_mm / (2 * f_mm)) FoV_h = round(h_full_angle / math.pi * 180, 1) FoV_v = round(v_angle / math.pi * 180, 1) FoV = str(FoV_h) + '° x ' + str(FoV_v) + '°' return FoV, roi_full_pixel def _callback(self): if (self.ui_sensor_size.io.get() and self.ui_img_width.io.get() and self.ui_img_height.io.get() and self.ui_focal_fov.io.get()): self.sensor_size = float(self.ui_sensor_size.io.get()) size = self.ui_sensor_size.units["text"] self.img_width = int(self.ui_img_width.io.get()) self.img_height = int(self.ui_img_height.io.get()) self.focal_fov = float(self.ui_focal_fov.io.get()) fov_type = self.ui_focal_fov.units["text"] f_mm, roi_width_mm, roi_height_mm = self._focalLengthCalculator( size, fov_type) self.ui_focal_length.io["text"] = round(f_mm, 2) if (self.ui_perf_depth.io.get() and self.ui_perf_depth_error.io.get() and self.ui_disp_max.io.get() and self.ui_disp_cal_error.io.get()): self.perf_depth = self.calculateToMeter( float(self.ui_perf_depth.io.get()), self.ui_perf_depth.units["text"]) self.perf_depth_error = self.calculateToMeter( float(self.ui_perf_depth_error.io.get()), self.ui_perf_depth_error.units["text"]) self.perf_disp = 1 if not self.ui_perf_disp.io.get() else int( self.ui_perf_disp.io.get()) self.perf_disp_max = int(self.ui_disp_max.io.get()) self.perf_disp_calibration_error = float( self.ui_disp_cal_error.io.get()) self._baselineCalculator() d_max = self.perf_disp_max - 1 depth_fov, depth_res = self._depthCalculator( self.img_width, self.img_height, roi_width_mm, roi_height_mm, self.img_width, d_max, f_mm) self.ui_baseline.io["text"] = round(self._baseline * 1000, 2) self.ui_depth_min.io["text"] = round(self._min_depth * 1000, 2) self.ui_depth_res.io["text"] = depth_res self.ui_depth_fov.io["text"] = depth_fov if self.ui_auto_calculate.instate(["selected"]): self.root.after(100, self._callback) def _disp(self): if self.ui_perf_disp.activate.instate(["selected"]): self.ui_perf_disp.io["state"] = tk.NORMAL else: self.ui_perf_disp.io["state"] = tk.DISABLED def _capture(self): x1 = self.root.winfo_rootx() x2 = x1 + self.root.winfo_reqwidth() y1 = self.root.winfo_rooty() y2 = y1 + self.root.winfo_reqheight() im = grab(bbox=(x1, y1, x2, y2)) im.show() def _plot(self): # Parameters if not (self._focal_length and self._baseline and self._min_depth): self.error = ThemedTk(theme="arc") self.error.tk_setPalette(background='#f5f6f7') self.error.title("Error!") label = ttk.Label(self.error, text="Missing input variables!").grid(padx=15, pady=25) self.error.mainloop() else: style.use('seaborn-whitegrid') fig1, ax = plt.subplots() fig1.canvas.set_window_title('Plot') plt.title("Depth Error Chart") plt.xlabel("Depth (m)") plt.ylabel("Depth error (m)") x1 = [] y1 = [] # Light theme fig1.patch.set_facecolor('#f5f6f7') # 212121 Dark ax.patch.set_facecolor('#f5f6f7') ax.spines['bottom'].set_color('#5c616c') # FAFAFA Dark ax.spines['top'].set_color('#5c616c') ax.spines['right'].set_color('#5c616c') ax.spines['left'].set_color('#5c616c') ax.tick_params(axis='x', colors='#5c616c', which='both') ax.tick_params(axis='y', colors='#5c616c', which='both') ax.yaxis.label.set_color('#5c616c') ax.xaxis.label.set_color('#5c616c') ax.title.set_color('#5c616c') # Plot # Min range to max range max_depth = self._baseline * self._focal_length * 10 for x in range(int(self._min_depth * 10), int(max_depth)): y = self._depthErrorCalculator(float(x / 10)) x1.append(float(x / 10)) y1.append(y) plt.plot(x1, y1, color="#039BE5") # Show plt.show()