adding changes to the scripts tab, also added more capabilities

This commit is contained in:
frostyripper1
2026-05-19 16:31:18 +02:00
parent 18e1e232d6
commit d6af2fe753
275 changed files with 372 additions and 32 deletions
+198 -9
View File
@@ -68,6 +68,131 @@ pub fn execute_command(cmd: &str, args: &[&str], timeout_secs: u64) -> Result<Ex
}
}
pub fn detect_language(code: &str) -> &'static str {
let trimmed = code.trim();
let first_line = trimmed.lines().next().unwrap_or("").trim();
// Shebang detection
if first_line.starts_with("#!/") {
if first_line.contains("python") || first_line.contains("python3") {
return "python";
}
if first_line.contains("bash") {
return "bash";
}
if first_line.contains("sh") && !first_line.contains("bash") {
return "bash";
}
if first_line.contains("ruby") {
return "ruby";
}
if first_line.contains("perl") {
return "perl";
}
if first_line.contains("node") {
return "node";
}
}
// Rust: fn main, println!, use std, let mut
if trimmed.contains("fn main")
|| (trimmed.contains("println!") && trimmed.contains("fn "))
|| trimmed.contains("use std::")
{
return "rust";
}
// Go: package main, func main, import (, fmt.
if (trimmed.contains("package main") && trimmed.contains("func main"))
|| trimmed.contains("import (")
|| trimmed.starts_with("package ")
{
return "go";
}
// C/C++: #include
if trimmed.contains("#include <") {
if trimmed.contains("iostream") || trimmed.contains("std::") || trimmed.contains("using namespace") {
return "cpp";
}
return "c";
}
// PowerShell: Cmdlets (Get-*, Write-*), Param(, $var =, common aliases
let ps_score = [
"Write-Host", "Get-Process", "Get-Service", "Get-ChildItem", "Param(",
"Write-Output", "Write-Error", "Get-Item", "Set-Item", "New-Item",
"Remove-Item", "ForEach-Object", "Where-Object", "Select-Object",
"| ForEach-Object", "foreach ($", "function ", "Export-Csv",
].iter().filter(|&&kw| trimmed.contains(kw)).count();
if ps_score >= 2 || (trimmed.starts_with("#requires") || trimmed.starts_with("<#")) {
return "powershell";
}
if trimmed.contains("$") && (trimmed.contains("Write-Host") || trimmed.contains("Write-Output")) {
return "powershell";
}
// Python: import, def, print(, class, if __name__, @
let py_score = [
"import ", "from ", "def ", "class ", "print(",
"if __name__", "elif ", "except ", "with ", "as ",
"lambda ", "yield ", "async def", "await ",
].iter().filter(|&&kw| trimmed.contains(kw)).count();
if py_score >= 3 {
return "python";
}
// Node.js/JavaScript: require(, console.log, module.exports, process., =>
let js_score = [
"require(", "console.log", "module.exports", "process.env",
"=>", "const ", "let ", "var ", "function(", "async (",
"document.", "window.", "export default", "import ",
].iter().filter(|&&kw| trimmed.contains(kw)).count();
if js_score >= 2 {
return "node";
}
// Ruby: def, end, puts, attr_accessor, require ', class .. <
let rb_score = [
"def ", "\nend", "puts ", "require '", "attr_accessor",
"attr_reader", "attr_writer", "do |", "=>", "::",
].iter().filter(|&&kw| trimmed.contains(kw)).count();
if rb_score >= 2 {
return "ruby";
}
// Perl: use strict, my $, sub, shift, print "
let pl_score = [
"use strict", "use warnings", "my $", "sub ", "shift",
"print \"", "print '", "chomp", "foreach my", "while (<",
].iter().filter(|&&kw| trimmed.contains(kw)).count();
if pl_score >= 2 {
return "perl";
}
// Bash: if [, $#, fi, done, then, case, esac, redirects
let sh_score = [
"if [", "if [[", "$#", "\nfi", "\ndone", "\nthen",
"case ", "esac", ">&2", "2>&1", "#!/", "echo \"",
"while read", "for i in", "do\n", "$((", "${",
].iter().filter(|&&kw| trimmed.contains(kw)).count();
if sh_score >= 2 {
return "bash";
}
// CMD/BAT: @echo, setlocal, %var%, REM
let cmd_score = [
"@echo", "echo off", "setlocal", "endlocal", "%",
"REM ", "rem ", "color ", "title ", "exit /b",
"if not", "if defined", "set \"", ">nul",
].iter().filter(|&&kw| trimmed.contains(kw)).count();
if cmd_score >= 2 {
return "cmd";
}
"python"
}
pub fn execute_script(language: &str, code: &str, timeout_secs: u64) -> Result<ExecutionResult> {
let (interpreter, ext) = match language.to_lowercase().as_str() {
"python" | "py" => ("python", ".py"),
@@ -78,13 +203,16 @@ pub fn execute_script(language: &str, code: &str, timeout_secs: u64) -> Result<E
"perl" => ("perl", ".pl"),
"node" | "javascript" | "js" => ("node", ".js"),
"rust" => return compile_and_run_rust(code, timeout_secs),
_ => return Err(anyhow::anyhow!("Unsupported language: {}. Supported: python, bash, powershell, cmd, ruby, perl, node, rust", language)),
"go" | "golang" => return compile_and_run_go(code, timeout_secs),
"c" => return compile_and_run_c_cpp(code, timeout_secs, "c"),
"cpp" | "c++" | "cxx" => return compile_and_run_c_cpp(code, timeout_secs, "cpp"),
_ => return Err(anyhow::anyhow!("Unsupported language: {}. Supported: python, bash, powershell, cmd, ruby, perl, node, rust, go, c, cpp", language)),
};
let temp_dir = std::env::temp_dir().join("airust_scripts");
std::fs::create_dir_all(&temp_dir)?;
let script_path = temp_dir.join(format!("script_{}{}", std::process::id(), ext));
let mut file = std::fs::File::create(&script_path)?;
file.write_all(code.as_bytes())?;
drop(file);
@@ -102,10 +230,10 @@ pub fn execute_script(language: &str, code: &str, timeout_secs: u64) -> Result<E
fn compile_and_run_rust(code: &str, timeout_secs: u64) -> Result<ExecutionResult> {
let temp_dir = std::env::temp_dir().join("airust_scripts");
std::fs::create_dir_all(&temp_dir)?;
let source_path = temp_dir.join(format!("script_{}.rs", std::process::id()));
let bin_path = temp_dir.join(format!("script_{}", std::process::id()));
let mut file = std::fs::File::create(&source_path)?;
file.write_all(code.as_bytes())?;
drop(file);
@@ -122,11 +250,69 @@ fn compile_and_run_rust(code: &str, timeout_secs: u64) -> Result<ExecutionResult
});
}
let run_result = if cfg!(windows) {
execute_command(bin_path.to_str().unwrap(), &[], timeout_secs)
} else {
execute_command(&bin_path.to_str().unwrap(), &[], timeout_secs)
};
let run_result = execute_command(bin_path.to_str().unwrap(), &[], timeout_secs);
let _ = std::fs::remove_file(&source_path);
let _ = std::fs::remove_file(&bin_path);
run_result
}
fn compile_and_run_go(code: &str, timeout_secs: u64) -> Result<ExecutionResult> {
let temp_dir = std::env::temp_dir().join("airust_scripts");
std::fs::create_dir_all(&temp_dir)?;
let source_path = temp_dir.join(format!("script_{}.go", std::process::id()));
let bin_path = temp_dir.join(format!("script_{}.exe", std::process::id()));
let mut file = std::fs::File::create(&source_path)?;
file.write_all(code.as_bytes())?;
drop(file);
let compile = execute_command("go", &["build", "-o", bin_path.to_str().unwrap(), source_path.to_str().unwrap()], timeout_secs)?;
if !compile.success {
return Ok(ExecutionResult {
command: "go build".to_string(),
exit_code: compile.exit_code,
stdout: String::new(),
stderr: compile.stderr,
duration_ms: compile.duration_ms,
success: false,
});
}
let run_result = execute_command(bin_path.to_str().unwrap(), &[], timeout_secs);
let _ = std::fs::remove_file(&source_path);
let _ = std::fs::remove_file(&bin_path);
run_result
}
fn compile_and_run_c_cpp(code: &str, timeout_secs: u64, lang: &str) -> Result<ExecutionResult> {
let temp_dir = std::env::temp_dir().join("airust_scripts");
std::fs::create_dir_all(&temp_dir)?;
let ext = if lang == "cpp" { ".cpp" } else { ".c" };
let source_path = temp_dir.join(format!("script_{}{}", std::process::id(), ext));
let bin_path = temp_dir.join(format!("script_{}.exe", std::process::id()));
let mut file = std::fs::File::create(&source_path)?;
file.write_all(code.as_bytes())?;
drop(file);
let compiler = if lang == "cpp" { "g++" } else { "gcc" };
let compile = execute_command(compiler, &[source_path.to_str().unwrap(), "-o", bin_path.to_str().unwrap()], timeout_secs)?;
if !compile.success {
return Ok(ExecutionResult {
command: format!("{} (compile)", compiler),
exit_code: compile.exit_code,
stdout: String::new(),
stderr: compile.stderr,
duration_ms: compile.duration_ms,
success: false,
});
}
let run_result = execute_command(bin_path.to_str().unwrap(), &[], timeout_secs);
let _ = std::fs::remove_file(&source_path);
let _ = std::fs::remove_file(&bin_path);
@@ -144,5 +330,8 @@ pub fn list_supported_languages() -> Vec<String> {
"ruby".to_string(),
"perl".to_string(),
"rust".to_string(),
"go".to_string(),
"c".to_string(),
"cpp".to_string(),
]
}