Skip to content

Commit f6fb526

Browse files
Add quick start guide, better error handling, and improved logging
Co-authored-by: codingwithnsh <138281862+codingwithnsh@users.noreply.github.com>
1 parent 480b3ef commit f6fb526

File tree

3 files changed

+171
-23
lines changed

3 files changed

+171
-23
lines changed

main.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2106,8 +2106,24 @@ def open_sandbox_manager(self):
21062106
if hasattr(self, 'sandbox_dashboard'):
21072107
self.sandbox_dashboard.show()
21082108
else:
2109-
messagebox.showinfo("Sandbox Manager",
2110-
"Sandbox Manager is not available.\nPlease check that sandbox_dashboard.py is installed.")
2109+
# Show error with more helpful message
2110+
error_dialog = tk.Toplevel(self.root)
2111+
error_dialog.title("Sandbox Manager Not Available")
2112+
error_dialog.geometry("400x200")
2113+
error_dialog.configure(bg=self.bg_color)
2114+
2115+
tk.Label(error_dialog, text="⚠️ Sandbox Manager Not Available",
2116+
bg=self.bg_color, fg=self.fg_color,
2117+
font=('Arial', 14, 'bold')).pack(pady=20)
2118+
2119+
tk.Label(error_dialog,
2120+
text="The Sandbox Manager module is not loaded.\n\nPlease ensure sandbox_dashboard.py is present\nin the application directory.",
2121+
bg=self.bg_color, fg=self.fg_color,
2122+
font=('Arial', 10), justify=tk.CENTER).pack(pady=10)
2123+
2124+
tk.Button(error_dialog, text="OK", command=error_dialog.destroy,
2125+
bg=self.accent_color, fg='white', relief=tk.FLAT,
2126+
font=('Arial', 11), padx=30, pady=8).pack(pady=20)
21112127

21122128

21132129
if __name__ == "__main__":

sandbox_dashboard.py

Lines changed: 136 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""
22
Sandbox Dashboard - GUI for creating, managing, and monitoring sandboxes
3+
Enhanced with modern UI elements and better user experience
34
"""
45

56
import tkinter as tk
@@ -9,14 +10,15 @@
910

1011

1112
class SandboxDashboard:
12-
"""Dashboard for managing sandboxes"""
13+
"""Dashboard for managing sandboxes with modern UI"""
1314

1415
def __init__(self, root, os_instance):
1516
self.root = root
1617
self.os = os_instance
1718
self.manager = SandboxManager()
1819
self.refresh_interval = 2000 # ms
1920
self.auto_refresh = True
21+
self.first_time_user = len(self.manager.list_sandboxes()) == 0
2022

2123
def show(self):
2224
"""Show sandbox dashboard"""
@@ -299,6 +301,10 @@ def open_terminal():
299301
# Initial load
300302
self.refresh_sandbox_list(sandbox_list)
301303

304+
# Show quick start guide for first-time users
305+
if self.first_time_user:
306+
self.show_quick_start_guide(dashboard)
307+
302308
# Auto-refresh
303309
def auto_refresh_loop():
304310
if self.auto_refresh and dashboard.winfo_exists():
@@ -320,24 +326,46 @@ def refresh_sandbox_list(self, treeview):
320326
for item in treeview.get_children():
321327
treeview.delete(item)
322328

323-
# Add sandboxes
324-
for sb in self.manager.list_sandboxes():
325-
sb.update_stats()
326-
327-
status_icon = {
328-
'running': '🟢',
329-
'paused': '🟡',
330-
'stopped': '🔴'
331-
}.get(sb.status, '⚪')
332-
329+
# Get all sandboxes
330+
sandboxes = self.manager.list_sandboxes()
331+
332+
# If no sandboxes, show empty state message
333+
if not sandboxes:
334+
# Insert a placeholder item
333335
treeview.insert('', tk.END, values=(
334-
sb.name,
335-
sb.type.title(),
336-
f"{status_icon} {sb.status.title()}",
337-
f"{sb.stats['cpu_usage']:.1f}",
338-
f"{sb.stats['memory_usage']:.0f} MB",
339-
f"{sb.stats['disk_usage']:.0f} MB"
340-
))
336+
"No virtual machines created yet",
337+
"—",
338+
"Click 'Create New Sandbox' to get started",
339+
"—",
340+
"—",
341+
"—"
342+
), tags=('empty',))
343+
344+
# Configure tag to center and style the empty state
345+
treeview.tag_configure('empty', foreground='#888888', font=('Arial', 10, 'italic'))
346+
return
347+
348+
# Add sandboxes
349+
for sb in sandboxes:
350+
try:
351+
sb.update_stats()
352+
353+
status_icon = {
354+
'running': '🟢',
355+
'paused': '🟡',
356+
'stopped': '🔴'
357+
}.get(sb.status, '⚪')
358+
359+
treeview.insert('', tk.END, values=(
360+
sb.name,
361+
sb.type.title(),
362+
f"{status_icon} {sb.status.title()}",
363+
f"{sb.stats['cpu_usage']:.1f}",
364+
f"{sb.stats['memory_usage']:.0f} MB",
365+
f"{sb.stats['disk_usage']:.0f} MB"
366+
))
367+
except Exception as e:
368+
print(f"Error adding sandbox {sb.name} to list: {e}")
341369

342370
def create_sandbox_dialog(self, parent):
343371
"""Show dialog to create new sandbox"""
@@ -865,3 +893,93 @@ def execute_command(event=None):
865893
command_var.set("")
866894

867895
command_entry.bind('<Return>', execute_command)
896+
897+
def show_quick_start_guide(self, parent):
898+
"""Show quick start guide for first-time users"""
899+
guide = tk.Toplevel(parent)
900+
guide.title("Welcome to Sandbox Manager")
901+
guide.geometry("600x500")
902+
guide.configure(bg='#1a1a1a' if self.os.theme_mode == 'dark' else '#f5f5f5')
903+
guide.transient(parent)
904+
905+
# Header
906+
header = tk.Frame(guide, bg='#2d2d30' if self.os.theme_mode == 'dark' else '#ffffff', height=80)
907+
header.pack(fill=tk.X)
908+
header.pack_propagate(False)
909+
910+
tk.Label(header, text="🚀 Welcome to Sandbox Manager!",
911+
bg='#2d2d30' if self.os.theme_mode == 'dark' else '#ffffff',
912+
fg='#ffffff' if self.os.theme_mode == 'dark' else '#1a1a1a',
913+
font=('Arial', 18, 'bold')).pack(pady=(20, 5))
914+
915+
tk.Label(header, text="Create isolated virtual environments for your applications",
916+
bg='#2d2d30' if self.os.theme_mode == 'dark' else '#ffffff',
917+
fg='#888888',
918+
font=('Arial', 10)).pack()
919+
920+
# Content
921+
content = tk.Frame(guide, bg='#1a1a1a' if self.os.theme_mode == 'dark' else '#f5f5f5')
922+
content.pack(fill=tk.BOTH, expand=True, padx=30, pady=20)
923+
924+
guide_text = """
925+
🔒 What are Sandboxes?
926+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
927+
Sandboxes are isolated virtual machines that provide:
928+
929+
✅ Security - Run untrusted applications safely
930+
✅ Isolation - Each sandbox has its own file system
931+
✅ Resource Control - Set CPU, memory, and disk limits
932+
✅ Easy Management - Create, start, stop, and delete with ease
933+
934+
935+
📋 Getting Started
936+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
937+
1. Click "Create New Sandbox" button
938+
2. Choose a name for your virtual machine
939+
3. Select a template (or customize resources)
940+
4. Click "Create Virtual Machine"
941+
5. Use the control panel to manage your sandbox
942+
943+
944+
🎯 Available Templates
945+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
946+
🔧 General Purpose - For everyday tasks
947+
💻 Development - Enhanced resources for coding
948+
🧪 Testing - Isolated environment for safe testing
949+
⚡ Lightweight - Minimal resources for simple tasks
950+
🚀 Heavy Workload - Maximum resources for demanding apps
951+
952+
953+
💡 Tips
954+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
955+
• Use the Terminal feature to execute commands in a sandbox
956+
• Monitor resource usage in real-time
957+
• Pause sandboxes when not in use to save resources
958+
• Delete sandboxes you no longer need to free up space
959+
"""
960+
961+
text_widget = scrolledtext.ScrolledText(content,
962+
bg='#2d2d30' if self.os.theme_mode == 'dark' else '#ffffff',
963+
fg='#ffffff' if self.os.theme_mode == 'dark' else '#1a1a1a',
964+
font=('Arial', 10), relief=tk.FLAT, wrap=tk.WORD)
965+
text_widget.pack(fill=tk.BOTH, expand=True)
966+
text_widget.insert('1.0', guide_text)
967+
text_widget.config(state='disabled')
968+
969+
# Buttons
970+
btn_frame = tk.Frame(guide, bg='#1a1a1a' if self.os.theme_mode == 'dark' else '#f5f5f5')
971+
btn_frame.pack(pady=(0, 20))
972+
973+
tk.Button(btn_frame, text="Create My First Sandbox",
974+
command=lambda: (guide.destroy(), self.create_sandbox_dialog(parent)),
975+
bg='#007acc', fg='white', relief=tk.FLAT,
976+
font=('Arial', 11, 'bold'), padx=25, pady=10,
977+
cursor='hand2').pack(side=tk.LEFT, padx=5)
978+
979+
tk.Button(btn_frame, text="Close",
980+
command=guide.destroy,
981+
bg='#3c3c3c' if self.os.theme_mode == 'dark' else '#d0d0d0',
982+
fg='#ffffff' if self.os.theme_mode == 'dark' else '#1a1a1a',
983+
relief=tk.FLAT,
984+
font=('Arial', 11), padx=25, pady=10,
985+
cursor='hand2').pack(side=tk.LEFT, padx=5)

sandbox_manager.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,20 +51,27 @@ def create(self):
5151
"""Create sandbox directory structure"""
5252
try:
5353
# Create directories
54+
print(f"Creating sandbox directories at: {self.base_path}")
5455
self.base_path.mkdir(parents=True, exist_ok=True)
5556
self.root_path.mkdir(exist_ok=True)
5657
self.data_path.mkdir(exist_ok=True)
5758

5859
# Create subdirectories
5960
for subdir in ['bin', 'home', 'tmp', 'lib', 'usr', 'var']:
60-
(self.root_path / subdir).mkdir(exist_ok=True)
61+
subdir_path = self.root_path / subdir
62+
subdir_path.mkdir(exist_ok=True)
63+
print(f"Created subdirectory: {subdir_path}")
6164

6265
# Save configuration
63-
self.save_config()
66+
if not self.save_config():
67+
print("Warning: Failed to save sandbox configuration")
6468

69+
print(f"Sandbox created successfully: {self.name} ({self.id})")
6570
return True
6671
except (OSError, PermissionError) as e:
6772
print(f"Error creating sandbox: {e}")
73+
import traceback
74+
traceback.print_exc()
6875
return False
6976

7077
def start(self):
@@ -294,23 +301,30 @@ def create_sandbox(self, name, sandbox_type="general", config=None):
294301
try:
295302
# Generate unique ID
296303
sandbox_id = str(uuid.uuid4())[:8]
304+
print(f"Creating new sandbox: {name} (ID: {sandbox_id}, Type: {sandbox_type})")
297305

298306
# Create sandbox object
299307
sandbox = Sandbox(sandbox_id, name, sandbox_type, config)
300308

301309
# Create sandbox structure
302310
if not sandbox.create():
311+
print(f"Failed to create sandbox structure for: {name}")
303312
return None
304313

305314
# Add to manager
306315
self.sandboxes[sandbox_id] = sandbox
316+
print(f"Added sandbox to manager: {name} ({sandbox_id})")
307317

308318
# Save configuration
309-
self.save_config()
319+
if not self.save_config():
320+
print("Warning: Failed to save manager configuration")
310321

322+
print(f"Sandbox creation completed successfully: {name}")
311323
return sandbox
312324
except Exception as e:
313325
print(f"Error creating sandbox: {e}")
326+
import traceback
327+
traceback.print_exc()
314328
return None
315329

316330
def get_sandbox(self, sandbox_id):

0 commit comments

Comments
 (0)