├── .gitignore ├── LICENSE ├── README.md ├── backend ├── __init__.py ├── core │ ├── __init__.py │ ├── apis │ │ ├── __init__.py │ │ └── runner.py │ ├── controllers │ │ └── __init__.py │ ├── models │ │ └── __init__.py │ ├── services │ │ ├── __init__.py │ │ └── runner.py │ ├── settings.py │ ├── utils │ │ ├── __init__.py │ │ └── uuid.py │ └── views │ │ └── __init__.py ├── run.py └── sh │ ├── run.sh │ ├── run_code.sh │ └── run_code_ex.sh ├── docs ├── .gitkeep └── reference.md ├── frontend ├── .babelrc ├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .postcssrc.js ├── README.md ├── config │ ├── dev.env.js │ ├── index.js │ ├── prod.env.js │ └── test.env.js ├── index.html ├── node_modules │ └── .gitkeep ├── package.json ├── src │ ├── App.vue │ ├── assets │ │ └── logo.png │ ├── components │ │ └── Hello.vue │ ├── main.js │ └── router │ │ └── index.js ├── static │ └── .gitkeep └── test │ ├── e2e │ ├── custom-assertions │ │ └── elementCount.js │ ├── nightwatch.conf.js │ ├── runner.js │ └── specs │ │ └── test.js │ └── unit │ ├── .eslintrc │ ├── index.js │ ├── karma.conf.js │ └── specs │ └── Hello.spec.js ├── log └── .gitkeep ├── requirements.txt └── run.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Node template 3 | # Logs 4 | logs 5 | *.log 6 | npm-debug.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # node-waf configuration 27 | .lock-wscript 28 | 29 | # Compiled binary addons (http://nodejs.org/api/addons.html) 30 | build/Release 31 | 32 | # Dependency directories 33 | node_modules 34 | jspm_packages 35 | 36 | # Optional npm cache directory 37 | .npm 38 | 39 | # Optional eslint cache 40 | .eslintcache 41 | 42 | # Optional REPL history 43 | .node_repl_history 44 | 45 | # Output of 'npm pack' 46 | *.tgz 47 | 48 | # Yarn Integrity file 49 | .yarn-integrity 50 | 51 | ### VisualStudioCode template 52 | .vscode/* 53 | !.vscode/settings.json 54 | !.vscode/tasks.json 55 | !.vscode/launch.json 56 | !.vscode/extensions.json 57 | ### Python template 58 | # Byte-compiled / optimized / DLL files 59 | __pycache__/ 60 | *.py[cod] 61 | *$py.class 62 | 63 | # C extensions 64 | *.so 65 | 66 | # Distribution / packaging 67 | .Python 68 | env/ 69 | build/ 70 | develop-eggs/ 71 | dist/ 72 | downloads/ 73 | eggs/ 74 | .eggs/ 75 | lib/ 76 | lib64/ 77 | parts/ 78 | sdist/ 79 | var/ 80 | *.egg-info/ 81 | .installed.cfg 82 | *.egg 83 | 84 | # PyInstaller 85 | # Usually these files are written by a python script from a template 86 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 87 | *.manifest 88 | *.spec 89 | 90 | # Installer logs 91 | pip-log.txt 92 | pip-delete-this-directory.txt 93 | 94 | # Unit test / coverage reports 95 | htmlcov/ 96 | .tox/ 97 | .coverage 98 | .coverage.* 99 | .cache 100 | nosetests.xml 101 | coverage.xml 102 | *,cover 103 | .hypothesis/ 104 | 105 | # Translations 106 | *.mo 107 | *.pot 108 | 109 | # Django stuff: 110 | local_settings.py 111 | 112 | # Flask stuff: 113 | instance/ 114 | .webassets-cache 115 | 116 | # Scrapy stuff: 117 | .scrapy 118 | 119 | # Sphinx documentation 120 | docs/_build/ 121 | 122 | # PyBuilder 123 | target/ 124 | 125 | # Jupyter Notebook 126 | .ipynb_checkpoints 127 | 128 | # pyenv 129 | .python-version 130 | 131 | # celery beat schedule file 132 | celerybeat-schedule 133 | 134 | # dotenv 135 | .env 136 | 137 | # virtualenv 138 | .venv/ 139 | venv/ 140 | ENV/ 141 | 142 | # Spyder project settings 143 | .spyderproject 144 | 145 | # Rope project settings 146 | .ropeproject 147 | ### Linux template 148 | *~ 149 | 150 | # temporary files which can be created if a process still has a handle open of a deleted file 151 | .fuse_hidden* 152 | 153 | # KDE directory preferences 154 | .directory 155 | 156 | # Linux trash folder which might appear on any partition or disk 157 | .Trash-* 158 | 159 | # .nfs files are created when an open file is removed but is still being accessed 160 | .nfs* 161 | ### Example user template template 162 | ### Example user template 163 | 164 | # IntelliJ project files 165 | out 166 | gen### macOS template 167 | *.DS_Store 168 | .AppleDouble 169 | .LSOverride 170 | 171 | # Icon must end with two \r 172 | Icon 173 | 174 | 175 | # Thumbnails 176 | ._* 177 | 178 | # Files that might appear in the root of a volume 179 | .DocumentRevisions-V100 180 | .fseventsd 181 | .Spotlight-V100 182 | .TemporaryItems 183 | .Trashes 184 | .VolumeIcon.icns 185 | .com.apple.timemachine.donotpresent 186 | 187 | # Directories potentially created on remote AFP share 188 | .AppleDB 189 | .AppleDesktop 190 | Network Trash Folder 191 | Temporary Items 192 | .apdisk 193 | ### Windows template 194 | # Windows image file caches 195 | Thumbs.db 196 | ehthumbs.db 197 | 198 | # Folder config file 199 | Desktop.ini 200 | 201 | # Recycle Bin used on file shares 202 | $RECYCLE.BIN/ 203 | 204 | # Windows Installer files 205 | *.cab 206 | *.msi 207 | *.msm 208 | *.msp 209 | 210 | # Windows shortcuts 211 | *.lnk 212 | ### JetBrains template 213 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 214 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 215 | 216 | # User-specific stuff: 217 | .idea/tasks.xml 218 | 219 | # Sensitive or high-churn files: 220 | .idea/dataSources/ 221 | .idea/dataSources.ids 222 | .idea/dataSources.xml 223 | .idea/dataSources.local.xml 224 | .idea/sqlDataSources.xml 225 | .idea/dynamic.xml 226 | .idea/uiDesigner.xml 227 | 228 | # Gradle: 229 | .idea/gradle.xml 230 | .idea/libraries 231 | 232 | # Mongo Explorer plugin: 233 | .idea/mongoSettings.xml 234 | 235 | ## File-based project format: 236 | *.iws 237 | 238 | ## Plugin-specific files: 239 | 240 | # IntelliJ 241 | /out/ 242 | 243 | # mpeltonen/sbt-idea plugin 244 | .idea_modules/ 245 | 246 | # JIRA plugin 247 | atlassian-ide-plugin.xml 248 | 249 | # Crashlytics plugin (for Android Studio and IntelliJ) 250 | com_crashlytics_export_strings.xml 251 | crashlytics.properties 252 | crashlytics-build.properties 253 | fabric.properties 254 | 255 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 hh 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # code-runner 2 | 基于 Flask, Docker 实现的在线编程网站. 3 | 4 | 5 | 6 | ## 项目依赖: 7 | 8 | - 前端: 9 | - vue.js 10 | - [CodeMirror](http://codemirror.net/demo/theme.html) 11 | - [vue-codemirror](https://github.com/surmon-china/vue-codemirror) 12 | - [vue-codemirror: 文档](https://surmon-china.github.io/vue-codemirror/) 13 | - 后端: 14 | - [docker-py](https://github.com/docker/docker-py) 15 | - [文档](https://docker-py.readthedocs.io/en/stable/) 16 | - [Pika](https://github.com/pika/pika) 17 | - [celery](https://github.com/celery/celery) 18 | - flask 19 | - docker 20 | 21 | ## 开发环境搭建: 22 | 23 | 24 | 25 | ### 1. 前端环境初始化: 26 | 27 | ```bash 28 | 29 | # vue-cli · Generated "frontend". 30 | # To get started: 31 | 32 | cd frontend 33 | npm install 34 | npm run dev 35 | 36 | 37 | ``` 38 | 39 | ### 2. 拉取 docker 容器: 40 | 41 | - [daocloud - gcc:4.9.2 镜像](https://hub.daocloud.io/repos/9bd717cf-7e5b-4943-843a-1c9104cb596f) 42 | - [配置 Docker 加速器](https://www.daocloud.io/mirror#accelerator-doc) 43 | 44 | 45 | ```bash 46 | 47 | docker pull daocloud.io/library/gcc:4.9.2 48 | 49 | 50 | ``` 51 | 52 | ### 3. 运行项目后台服务: 53 | 54 | ```bash 55 | # server: 56 | 57 | python 58 | 59 | ``` 60 | 61 | 62 | 63 | ## 参考: 64 | 65 | - [Docker SDK for Python](https://docker-py.readthedocs.io/en/stable/) 66 | - [about docker run ](https://github.com/docker/docker-py/issues/933) 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /backend/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /backend/core/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhstore/code-runner/064474908ac0abefebbc7d9759bc8ae2e30721f2/backend/core/__init__.py -------------------------------------------------------------------------------- /backend/core/apis/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /backend/core/apis/runner.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from flask import request 5 | from flask_restful import Resource, reqparse, abort 6 | 7 | from backend.core.services.runner import CodeRunner 8 | from backend.core.settings import ContainerConfig 9 | 10 | parser = reqparse.RequestParser() 11 | 12 | # 参数校验: 13 | parser.add_argument("lang", type=str) 14 | parser.add_argument("code", type=str) 15 | 16 | 17 | class Runner(Resource): 18 | def post(self): 19 | #data = request.get_json() 20 | data = parser.parse_args() 21 | lang = data.get("lang").lower() # 语言类型不区分大小写 22 | code = data.get("code") 23 | 24 | # 编程语言类型不支持: 25 | if lang not in ContainerConfig.language_support: 26 | abort(400) # 参数不合法, 直接返回 [400 Bad Request] 27 | 28 | r = CodeRunner(code, lang) 29 | return r.run() 30 | 31 | -------------------------------------------------------------------------------- /backend/core/controllers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhstore/code-runner/064474908ac0abefebbc7d9759bc8ae2e30721f2/backend/core/controllers/__init__.py -------------------------------------------------------------------------------- /backend/core/models/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhstore/code-runner/064474908ac0abefebbc7d9759bc8ae2e30721f2/backend/core/models/__init__.py -------------------------------------------------------------------------------- /backend/core/services/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhstore/code-runner/064474908ac0abefebbc7d9759bc8ae2e30721f2/backend/core/services/__init__.py -------------------------------------------------------------------------------- /backend/core/services/runner.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | import os 4 | import docker 5 | from requests.exceptions import ReadTimeout 6 | 7 | from backend.core.settings import ContainerConfig 8 | from backend.core.utils.uuid import create_uuid 9 | 10 | # 保存待执行的源码文件: 11 | class CodeWriter(ContainerConfig): 12 | def __init__(self, content, file_type, java_class_name=None): 13 | self.file_name = create_uuid() # 随机生成 14 | self.file_type = file_type 15 | self.java_class_name = java_class_name 16 | 17 | # 保存代码文件 18 | self.save_code(content) 19 | # 保存命令 20 | self.cmd = self.save_cmd() 21 | 22 | @property 23 | def file_path(self): 24 | """文件名称+后缀拼接 25 | 26 | :return: 27 | """ 28 | lang = self.language_support.get(self.file_type) 29 | 30 | if self.java_class_name: 31 | fp = "{}_{}.{}".format(self.file_name, self.java_class_name, lang) 32 | else: 33 | fp = "{}.{}".format(self.file_name, lang) 34 | 35 | return fp 36 | 37 | def save_code(self, content): 38 | """保存代码文件 39 | :param content: 代码内容 40 | :return: 41 | """ 42 | # 文件保存的绝对路径: 43 | file_path = os.path.join(self.volume_path, self.file_path) 44 | 45 | with open(file_path, mode="w", encoding="utf8") as f: 46 | f.write(content[:1024*64]) # 文件大小限定64k 47 | 48 | def save_cmd(self): 49 | """保存代码执行的 shell 命令 50 | :return: 51 | """ 52 | # 容器中执行文件的绝对路径: 53 | file_path = os.path.join(self.volume_bind_path, self.file_path) 54 | 55 | cmd = "/bin/bash {0}/{1} {2} {3}/{4} {5} {5}".format( 56 | self.volume_bind_path, 57 | self.shell_01, 58 | self.timeout, 59 | self.volume_bind_path, 60 | self.shell_02, 61 | file_path 62 | ) 63 | return cmd 64 | 65 | 66 | # 启动容器: 67 | class ContainerWorker(ContainerConfig): 68 | """ 69 | 源码中关于 volume 的配置参数设置: 70 | 71 | container_id = cli.create_container( 72 | 'busybox', 'ls', volumes=['/mnt/vol1', '/mnt/vol2'], 73 | host_config=cli.create_host_config(binds={ 74 | '/home/user1/': { 75 | 'bind': '/mnt/vol2', 76 | 'mode': 'rw', 77 | }, 78 | '/var/www': { 79 | 'bind': '/mnt/vol1', 80 | 'mode': 'ro', 81 | } 82 | }) 83 | ) 84 | 85 | 86 | """ 87 | def __init__(self, cmd): 88 | self.client = docker.APIClient() 89 | # 容器待执行指令: 90 | self.cmd = cmd 91 | 92 | def create(self): 93 | #self.cmd = "ls /code-runner" 94 | 95 | # 容器共享 volume 配置参数设置: 96 | container = self.client.create_container( 97 | image=self.image_name, 98 | command=self.cmd, 99 | volumes=[self.volume_path], # 只定义了共享目录, 下一个配置中设置目录映射 100 | host_config=self.client.create_host_config(binds={ 101 | self.volume_path: { 102 | 'bind': self.volume_bind_path, # 映射到容器中的路径 103 | 'mode': self.volume_mode, 104 | }, 105 | }) 106 | ) 107 | return container 108 | 109 | def run(self): 110 | ctr = self.create() 111 | 112 | self.client.start(container=ctr.get("Id")) # 启动容器 113 | try: 114 | self.client.wait(container=ctr, timeout=self.timeout) # 等待执行, 超时判断 115 | except ReadTimeout as e: 116 | print("too slow, killed!") 117 | self.client.kill(container=ctr) # 超时, kill 掉 118 | 119 | ctr_logs = self.client.logs(container=ctr.get("Id")) 120 | 121 | self.client.stop(ctr) # 退出容器 122 | self.client.remove_container(ctr, v=True, force=True) # 清理容器 123 | return ctr_logs[:1024*64] # 截取日志长度,保留64k 124 | 125 | # 代码执行服务: 126 | class CodeRunner(object): 127 | def __init__(self, content, file_type, java_class_name=None): 128 | self.cw = CodeWriter(content, file_type, java_class_name) 129 | self.cmd = self.cw.cmd 130 | self.runner = ContainerWorker(self.cmd) 131 | 132 | def run(self): 133 | log = self.runner.run() 134 | return self.parse(log) 135 | 136 | def parse(self, logs): 137 | sep = "=1=2=3=4=5=== I Am A Dividing Line ! ===5=4=3=2=1=" 138 | flag1 = "RESULT: " 139 | flag2 = "STATUS_CODE: " 140 | flag3 = "TIME_COST: " 141 | 142 | if isinstance(logs, bytes): 143 | logs = logs.decode() 144 | 145 | values = logs.split(sep) 146 | #print(values) 147 | _, v_result, v_status, v_time = values 148 | 149 | result = { 150 | "result": v_result.strip().lstrip(flag1).strip(), 151 | "status": v_status.strip().lstrip(flag2).strip(), 152 | "time": v_time.strip().lstrip(flag3).strip() 153 | } 154 | print(result) 155 | return result 156 | 157 | 158 | if __name__ == '__main__': 159 | image_name = "daocloud.io/library/gcc:4.9.2" 160 | code = """ 161 | 162 | import datetime 163 | import os 164 | print("hello world!") 165 | #print(os.getcwd()) 166 | print(datetime.datetime.now()) 167 | 168 | 169 | """ 170 | 171 | code_timeout = """ 172 | 173 | import time 174 | time.sleep(4) 175 | print("can you see me?") 176 | 177 | """ 178 | 179 | a = CodeWriter(code, "python") 180 | 181 | 182 | runner = CodeRunner(code, "python") 183 | runner.run() 184 | 185 | # 超时判断: 186 | runner2 = CodeRunner(code_timeout, "python") 187 | runner2.run() 188 | -------------------------------------------------------------------------------- /backend/core/settings.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | 5 | # docker 容器 默认配置项: 6 | class ContainerConfig(object): 7 | # 容器镜像名: 8 | image_name = "daocloud.io/library/gcc:4.9.2" 9 | 10 | # 宿主机共享目录: 11 | volume_path = "/iDockerShare/codebox" #"/code-runner" 12 | # 映射到容器中的路径: 13 | volume_bind_path = "/code-runner" # /code-runner 14 | volume_mode = "rw" 15 | 16 | shell_01 = "run.sh" 17 | shell_02 = "run_code.sh" 18 | 19 | # 支持的编程语言: 20 | language_support = { 21 | "python": "py", 22 | "ruby": "rb", 23 | "c": "c", 24 | "c++": "cpp", 25 | "java": "java", 26 | "go": "go", 27 | "perl": "pl", 28 | } 29 | 30 | # 程序执行超时时间: 31 | timeout = 3 32 | -------------------------------------------------------------------------------- /backend/core/utils/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /backend/core/utils/uuid.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import time 5 | import random 6 | 7 | 8 | # 生成随机ID 9 | def create_uuid(): 10 | ts = int(time.time() * 1000) - 1400000000000 11 | value = (ts << 16) + random.randint(0, 65535) 12 | return hex(value)[2:-1] 13 | -------------------------------------------------------------------------------- /backend/core/views/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhstore/code-runner/064474908ac0abefebbc7d9759bc8ae2e30721f2/backend/core/views/__init__.py -------------------------------------------------------------------------------- /backend/run.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | 5 | import time 6 | from flask import Flask, request, jsonify 7 | from flask_restful import Api 8 | 9 | from backend.core.apis.runner import Runner 10 | 11 | app = Flask(__name__) 12 | api = Api(app) 13 | 14 | # restful API: 15 | 16 | api.add_resource(Runner, '/run') 17 | 18 | 19 | @app.route("/") 20 | def index(): 21 | current_time = time.strftime("Current time:\n%Z # %Y-%m-%d # %p %I:%M:%S", 22 | time.localtime(time.time())) 23 | 24 | return "

Hello, visitor.\r\n %s

" % current_time 25 | 26 | 27 | if __name__ == '__main__': 28 | app.run(host='0.0.0.0', port=5000, debug=True) 29 | -------------------------------------------------------------------------------- /backend/sh/run.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | kill_time=$1 3 | sh_file=$2 4 | code_file=$3 5 | 6 | ################################################### 7 | # msg: 8 | SEP="=1=2=3=4=5=== I Am A Dividing Line ! ===5=4=3=2=1=" 9 | ERROR_LOG="RESULT: timeout! killed! ${SEP} STATUS_CODE: -1 ${SEP} TIME_COST: 0" 10 | 11 | ################################################### 12 | 13 | # run 14 | timeout -s 9 ${kill_time} ${sh_file} ${code_file} 15 | 16 | ################################################### 17 | 18 | # kill judge. 19 | if [ $? != 0 ] 20 | then 21 | echo "${ERROR_LOG}" 22 | fi 23 | 24 | 25 | 26 | # clean 27 | #rm -rf ${code_file} ${code_file}.* 28 | -------------------------------------------------------------------------------- /backend/sh/run_code.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | code_file=$1 3 | 4 | ###########error log info : ################ 5 | SEP="=1=2=3=4=5=== I Am A Dividing Line ! ===5=4=3=2=1=" 6 | 7 | ERROR_1="you must provide a file!" 8 | ERROR_2="file does not exist!" 9 | ERROR_3="invalid language!" 10 | 11 | ERROR_LOG_1="${SEP} RESULT: ${ERROR_1} ${SEP} STATUS_CODE: -2 ${SEP} TIME_COST: 0" 12 | ERROR_LOG_2="${SEP} RESULT: ${ERROR_2} ${SEP} STATUS_CODE: -3 ${SEP} TIME_COST: 0" 13 | ERROR_LOG_3="${ERROR_3} ${SEP} STATUS_CODE: -4 ${SEP} TIME_COST: 0" 14 | OK_LOG="${SEP} STATUS_CODE: 1 ${SEP} TIME_COST: 0" 15 | 16 | 17 | ########## error judge : #################### 18 | if [ -z $1 ];then 19 | echo ${ERROR_LOG_1} 20 | exit 1 21 | fi 22 | 23 | if [ ! -f $1 ];then 24 | echo ${ERROR_LOG_2} 25 | exit 1 26 | fi 27 | 28 | ########################################### 29 | 30 | # create code_folder 31 | 32 | file="${code_file##*/}" 33 | folder="${file%%.*}" 34 | extension="${file##*.}" 35 | 36 | 37 | mkdir ${folder} 38 | chmod 777 ${folder} 39 | mv ${code_file} ${folder} 40 | code_path="./${folder}/${folder}.${extension}" 41 | 42 | 43 | ########################################### 44 | # test log: 45 | 46 | #echo "Server Log:" 47 | #echo "mkdir Folder name: ${folder}" 48 | #rm -rf "/iDockerShare" 49 | #echo "Current Folder: $(pwd)" 50 | ##echo "Current Folder Content: $(ls -a)" 51 | #echo "Current Folder Content: $(ls)" 52 | #echo "Code Path: ${code_path}" 53 | 54 | ######### run code : ####################### 55 | 56 | echo "${SEP} RESULT: " 57 | 58 | TIME_START=`date +%s%N`; #time_countion 59 | 60 | case "$extension" in 61 | "c") 62 | gcc -o ${code_path}.out -g ${code_path} &&./${code_path}.out 63 | ;; 64 | "cpp") 65 | g++ -o ${code_path}.out -g ${code_path} &&./${code_path}.out 66 | ;; 67 | "java") 68 | java_class=${code_path##*_} 69 | java_path="${folder}/${java_class}" 70 | mv ${code_path} ${java_path} 71 | cd ${folder} 72 | javac ${java_class} && java ${java_class%.*} 73 | cd .. 74 | ;; 75 | "go") 76 | go run ${code_path} 77 | ;; 78 | "pl") 79 | perl ${code_path} 80 | ;; 81 | "py") 82 | python ${code_path} 83 | ;; 84 | "rb") 85 | ruby ${code_path} 86 | ;; 87 | *) 88 | echo ${ERROR_LOG_3} 89 | ;; 90 | esac 91 | 92 | ########################################### 93 | 94 | echo "${SEP} STATUS_CODE: $?" 95 | 96 | TIME_END=`date +%s%N`; 97 | time=$((TIME_END-TIME_START)) 98 | time=`expr ${time} / 1000000` 99 | 100 | echo "${SEP} TIME_COST: ${time}" 101 | 102 | ########################################### 103 | -------------------------------------------------------------------------------- /backend/sh/run_code_ex.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | prog=$1 3 | 4 | ###########error log info : ################ 5 | SEP="@@--@@--codebox--@@--@@" 6 | 7 | ERROR_1="you must provide a file!" 8 | ERROR_2="file does not exist!" 9 | ERROR_3="invalid language!" 10 | 11 | ERROR_LOG_1="INFO: ${ERROR_1} ${SEP} STATUS_CODE: 1 ${SEP} TIME_COST: 0" 12 | ERROR_LOG_2="INFO: ${ERROR_2} ${SEP} STATUS_CODE: 1 ${SEP} TIME_COST: 0" 13 | ERROR_LOG_3="INFO: ${ERROR_3} ${SEP} STATUS_CODE: 1 ${SEP} TIME_COST: 0" 14 | 15 | ##########error judge : #################### 16 | if [ -z $1 ];then 17 | echo ${ERROR_LOG_1} 18 | exit 1 19 | fi 20 | 21 | if [ ! -f $1 ];then 22 | echo ${ERROR_LOG_2} 23 | exit 1 24 | fi 25 | 26 | #########run code : ####################### 27 | 28 | echo "INFO: " 29 | TIME_START=`date +%s%N`; #time_countion 30 | 31 | extension="${prog##*.}" 32 | case "$extension" in # 多版本支持 33 | "c99") 34 | gcc -o $prog.out -g $prog &&./$prog.out 35 | ;; 36 | "c11") 37 | gcc -o $prog.out -g $prog &&./$prog.out # 待修改C11编译选项 38 | ;; 39 | "cpp99") 40 | g++ -o $prog.out -g $prog &&./$prog.out 41 | ;; 42 | "cpp11") 43 | g++ -o $prog.out -g $prog &&./$prog.out # 待修改C++11编译选项 44 | ;; 45 | "java") 46 | javac $prog && java ${prog%.*} # 待修改 47 | ;; 48 | "py2") 49 | python $prog # 待修改 50 | ;; 51 | "py3") 52 | python $prog # 待修改 53 | ;; 54 | "rb") 55 | ruby $prog 56 | ;; 57 | "go") 58 | go run $prog 59 | ;; 60 | "pl") 61 | perl $prog 62 | ;; 63 | *) 64 | echo ${ERROR_LOG_3} 65 | ;; 66 | esac 67 | 68 | ########################################### 69 | 70 | echo "${SEP} STATUS_CODE: $?" 71 | TIME_END=`date +%s%N`; 72 | time=$((TIME_END-TIME_START)) 73 | time=`expr $time / 1000000` 74 | 75 | echo "${SEP} TIME_COST: ${time}" 76 | 77 | ########################################### 78 | -------------------------------------------------------------------------------- /docs/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhstore/code-runner/064474908ac0abefebbc7d9759bc8ae2e30721f2/docs/.gitkeep -------------------------------------------------------------------------------- /docs/reference.md: -------------------------------------------------------------------------------- 1 | 2 | # 参考: 3 | 4 | 5 | ## Flask-RESTful API 6 | 7 | - [ Flask-RESTful API ](http://www.pythondoc.com/Flask-RESTful/quickstart.html) 8 | - [install](https://flask-restful.readthedocs.io/en/0.3.5/installation.html) 9 | - [POST 提交参数合法性校验](http://flask-restful.readthedocs.io/en/0.3.5/quickstart.html#argument-parsing) 10 | - [完整示例, 给出最佳实践](http://flask-restful.readthedocs.io/en/0.3.5/quickstart.html#full-example) 11 | 12 | ```bash 13 | 14 | pip install flask-restful 15 | 16 | 17 | ``` 18 | 19 | 20 | ## API 设计规范: 21 | 22 | - [跟着 Github 学习 Restful HTTP API 设计](http://cizixs.com/2016/12/12/restful-api-design-guide) 23 | 24 | 25 | -------------------------------------------------------------------------------- /frontend/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { "modules": false }], 4 | "stage-2" 5 | ], 6 | "plugins": ["transform-runtime"], 7 | "comments": false, 8 | "env": { 9 | "test": { 10 | "presets": ["env", "stage-2"], 11 | "plugins": [ "istanbul" ] 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /frontend/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /frontend/.eslintignore: -------------------------------------------------------------------------------- 1 | build/*.js 2 | config/*.js 3 | -------------------------------------------------------------------------------- /frontend/.eslintrc.js: -------------------------------------------------------------------------------- 1 | // http://eslint.org/docs/user-guide/configuring 2 | 3 | module.exports = { 4 | root: true, 5 | parser: 'babel-eslint', 6 | parserOptions: { 7 | sourceType: 'module' 8 | }, 9 | env: { 10 | browser: true, 11 | }, 12 | // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style 13 | extends: 'standard', 14 | // required to lint *.vue files 15 | plugins: [ 16 | 'html' 17 | ], 18 | // add your custom rules here 19 | 'rules': { 20 | // allow paren-less arrow functions 21 | 'arrow-parens': 0, 22 | // allow async-await 23 | 'generator-star-spacing': 0, 24 | // allow debugger during development 25 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /frontend/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | test/unit/coverage 8 | test/e2e/reports 9 | selenium-debug.log 10 | -------------------------------------------------------------------------------- /frontend/.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | // to edit target browsers: use "browserlist" field in package.json 6 | "autoprefixer": {} 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /frontend/README.md: -------------------------------------------------------------------------------- 1 | # frontend 2 | 3 | > A Vue.js project 4 | 5 | ## Build Setup 6 | 7 | ``` bash 8 | # install dependencies 9 | npm install 10 | 11 | # serve with hot reload at localhost:8080 12 | npm run dev 13 | 14 | # build for production with minification 15 | npm run build 16 | 17 | # build for production and view the bundle analyzer report 18 | npm run build --report 19 | 20 | # run unit tests 21 | npm run unit 22 | 23 | # run e2e tests 24 | npm run e2e 25 | 26 | # run all tests 27 | npm test 28 | ``` 29 | 30 | For detailed explanation on how things work, checkout the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader). 31 | -------------------------------------------------------------------------------- /frontend/config/dev.env.js: -------------------------------------------------------------------------------- 1 | var merge = require('webpack-merge') 2 | var prodEnv = require('./prod.env') 3 | 4 | module.exports = merge(prodEnv, { 5 | NODE_ENV: '"development"' 6 | }) 7 | -------------------------------------------------------------------------------- /frontend/config/index.js: -------------------------------------------------------------------------------- 1 | // see http://vuejs-templates.github.io/webpack for documentation. 2 | var path = require('path') 3 | 4 | module.exports = { 5 | build: { 6 | env: require('./prod.env'), 7 | index: path.resolve(__dirname, '../dist/index.html'), 8 | assetsRoot: path.resolve(__dirname, '../dist'), 9 | assetsSubDirectory: 'static', 10 | assetsPublicPath: '/', 11 | productionSourceMap: true, 12 | // Gzip off by default as many popular static hosts such as 13 | // Surge or Netlify already gzip all static assets for you. 14 | // Before setting to `true`, make sure to: 15 | // npm install --save-dev compression-webpack-plugin 16 | productionGzip: false, 17 | productionGzipExtensions: ['js', 'css'], 18 | // Run the build command with an extra argument to 19 | // View the bundle analyzer report after build finishes: 20 | // `npm run build --report` 21 | // Set to `true` or `false` to always turn it on or off 22 | bundleAnalyzerReport: process.env.npm_config_report 23 | }, 24 | dev: { 25 | env: require('./dev.env'), 26 | port: 8080, 27 | autoOpenBrowser: true, 28 | assetsSubDirectory: 'static', 29 | assetsPublicPath: '/', 30 | proxyTable: {}, 31 | // CSS Sourcemaps off by default because relative paths are "buggy" 32 | // with this option, according to the CSS-Loader README 33 | // (https://github.com/webpack/css-loader#sourcemaps) 34 | // In our experience, they generally work as expected, 35 | // just be aware of this issue when enabling this option. 36 | cssSourceMap: false 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /frontend/config/prod.env.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | NODE_ENV: '"production"' 3 | } 4 | -------------------------------------------------------------------------------- /frontend/config/test.env.js: -------------------------------------------------------------------------------- 1 | var merge = require('webpack-merge') 2 | var devEnv = require('./dev.env') 3 | 4 | module.exports = merge(devEnv, { 5 | NODE_ENV: '"testing"' 6 | }) 7 | -------------------------------------------------------------------------------- /frontend/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | frontend 6 | 7 | 8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /frontend/node_modules/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhstore/code-runner/064474908ac0abefebbc7d9759bc8ae2e30721f2/frontend/node_modules/.gitkeep -------------------------------------------------------------------------------- /frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend", 3 | "version": "1.0.0", 4 | "description": "A Vue.js project", 5 | "author": "hhstore ", 6 | "private": true, 7 | "scripts": { 8 | "dev": "node build/dev-server.js", 9 | "start": "node build/dev-server.js", 10 | "build": "node build/build.js", 11 | "unit": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run", 12 | "e2e": "node test/e2e/runner.js", 13 | "test": "npm run unit && npm run e2e", 14 | "lint": "eslint --ext .js,.vue src test/unit/specs test/e2e/specs" 15 | }, 16 | "dependencies": { 17 | "vue": "^2.3.3", 18 | "vue-router": "^2.3.1" 19 | }, 20 | "devDependencies": { 21 | "autoprefixer": "^6.7.2", 22 | "babel-core": "^6.22.1", 23 | "babel-eslint": "^7.1.1", 24 | "babel-loader": "^6.2.10", 25 | "babel-plugin-transform-runtime": "^6.22.0", 26 | "babel-preset-env": "^1.3.2", 27 | "babel-preset-stage-2": "^6.22.0", 28 | "babel-register": "^6.22.0", 29 | "chalk": "^1.1.3", 30 | "connect-history-api-fallback": "^1.3.0", 31 | "copy-webpack-plugin": "^4.0.1", 32 | "css-loader": "^0.28.0", 33 | "eslint": "^3.19.0", 34 | "eslint-friendly-formatter": "^2.0.7", 35 | "eslint-loader": "^1.7.1", 36 | "eslint-plugin-html": "^2.0.0", 37 | "eslint-config-standard": "^6.2.1", 38 | "eslint-plugin-promise": "^3.4.0", 39 | "eslint-plugin-standard": "^2.0.1", 40 | "eventsource-polyfill": "^0.9.6", 41 | "express": "^4.14.1", 42 | "extract-text-webpack-plugin": "^2.0.0", 43 | "file-loader": "^0.11.1", 44 | "friendly-errors-webpack-plugin": "^1.1.3", 45 | "html-webpack-plugin": "^2.28.0", 46 | "http-proxy-middleware": "^0.17.3", 47 | "webpack-bundle-analyzer": "^2.2.1", 48 | "cross-env": "^4.0.0", 49 | "karma": "^1.4.1", 50 | "karma-coverage": "^1.1.1", 51 | "karma-mocha": "^1.3.0", 52 | "karma-phantomjs-launcher": "^1.0.2", 53 | "karma-phantomjs-shim": "^1.4.0", 54 | "karma-sinon-chai": "^1.3.1", 55 | "karma-sourcemap-loader": "^0.3.7", 56 | "karma-spec-reporter": "0.0.30", 57 | "karma-webpack": "^2.0.2", 58 | "lolex": "^1.5.2", 59 | "mocha": "^3.2.0", 60 | "chai": "^3.5.0", 61 | "sinon": "^2.1.0", 62 | "sinon-chai": "^2.8.0", 63 | "inject-loader": "^3.0.0", 64 | "babel-plugin-istanbul": "^4.1.1", 65 | "phantomjs-prebuilt": "^2.1.14", 66 | "chromedriver": "^2.27.2", 67 | "cross-spawn": "^5.0.1", 68 | "nightwatch": "^0.9.12", 69 | "selenium-server": "^3.0.1", 70 | "semver": "^5.3.0", 71 | "shelljs": "^0.7.6", 72 | "opn": "^4.0.2", 73 | "optimize-css-assets-webpack-plugin": "^1.3.0", 74 | "ora": "^1.2.0", 75 | "rimraf": "^2.6.0", 76 | "url-loader": "^0.5.8", 77 | "vue-loader": "^12.1.0", 78 | "vue-style-loader": "^3.0.1", 79 | "vue-template-compiler": "^2.3.3", 80 | "webpack": "^2.6.1", 81 | "webpack-dev-middleware": "^1.10.0", 82 | "webpack-hot-middleware": "^2.18.0", 83 | "webpack-merge": "^4.1.0" 84 | }, 85 | "engines": { 86 | "node": ">= 4.0.0", 87 | "npm": ">= 3.0.0" 88 | }, 89 | "browserslist": [ 90 | "> 1%", 91 | "last 2 versions", 92 | "not ie <= 8" 93 | ] 94 | } 95 | -------------------------------------------------------------------------------- /frontend/src/App.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 13 | 14 | 24 | -------------------------------------------------------------------------------- /frontend/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhstore/code-runner/064474908ac0abefebbc7d9759bc8ae2e30721f2/frontend/src/assets/logo.png -------------------------------------------------------------------------------- /frontend/src/components/Hello.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 33 | 34 | 35 | 54 | -------------------------------------------------------------------------------- /frontend/src/main.js: -------------------------------------------------------------------------------- 1 | // The Vue build version to load with the `import` command 2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias. 3 | import Vue from 'vue' 4 | import App from './App' 5 | import router from './router' 6 | 7 | Vue.config.productionTip = false 8 | 9 | /* eslint-disable no-new */ 10 | new Vue({ 11 | el: '#app', 12 | router, 13 | template: '', 14 | components: { App } 15 | }) 16 | -------------------------------------------------------------------------------- /frontend/src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | import Hello from '@/components/Hello' 4 | 5 | Vue.use(Router) 6 | 7 | export default new Router({ 8 | routes: [ 9 | { 10 | path: '/', 11 | name: 'Hello', 12 | component: Hello 13 | } 14 | ] 15 | }) 16 | -------------------------------------------------------------------------------- /frontend/static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhstore/code-runner/064474908ac0abefebbc7d9759bc8ae2e30721f2/frontend/static/.gitkeep -------------------------------------------------------------------------------- /frontend/test/e2e/custom-assertions/elementCount.js: -------------------------------------------------------------------------------- 1 | // A custom Nightwatch assertion. 2 | // the name of the method is the filename. 3 | // can be used in tests like this: 4 | // 5 | // browser.assert.elementCount(selector, count) 6 | // 7 | // for how to write custom assertions see 8 | // http://nightwatchjs.org/guide#writing-custom-assertions 9 | exports.assertion = function (selector, count) { 10 | this.message = 'Testing if element <' + selector + '> has count: ' + count 11 | this.expected = count 12 | this.pass = function (val) { 13 | return val === this.expected 14 | } 15 | this.value = function (res) { 16 | return res.value 17 | } 18 | this.command = function (cb) { 19 | var self = this 20 | return this.api.execute(function (selector) { 21 | return document.querySelectorAll(selector).length 22 | }, [selector], function (res) { 23 | cb.call(self, res) 24 | }) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /frontend/test/e2e/nightwatch.conf.js: -------------------------------------------------------------------------------- 1 | require('babel-register') 2 | var config = require('../../config') 3 | 4 | // http://nightwatchjs.org/gettingstarted#settings-file 5 | module.exports = { 6 | src_folders: ['test/e2e/specs'], 7 | output_folder: 'test/e2e/reports', 8 | custom_assertions_path: ['test/e2e/custom-assertions'], 9 | 10 | selenium: { 11 | start_process: true, 12 | server_path: require('selenium-server').path, 13 | host: '127.0.0.1', 14 | port: 4444, 15 | cli_args: { 16 | 'webdriver.chrome.driver': require('chromedriver').path 17 | } 18 | }, 19 | 20 | test_settings: { 21 | default: { 22 | selenium_port: 4444, 23 | selenium_host: 'localhost', 24 | silent: true, 25 | globals: { 26 | devServerURL: 'http://localhost:' + (process.env.PORT || config.dev.port) 27 | } 28 | }, 29 | 30 | chrome: { 31 | desiredCapabilities: { 32 | browserName: 'chrome', 33 | javascriptEnabled: true, 34 | acceptSslCerts: true 35 | } 36 | }, 37 | 38 | firefox: { 39 | desiredCapabilities: { 40 | browserName: 'firefox', 41 | javascriptEnabled: true, 42 | acceptSslCerts: true 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /frontend/test/e2e/runner.js: -------------------------------------------------------------------------------- 1 | // 1. start the dev server using production config 2 | process.env.NODE_ENV = 'testing' 3 | var server = require('../../build/dev-server.js') 4 | 5 | server.ready.then(() => { 6 | // 2. run the nightwatch test suite against it 7 | // to run in additional browsers: 8 | // 1. add an entry in test/e2e/nightwatch.conf.json under "test_settings" 9 | // 2. add it to the --env flag below 10 | // or override the environment flag, for example: `npm run e2e -- --env chrome,firefox` 11 | // For more information on Nightwatch's config file, see 12 | // http://nightwatchjs.org/guide#settings-file 13 | var opts = process.argv.slice(2) 14 | if (opts.indexOf('--config') === -1) { 15 | opts = opts.concat(['--config', 'test/e2e/nightwatch.conf.js']) 16 | } 17 | if (opts.indexOf('--env') === -1) { 18 | opts = opts.concat(['--env', 'chrome']) 19 | } 20 | 21 | var spawn = require('cross-spawn') 22 | var runner = spawn('./node_modules/.bin/nightwatch', opts, { stdio: 'inherit' }) 23 | 24 | runner.on('exit', function (code) { 25 | server.close() 26 | process.exit(code) 27 | }) 28 | 29 | runner.on('error', function (err) { 30 | server.close() 31 | throw err 32 | }) 33 | }) 34 | -------------------------------------------------------------------------------- /frontend/test/e2e/specs/test.js: -------------------------------------------------------------------------------- 1 | // For authoring Nightwatch tests, see 2 | // http://nightwatchjs.org/guide#usage 3 | 4 | module.exports = { 5 | 'default e2e tests': function (browser) { 6 | // automatically uses dev Server port from /config.index.js 7 | // default: http://localhost:8080 8 | // see nightwatch.conf.js 9 | const devServer = browser.globals.devServerURL 10 | 11 | browser 12 | .url(devServer) 13 | .waitForElementVisible('#app', 5000) 14 | .assert.elementPresent('.hello') 15 | .assert.containsText('h1', 'Welcome to Your Vue.js App') 16 | .assert.elementCount('img', 1) 17 | .end() 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /frontend/test/unit/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "mocha": true 4 | }, 5 | "globals": { 6 | "expect": true, 7 | "sinon": true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /frontend/test/unit/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | 3 | Vue.config.productionTip = false 4 | 5 | // require all test files (files that ends with .spec.js) 6 | const testsContext = require.context('./specs', true, /\.spec$/) 7 | testsContext.keys().forEach(testsContext) 8 | 9 | // require all src files except main.js for coverage. 10 | // you can also change this to match only the subset of files that 11 | // you want coverage for. 12 | const srcContext = require.context('../../src', true, /^\.\/(?!main(\.js)?$)/) 13 | srcContext.keys().forEach(srcContext) 14 | -------------------------------------------------------------------------------- /frontend/test/unit/karma.conf.js: -------------------------------------------------------------------------------- 1 | // This is a karma config file. For more details see 2 | // http://karma-runner.github.io/0.13/config/configuration-file.html 3 | // we are also using it with karma-webpack 4 | // https://github.com/webpack/karma-webpack 5 | 6 | var webpackConfig = require('../../build/webpack.test.conf') 7 | 8 | module.exports = function (config) { 9 | config.set({ 10 | // to run in additional browsers: 11 | // 1. install corresponding karma launcher 12 | // http://karma-runner.github.io/0.13/config/browsers.html 13 | // 2. add it to the `browsers` array below. 14 | browsers: ['PhantomJS'], 15 | frameworks: ['mocha', 'sinon-chai', 'phantomjs-shim'], 16 | reporters: ['spec', 'coverage'], 17 | files: ['./index.js'], 18 | preprocessors: { 19 | './index.js': ['webpack', 'sourcemap'] 20 | }, 21 | webpack: webpackConfig, 22 | webpackMiddleware: { 23 | noInfo: true 24 | }, 25 | coverageReporter: { 26 | dir: './coverage', 27 | reporters: [ 28 | { type: 'lcov', subdir: '.' }, 29 | { type: 'text-summary' } 30 | ] 31 | } 32 | }) 33 | } 34 | -------------------------------------------------------------------------------- /frontend/test/unit/specs/Hello.spec.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Hello from '@/components/Hello' 3 | 4 | describe('Hello.vue', () => { 5 | it('should render correct contents', () => { 6 | const Constructor = Vue.extend(Hello) 7 | const vm = new Constructor().$mount() 8 | expect(vm.$el.querySelector('.hello h1').textContent) 9 | .to.equal('Welcome to Your Vue.js App') 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /log/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhstore/code-runner/064474908ac0abefebbc7d9759bc8ae2e30721f2/log/.gitkeep -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | 2 | # python3.5: 3 | # base: 4 | Flask==0.12 5 | Flask-Script==2.0.5 6 | Flask-Cache==0.13.1 7 | Flask-WTF==0.14.2 8 | 9 | flask-restful 10 | 11 | Flask-Celery-Helper==1.1.0 12 | 13 | Flask-Assets==0.12 14 | 15 | ######################### 16 | 17 | Flask-Bcrypt==0.7.1 18 | Flask-Login==0.4.0 19 | Flask-Mail==0.9.1 20 | Flask-Migrate==2.0.2 21 | flask-mongoengine==0.8.2 22 | Flask-OAuth==0.12 23 | Flask-OpenID==1.2.5 24 | Flask-Principal==0.4.0 25 | Flask-SQLAlchemy==2.1 26 | 27 | # dev: 28 | Flask-DebugToolbar==0.10.0 29 | 30 | # sanic 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /run.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hhstore/code-runner/064474908ac0abefebbc7d9759bc8ae2e30721f2/run.py --------------------------------------------------------------------------------