Skip to content
DnsLister Forum

Where domain hunters compare notes

Jj

import customtkinter as ctk
import socket
import platform
from datetime import datetime

# =========================
# CONFIG
# =========================

ctk.set_appearance_mode("dark")
ctk.set_default_color_theme("dark-blue")

PURPLE = "#8B5CF6"
PURPLE_DARK = "#6D28D9"
BG = "#08080D"
PANEL = "#101016"
PANEL_2 = "#15151D"
TEXT = "#F5F5F5"
MUTED = "#888899"

class NexusAI(ctk.CTk):

def __init__(self):
super().__init__()

self.title("NEXUS AI")
self.geometry("1200×720")
self.minsize(950, 600)
self.configure(fg_color=BG)

self.build_ui()
self.show_home()

# =========================
# UI PRINCIPALE
# =========================

def build_ui(self):

# Sidebar
self.sidebar = ctk.CTkFrame(
self,
width=210,
corner_radius=0,
fg_color=PANEL
)
self.sidebar.pack(side="left", fill="y")
self.sidebar.pack_propagate(False)

# Logo
logo = ctk.CTkLabel(
self.sidebar,
text="NEXUS",
font=ctk.CTkFont(size=25, weight="bold"),
text_color=PURPLE
)
logo.pack(pady=(30, 2))

sub = ctk.CTkLabel(
self.sidebar,
text="AI SYSTEM",
font=ctk.CTkFont(size=10),
text_color=MUTED
)
sub.pack(pady=(0, 30))

# Boutons
self.add_button("⌂ Dashboard", self.show_home)
self.add_button("◈ Assistant", self.show_chat)
self.add_button("◎ OSINT public", self.show_osint)
self.add_button("⌁ Network / DNS", self.show_network)
self.add_button("▣ PC Info", self.show_pc)
self.add_button("</> Python", self.show_python)
self.add_button("⚙ Settings", self.show_settings)

# Bas sidebar
self.status = ctk.CTkLabel(
self.sidebar,
text="● SYSTEM ONLINE",
text_color="#6EE7B7",
font=ctk.CTkFont(size=11, weight="bold")
)
self.status.pack(side="bottom", pady=25)

# Zone principale
self.main = ctk.CTkFrame(
self,
corner_radius=0,
fg_color=BG
)
self.main.pack(side="left", fill="both", expand=True)

# Header
self.header = ctk.CTkFrame(
self.main,
height=70,
fg_color=PANEL,
corner_radius=0
)
self.header.pack(fill="x")
self.header.pack_propagate(False)

self.page_title = ctk.CTkLabel(
self.header,
text="Dashboard",
font=ctk.CTkFont(size=21, weight="bold")
)
self.page_title.pack(side="left", padx=25)

self.clock = ctk.CTkLabel(
self.header,
text="",
text_color=MUTED
)
self.clock.pack(side="right", padx=25)

self.update_clock()

# Contenu
self.content = ctk.CTkFrame(
self.main,
fg_color=BG,
corner_radius=0
)
self.content.pack(fill="both", expand=True, padx=20, pady=20)

# =========================
# SIDEBAR BUTTON
# =========================

def add_button(self, text, command):

button = ctk.CTkButton(
self.sidebar,
text=text,
command=command,
height=42,
corner_radius=8,
fg_color="transparent",
hover_color="#211B35",
text_color="#D8D8E5",
anchor="w",
font=ctk.CTkFont(size=13)
)

button.pack(fill="x", padx=12, pady=4)

# =========================
# UTILITAIRES
# =========================

def clear_content(self):

for widget in self.content.winfo_children():
widget.destroy()

def set_title(self, title):

self.page_title.configure(text=title)

def update_clock(self):

now = datetime.now().strftime("%H:%M:%S")
self.clock.configure(text=now)
self.after(1000, self.update_clock)

# =========================
# DASHBOARD
# =========================

def show_home(self):

self.clear_content()
self.set_title("Dashboard")

welcome = ctk.CTkLabel(
self.content,
text="Bienvenue dans NEXUS AI",
font=ctk.CTkFont(size=30, weight="bold")
)
welcome.pack(anchor="w", pady=(20, 5))

desc = ctk.CTkLabel(
self.content,
text="Centre de contrôle • Assistant • OSINT public • Network",
text_color=MUTED,
font=ctk.CTkFont(size=13)
)
desc.pack(anchor="w")

cards = ctk.CTkFrame(
self.content,
fg_color="transparent"
)
cards.pack(fill="x", pady=35)

self.card(cards, "AI", "Assistant offline", "READY", 0)
self.card(cards, "OSINT", "Informations publiques", "READY", 1)
self.card(cards, "NET", "DNS / réseau", "READY", 2)

info = ctk.CTkFrame(
self.content,
fg_color=PANEL,
corner_radius=12
)
info.pack(fill="both", expand=True)

ctk.CTkLabel(
info,
text="QUICK START",
font=ctk.CTkFont(size=13, weight="bold"),
text_color=PURPLE
).pack(anchor="w", padx=20, pady=(20, 8))

ctk.CTkLabel(
info,
text="Choisis un module dans la barre de gauche pour commencer.",
text_color=MUTED
).pack(anchor="w", padx=20)

def card(self, parent, title, description, status, column):

card = ctk.CTkFrame(
parent,
fg_color=PANEL,
corner_radius=12,
width=200,
height=120
)
card.grid(row=0, column=column, padx=8, sticky="nsew")
card.grid_propagate(False)

ctk.CTkLabel(
card,
text=title,
text_color=PURPLE,
font=ctk.CTkFont(size=20, weight="bold")
).pack(anchor="w", padx=15, pady=(15, 3))

ctk.CTkLabel(
card,
text=description,
text_color=MUTED
).pack(anchor="w", padx=15)

ctk.CTkLabel(
card,
text="● " + status,
text_color="#6EE7B7",
font=ctk.CTkFont(size=10, weight="bold")
).pack(anchor="w", padx=15, pady=10)

# =========================
# CHAT
# =========================

def show_chat(self):

self.clear_content()
self.set_title("Assistant")

self.chat_box = ctk.CTkTextbox(
self.content,
fg_color=PANEL,
corner_radius=12,
font=ctk.CTkFont(size=13)
)
self.chat_box.pack(fill="both", expand=True)
self.chat_box.insert(
"end",
"NEXUS AI\n"
"──────────────\n"
"Salut 👋 Je suis prêt.\n"
"Pose-moi une question.\n\n"
)
self.chat_box.configure(state="disabled")

bottom = ctk.CTkFrame(
self.content,
fg_color="transparent"
)
bottom.pack(fill="x", pady=(10, 0))

self.chat_entry = ctk.CTkEntry(
bottom,
height=45,
placeholder_text="Écris ton message…"
)
self.chat_entry.pack(side="left", fill="x", expand=True, padx=(0, 10))

self.chat_entry.bind(
"<Return>",
lambda event: self.send_message()
)

ctk.CTkButton(
bottom,
text="SEND",
width=100,
height=45,
fg_color=PURPLE,
hover_color=PURPLE_DARK,
command=self.send_message
).pack(side="right")

def send_message(self):

message = self.chat_entry.get().strip()

if not message:
return

self.chat_entry.delete(0, "end")

if "bonjour" in message.lower() or "salut" in message.lower():
response = "Salut 👋 Comment je peux t'aider ?"

elif "python" in message.lower():
response = "Je peux t'aider à créer ou corriger du Python."

elif "osint" in message.lower():
response = "Le module OSINT permet de récupérer des informations techniques publiques."

elif "pc" in message.lower():
response = "Regarde le module PC Info pour voir les informations de ta machine."

else:
response = "Je suis en mode offline pour cette V1."

self.chat_box.configure(state="normal")
self.chat_box.insert("end", f"\nYOU\n{message}\n\nNEXUS\n{response}\n")
self.chat_box.see("end")
self.chat_box.configure(state="disabled")

# =========================
# OSINT
# =========================

def show_osint(self):

self.clear_content()
self.set_title("OSINT public")

ctk.CTkLabel(
self.content,
text="Domain Lookup",
font=ctk.CTkFont(size=25, weight="bold")
).pack(anchor="w", pady=(10, 5))

ctk.CTkLabel(
self.content,
text="Recherche technique publique d'un domaine.",
text_color=MUTED
).pack(anchor="w")

self.osint_entry = ctk.CTkEntry(
self.content,
height=45,
placeholder_text="exemple.com"
)
self.osint_entry.pack(fill="x", pady=20)

ctk.CTkButton(
self.content,
text="ANALYSER",
height=42,
fg_color=PURPLE,
hover_color=PURPLE_DARK,
command=self.run_osint
).pack(anchor="w")

self.osint_result = ctk.CTkTextbox(
self.content,
fg_color=PANEL,
corner_radius=12
)
self.osint_result.pack(fill="both", expand=True, pady=20)

def run_osint(self):

domain = self.osint_entry.get().strip()

if not domain:
return

try:
ip = socket.gethostbyname(domain)

result = (
"NEXUS OSINT\n"
"──────────────\n\n"
f"Domaine : {domain}\n"
f"IPv4 : {ip}\n\n"
"Source : résolution DNS publique\n"
)

except Exception as e:

result = f"Erreur : {e}"

self.osint_result.delete("1.0", "end")
self.osint_result.insert("end", result)

# =========================
# NETWORK
# =========================

def show_network(self):

self.clear_content()
self.set_title("Network / DNS")

ctk.CTkLabel(
self.content,
text="DNS Resolver",
font=ctk.CTkFont(size=25, weight="bold")
).pack(anchor="w", pady=(10, 5))

self.net_entry = ctk.CTkEntry(
self.content,
height=45,
placeholder_text="Domaine à résoudre…"
)
self.net_entry.pack(fill="x", pady=20)

ctk.CTkButton(
self.content,
text="RESOLVE",
height=42,
fg_color=PURPLE,
hover_color=PURPLE_DARK,
command=self.resolve_dns
).pack(anchor="w")

self.net_result = ctk.CTkTextbox(
self.content,
fg_color=PANEL
)
self.net_result.pack(fill="both", expand=True, pady=20)

def resolve_dns(self):

domain = self.net_entry.get().strip()

if not domain:
return

try:
infos = socket.getaddrinfo(domain, None)

addresses = set()

for info in infos:
addresses.add(info[4][0])

result = "DNS RESULTS\n──────────────\n\n"

for address in addresses:
result += f"• {address}\n"

except Exception as e:

result = f"Erreur : {e}"

self.net_result.delete("1.0", "end")
self.net_result.insert("end", result)

# =========================
# PC INFO
# =========================

def show_pc(self):

self.clear_content()
self.set_title("PC Information")

ctk.CTkLabel(
self.content,
text="System Information",
font=ctk.CTkFont(size=25, weight="bold")
).pack(anchor="w", pady=(10, 20))

frame = ctk.CTkFrame(
self.content,
fg_color=PANEL,
corner_radius=12
)
frame.pack(fill="both", expand=True)

info = (
f"Système : {platform.system()}\n"
f"Version : {platform.version()}\n"
f"Machine : {platform.machine()}\n"
f"Processeur : {platform.processor()}\n"
f"Architecture : {platform.architecture()[0]}\n"
f"Python : {platform.python_version()}\n"
)

ctk.CTkLabel(
frame,
text=info,
justify="left",
font=ctk.CTkFont(size=14)
).pack(anchor="nw", padx=25, pady=25)

# =========================
# PYTHON
# =========================

def show_python(self):

self.clear_content()
self.set_title("Python")

ctk.CTkLabel(
self.content,
text="Python Tools",
font=ctk.CTkFont(size=25, weight="bold")
).pack(anchor="w", pady=(10, 5))

ctk.CTkLabel(
self.content,
text="Espace réservé aux outils Python.",
text_color=MUTED
).pack(anchor="w", pady=(0, 20))

box = ctk.CTkTextbox(
self.content,
fg_color=PANEL,
corner_radius=12
)
box.pack(fill="both", expand=True)

box.insert(
"end",
"# NEXUS Python Workspace\n\n"
"print('Hello NEXUS')\n"
)

# =========================
# SETTINGS
# =========================

def show_settings(self):

self.clear_content()
self.set_title("Settings")

ctk.CTkLabel(
self.content,
text="Settings",
font=ctk.CTkFont(size=25, weight="bold")
).pack(anchor="w", pady=(10, 25))

frame = ctk.CTkFrame(
self.content,
fg_color=PANEL,
corner_radius=12
)
frame.pack(fill="x")

ctk.CTkLabel(
frame,
text="Interface",
font=ctk.CTkFont(size=15, weight="bold")
).pack(anchor="w", padx=20, pady=(20, 5))

ctk.CTkLabel(
frame,
text="Mode sombre activé",
text_color=MUTED
).pack(anchor="w", padx=20, pady=(0, 15))

switch = ctk.CTkSwitch(
frame,
text="Dark Mode",
command=self.toggle_theme
)
switch.select()
switch.pack(anchor="w", padx=20, pady=(0, 20))

def toggle_theme(self):

mode = ctk.get_appearance_mode()

if mode == "Dark":
ctk.set_appearance_mode("Light")
else:
ctk.set_appearance_mode("Dark")

# =========================
# START
# =========================

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

Source: r/u/Ill-Gain8546 · by /u/Ill-Gain8546

Leave a Reply

Your email address will not be published. Required fields are marked *