JustPaste
HomeCategoriesAboutDonateContactTerms of UsePrivacy Policy
JustPaste

Free online notepad — write and share instantly

Navigate

  • Home
  • Timeline
  • Categories

Info

  • About
  • Donate
  • Contact

Legal

  • Terms of Use
  • Privacy Policy

© 2026 JustPaste.app. All rights reserved.

Made with ♥ by JustPaste

Hdgs | JustPaste.app
21 days ago13 views
👨‍💻Programming

Hdgs

import tkinter as tk
from tkinter import ttk, filedialog, scrolledtext, messagebox
import openpyxl
from pathlib import Path
import threading
from datetime import datetime
import re
import warnings

# Suppress escape sequence warnings
warnings.filterwarnings("ignore", category=SyntaxWarning)

class BlackhatExcelSearcher(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("🔥 EXCEL SHADOW SEARCH v3.3 - FULL ROW MODE 🔥")
        self.geometry("1250x820")
        self.configure(bg='#0a0a0a')
        
        self.folder_paths = []
        self.search_text = tk.StringVar()
        self.is_searching = False
        
        self.create_widgets()

    def create_widgets(self):
        main_frame = ttk.Frame(self, padding="10")
        main_frame.grid(row=0, column=0, sticky="nsew")
        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)

        ttk.Label(main_frame, text="EXCEL SHADOW SEARCH v3.3 - FULL ROW", 
                 font=('Consolas', 16, 'bold'), foreground='#00ff00').grid(row=0, column=0, columnspan=4, pady=10)

        # Folders
        folder_frame = ttk.LabelFrame(main_frame, text="TARGET FOLDERS", padding=8)
        folder_frame.grid(row=1, column=0, columnspan=4, sticky="ew", pady=5)
        
        self.folder_listbox = tk.Listbox(folder_frame, height=6, bg='#1e1e1e', fg='#00ff41')
        self.folder_listbox.pack(fill=tk.X, padx=5, pady=5)

        btnf = ttk.Frame(folder_frame)
        btnf.pack(fill=tk.X)
        ttk.Button(btnf, text="Add Folder", command=self.add_folder).pack(side=tk.LEFT, padx=5)
        ttk.Button(btnf, text="Remove", command=self.remove_folder).pack(side=tk.LEFT, padx=5)
        ttk.Button(btnf, text="Clear", command=self.clear_folders).pack(side=tk.LEFT)

        # Search
        sf = ttk.LabelFrame(main_frame, text="HUNT CONFIG", padding=10)
        sf.grid(row=2, column=0, columnspan=4, sticky="ew", pady=8)

        ttk.Label(sf, text="Search Term:").grid(row=0, column=0, sticky=tk.W, padx=5)
        ttk.Entry(sf, textvariable=self.search_text, width=55, font=('Consolas', 11)).grid(row=0, column=1, padx=5, sticky="ew")
        
        self.search_btn = ttk.Button(sf, text="🚀 START SEARCH", command=self.start_search)
        self.search_btn.grid(row=0, column=2, padx=10)

        self.fuzzy_var = tk.BooleanVar(value=True)
        ttk.Checkbutton(sf, text="Enable Number Cleaning + Fuzzy", variable=self.fuzzy_var).grid(row=1, column=0, columnspan=3, pady=5)

        self.progress = ttk.Progressbar(main_frame, mode='indeterminate')
        self.progress.grid(row=3, column=0, columnspan=4, sticky="ew", pady=5)

        # Results
        rf = ttk.LabelFrame(main_frame, text="RESULTS (Full Row Shown on Match)", padding=8)
        rf.grid(row=4, column=0, columnspan=4, sticky="nsew")
        rf.rowconfigure(0, weight=1)
        rf.columnconfigure(0, weight=1)
        
        self.results_text = scrolledtext.ScrolledText(rf, bg='#0a0a0a', fg='#00ff41', font=('Consolas', 10))
        self.results_text.grid(row=0, column=0, sticky="nsew")

        ttk.Button(main_frame, text="💾 Save Results", command=self.save_results).grid(row=5, column=0, columnspan=4, pady=8)

        self.status = ttk.Label(main_frame, text="Ready", relief=tk.SUNKEN, foreground="#00ff00")
        self.status.grid(row=6, column=0, columnspan=4, sticky="ew")

    def add_folder(self):
        folder = filedialog.askdirectory()
        if folder and folder not in self.folder_paths:
            self.folder_paths.append(folder)
            self.folder_listbox.insert(tk.END, folder)

    def remove_folder(self):
        sel = self.folder_listbox.curselection()
        if sel:
            idx = sel[0]
            self.folder_listbox.delete(idx)
            del self.folder_paths[idx]

    def clear_folders(self):
        self.folder_paths.clear()
        self.folder_listbox.delete(0, tk.END)

    def log(self, message):
        self.results_text.insert(tk.END, f"[LOG] {message}\n")
        self.results_text.see(tk.END)

    def get_full_row(self, sheet, row_idx):
        """Get all values in a row as tab-separated string"""
        row_values = []
        for cell in sheet[row_idx]:
            val = cell.value
            row_values.append(str(val).strip() if val is not None else "")
        return " | ".join(row_values)

    def search_excel_file(self, file_path, term):
        matches = []
        try:
            self.log(f"Scanning {file_path.name}")
            wb = openpyxl.load_workbook(file_path, read_only=True, data_only=True)
            
            for sheet_name in wb.sheetnames:
                sheet = wb[sheet_name]
                self.log(f"  → Sheet: {sheet_name} ({sheet.max_row} rows)")
                
                for r_idx, row in enumerate(sheet.iter_rows(values_only=True), start=1):
                    for c_idx, value in enumerate(row, start=1):
                        if value is None:
                            continue
                        
                        cell_str = str(value).strip()
                        if not cell_str:
                            continue
                        
                        found = False
                        col_letter = openpyxl.utils.get_column_letter(c_idx)
                        
                        # Direct match
                        if term.lower() in cell_str.lower():
                            found = True
                        
                        # Number cleaning
                        if not found and self.fuzzy_var.get():
                            clean_cell = re.sub(r'[^0-9a-zA-Z]', '', cell_str.lower())
                            clean_term = re.sub(r'[^0-9a-zA-Z]', '', term.lower())
                            if clean_term and clean_term in clean_cell:
                                found = True
                        
                        if found:
                            full_row = self.get_full_row(sheet, r_idx)
                            matches.append({
                                'file': str(file_path),
                                'sheet': sheet_name,
                                'location': f"{sheet_name}!{col_letter}{r_idx}",
                                'matched_value': cell_str,
                                'full_row': full_row
                            })
                            break  # One match per row is enough (to avoid duplicates)
            
            wb.close()
            if matches:
                self.log(f"  → FOUND {len(matches)} matching rows in {file_path.name}")
            
        except Exception as e:
            self.log(f"ERROR {file_path.name}: {e}")
        
        return matches

    def start_search(self):
        if not self.folder_paths:
            messagebox.showwarning("Error", "Add at least one folder!")
            return
        term = self.search_text.get().strip()
        if not term:
            messagebox.showwarning("Error", "Enter search term!")
            return

        self.is_searching = True
        self.search_btn.config(state='disabled')
        self.progress.start(10)
        self.results_text.delete(1.0, tk.END)
        self.log(f"Starting hunt for: '{term}'")

        thread = threading.Thread(target=self.perform_search, args=(term,))
        thread.daemon = True
        thread.start()

    def perform_search(self, term):
        all_results = []
        total_files = 0

        for folder in self.folder_paths:
            p = Path(folder)
            excel_files = list(p.glob("**/*.xlsx")) + list(p.glob("**/*.xlsm")) + list(p.glob("**/*.xls"))
            total_files += len(excel_files)

            for file_path in excel_files:
                if file_path.name.startswith('\~$'):
                    continue
                file_matches = self.search_excel_file(file_path, term)
                if file_matches:
                    all_results.extend(file_matches)

        self.after(0, lambda: self.show_results(all_results, total_files, term))

    def show_results(self, all_matches, total_files, term):
        self.progress.stop()
        self.search_btn.config(state='normal')
        self.is_searching = False

        header = f"\n{'='*100}\nFULL ROW SEARCH REPORT - {datetime.now().strftime('%Y-%m-%d %H:%M')}\n"
        header += f"Search Term: {term} | Files Scanned: {total_files} | Matching Rows: {len(all_matches)}\n{'='*100}\n\n"
        self.results_text.insert(tk.END, header)

        if not all_matches:
            self.results_text.insert(tk.END, "No matches found.\n")
            return

        for m in all_matches:
            self.results_text.insert(tk.END, f"📁 {m['file']}\n")
            self.results_text.insert(tk.END, f"📍 Location : {m['location']}\n")
            self.results_text.insert(tk.END, f"🔍 Matched  : {m['matched_value']}\n")
            self.results_text.insert(tk.END, f"📋 Full Row: {m['full_row']}\n")
            self.results_text.insert(tk.END, "-"*120 + "\n\n")

        self.status.config(text=f"Complete → {len(all_matches)} matching rows found")

    def save_results(self):
        content = self.results_text.get(1.0, tk.END).strip()
        if not content:
            return
        path = filedialog.asksaveasfilename(defaultextension=".txt", 
                                          initialfile=f"search_results_{datetime.now().strftime('%Y%m%d_%H%M')}.txt")
        if path:
            with open(path, "w", encoding="utf-8") as f:
                f.write(content)
            messagebox.showinfo("Saved", f"Results saved to {path}")

if __name__ == "__main__":
    app = BlackhatExcelSearcher()
    app.mainloop()
← Back to timeline