557 lines
19 KiB
Python
557 lines
19 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
OverCode Shell - Enhanced polyglot programming environment
|
||
With advanced features, games, and developer tools
|
||
"""
|
||
|
||
import os
|
||
import cmd
|
||
import json
|
||
import random
|
||
import time
|
||
import sys
|
||
import re
|
||
from datetime import datetime
|
||
from pathlib import Path
|
||
from colorama import init, Fore, Back, Style
|
||
from pyfiglet import Figlet
|
||
|
||
# Check if running as PyInstaller executable and set mode early
|
||
if getattr(sys, 'frozen', False):
|
||
os.environ['OVERCODE_EXE_MODE'] = '1'
|
||
# Completely disable readline to avoid backend issues
|
||
sys.modules['readline'] = None
|
||
sys.modules['pyreadline3'] = None
|
||
# Try to import readline for command history (Linux/Mac) or pyreadline (Windows)
|
||
readline = None
|
||
try:
|
||
import readline # For Unix systems
|
||
# Test if readline is working properly
|
||
if hasattr(readline, 'add_history'):
|
||
readline = readline
|
||
else:
|
||
readline = None
|
||
except (ImportError, AttributeError):
|
||
try:
|
||
import pyreadline3 as readline # For Windows
|
||
if hasattr(readline, 'add_history'):
|
||
readline = readline
|
||
else:
|
||
readline = None
|
||
except (ImportError, AttributeError):
|
||
readline = None
|
||
|
||
if readline is None and __name__ == "__main__":
|
||
print("Note: Command history not available")
|
||
|
||
# Initialize colorama
|
||
init(autoreset=True)
|
||
|
||
# Import command modules
|
||
from commands.cmd_new import NewCommand
|
||
from commands.cmd_run import RunCommand
|
||
from commands.cmd_theme import ThemeCommand
|
||
from commands.cmd_game import GameCommand
|
||
from commands.cmd_stubs import (
|
||
NanoCommand, FastfetchCommand, CreditsCommand, CdCommand,
|
||
ExitCommand, WdirCommand, FormatCommand, DebugCommand,
|
||
PackageCommand, AsciiCommand, StatsCommand, BenchmarkCommand, EncryptCommand
|
||
)
|
||
from commands.cmd_demo import DemoCommand, SuggestCommand
|
||
|
||
# Try Discord RPC (optional)
|
||
try:
|
||
from pypresence import Presence, exceptions
|
||
RPC_AVAILABLE = True
|
||
except ImportError:
|
||
RPC_AVAILABLE = False
|
||
print("Note: Discord RPC not available (install pypresence for Discord integration)")
|
||
|
||
# Import auto-completion and progress bars
|
||
try:
|
||
# Skip utils import in executable mode to avoid readline issues
|
||
if os.environ.get('OVERCODE_EXE_MODE') != '1':
|
||
from utils.autocomplete import AutoComplete, setup_autocomplete
|
||
from utils.progress import SpinnerProgress, simulate_progress
|
||
UTILS_AVAILABLE = True
|
||
else:
|
||
UTILS_AVAILABLE = False
|
||
except ImportError:
|
||
UTILS_AVAILABLE = False
|
||
|
||
CLIENT_ID = '1414669512158220409'
|
||
|
||
class Theme:
|
||
"""Theme management for the shell"""
|
||
themes = {
|
||
'cyberpunk': {
|
||
'primary': Fore.MAGENTA,
|
||
'secondary': Fore.CYAN,
|
||
'accent': Fore.GREEN,
|
||
'error': Fore.RED,
|
||
'warning': Fore.YELLOW,
|
||
'info': Fore.BLUE,
|
||
'text': Fore.WHITE
|
||
},
|
||
'matrix': {
|
||
'primary': Fore.GREEN,
|
||
'secondary': Fore.LIGHTGREEN_EX,
|
||
'accent': Fore.WHITE,
|
||
'error': Fore.RED,
|
||
'warning': Fore.YELLOW,
|
||
'info': Fore.GREEN,
|
||
'text': Fore.LIGHTGREEN_EX
|
||
},
|
||
'ocean': {
|
||
'primary': Fore.BLUE,
|
||
'secondary': Fore.CYAN,
|
||
'accent': Fore.LIGHTBLUE_EX,
|
||
'error': Fore.RED,
|
||
'warning': Fore.YELLOW,
|
||
'info': Fore.LIGHTCYAN_EX,
|
||
'text': Fore.WHITE
|
||
},
|
||
'sunset': {
|
||
'primary': Fore.LIGHTYELLOW_EX,
|
||
'secondary': Fore.LIGHTRED_EX,
|
||
'accent': Fore.MAGENTA,
|
||
'error': Fore.RED,
|
||
'warning': Fore.YELLOW,
|
||
'info': Fore.LIGHTMAGENTA_EX,
|
||
'text': Fore.WHITE
|
||
},
|
||
'hacker': {
|
||
'primary': Fore.LIGHTBLACK_EX,
|
||
'secondary': Fore.GREEN,
|
||
'accent': Fore.LIGHTGREEN_EX,
|
||
'error': Fore.LIGHTRED_EX,
|
||
'warning': Fore.LIGHTYELLOW_EX,
|
||
'info': Fore.LIGHTCYAN_EX,
|
||
'text': Fore.GREEN
|
||
}
|
||
}
|
||
|
||
def __init__(self, theme_name='cyberpunk'):
|
||
self.current_theme = theme_name
|
||
self.colors = self.themes.get(theme_name, self.themes['cyberpunk'])
|
||
|
||
def set_theme(self, theme_name):
|
||
if theme_name in self.themes:
|
||
self.current_theme = theme_name
|
||
self.colors = self.themes[theme_name]
|
||
return True
|
||
return False
|
||
|
||
def get_color(self, color_type):
|
||
return self.colors.get(color_type, Fore.WHITE)
|
||
|
||
class OverCodeShell(cmd.Cmd):
|
||
"""Enhanced OverCode Shell with advanced features"""
|
||
|
||
def __init__(self):
|
||
super().__init__()
|
||
|
||
# Disable readline functionality in executable mode
|
||
if os.environ.get('OVERCODE_EXE_MODE') == '1':
|
||
import cmd
|
||
self.use_rawinput = False # Disable readline use
|
||
cmd.readline = None # Force cmd to not use readline
|
||
|
||
self.version = "2.0.0-ULTRA"
|
||
self.theme = Theme()
|
||
self.stats = {
|
||
'commands_run': 0,
|
||
'files_created': 0,
|
||
'code_executed': 0,
|
||
'games_played': 0,
|
||
'session_start': datetime.now()
|
||
}
|
||
|
||
# Set up directories
|
||
self.base_dir = os.path.join(os.path.expanduser("~"), "overcode", "workspace")
|
||
os.makedirs(self.base_dir, exist_ok=True)
|
||
|
||
self.cwd = self.base_dir
|
||
os.chdir(self.cwd)
|
||
|
||
# Initialize features
|
||
self.history = []
|
||
self.aliases = {}
|
||
self.macros = {}
|
||
self.plugins = []
|
||
|
||
# Set up Discord RPC if available
|
||
self.rpc_active = False
|
||
self.rpc = None
|
||
if RPC_AVAILABLE:
|
||
self._connect_rpc()
|
||
|
||
# Set up auto-completion (only if readline is available)
|
||
if UTILS_AVAILABLE and readline is not None:
|
||
try:
|
||
self.autocomplete = setup_autocomplete(self)
|
||
except Exception as e:
|
||
self.autocomplete = None
|
||
if hasattr(self, 'debug') and self.debug:
|
||
print(f"Debug: Auto-completion setup failed: {e}")
|
||
else:
|
||
self.autocomplete = None
|
||
|
||
self.update_prompt()
|
||
|
||
def _connect_rpc(self):
|
||
"""Connect to Discord RPC"""
|
||
try:
|
||
self.rpc = Presence(CLIENT_ID)
|
||
self.rpc.connect()
|
||
self.rpc_active = True
|
||
self._set_presence("OverCode Shell", "Coding in the future")
|
||
except Exception as e:
|
||
self.rpc_active = False
|
||
# Only show RPC error in debug mode
|
||
if hasattr(self, 'debug') and self.debug:
|
||
print(f"Debug: Discord RPC connection failed: {e}")
|
||
|
||
def _set_presence(self, details, state):
|
||
"""Update Discord presence"""
|
||
if self.rpc_active and self.rpc:
|
||
try:
|
||
self.rpc.update(
|
||
details=details,
|
||
state=state,
|
||
large_image="overcode_logo",
|
||
large_text="OverCode Shell v" + self.version,
|
||
small_image="coding",
|
||
small_text="Enhanced Polyglot Environment"
|
||
)
|
||
except Exception as e:
|
||
self.rpc_active = False
|
||
if hasattr(self, 'debug') and self.debug:
|
||
print(f"Debug: Discord RPC update failed: {e}")
|
||
|
||
def update_prompt(self):
|
||
"""Update command prompt with theme colors"""
|
||
c = self.theme.colors
|
||
self.prompt = (
|
||
c['primary'] + "╭─[" +
|
||
c['accent'] + "OverCode" +
|
||
c['primary'] + " " +
|
||
c['secondary'] + "v" + self.version +
|
||
c['primary'] + "] " +
|
||
c['info'] + self.cwd +
|
||
"\n" + c['primary'] + "╰─" +
|
||
c['accent'] + "▶ " +
|
||
Style.RESET_ALL
|
||
)
|
||
|
||
def preloop(self):
|
||
"""Initialize shell with banner"""
|
||
self._print_banner()
|
||
self._load_config()
|
||
if self.rpc_active:
|
||
self._set_presence("Ready", "Awaiting commands...")
|
||
|
||
def _print_banner(self):
|
||
"""Print stylized banner"""
|
||
c = self.theme.colors
|
||
|
||
# Random ASCII art fonts
|
||
fonts = ['slant', 'big', 'doom', 'larry3d', 'alligator']
|
||
font = random.choice(fonts)
|
||
fig = Figlet(font=font)
|
||
|
||
print(c['primary'] + "═" * 70)
|
||
print(c['accent'] + fig.renderText("OverCode"))
|
||
print(c['secondary'] + " Enhanced Polyglot Programming Environment")
|
||
print(c['info'] + f" Version {self.version}")
|
||
print(c['primary'] + "═" * 70)
|
||
print()
|
||
print(c['text'] + "Welcome to the future of coding! Type 'help' for commands.")
|
||
print(c['warning'] + "New: Games, Themes, Package Manager, and more!")
|
||
print(c['primary'] + "═" * 70 + Style.RESET_ALL)
|
||
|
||
def _load_config(self):
|
||
"""Load user configuration"""
|
||
config_path = Path.home() / ".overcode" / "config.json"
|
||
if config_path.exists():
|
||
try:
|
||
with open(config_path) as f:
|
||
config = json.load(f)
|
||
self.theme.set_theme(config.get('theme', 'cyberpunk'))
|
||
self.aliases = config.get('aliases', {})
|
||
self.macros = config.get('macros', {})
|
||
except:
|
||
pass
|
||
|
||
def _save_config(self):
|
||
"""Save user configuration"""
|
||
config_path = Path.home() / ".overcode"
|
||
config_path.mkdir(exist_ok=True)
|
||
|
||
config = {
|
||
'theme': self.theme.current_theme,
|
||
'aliases': self.aliases,
|
||
'macros': self.macros,
|
||
'stats': self.stats
|
||
}
|
||
|
||
with open(config_path / "config.json", 'w') as f:
|
||
json.dump(config, f, indent=2, default=str)
|
||
|
||
def postcmd(self, stop, line):
|
||
"""After command execution"""
|
||
self.stats['commands_run'] += 1
|
||
if self.rpc_active:
|
||
self._set_presence("Active", f"Commands run: {self.stats['commands_run']}")
|
||
return stop
|
||
|
||
def default(self, line):
|
||
"""Handle unknown commands with smart suggestions"""
|
||
# Check for aliases
|
||
parts = line.split()
|
||
if parts and parts[0] in self.aliases:
|
||
line = self.aliases[parts[0]] + ' '.join(parts[1:])
|
||
self.onecmd(line)
|
||
return
|
||
|
||
# Check for macros
|
||
if line in self.macros:
|
||
for cmd in self.macros[line]:
|
||
self.onecmd(cmd)
|
||
return
|
||
|
||
c = self.theme.colors
|
||
print(c['error'] + f"✗ Unknown command: '{line}'")
|
||
|
||
# Show smart suggestions if auto-completion is available
|
||
if self.autocomplete:
|
||
suggestion = self.autocomplete.smart_suggest(line)
|
||
if suggestion:
|
||
print(suggestion)
|
||
else:
|
||
print(c['warning'] + "→ Type 'help' for available commands")
|
||
else:
|
||
print(c['warning'] + "→ Type 'help' for available commands")
|
||
print(c['info'] + "→ Type 'suggest' for command suggestions")
|
||
|
||
def emptyline(self):
|
||
"""Do nothing on empty line"""
|
||
pass
|
||
|
||
def do_help(self, arg):
|
||
"""Enhanced help system"""
|
||
if arg:
|
||
super().do_help(arg)
|
||
else:
|
||
c = self.theme.colors
|
||
|
||
print("\n" + c['primary'] + "═" * 60)
|
||
print(c['accent'] + " " * 20 + "OVERCODE COMMANDS")
|
||
print(c['primary'] + "═" * 60)
|
||
|
||
categories = {
|
||
"📁 File Management": [
|
||
("new", "Create a new polyglot file"),
|
||
("nano", "Edit files with enhanced editor"),
|
||
("run", "Execute polyglot scripts"),
|
||
("compile", "Compile code to executables"),
|
||
],
|
||
"🎮 Entertainment": [
|
||
("game", "Play built-in games"),
|
||
("ascii", "Generate ASCII art"),
|
||
("matrix", "Matrix rain animation"),
|
||
("music", "Play background music"),
|
||
],
|
||
"🛠️ Developer Tools": [
|
||
("format", "Format and beautify code"),
|
||
("debug", "Debug code with breakpoints"),
|
||
("benchmark", "Performance testing"),
|
||
("profile", "Code profiling"),
|
||
("lint", "Code quality check"),
|
||
],
|
||
"📦 Package Management": [
|
||
("package", "Manage packages and extensions"),
|
||
("install", "Install new packages"),
|
||
("update", "Update packages"),
|
||
("list", "List installed packages"),
|
||
],
|
||
"🎨 Customization": [
|
||
("theme", "Change shell theme"),
|
||
("alias", "Create command aliases"),
|
||
("macro", "Record command macros"),
|
||
("config", "Edit configuration"),
|
||
],
|
||
"📊 Data & Visualization": [
|
||
("plot", "Create graphs and charts"),
|
||
("table", "Display data tables"),
|
||
("stats", "Show session statistics"),
|
||
("export", "Export data"),
|
||
],
|
||
"🔒 Security": [
|
||
("encrypt", "Encrypt files"),
|
||
("decrypt", "Decrypt files"),
|
||
("hash", "Generate file hashes"),
|
||
("secure", "Secure delete"),
|
||
],
|
||
"🌐 Network": [
|
||
("api", "API testing tool"),
|
||
("webhook", "Webhook manager"),
|
||
("server", "Start local server"),
|
||
("share", "Share files online"),
|
||
],
|
||
"🎭 Demos & Features": [
|
||
("demo", "Feature demonstrations"),
|
||
("suggest", "Smart command suggestions"),
|
||
],
|
||
"ℹ️ Information": [
|
||
("fastfetch", "System information"),
|
||
("credits", "Show credits"),
|
||
("version", "Version info"),
|
||
("changelog", "Recent changes"),
|
||
],
|
||
"🔧 System": [
|
||
("cd", "Change directory"),
|
||
("ls", "List directory contents"),
|
||
("clear", "Clear screen"),
|
||
("exit", "Exit OverCode"),
|
||
]
|
||
}
|
||
|
||
for category, commands in categories.items():
|
||
print(f"\n{c['secondary']}{category}")
|
||
print(c['primary'] + "─" * 40)
|
||
for cmd, desc in commands:
|
||
print(f" {c['accent']}{cmd:<15} {c['text']}→ {desc}")
|
||
|
||
print("\n" + c['primary'] + "═" * 60)
|
||
print(c['info'] + "Type 'help <command>' for detailed help")
|
||
print(c['warning'] + "Type 'tutorial' for interactive tutorial")
|
||
print(c['primary'] + "═" * 60 + Style.RESET_ALL + "\n")
|
||
|
||
# Core commands
|
||
def do_new(self, arg):
|
||
"""Create a new polyglot file"""
|
||
if self.rpc_active:
|
||
self._set_presence("Creating", f"New file: {arg}")
|
||
NewCommand(self.cwd, arg.strip()).run()
|
||
self.stats['files_created'] += 1
|
||
|
||
def do_nano(self, arg):
|
||
"""Edit a file"""
|
||
if self.rpc_active:
|
||
self._set_presence("Editing", arg.strip())
|
||
NanoCommand(self.cwd, arg.strip()).run()
|
||
|
||
def do_run(self, arg):
|
||
"""Run a polyglot script"""
|
||
if self.rpc_active:
|
||
self._set_presence("Executing", arg.strip())
|
||
RunCommand(self.cwd, arg.strip()).run()
|
||
self.stats['code_executed'] += 1
|
||
|
||
def do_game(self, arg):
|
||
"""Launch a game"""
|
||
if self.rpc_active:
|
||
self._set_presence("Gaming", f"Playing: {arg or 'Game Menu'}")
|
||
GameCommand(arg.strip()).run()
|
||
self.stats['games_played'] += 1
|
||
|
||
def do_theme(self, arg):
|
||
"""Change shell theme"""
|
||
ThemeCommand(self.theme, arg.strip()).run()
|
||
self.update_prompt()
|
||
self._save_config()
|
||
|
||
def do_stats(self, arg):
|
||
"""Show session statistics"""
|
||
StatsCommand(self.stats).run()
|
||
|
||
def do_demo(self, arg):
|
||
"""Run feature demonstrations"""
|
||
if self.rpc_active:
|
||
self._set_presence("Demo Mode", f"Testing: {arg or 'Features'}")
|
||
DemoCommand(arg.strip()).run()
|
||
|
||
def do_suggest(self, arg):
|
||
"""Show command suggestions"""
|
||
SuggestCommand(self).run()
|
||
|
||
def do_clear(self, arg):
|
||
"""Clear the screen"""
|
||
os.system('cls' if os.name == 'nt' else 'clear')
|
||
self._print_banner()
|
||
|
||
def do_exit(self, arg):
|
||
"""Exit OverCode Shell"""
|
||
self._save_config()
|
||
if self.rpc_active and self.rpc:
|
||
self.rpc.close()
|
||
|
||
c = self.theme.colors
|
||
print(c['primary'] + "\n" + "═" * 50)
|
||
print(c['accent'] + "Thanks for using OverCode!")
|
||
print(c['info'] + f"Session Stats: {self.stats['commands_run']} commands run")
|
||
print(c['primary'] + "═" * 50 + Style.RESET_ALL)
|
||
return True
|
||
|
||
def do_cd(self, arg):
|
||
"""Change directory"""
|
||
CdCommand(self.base_dir, [self], arg).run()
|
||
os.chdir(self.cwd)
|
||
self.update_prompt()
|
||
|
||
def do_ls(self, arg):
|
||
"""List directory contents with colors"""
|
||
c = self.theme.colors
|
||
try:
|
||
items = os.listdir(self.cwd)
|
||
if not items:
|
||
print(c['warning'] + "Directory is empty")
|
||
return
|
||
|
||
dirs = []
|
||
files = []
|
||
|
||
for item in items:
|
||
path = os.path.join(self.cwd, item)
|
||
if os.path.isdir(path):
|
||
dirs.append(item)
|
||
else:
|
||
files.append(item)
|
||
|
||
if dirs:
|
||
print(c['secondary'] + "\n📁 Directories:")
|
||
for d in sorted(dirs):
|
||
print(f" {c['accent']}{d}/")
|
||
|
||
if files:
|
||
print(c['secondary'] + "\n📄 Files:")
|
||
for f in sorted(files):
|
||
ext = os.path.splitext(f)[1]
|
||
if ext in ['.py', '.js', '.cpp', '.c', '.java', '.go', '.rs']:
|
||
icon = "🔧"
|
||
elif ext in ['.txt', '.md', '.doc']:
|
||
icon = "📝"
|
||
elif ext in ['.jpg', '.png', '.gif']:
|
||
icon = "🖼️"
|
||
elif ext in ['.mp3', '.wav']:
|
||
icon = "🎵"
|
||
elif ext == '.ovc':
|
||
icon = "⚡"
|
||
else:
|
||
icon = "📄"
|
||
print(f" {icon} {c['text']}{f}")
|
||
|
||
except Exception as e:
|
||
print(c['error'] + f"Error: {e}")
|
||
|
||
if __name__ == "__main__":
|
||
try:
|
||
shell = OverCodeShell()
|
||
shell.cmdloop()
|
||
except KeyboardInterrupt:
|
||
print("\n\nGoodbye! 👋")
|
||
except Exception as e:
|
||
print(f"Fatal error: {e}")
|
||
sys.exit(1)
|