Files
overcode/overshell.py

557 lines
19 KiB
Python
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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)