From fec3f73d29094a674c9353faf1cc800bbb4a30e9 Mon Sep 17 00:00:00 2001 From: Shweta Date: Fri, 8 Jan 2021 18:21:09 +0530 Subject: [PATCH 1/2] fixed minor bugs --- .../server/api/services/code.service.js | 106 +++++++++--------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/rce-server/server/api/services/code.service.js b/rce-server/server/api/services/code.service.js index d90512b..1671ec5 100644 --- a/rce-server/server/api/services/code.service.js +++ b/rce-server/server/api/services/code.service.js @@ -1,12 +1,12 @@ -import fs from 'fs'; -import path from 'path'; -import util from 'util'; -import { execFile, spawn, exec } from 'child_process'; -import ValidationService from './validation.service'; +import fs from "fs"; +import path from "path"; +import util from "util"; +import { execFile, spawn, exec } from "child_process"; +import ValidationService from "./validation.service"; const ROOT_DIR = `${process.cwd()}`; -const SOURCE_DIR = path.join(ROOT_DIR, 'executor'); +const SOURCE_DIR = path.join(ROOT_DIR, "executor"); const TARGET_DIR = `/app/codes`; -const IMAGE_NAME = 'executor:1.0'; +const IMAGE_NAME = "executor:1.0"; //const VOL_NAME = `my_vol`; const VOL_NAME = SOURCE_DIR; @@ -14,7 +14,7 @@ class CodeService { async execute(code, input, lang, id) { //console.log('code', code); try { - !input ? (input = '') : null; + !input ? (input = "") : null; // validating code // await this.validateCode(code, input, lang, id); @@ -26,7 +26,7 @@ class CodeService { ); if (!isValid) { throw { - message + message, }; } @@ -54,7 +54,7 @@ class CodeService { ); if (OUTPUT) { - console.log('output', OUTPUT.toString()); + console.log("output", OUTPUT.toString()); return OUTPUT.toString(); } } catch (error) { @@ -65,28 +65,28 @@ class CodeService { async writeFile(code, lang, input, id) { let fileName = `${id}code`; switch (lang) { - case 'javascript': { - fileName += '.js'; + case "javascript": { + fileName += ".js"; break; } - case 'cpp': { - fileName += '.cpp'; + case "cpp": { + fileName += ".cpp"; break; } - case 'python': { - fileName += '.py'; + case "python": { + fileName += ".py"; break; } - case 'java': { - fileName += '.java'; + case "java": { + fileName += ".java"; break; } - case 'c': { - fileName += '.c'; + case "c": { + fileName += ".c"; break; } default: { - throw { message: 'Invalid language' }; + throw { message: "Invalid language" }; } } const write = util.promisify(fs.writeFile); @@ -96,7 +96,7 @@ class CodeService { await write(path.join(SOURCE_DIR, `${id}input.txt`), input); return { file: fileName, - inputFile: `${id}input.txt` + inputFile: `${id}input.txt`, }; } catch (error) { throw { message: error }; @@ -104,33 +104,33 @@ class CodeService { } async writeCommand(lang, file, input, id, code) { - let command = ''; + let command = ""; switch (lang) { - case 'javascript': { - command = `cd ${TARGET_DIR} && node ${file} < ${input}`; + case "javascript": { + command = `cd "${TARGET_DIR}" && node ${file} < ${input}`; break; } - case 'cpp': { - command = `cd ${TARGET_DIR} && g++ -o ${id} ${file} && ./${id} < ${input}`; + case "cpp": { + command = `cd "${TARGET_DIR}" && g++ -o ${id} ${file} && ./${id} < ${input}`; break; } - case 'python': { - command = `cd ${TARGET_DIR} && python ${file} < ${input}`; + case "python": { + command = `cd "${TARGET_DIR}" && python ${file} < ${input}`; break; } - case 'java': { + case "java": { let className = await this.extractJavaClassName(code); - className = className.split(/\s/).join(''); - console.log('class ', className); - command = `cd ${TARGET_DIR} && javac ${file} && java ${className} < ${input}`; + className = className.split(/\s/).join(""); + console.log("class ", className); + command = `cd "${TARGET_DIR}" && javac ${file} && java ${className} < ${input}`; break; } - case 'c': { - command = `cd ${TARGET_DIR} && gcc -o ${id} ${file} && ./${id} < ${input}`; + case "c": { + command = `cd "${TARGET_DIR}" && gcc -o ${id} ${file} && ./${id} < ${input}`; break; } default: { - throw { message: 'Invalid language' }; + throw { message: "Invalid language" }; } } @@ -138,7 +138,7 @@ class CodeService { const runCode = `docker exec ${containerName} sh -c "${command}"`; - const runContainer = `docker run -it -d --name ${containerName} -v ${VOL_NAME}:${TARGET_DIR} ${IMAGE_NAME}`; + const runContainer = `docker run -it -d --name ${containerName} -v "${VOL_NAME}":${TARGET_DIR} ${IMAGE_NAME}`; return { runCode, runContainer }; } @@ -146,10 +146,10 @@ class CodeService { async execChild(runCode, runContainer, id, file, inputFile, lang, code) { return new Promise((resolve, reject) => { const execCont = exec(`${runContainer}`); - execCont.on('error', err => { - throw { status: '404', message: err }; + execCont.on("error", (err) => { + throw { status: "404", message: err }; }); - execCont.stdout.on('data', () => { + execCont.stdout.on("data", () => { exec(`${runCode}`, async (error, stdout, stderr) => { await this.endContainer(id); await this.deleteFiles(file, inputFile, lang, id, code); @@ -164,26 +164,26 @@ class CodeService { } async deleteFiles(fileName, inputName, lang, id, code) { - fs.unlinkSync(path.join(SOURCE_DIR, fileName), err => { + fs.unlinkSync(path.join(SOURCE_DIR, fileName), (err) => { if (err) throw { message: err }; }); if (inputName) { - fs.unlinkSync(path.join(SOURCE_DIR, inputName), err => { + fs.unlinkSync(path.join(SOURCE_DIR, inputName), (err) => { if (err) throw { message: err }; }); } - if (lang == 'cpp' || lang == 'c') { + if (lang == "cpp" || lang == "c") { if (fs.existsSync(path.join(SOURCE_DIR, id))) - fs.unlinkSync(path.join(SOURCE_DIR, id), err => { + fs.unlinkSync(path.join(SOURCE_DIR, id), (err) => { if (err) throw err; }); } - if (lang == 'java') { + if (lang == "java") { let className = await this.extractJavaClassName(code); - className = className.split(/\s/).join(''); - console.log('delete', className); + className = className.split(/\s/).join(""); + console.log("delete", className); if (fs.existsSync(path.join(SOURCE_DIR, `${className}.class`))) - fs.unlinkSync(path.join(SOURCE_DIR, `${className}.class`), err => { + fs.unlinkSync(path.join(SOURCE_DIR, `${className}.class`), (err) => { if (err) throw err; }); } @@ -195,25 +195,25 @@ class CodeService { exec(`${exit}`, (error, stdout, stderr) => { if (error) { console.log(error); - } else console.log('Container stoped and deleted'); + } else console.log("Container stoped and deleted"); }); } async extractJavaClassName(s) { - let prefix = 'class'; - let suffix = '{'; + let prefix = "class"; + let suffix = "{"; let i = s.indexOf(prefix); if (i >= 0) { s = s.substring(i + prefix.length); } else { - return ''; + return ""; } if (suffix) { i = s.indexOf(suffix); if (i >= 0) { s = s.substring(0, i); } else { - return ''; + return ""; } } return s; From bbb399a9f56eb03212692defd9d39d8407873ca9 Mon Sep 17 00:00:00 2001 From: tomarviii88 Date: Sat, 9 Jan 2021 17:09:56 +0530 Subject: [PATCH 2/2] UI changes --- client/.eslintcache | 2 +- client/public/index.html | 7 ++ .../src/components/code-editor/CodeEditor.js | 76 +++++++++++++++---- client/src/components/code-editor/Submit.js | 17 +++++ client/src/components/code-editor/style.css | 25 ++++++ client/src/components/output/InputOutput.js | 22 ++++-- client/src/components/output/style.css | 12 +++ client/src/constants/global.js | 1 + client/src/constants/theme.js | 2 +- 9 files changed, 140 insertions(+), 24 deletions(-) create mode 100644 client/src/components/code-editor/Submit.js create mode 100644 client/src/components/code-editor/style.css create mode 100644 client/src/components/output/style.css diff --git a/client/.eslintcache b/client/.eslintcache index 1f81c00..df47075 100644 --- a/client/.eslintcache +++ b/client/.eslintcache @@ -1 +1 @@ -[{"/media/shweta/New Volume/projects/RCE-aasf/remote-code-executor/client/src/components/header/Header.js":"1","/media/shweta/New Volume/projects/RCE-aasf/remote-code-executor/client/src/constants/theme.js":"2"},{"size":388,"mtime":1609927468679,"results":"3","hashOfConfig":"4"},{"size":285,"mtime":1609927468686,"results":"5","hashOfConfig":"4"},{"filePath":"6","messages":"7","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"kizngo",{"filePath":"8","messages":"9","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"/media/shweta/New Volume/projects/RCE-aasf/remote-code-executor/client/src/components/header/Header.js",[],"/media/shweta/New Volume/projects/RCE-aasf/remote-code-executor/client/src/constants/theme.js",[]] \ No newline at end of file +[{"/home/tomarviii88/Desktop/remote-code-executor/client/src/components/header/Header.js":"1","/home/tomarviii88/Desktop/remote-code-executor/client/src/components/code-editor/CodeEditor.js":"2","/home/tomarviii88/Desktop/remote-code-executor/client/src/components/output/InputOutput.js":"3","/home/tomarviii88/Desktop/remote-code-executor/client/src/constants/global.js":"4","/home/tomarviii88/Desktop/remote-code-executor/client/src/components/code-editor/Submit.js":"5","/home/tomarviii88/Desktop/remote-code-executor/client/src/constants/theme.js":"6"},{"size":388,"mtime":1609839782860,"results":"7","hashOfConfig":"8"},{"size":2623,"mtime":1610192088920,"results":"9","hashOfConfig":"8"},{"size":1390,"mtime":1610190812112,"results":"10","hashOfConfig":"8"},{"size":514,"mtime":1610187681416,"results":"11","hashOfConfig":"8"},{"size":462,"mtime":1610189429376,"results":"12","hashOfConfig":"8"},{"size":285,"mtime":1610192356464,"results":"13","hashOfConfig":"8"},{"filePath":"14","messages":"15","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"1ld0h7m",{"filePath":"16","messages":"17","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"18","messages":"19","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"20","messages":"21","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"22","messages":"23","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"24","messages":"25","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"/home/tomarviii88/Desktop/remote-code-executor/client/src/components/header/Header.js",[],"/home/tomarviii88/Desktop/remote-code-executor/client/src/components/code-editor/CodeEditor.js",[],"/home/tomarviii88/Desktop/remote-code-executor/client/src/components/output/InputOutput.js",["26"],"/home/tomarviii88/Desktop/remote-code-executor/client/src/constants/global.js",[],"/home/tomarviii88/Desktop/remote-code-executor/client/src/components/code-editor/Submit.js",[],"/home/tomarviii88/Desktop/remote-code-executor/client/src/constants/theme.js",[],{"ruleId":"27","severity":1,"message":"28","line":32,"column":7,"nodeType":"29","messageId":"30","endLine":32,"endColumn":12},"no-unused-vars","'error' is assigned a value but never used.","Identifier","unusedVar"] \ No newline at end of file diff --git a/client/public/index.html b/client/public/index.html index aa069f2..0d6968c 100644 --- a/client/public/index.html +++ b/client/public/index.html @@ -26,6 +26,13 @@ --> React App +
diff --git a/client/src/components/code-editor/CodeEditor.js b/client/src/components/code-editor/CodeEditor.js index 20ee736..524eb2d 100644 --- a/client/src/components/code-editor/CodeEditor.js +++ b/client/src/components/code-editor/CodeEditor.js @@ -3,6 +3,44 @@ import Editor from '@monaco-editor/react'; import { executeCode, setLoadingTrue } from '../../actions/code'; import { useDispatch, useSelector } from 'react-redux'; import InputOutput from '../output/InputOutput'; +import Submit from './Submit'; +import styled from 'styled-components'; +import './style.css'; + +const Row = styled.div` + display: flex; + flex-direction: row; +`; + +const Column = styled.div` + display: flex; + flex-direction: column; + box-sizing: border-box; + flex: 1; +`; + +const SubmitButton = styled.button` + background-color: #3b8d47; + color: white; + margin-left: 10px; + padding: 10px; + box-sizing: border-box; + border: none; + outline: none; + font-size: 16px; + width: 100px; +`; + +const OutputWindow = styled.div` + flex: 1; + background-color: #eeeeee; + margin: 20px; + border-radius: 5px; + padding: 10px; + box-sizing: border-box; + overflow: auto; + color: ${props => (props.error ? 'red' : 'black')}; +`; const CodeEditor = ({ theme }) => { const loading = useSelector(state => state.code.isFetching); @@ -11,6 +49,8 @@ const CodeEditor = ({ theme }) => { const [input, setInput] = useState(''); const dispatch = useDispatch(); const valueGetter = useRef(); + let output = useSelector(state => state.code.output); + let error = useSelector(state => state.code.error); const handleEditorDidMount = _valueGetter => { setIsEditorReady(true); @@ -30,22 +70,26 @@ const CodeEditor = ({ theme }) => { return ( <> - - - + + + + + + + {loading ? 'Loading..' : 'Submit'} + + + +
{output === '' ? error : output}
+
+
+
); diff --git a/client/src/components/code-editor/Submit.js b/client/src/components/code-editor/Submit.js new file mode 100644 index 0000000..9ffa5be --- /dev/null +++ b/client/src/components/code-editor/Submit.js @@ -0,0 +1,17 @@ +import React from 'react'; + +const Submit = ({ language, changeLanguage }) => { + return ( +
+ +
+ ); +}; + +export default Submit; diff --git a/client/src/components/code-editor/style.css b/client/src/components/code-editor/style.css new file mode 100644 index 0000000..0c622b9 --- /dev/null +++ b/client/src/components/code-editor/style.css @@ -0,0 +1,25 @@ +.sel-lang > select { + display: block; + font-size: 16px; + font-family: sans-serif; + font-weight: 700; + color: #444; + line-height: 1.3; + padding: 10px; + width: 100%; + box-sizing: border-box; + margin: 0; + outline: none; + border: none; + background-color: white; +} + +.sel-lang > select > option { + font-size: 16px; + font-family: sans-serif; + font-weight: 700; + color: #444; + line-height: 1.3; + padding: 10px; + display: block; +} diff --git a/client/src/components/output/InputOutput.js b/client/src/components/output/InputOutput.js index 2e9a775..bf8aa27 100644 --- a/client/src/components/output/InputOutput.js +++ b/client/src/components/output/InputOutput.js @@ -1,25 +1,33 @@ import React, { useEffect } from 'react'; import styled from 'styled-components'; import { useSelector } from 'react-redux'; +import './style.css'; const Container = styled.div` display: flex; flex-direction: row; justify-content: space-between; margin-top: 10px; + flex: 1; `; const Div = styled.div` - height: 100px; + height: 100%; flex: 1; box-sizing: border-box; margin: 20; color: ${props => props.error && 'red'}; background-color: '#eeeeee'; overflow: scroll; + outline: none; +`; + +const TextInput = styled.textarea` + color: ${props => (props.theme === 'dark' ? 'white' : 'black')}; + background-color: ${props => (props.theme === 'dark' ? '#1e1e1e' : 'white')}; `; -const InputOutput = ({ input, setInput }) => { +const InputOutput = ({ input, setInput, theme }) => { let output = useSelector(state => state.code.output); let error = useSelector(state => state.code.error); @@ -28,18 +36,20 @@ const InputOutput = ({ input, setInput }) => { }, [output]); return ( -
-