Skip to content

Commit

Permalink
Create LazyOwnExplorer.py
Browse files Browse the repository at this point in the history
  • Loading branch information
grisuno authored May 23, 2024
1 parent 38a5af3 commit 5284013
Showing 1 changed file with 204 additions and 0 deletions.
204 changes: 204 additions & 0 deletions LazyOwnExplorer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
import tkinter as tk
from tkinter import ttk, filedialog, messagebox, Text
import pandas as pd
import os
import numpy as np

class AutocompleteEntry(tk.Entry):
def __init__(self, lista, *args, **kwargs):
super().__init__(*args, **kwargs)
self.lista = [item for item in lista if item is not None] # Filter out None values
self.var = self["textvariable"]
if self.var == '':
self.var = self["textvariable"] = tk.StringVar()

self.var.trace_add('write', self.changed)
self.bind("<Right>", self.selection)
self.bind("<Up>", self.move_up)
self.bind("<Down>", self.move_down)

self.lb_up = False

def changed(self, name, index, mode):
if self.var.get() == '':
if self.lb_up:
self.lb.destroy()
self.lb_up = False
else:
words = self.comparison()
if words:
if not self.lb_up:
self.lb = tk.Listbox(width=self["width"])
self.lb.bind("<Double-Button-1>", self.selection)
self.lb.bind("<Right>", self.selection)
self.lb.place(x=self.winfo_x(), y=self.winfo_y() + self.winfo_height())
self.lb_up = True

self.lb.delete(0, tk.END)
for w in words:
self.lb.insert(tk.END, w)
else:
if self.lb_up:
self.lb.destroy()
self.lb_up = False

def selection(self, event):
if self.lb_up:
self.var.set(self.lb.get(tk.ACTIVE))
self.lb.destroy()
self.lb_up = False
self.icursor(tk.END)

def move_up(self, event):
if self.lb_up:
if self.lb.curselection() == ():
index = '0'
else:
index = self.lb.curselection()[0]
if index != '0':
self.lb.selection_clear(first=index)
index = str(int(index) - 1)
self.lb.selection_set(first=index)
self.lb.activate(index)

def move_down(self, event):
if self.lb_up:
if self.lb.curselection() == ():
index = '0'
else:
index = self.lb.curselection()[0]
if index != tk.END:
self.lb.selection_clear(first=index)
index = str(int(index) + 1)
self.lb.selection_set(first=index)
self.lb.activate(index)

def comparison(self):
pattern = self.var.get()
return [w for w in self.lista if w.lower().startswith(pattern.lower())]

class LazyOwnGUI(tk.Tk):
def __init__(self):
super().__init__()
self.title("LazyOwn - Análisis de Binarios")
self.geometry("1366x768") # Establecer la resolución de la ventana

self.parquet_files = ["binarios.parquet", "detalles.parquet"]
self.dataframe = self.load_parquet_files()
self.create_widgets()

def create_widgets(self):
self.label = tk.Label(self, text="Término de búsqueda:")
self.label.pack(pady=10)

# Crear AutocompleteEntry
unique_values = self.get_unique_values()
self.search_term_entry = AutocompleteEntry(unique_values, self)
self.search_term_entry.pack(pady=10)
self.search_term_entry.bind("<Return>", lambda event: self.search()) # Búsqueda al presionar Enter

self.search_button = tk.Button(self, text="Buscar", command=self.search)
self.search_button.pack(pady=10)

# Crear el marco para Treeview y Scrollbars
self.result_frame = tk.Frame(self)
self.result_frame.pack(pady=10, fill=tk.BOTH, expand=True)

# Crear Treeview
self.result_tree = ttk.Treeview(self.result_frame, columns=("Binary", "Function Name", "Description", "Example"), show='headings')
self.result_tree.heading("Binary", text="Binary")
self.result_tree.heading("Function Name", text="Function Name")
self.result_tree.heading("Description", text="Description")
self.result_tree.heading("Example", text="Example")

self.result_tree.column("Binary", width=100, anchor=tk.W)
self.result_tree.column("Function Name", width=150, anchor=tk.W)
self.result_tree.column("Description", width=500, anchor=tk.W)
self.result_tree.column("Example", width=500, anchor=tk.W)

self.result_tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

# Scrollbars
self.scrollbar_y = ttk.Scrollbar(self.result_frame, orient=tk.VERTICAL, command=self.result_tree.yview)
self.scrollbar_y.pack(side=tk.RIGHT, fill=tk.Y)
self.result_tree.config(yscrollcommand=self.scrollbar_y.set)

self.scrollbar_x = ttk.Scrollbar(self, orient=tk.HORIZONTAL, command=self.result_tree.xview)
self.scrollbar_x.pack(side=tk.BOTTOM, fill=tk.X)
self.result_tree.config(xscrollcommand=self.scrollbar_x.set)

# Bind double-click event on rows
self.result_tree.bind("<Double-1>", self.on_row_double_click)

def load_parquet_files(self):
dataframes = [pd.read_parquet(file) for file in self.parquet_files if os.path.exists(file)]
if not dataframes:
messagebox.showerror("Error", "No se encontraron archivos Parquet.")
return pd.DataFrame()

df = pd.concat(dataframes, ignore_index=True)
df = df.replace({np.nan: None}) # Reemplazar NaN por None para manejar mejor los datos
return df

def get_unique_values(self):
if self.dataframe.empty:
return []
unique_values = pd.concat([self.dataframe[col] for col in self.dataframe.columns]).unique()
return unique_values.tolist()

def search(self):
search_term = self.search_term_entry.get()
if not search_term:
messagebox.showwarning("Advertencia", "Por favor, ingrese un término de búsqueda.")
return

# Realizar la búsqueda en el DataFrame
result = self.search_in_parquet(search_term)

# Limpiar Treeview
for i in self.result_tree.get_children():
self.result_tree.delete(i)

# Insertar resultados en el Treeview
for idx, row in result.iterrows():
self.result_tree.insert("", "end", values=(row["Binary"], row["Function Name"], row["Description"], row["Example"]))

def search_in_parquet(self, term):
if self.dataframe.empty:
return pd.DataFrame()

result = self.dataframe[self.dataframe.apply(lambda row: row.astype(str).str.contains(term, case=False).any(), axis=1)]
result = result.dropna(subset=["Example"]) # Filtrar las filas donde 'Example' es NaN

return result

def on_row_double_click(self, event):
selected_item = self.result_tree.selection()[0]
selected_row = self.result_tree.item(selected_item, "values")
self.show_row_details(selected_row)

def show_row_details(self, row):
detail_window = tk.Toplevel(self)
detail_window.title("Detalles de la fila")

tk.Label(detail_window, text="Binary:").grid(row=0, column=0, sticky=tk.W, padx=10, pady=5)
tk.Label(detail_window, text=row[0]).grid(row=0, column=1, sticky=tk.W, padx=10, pady=5)

tk.Label(detail_window, text="Function Name:").grid(row=1, column=0, sticky=tk.W, padx=10, pady=5)
tk.Label(detail_window, text=row[1]).grid(row=1, column=1, sticky=tk.W, padx=10, pady=5)

tk.Label(detail_window, text="Description:").grid(row=2, column=0, sticky=tk.W, padx=10, pady=5)
description_text = Text(detail_window, wrap=tk.WORD, height=10, width=50)
description_text.grid(row=2, column=1, padx=10, pady=5)
description_text.insert(tk.END, row[2])
description_text.config(state=tk.DISABLED)

tk.Label(detail_window, text="Example:").grid(row=3, column=0, sticky=tk.W, padx=10, pady=5)
example_text = Text(detail_window, wrap=tk.WORD, height=10, width=50)
example_text.grid(row=3, column=1, padx=10, pady=5)
example_text.insert(tk.END, row[3])
example_text.config(state=tk.DISABLED)

if __name__ == "__main__":
app = LazyOwnGUI()
app.mainloop()

0 comments on commit 5284013

Please sign in to comment.