feat: add python feature

This commit is contained in:
2024-12-29 17:25:34 +08:00
parent 3093f7e624
commit 46493cf1b4
8 changed files with 3674 additions and 57 deletions
+13 -6
View File
@@ -4,6 +4,7 @@ import Docker from 'dockerode';
import fs from 'fs';
import path from 'path';
// 创建 Docker 客户端实例
const docker = new Docker();
@@ -15,14 +16,20 @@ export const runCode = async (params: { code: string; language: string }) => {
throw new Error('Code and language are required.');
}
const supportedLanguages = ['c', 'java'];
const supportedLanguages = ['c', 'java', 'python'];
if (!supportedLanguages.includes(language)) {
throw new Error(`Language '${language}' is not supported. Only 'c' and 'java' are supported.`);
throw new Error(`Language '${language}' is not supported. Only 'c', 'java', and 'python' are supported.`);
}
// 根据语言选择文件名和编译命令
const fileName = language === 'c' ? 'main.c' : 'Main.java';
const compileCmd = language === 'c' ? 'gcc main.c -o main && ./main' : 'javac Main.java && java Main';
// 根据语言选择文件名和编译/运行命令
const fileName =
language === 'c' ? 'main.c' :
language === 'java' ? 'Main.java' :
'script.py';
const runCmd =
language === 'c' ? 'gcc main.c -o main && ./main' :
language === 'java' ? 'javac Main.java && java Main' :
'python3 script.py';
// 创建临时目录用于存储代码文件
const tempDir = path.join('/tmp', `${Date.now()}`);
@@ -35,7 +42,7 @@ export const runCode = async (params: { code: string; language: string }) => {
// 创建并启动 Docker 容器
const container = await docker.createContainer({
Image: 'fly6516.synology.me:8080/multilang:latest',
Cmd: ['sh', '-c', compileCmd],
Cmd: ['sh', '-c', runCmd],
AttachStdout: true,
AttachStderr: true,
Tty: false,
+73 -49
View File
@@ -1,62 +1,86 @@
'use client';
import { useState } from 'react';
import { runCode } from '@/actions'; // 导入 Server Action
import { runCode } from '@/actions'; // 导入 Server Action
import './styles.css'; // 引入样式
const root = document.getElementById('root');
if (root) {
root.innerHTML = 'Hello, world!';
}
/// <reference types="webpack-env" />
if (module.hot) {
module.hot.accept(() => {
console.log('HMR is working!');
});
}
// 启用 HMR
if (module.hot) {
module.hot.accept('./styles.css', () => {
console.log('CSS updated!');
});
}
const CodeRunner = () => {
const [code, setCode] = useState('');
const [language, setLanguage] = useState('c');
const [output, setOutput] = useState('');
const [error, setError] = useState('');
const [code, setCode] = useState('');
const [language, setLanguage] = useState('c'); // 默认语言为 C
const [output, setOutput] = useState('');
const [error, setError] = useState('');
const runCodeHandler = async () => {
try {
// 调用 Server Action 执行代码
const result = await runCode({ code, language });
const runCodeHandler = async () => {
try {
// 调用 Server Action 执行代码
const result = await runCode({ code, language });
setOutput(result.output);
setError('');
} catch (err) {
setError((err as Error).message);
setOutput('');
}
};
setOutput(result.output || ''); // 如果没有输出,设置为空字符串
setError(result.error || ''); // 如果没有错误,设置为空字符串
} catch (err) {
setError((err as Error).message);
setOutput('');
}
};
return (
<div>
<h1>Code Runner</h1>
<textarea
value={code}
onChange={(e) => setCode(e.target.value)}
placeholder="Write your code here"
rows={10}
cols={50}
/>
return (
<div>
<label>
Language:
<select value={language} onChange={(e) => setLanguage(e.target.value)}>
<option value="c">C</option>
<option value="java">Java</option>
</select>
</label>
</div>
<button onClick={runCodeHandler}>Run Code</button>
<h1>Code Runner</h1>
<textarea
value={code}
onChange={(e) => setCode(e.target.value)}
placeholder="Write your code here"
rows={10}
cols={50}
/>
<div>
<label>
Language:
<select value={language} onChange={(e) => setLanguage(e.target.value)}>
<option value="c">C</option>
<option value="java">Java</option>
<option value="python">Python</option> {/* 添加 Python */}
</select>
</label>
</div>
<button onClick={runCodeHandler}>Run Code</button>
{output && (
<div>
<h3>Output:</h3>
<pre>{output}</pre>
</div>
)}
{error && (
<div>
<h3>Error:</h3>
<pre>{error}</pre>
</div>
)}
</div>
);
{output && (
<div>
<h3>Output:</h3>
<pre>{output}</pre>
</div>
)}
{error && (
<div>
<h3>Error:</h3>
<pre>{error}</pre>
</div>
)}
</div>
);
};
export default CodeRunner;
+11
View File
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Webpack HMR</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
+6
View File
@@ -0,0 +1,6 @@
body {
font-family: Arial, sans-serif;
background-color: lightblue;
text-align: center;
padding: 20px;
}