@ -0,0 +1,316 @@ | |||
# vscode-oj | |||
# 部署 | |||
## 一、基础配置 | |||
Ubuntu 20.04 | |||
由于前端中安装了自己编写的VScode插件,其中的后端服务器IP是直接写在插件的代码中的,所以如果后端IP地址发生了变化的话需要重新编译打包插件,因此对于前端和后端可以单独验证。 | |||
从前端镜像创建好云主机后可以从浏览器打开 `http://<ip>:8080` 访问code-server和使用我们开发的插件,此时插件访问的还是我们自己配置的后端。 | |||
对于后端的话,根据后端镜像创建好云主机后需要修改 `/etc/nginx/sites-available/be` 中的 `server_name` 为后端云主机的IP地址,然后可以在浏览器中输入 `http://<IP>/get-problem-items/` 或者 `http://<IP>/get-problem-description/<题目id: 1~400>/` 进行测试,只有这两个是GET请求,其他的接口是 POST 请求。 | |||
POST请求接口 | |||
1.`http://<ip>/case_test/` | |||
|变量|值| | |||
|:---:|:---:| | |||
|pid|1到400的数字字符串| | |||
|code|string| | |||
2.`http://<ip>/check-logic-error/` | |||
|变量|值| | |||
|:---:|:---:| | |||
|pid|1到400的数字字符串| | |||
|code|string| | |||
3.`http://<ip>/submit/` | |||
|变量|值| | |||
|:---:|:---:| | |||
|pid|1到400的数字字符串| | |||
|code|string| | |||
## 二、数据库配置 | |||
创建 Mysql 云数据库,执行 `be/SQL/problem.sql` 中的sql语句,并修改 `be/app.py` 中的配置为相应的数据库信息。 | |||
## 三、服务端配置 | |||
### 2.1 安装Python3.7 | |||
```shell | |||
# 升级包索引和软件 | |||
sudo apt update | |||
sudo apt upgrade -y | |||
# 安装编译所需包 | |||
sudo apt install -y build-essential zlib1g-dev libbz2-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev wget | |||
# 官网下载 Python3.7 | |||
wget https://www.python.org/ftp/python/3.7.4/Python-3.7.4.tgz | |||
# 解压 | |||
tar -xzvf Python-3.7.4.tgz | |||
# 编译安装 | |||
cd Python-3.7.4 | |||
./configure --prefix=/usr/lib/python3.7 # 配置安装位置 | |||
sudo make | |||
sudo make install | |||
# 建立软链接 | |||
sudo ln -s /usr/lib/python3.7/bin/python3.7 /usr/bin/python3.7 | |||
sudo ln -s /usr/lib/python3.7/bin/pip3.7 /usr/bin/pip3.7 | |||
``` | |||
### 2.2 安装JDK-11 | |||
```shell | |||
sudo apt update | |||
# 安装 JDK-11 | |||
sudo apt install -y openjdk-11-jdk | |||
# 查看是否安装成功 | |||
java -version | |||
# 配置环境变量 | |||
sudo nano /etc/environment | |||
# 写入: | |||
JAVA_HOME="/usr/lib/jvm/java-11-openjdk-amd64" | |||
# 更新 | |||
source /etc/environment | |||
# 查看 | |||
echo $JAVA_HOME | |||
``` | |||
### 2.3 安装Nginx | |||
```shell | |||
sudo apt-get install -y nginx | |||
# 启动 | |||
sudo /etc/init.d/nginx start | |||
# 使用以下命令重启、停止、查看Nginx状态 | |||
sudo systemctl restart nginx | |||
sudo systemctl start nginx | |||
sudo systemctl stop nginx | |||
sudo systemctl status nginx | |||
``` | |||
### 2.4 创建Python虚拟环境 | |||
```shell | |||
# 更新并安装组件 | |||
sudo apt update | |||
sudo apt install -y python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools | |||
# 安装 python3-venv 软件包 | |||
sudo apt install -y python3-venv | |||
# 创建虚拟环境 | |||
cd ~ | |||
python3.7 -m venv be | |||
# 将 be 文件夹中的文件上传至云主机 ~/be 下 | |||
# 激活虚拟环境 | |||
source ~/be/bin/activate | |||
# 安装依赖(注意使用pip而不是pip3) | |||
cd ~/be | |||
pip install -r requirements.txt | |||
# 安装 uWSGI | |||
pip install uwsgi | |||
``` | |||
### 2.5 配置 uWSGI | |||
```shell | |||
# 启用 UFW 防火墙,允许访问端口5000 | |||
sudo ufw allow 5000 | |||
# 测试 uWSGI 服务(若本地开启了代理请关闭) | |||
uwsgi --socket 0.0.0.0:5000 --protocol=http -w wsgi:app | |||
# 从本地浏览器输入 http://<ip address>:5000/get-problem-items/ 能够返回数据即表示成功 | |||
# 现在可以关闭虚拟环境 | |||
deactivate | |||
# 创建 uWSGI 配置文件 | |||
nano ~be/be.ini | |||
# 写入如下内容 | |||
[uwsgi] | |||
module = wsgi:app | |||
master = true | |||
processes = 5 | |||
socket = be.sock | |||
chmod-socket = 660 | |||
vacuum = true | |||
die-on-term = true | |||
# 保存并关闭 | |||
``` | |||
### 2.6 创建 systemd 单元文件 | |||
```shell | |||
sudo nano /etc/systemd/system/be.service | |||
# 写入如下内容 | |||
[Unit] | |||
Description=uWSGI instance to serve be | |||
After=network.target | |||
[Service] | |||
User=ubuntu | |||
Group=www-data | |||
WorkingDirectory=/home/ubuntu/be | |||
Environment="PATH=/home/ubuntu/be/bin" | |||
ExecStart=/home/ubuntu/be/bin/uwsgi --ini be.ini | |||
[Install] | |||
WantedBy=multi-user.target | |||
# 保存并关闭 | |||
# 现在可以启动创建的 uWSGI 服务并启用,以便在启动时启动 | |||
sudo systemctl start be | |||
sudo systemctl enable be | |||
# 查看状态 | |||
sudo systemctl status be | |||
``` | |||
### 2.7 将 Nginx 配置为代理请求 | |||
```shell | |||
sudo nano /etc/nginx/sites-available/be | |||
# 写入 | |||
server { | |||
listen 80; | |||
server_name <公网IP,服务端外网IP或者负载均衡外网IP>; | |||
location / { | |||
include uwsgi_params; | |||
uwsgi_pass unix:/home/ubuntu/be/be.sock; | |||
} | |||
} | |||
# 保存并关闭 | |||
# 若要启用该配置,需将文件链接至 sites-enabled 目录 | |||
sudo ln -s /etc/nginx/sites-available/be /etc/nginx/sites-enabled | |||
# 通过如下命令测试语法错误 | |||
sudo nginx -t | |||
# 返回成功则重启 Nginx 进程以读取新配置 | |||
sudo systemctl restart nginx | |||
# 再次调整防火墙,不再需要通过5000端口访问,可以删除该规则,最后可以允许访问Nginx服务器 | |||
sudo ufw delete allow 5000 | |||
sudo ufw allow 'Nginx Full' | |||
# 现在可以直接通过 IP 地址访问 | |||
# 尝试 http://<ip address>/get-problem-items/ | |||
# 遇到错误使用如下方式检查 | |||
sudo less /var/log/nginx/error.log # 检查Nginx错误日志 | |||
sudo less /var/log/nginx/access.log # 检查Nginx访问日志 | |||
sudo journalctl -u nginx # 检查Nginx进程日志 | |||
sudo journalctl -u be # 检查你的Flask应用程序的uWSGI日志 | |||
``` | |||
## 四、前端配置 | |||
> 新建一台云主机 | |||
### 4.1 code-server 安装配置 | |||
```shell | |||
curl -fOL https://github.com/cdr/code-server/releases/download/v3.8.0/code-server_3.8.0_amd64.deb | |||
sudo dpkg -i code-server_3.8.0_amd64.deb | |||
# 启动服务 | |||
sudo systemctl enable --now code-server@$USER | |||
``` | |||
打开~/.config/code-server/config.yaml | |||
修改bind-addr: 0.0.0.0:8080,以便在浏览器中访问云主机的8080端口来访问code-server。也可以指定其他的端口。同时修改password为可记忆的密码方便后续访问。随后重启服务。 | |||
```shell | |||
sudo systemctl restart --now code-server@$USER | |||
``` | |||
浏览器访问云主机ip:8080,并输入密码,即可使用在线VSCode编辑器。 | |||
### 4.2 插件的编译安装(可在本地安装编译并上传到云主机) | |||
```shell | |||
# 安装 node.js、npm | |||
sudo apt update | |||
sudo apt install nodejs npm | |||
# 查看是否成功 | |||
nodejs --version | |||
npm --version | |||
# 安装 typescript | |||
npm install -g typescript | |||
# 查看是否成功 | |||
tsc -v | |||
# 安装脚手架 | |||
npm install -g yo generator-code | |||
# 进入 ShuiShan 目录 | |||
cd ShuiShan | |||
# 修改 ShuiShan/src/service.ts 第七行 domain 变量为后端服务器地址**** | |||
# 安装依赖 | |||
npm install | |||
# 打包 | |||
vsce package | |||
# 上传到前端服务器,将生成的 .vsix 文件上传至前端服务器 | |||
# 在 code-server 中安装该插件包 | |||
# 如果不想上传至云端可在本地使用 VScode 打开 ShuiShan 目录然后按 F5 运行 | |||
``` | |||
@ -0,0 +1,68 @@ | |||
# ShuiShan README | |||
This is the README for your extension "ShuiShan". After writing up a brief description, we recommend including the following sections. | |||
## Features | |||
Describe specific features of your extension including screenshots of your extension in action. Image paths are relative to this README file. | |||
For example if there is an image subfolder under your extension project workspace: | |||
\!\[feature X\]\(images/feature-x.png\) | |||
> Tip: Many popular extensions utilize animations. This is an excellent way to show off your extension! We recommend short, focused animations that are easy to follow. | |||
## Requirements | |||
If you have any requirements or dependencies, add a section describing those and how to install and configure them. | |||
## Extension Settings | |||
Include if your extension adds any VS Code settings through the `contributes.configuration` extension point. | |||
For example: | |||
This extension contributes the following settings: | |||
* `myExtension.enable`: enable/disable this extension | |||
* `myExtension.thing`: set to `blah` to do something | |||
## Known Issues | |||
Calling out known issues can help limit users opening duplicate issues against your extension. | |||
## Release Notes | |||
Users appreciate release notes as you update your extension. | |||
### 1.0.0 | |||
Initial release of ... | |||
### 1.0.1 | |||
Fixed issue #. | |||
### 1.1.0 | |||
Added features X, Y, and Z. | |||
----------------------------------------------------------------------------------------------------------- | |||
## Working with Markdown | |||
**Note:** You can author your README using Visual Studio Code. Here are some useful editor keyboard shortcuts: | |||
* Split the editor (`Cmd+\` on macOS or `Ctrl+\` on Windows and Linux) | |||
* Toggle preview (`Shift+CMD+V` on macOS or `Shift+Ctrl+V` on Windows and Linux) | |||
* Press `Ctrl+Space` (Windows, Linux) or `Cmd+Space` (macOS) to see a list of Markdown snippets | |||
### For more information | |||
* [Visual Studio Code's Markdown Support](http://code.visualstudio.com/docs/languages/markdown) | |||
* [Markdown Syntax Reference](https://help.github.com/articles/markdown-basics/) | |||
**Enjoy!** | |||
## 水杉编程 | |||
@ -0,0 +1,19 @@ | |||
{ | |||
"root": true, | |||
"parser": "@typescript-eslint/parser", | |||
"parserOptions": { | |||
"ecmaVersion": 6, | |||
"sourceType": "module" | |||
}, | |||
"plugins": [ | |||
"@typescript-eslint" | |||
], | |||
"rules": { | |||
"@typescript-eslint/naming-convention": "warn", | |||
"@typescript-eslint/semi": "warn", | |||
"curly": "warn", | |||
"eqeqeq": "warn", | |||
"no-throw-literal": "warn", | |||
"semi": "off" | |||
} | |||
} |
@ -0,0 +1,5 @@ | |||
out | |||
dist | |||
node_modules | |||
.vscode-test/ | |||
*.vsix |
@ -0,0 +1,9 @@ | |||
{ | |||
// See http://go.microsoft.com/fwlink/?LinkId=827846 | |||
// for the documentation about the extensions.json format | |||
"recommendations": [ | |||
"dbaeumer.vscode-eslint", | |||
"eamodio.tsl-problem-matcher", | |||
"yuxinli.shuishan" | |||
] | |||
} |
@ -0,0 +1,34 @@ | |||
// A launch configuration that compiles the extension and then opens it inside a new window | |||
// Use IntelliSense to learn about possible attributes. | |||
// Hover to view descriptions of existing attributes. | |||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 | |||
{ | |||
"version": "0.2.0", | |||
"configurations": [ | |||
{ | |||
"name": "Run Extension", | |||
"type": "extensionHost", | |||
"request": "launch", | |||
"args": [ | |||
"--extensionDevelopmentPath=${workspaceFolder}" | |||
], | |||
"outFiles": [ | |||
"${workspaceFolder}/dist/**/*.js" | |||
], | |||
"preLaunchTask": "${defaultBuildTask}" | |||
}, | |||
{ | |||
"name": "Extension Tests", | |||
"type": "extensionHost", | |||
"request": "launch", | |||
"args": [ | |||
"--extensionDevelopmentPath=${workspaceFolder}", | |||
"--extensionTestsPath=${workspaceFolder}/out/test/suite/index" | |||
], | |||
"outFiles": [ | |||
"${workspaceFolder}/out/test/**/*.js" | |||
], | |||
"preLaunchTask": "npm: test-watch" | |||
} | |||
] | |||
} |
@ -0,0 +1,11 @@ | |||
// Place your settings in this file to overwrite default and user settings. | |||
{ | |||
"files.exclude": { | |||
"out": false // set this to true to hide the "out" folder with the compiled JS files | |||
}, | |||
"search.exclude": { | |||
"out": true // set this to false to include "out" folder in search results | |||
}, | |||
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts | |||
"typescript.tsc.autoDetect": "off" | |||
} |
@ -0,0 +1,33 @@ | |||
// See https://go.microsoft.com/fwlink/?LinkId=733558 | |||
// for the documentation about the tasks.json format | |||
{ | |||
"version": "2.0.0", | |||
"tasks": [ | |||
{ | |||
"type": "npm", | |||
"script": "watch", | |||
"problemMatcher": [ | |||
"$ts-webpack-watch", | |||
"$tslint-webpack-watch" | |||
], | |||
"isBackground": true, | |||
"presentation": { | |||
"reveal": "never" | |||
}, | |||
"group": { | |||
"kind": "build", | |||
"isDefault": true | |||
} | |||
}, | |||
{ | |||
"type": "npm", | |||
"script": "test-watch", | |||
"problemMatcher": "$tsc-watch", | |||
"isBackground": true, | |||
"presentation": { | |||
"reveal": "never" | |||
}, | |||
"group": "build" | |||
} | |||
] | |||
} |
@ -0,0 +1,11 @@ | |||
.vscode/** | |||
.vscode-test/** | |||
out/** | |||
src/** | |||
.gitignore | |||
.yarnrc | |||
vsc-extension-quickstart.md | |||
**/tsconfig.json | |||
**/.eslintrc.json | |||
**/*.map | |||
**/*.ts |
@ -0,0 +1,9 @@ | |||
# Change Log | |||
All notable changes to the "ShuiShan" extension will be documented in this file. | |||
Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. | |||
## [Unreleased] | |||
- Initial release |
@ -0,0 +1 @@ | |||
# 水杉编程 v1.0 |
@ -0,0 +1,42 @@ | |||
//@ts-check | |||
'use strict'; | |||
const path = require('path'); | |||
/**@type {import('webpack').Configuration}*/ | |||
const config = { | |||
target: 'node', // vscode extensions run in a Node.js-context 📖 -> https://webpack.js.org/configuration/node/ | |||
mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production') | |||
entry: './src/extension.ts', // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/ | |||
output: { | |||
// the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/ | |||
path: path.resolve(__dirname, '..', 'dist'), | |||
filename: 'extension.js', | |||
libraryTarget: 'commonjs2', | |||
devtoolModuleFilenameTemplate: '../[resource-path]' | |||
}, | |||
devtool: 'source-map', | |||
externals: { | |||
vscode: 'commonjs vscode' // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/ | |||
}, | |||
resolve: { | |||
// support reading TypeScript and JavaScript files, 📖 -> https://github.com/TypeStrong/ts-loader | |||
extensions: ['.ts', '.js'] | |||
}, | |||
module: { | |||
rules: [ | |||
{ | |||
test: /\.ts$/, | |||
exclude: /node_modules/, | |||
use: [ | |||
{ | |||
loader: 'ts-loader' | |||
} | |||
] | |||
} | |||
] | |||
} | |||
}; | |||
module.exports = config; |
@ -0,0 +1,104 @@ | |||
{ | |||
"name": "ShuiShan", | |||
"publisher": "yuxinli", | |||
"displayName": "ShuiShan", | |||
"description": "online code", | |||
"version": "0.0.1", | |||
"icon": "images/shuishan.png", | |||
"engines": { | |||
"vscode": "^1.51.1" | |||
}, | |||
"categories": [ | |||
"Other" | |||
], | |||
"activationEvents": [ | |||
"onView:view.shuishan", | |||
"onCommand:ShuiShan.click", | |||
"onCommand:ShuiShan.helloWorld", | |||
"onCommand:ShuiShan.solveProblem", | |||
"onCommand:ShuiShan.compileSolution", | |||
"onCommand:ShuiShan.testSolution", | |||
"onCommand:ShuiShan.checkSolution", | |||
"onCommand:ShuiShan.submitSolution" | |||
], | |||
"main": "./dist/extension.js", | |||
"contributes": { | |||
"viewsContainers": { | |||
"activitybar": [ | |||
{ | |||
"id":"shuishanView", | |||
"title":"水杉编程", | |||
"icon":"images/shuishan.png" | |||
} | |||
] | |||
}, | |||
"views": { | |||
"shuishanView":[ | |||
{ | |||
"id":"view.shuishan", | |||
"name":"Shuishan" | |||
} | |||
] | |||
}, | |||
"commands": [ | |||
{ | |||
"command": "ShuiShan.helloWorld", | |||
"title": "Hello World" | |||
}, | |||
{ | |||
"command": "ShuiShan.click", | |||
"title": "Show Problem" | |||
}, | |||
{ | |||
"command": "ShuiShan.solveProblem", | |||
"title": "Solve Problem" | |||
}, | |||
{ | |||
"command": "ShuiShan.compileSolution", | |||
"title": "Compile Solution" | |||
}, | |||
{ | |||
"command": "ShuiShan.testSolution", | |||
"title": "Test Solution" | |||
}, | |||
{ | |||
"command": "ShuiShan.checkSolution", | |||
"title": "Check Solution" | |||
}, | |||
{ | |||
"command": "ShuiShan.submitSolution", | |||
"title": "Submit Solution" | |||
} | |||
] | |||
}, | |||
"scripts": { | |||
"vscode:prepublish": "npm run package", | |||
"compile": "webpack --devtool nosources-source-map --config ./build/node-extension.webpack.config.js", | |||
"watch": "webpack --watch --devtool nosources-source-map --info-verbosity verbose --config ./build/node-extension.webpack.config.js", | |||
"package": "webpack --mode production --config ./build/node-extension.webpack.config.js", | |||
"test-compile": "tsc -p ./", | |||
"test-watch": "tsc -watch -p ./", | |||
"pretest": "npm run test-compile && npm run lint", | |||
"lint": "eslint src --ext ts", | |||
"test": "node ./out/test/runTest.js" | |||
}, | |||
"devDependencies": { | |||
"@types/vscode": "^1.51.0", | |||
"@types/glob": "^7.1.3", | |||
"@types/mocha": "^8.0.0", | |||
"@types/node": "^12.11.7", | |||
"eslint": "^7.9.0", | |||
"@typescript-eslint/eslint-plugin": "^4.1.1", | |||
"@typescript-eslint/parser": "^4.1.1", | |||
"glob": "^7.1.6", | |||
"mocha": "^8.1.3", | |||
"typescript": "^4.0.2", | |||
"vscode-test": "^1.4.0", | |||
"ts-loader": "^8.0.3", | |||
"webpack": "^4.44.1", | |||
"webpack-cli": "^3.3.12" | |||
}, | |||
"dependencies": { | |||
"axios": "^0.21.1" | |||
} | |||
} |
@ -0,0 +1,24 @@ | |||
// Copyright (c) jdneo. All rights reserved. | |||
// Licensed under the MIT license. | |||
import { ConfigurationChangeEvent, Disposable, languages, workspace } from "vscode"; | |||
import { customCodeLensProvider, CustomCodeLensProvider } from "./CustomCodeLensProvider"; | |||
class CodeLensController implements Disposable { | |||
private internalProvider: CustomCodeLensProvider; | |||
private registeredProvider: Disposable | undefined; | |||
constructor() { | |||
this.internalProvider = customCodeLensProvider | |||
this.registeredProvider = languages.registerCodeLensProvider({ scheme: "file" }, this.internalProvider); | |||
} | |||
public dispose(): void { | |||
if (this.registeredProvider) { | |||
this.registeredProvider.dispose(); | |||
} | |||
} | |||
} | |||
export const codeLensController: CodeLensController = new CodeLensController(); |
@ -0,0 +1,94 @@ | |||
// Copyright (c) jdneo. All rights reserved. | |||
// Licensed under the MIT license. | |||
import * as vscode from "vscode"; | |||
// import { explorerNodeManager } from "../explorer/explorerNodeManager"; | |||
// import { LeetCodeNode } from "../explorer/LeetCodeNode"; | |||
// import { getEditorShortcuts } from "../utils/settingUtils"; | |||
export class CustomCodeLensProvider implements vscode.CodeLensProvider { | |||
private onDidChangeCodeLensesEmitter: vscode.EventEmitter<void> = new vscode.EventEmitter<void>(); | |||
get onDidChangeCodeLenses(): vscode.Event<void> { | |||
return this.onDidChangeCodeLensesEmitter.event; | |||
} | |||
public refresh(): void { | |||
this.onDidChangeCodeLensesEmitter.fire(); | |||
} | |||
public provideCodeLenses(document: vscode.TextDocument): vscode.ProviderResult<vscode.CodeLens[]> { | |||
// const shortcuts: string[] = getEditorShortcuts(); | |||
// if (!shortcuts) { | |||
// return; | |||
// } | |||
// const content: string = document.getText(); | |||
// const matchResult: RegExpMatchArray | null = content.match(/@lc app=.* id=(.*) lang=.*/); | |||
// if (!matchResult) { | |||
// return undefined; | |||
// } | |||
// const nodeId: string | undefined = matchResult[1]; | |||
// let node: LeetCodeNode | undefined; | |||
// if (nodeId) { | |||
// node = explorerNodeManager.getNodeById(nodeId); | |||
// } | |||
let codeLensLine: number = document.lineCount - 1; | |||
// for (let i: number = document.lineCount - 1; i >= 0; i--) { | |||
// const lineContent: string = document.lineAt(i).text; | |||
// if (lineContent.indexOf("@lc code=end") >= 0) { | |||
// codeLensLine = i; | |||
// break; | |||
// } | |||
// } | |||
const range: vscode.Range = new vscode.Range(codeLensLine, 0, codeLensLine, 0); | |||
const codeLens: vscode.CodeLens[] = []; | |||
// if (shortcuts.indexOf("submit") >= 0) { | |||
codeLens.push(new vscode.CodeLens(range, { | |||
title: "编译", | |||
command: "ShuiShan.compileSolution", | |||
arguments: [document.uri], | |||
})); | |||
// } | |||
// if (shortcuts.indexOf("test") >= 0) { | |||
codeLens.push(new vscode.CodeLens(range, { | |||
title: "执行", | |||
command: "ShuiShan.testSolution", | |||
arguments: [document.uri], | |||
})); | |||
// } | |||
// if (shortcuts.indexOf("star") >= 0 && node) { | |||
codeLens.push(new vscode.CodeLens(range, { | |||
title: "错误预测", | |||
command: "ShuiShan.checkSolution", | |||
arguments: [document.uri], | |||
})); | |||
// } | |||
// if (shortcuts.indexOf("solution") >= 0) { | |||
codeLens.push(new vscode.CodeLens(range, { | |||
title: "提交", | |||
command: "ShuiShan.submitSolution", | |||
arguments: [document.uri], | |||
})); | |||
// } | |||
// if (shortcuts.indexOf("description") >= 0) { | |||
// codeLens.push(new vscode.CodeLens(range, { | |||
// title: "Description", | |||
// command: "leetcode.previewProblem", | |||
// arguments: [document.uri], | |||
// })); | |||
// } | |||
return codeLens; | |||
} | |||
} | |||
export const customCodeLensProvider: CustomCodeLensProvider = new CustomCodeLensProvider(); |
@ -0,0 +1,203 @@ | |||
// The module 'vscode' contains the VS Code extensibility API | |||
// Import the module and reference it with the alias vscode in your code below | |||
import * as vscode from 'vscode'; | |||
import * as os from "os"; | |||
import * as path from "path"; | |||
import { commands, Disposable } from "vscode"; | |||
import { writeFileSync } from 'fs'; | |||
import * as fs from 'fs'; | |||
import { APIService } from './service'; | |||
import { ShuishanDataProvider } from './shuishanDataProvider'; | |||
import { codeLensController } from './codelens/CodeLensController'; | |||
import { exec } from 'child_process'; | |||
// this method is called when your extension is activated | |||
// your extension is activated the very first time the command is executed | |||
export function activate(context: vscode.ExtensionContext) { | |||
// Use the console to output diagnostic information (console.log) and errors (console.error) | |||
// This line of code will only be executed once when your extension is activated | |||
console.log('Congratulations, your extension "ShuiShan" is now active!'); | |||
const service = new APIService(); | |||
// 绑定视图 | |||
vscode.window.registerTreeDataProvider('view.shuishan', new ShuishanDataProvider(service)); | |||
// 输出窗口 | |||
let outputChannel = vscode.window.createOutputChannel("ShuiShan Msg"); | |||
outputChannel.show(); | |||
// 打开编辑器 | |||
let openEditor = vscode.commands.registerCommand("ShuiShan.solveProblem", (pid) =>{ | |||
// let path: string = ''; | |||
// console.log(path); | |||
let file_path = path.join(os.homedir(), ".shuishan"); | |||
fs.mkdir(file_path, (err)=>{}); | |||
let data: string = "#include <stdio.h>" + "\n\n" + "int main()" + "\n" + "{" + "\n" + "\treturn 0;" + "\n" + "}\n\n"; | |||
let i = 1; | |||
while(true){ | |||
// path = '/home/liyuxin/.shuishan/' + pid + '-' + (i) + '.c'; | |||
file_path = file_path + '/' + pid + '-' + (i) + '.c'; | |||
console.log(file_path); | |||
let stat:any = null; | |||
try{ | |||
stat = fs.statSync(file_path); | |||
i++; | |||
}catch(e){ | |||
writeFileSync(file_path, data); | |||
break; | |||
} | |||
} | |||
let textEditor: vscode.TextEditor | undefined; | |||
textEditor = vscode.window.activeTextEditor; | |||
vscode.window.showTextDocument(vscode.Uri.file(file_path), { preview: false, viewColumn: vscode.ViewColumn.Two }); | |||
}); | |||
// 显示题目详情 | |||
let showProDes = vscode.commands.registerCommand('ShuiShan.click',(pid, title)=>{ | |||
let panel = vscode.window.createWebviewPanel( | |||
"viewType", | |||
"题目详情", | |||
vscode.ViewColumn.One, | |||
{ | |||
enableScripts: true | |||
} | |||
); | |||
panel.webview.onDidReceiveMessage( | |||
message => { | |||
// console.log('a'); | |||
switch (message.command) { | |||
case "solveProblem": { | |||
commands.executeCommand("ShuiShan.solveProblem", message.id); | |||
break; | |||
} | |||
} | |||
}, | |||
undefined, | |||
context.subscriptions | |||
); | |||
let body = service.getDes(pid); | |||
body.then(result => { | |||
panel.title = pid + '. ' + title; | |||
panel.webview.html = ` | |||
<!DOCTYPE html> | |||
<html> | |||
<head> | |||
<style> | |||
#solve { | |||
position: fixed; | |||
bottom: 1rem; | |||
right: 1rem; | |||
border: 0; | |||
margin: 1rem 0; | |||
padding: 0.2rem 1rem; | |||
color: white; | |||
background-color: var(--vscode-button-background); | |||
} | |||
#solve:hover { | |||
background-color: var(--vscode-button-hoverBackground); | |||
} | |||
#solve:active { | |||
border: 0; | |||
} | |||
</style> | |||
<style> | |||
code { white-space: pre-wrap; } | |||
</style> | |||
<script> | |||
function buttonClick() { | |||
// console.log('aa'); | |||
const vscode = acquireVsCodeApi(); | |||
vscode.postMessage({ | |||
command: 'solveProblem', | |||
id:'${pid}', | |||
}); | |||
} | |||
</script> | |||
</head> | |||
<body style="font-size:18px"> | |||
<div>${String(result)}</div> | |||
<button id="solve" onclick="buttonClick()" style="height:50px;">Code Now</button> | |||
</body> | |||
</html>`; | |||
// console.log(String(result)); | |||
}); | |||
}); | |||
let compile = vscode.commands.registerCommand('ShuiShan.compileSolution', (uri) =>{ | |||
// console.log('compile' + uri); | |||
let _input: string = uri.toString().substring(7); // remove file:// | |||
let _output: string = _input.replace(".c", ""); | |||
let cmd: string = "gcc -o " + _output + " " + _input; | |||
exec(cmd, (error, stdout, stderr) => { | |||
outputChannel.appendLine('Compile Message:'); | |||
if (error) { | |||
outputChannel.appendLine(`error: ${error.message}`); | |||
return; | |||
} | |||
if (stderr) { | |||
outputChannel.appendLine(`stderr: ${stderr}`); | |||
return; | |||
} | |||
outputChannel.appendLine("Done!"); | |||
}); | |||
}); | |||
let test = vscode.commands.registerCommand('ShuiShan.testSolution', (uri) => { | |||
// console.log('test' + uri); | |||
let msg = service.testSolution(uri); | |||
msg.then(result => { | |||
outputChannel.appendLine(String(result)); | |||
}); | |||
}); | |||
let check = vscode.commands.registerCommand('ShuiShan.checkSolution', (uri) => { | |||
// console.log('check' + uri); | |||
let msg = service.checkSolution(uri); | |||
msg.then(result => { | |||
outputChannel.appendLine(String(result)); | |||
}); | |||
}); | |||
let submit = vscode.commands.registerCommand('ShuiShan.submitSolution', (uri) => { | |||
// console.log('submit' + uri); | |||
let msg = service.submitSolution(uri); | |||
msg.then(result => { | |||
outputChannel.appendLine(String(result)); | |||
}); | |||
}); | |||
// The command has been defined in the package.json file | |||
// Now provide the implementation of the command with registerCommand | |||
// The commandId parameter must match the command field in package.json | |||
let disposable = vscode.commands.registerCommand('ShuiShan.helloWorld', () => { | |||
// The code you place here will be executed every time your command is executed | |||
// Display a message box to the user | |||
vscode.window.showInformationMessage('Hello World from ShuiShan!'); | |||
}); | |||
context.subscriptions.push( | |||
disposable, | |||
showProDes, | |||
openEditor, | |||
codeLensController, | |||
compile, | |||
test, | |||
check, | |||
submit | |||
); | |||
} | |||
// this method is called when your extension is deactivated | |||
export function deactivate() {} |
@ -0,0 +1,17 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32pt" height="32pt" viewBox="0 0 32 32" version="1.1"> | |||
<g id="surface1"> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(82.352941%,39.215686%,19.607843%);fill-opacity:1;" d="M 18.007812 31.0625 L 13.992188 31.0625 C 13.472656 31.0625 13.054688 30.644531 13.054688 30.125 L 13.054688 27.046875 C 13.054688 26.527344 13.472656 26.109375 13.992188 26.109375 L 18.007812 26.109375 C 18.527344 26.109375 18.945312 26.527344 18.945312 27.046875 L 18.945312 30.125 C 18.945312 30.644531 18.527344 31.0625 18.007812 31.0625 Z M 18.007812 31.0625 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(64.705882%,27.45098%,15.686275%);fill-opacity:1;" d="M 18.945312 30.125 L 18.945312 27.046875 C 18.945312 26.527344 18.527344 26.109375 18.007812 26.109375 L 16 26.109375 L 16 31.0625 L 18.007812 31.0625 C 18.527344 31.0625 18.945312 30.644531 18.945312 30.125 Z M 18.945312 30.125 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(78.431373%,100%,31.372549%);fill-opacity:1;" d="M 23.027344 32 L 8.972656 32 C 8.453125 32 8.035156 31.582031 8.035156 31.0625 C 8.035156 30.542969 8.453125 30.125 8.972656 30.125 L 23.027344 30.125 C 23.546875 30.125 23.964844 30.542969 23.964844 31.0625 C 23.964844 31.582031 23.546875 32 23.027344 32 Z M 23.027344 32 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(30.588235%,78.823529%,37.254902%);fill-opacity:1;" d="M 26.042969 27.984375 L 5.957031 27.984375 C 5.617188 27.984375 5.304688 27.800781 5.140625 27.503906 C 4.972656 27.207031 4.980469 26.84375 5.160156 26.554688 L 9.175781 20.027344 C 9.347656 19.75 9.648438 19.582031 9.976562 19.582031 L 22.023438 19.582031 C 22.351562 19.582031 22.652344 19.75 22.824219 20.027344 L 26.839844 26.554688 C 27.019531 26.84375 27.027344 27.207031 26.859375 27.503906 C 26.695312 27.800781 26.382812 27.984375 26.042969 27.984375 Z M 26.042969 27.984375 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(52.941176%,90.588235%,32.156863%);fill-opacity:1;" d="M 23.964844 31.0625 C 23.964844 30.542969 23.546875 30.125 23.027344 30.125 L 16 30.125 L 16 32 L 23.027344 32 C 23.546875 32 23.964844 31.582031 23.964844 31.0625 Z M 23.964844 31.0625 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(7.843137%,66.666667%,41.960784%);fill-opacity:1;" d="M 26.859375 27.503906 C 27.027344 27.207031 27.019531 26.84375 26.839844 26.554688 L 22.824219 20.027344 C 22.652344 19.75 22.351562 19.582031 22.023438 19.582031 L 16 19.582031 L 16 27.984375 L 26.042969 27.984375 C 26.382812 27.984375 26.695312 27.800781 26.859375 27.503906 Z M 26.859375 27.503906 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(52.941176%,90.588235%,32.156863%);fill-opacity:1;" d="M 24.035156 21.457031 L 7.964844 21.457031 C 7.628906 21.457031 7.3125 21.273438 7.148438 20.976562 C 6.984375 20.679688 6.992188 20.316406 7.167969 20.027344 L 11.183594 13.5 C 11.355469 13.222656 11.65625 13.054688 11.984375 13.054688 L 20.015625 13.054688 C 20.34375 13.054688 20.644531 13.222656 20.816406 13.5 L 24.832031 20.027344 C 25.011719 20.316406 25.015625 20.679688 24.851562 20.976562 C 24.6875 21.273438 24.371094 21.457031 24.035156 21.457031 Z M 24.035156 21.457031 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(30.588235%,78.823529%,37.254902%);fill-opacity:1;" d="M 24.851562 20.976562 C 25.015625 20.679688 25.007812 20.316406 24.832031 20.027344 L 20.816406 13.5 C 20.644531 13.222656 20.34375 13.054688 20.015625 13.054688 L 16 13.054688 L 16 21.457031 L 24.035156 21.457031 C 24.371094 21.457031 24.6875 21.273438 24.851562 20.976562 Z M 24.851562 20.976562 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(78.431373%,100%,31.372549%);fill-opacity:1;" d="M 22.023438 14.929688 L 9.976562 14.929688 C 9.636719 14.929688 9.324219 14.746094 9.15625 14.449219 C 8.992188 14.152344 9 13.789062 9.175781 13.5 L 13.191406 6.972656 C 13.363281 6.695312 13.667969 6.527344 13.992188 6.527344 L 18.007812 6.527344 C 18.332031 6.527344 18.636719 6.695312 18.808594 6.972656 L 22.824219 13.5 C 23 13.789062 23.007812 14.152344 22.84375 14.449219 C 22.675781 14.746094 22.363281 14.929688 22.023438 14.929688 Z M 22.023438 14.929688 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(52.941176%,90.588235%,32.156863%);fill-opacity:1;" d="M 22.84375 14.449219 C 23.007812 14.152344 23 13.789062 22.824219 13.5 L 18.808594 6.972656 C 18.636719 6.695312 18.332031 6.527344 18.007812 6.527344 L 16 6.527344 L 16 14.929688 L 22.023438 14.929688 C 22.363281 14.929688 22.675781 14.746094 22.84375 14.449219 Z M 22.84375 14.449219 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(52.941176%,90.588235%,32.156863%);fill-opacity:1;" d="M 20.015625 8.402344 L 11.984375 8.402344 C 11.644531 8.402344 11.332031 8.21875 11.164062 7.921875 C 11 7.625 11.007812 7.261719 11.183594 6.972656 L 15.203125 0.445312 C 15.371094 0.167969 15.675781 0 16 0 C 16.324219 0 16.628906 0.167969 16.796875 0.445312 L 20.816406 6.972656 C 20.992188 7.261719 21 7.625 20.835938 7.921875 C 20.667969 8.21875 20.355469 8.402344 20.015625 8.402344 Z M 20.015625 8.402344 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(30.588235%,78.823529%,37.254902%);fill-opacity:1;" d="M 20.835938 7.921875 C 21 7.625 20.992188 7.261719 20.816406 6.972656 L 16.796875 0.445312 C 16.628906 0.167969 16.324219 0 16 0 L 16 8.402344 L 20.015625 8.402344 C 20.355469 8.402344 20.667969 8.21875 20.835938 7.921875 Z M 20.835938 7.921875 "/> | |||
</g> | |||
</svg> |
@ -0,0 +1,15 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32pt" height="32pt" viewBox="0 0 32 32" version="1.1"> | |||
<g id="surface1"> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(70.196078%,36.078431%,29.411765%);fill-opacity:1;" d="M 19.75 22.550781 L 23.5 22.550781 L 23.5 31.050781 L 19.75 31.050781 Z M 19.75 22.550781 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(54.509804%,26.27451%,17.647059%);fill-opacity:1;" d="M 21.625 22.550781 L 23.5 22.550781 L 23.5 31.050781 L 21.625 31.050781 Z M 21.625 22.550781 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(59.607843%,83.137255%,0%);fill-opacity:1;" d="M 31.828125 22.945312 L 27.457031 16.929688 L 29.125 16.929688 C 29.460938 16.929688 29.78125 16.742188 29.949219 16.441406 C 30.117188 16.121094 30.097656 15.765625 29.910156 15.464844 L 25.878906 9.429688 L 27.25 9.429688 C 27.605469 9.429688 27.925781 9.222656 28.09375 8.902344 C 28.242188 8.585938 28.207031 8.210938 28 7.929688 L 22.375 0.367188 C 22.1875 0.140625 21.90625 0.0117188 21.625 0.0117188 C 21.34375 0.0117188 21.0625 0.140625 20.875 0.367188 L 15.25 7.929688 C 15.042969 8.210938 15.007812 8.585938 15.15625 8.902344 C 15.324219 9.222656 15.644531 9.429688 16 9.429688 L 17.367188 9.429688 L 13.335938 15.464844 C 13.148438 15.765625 13.132812 16.121094 13.300781 16.441406 C 13.46875 16.742188 13.789062 16.929688 14.125 16.929688 L 15.792969 16.929688 L 11.480469 22.945312 C 11.273438 23.226562 11.257812 23.601562 11.425781 23.921875 C 11.574219 24.238281 11.894531 24.425781 12.25 24.425781 L 31.0625 24.425781 C 31.417969 24.425781 31.734375 24.238281 31.886719 23.921875 C 32.054688 23.601562 32.035156 23.226562 31.828125 22.945312 Z M 31.828125 22.945312 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(40%,74.117647%,12.941176%);fill-opacity:1;" d="M 31.886719 23.921875 C 31.734375 24.238281 31.417969 24.425781 31.0625 24.425781 L 21.625 24.425781 L 21.625 0.0117188 C 21.90625 0.0117188 22.1875 0.140625 22.375 0.367188 L 28 7.929688 C 28.207031 8.210938 28.242188 8.585938 28.09375 8.902344 C 27.925781 9.222656 27.605469 9.429688 27.25 9.429688 L 25.878906 9.429688 L 29.910156 15.464844 C 30.097656 15.765625 30.117188 16.121094 29.949219 16.441406 C 29.78125 16.742188 29.460938 16.929688 29.125 16.929688 L 27.457031 16.929688 L 31.828125 22.945312 C 32.035156 23.226562 32.054688 23.601562 31.886719 23.921875 Z M 31.886719 23.921875 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(70.196078%,36.078431%,29.411765%);fill-opacity:1;" d="M 8.5 22.550781 L 12.25 22.550781 L 12.25 31.050781 L 8.5 31.050781 Z M 8.5 22.550781 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(54.509804%,26.27451%,17.647059%);fill-opacity:1;" d="M 10.375 22.550781 L 12.25 22.550781 L 12.25 31.050781 L 10.375 31.050781 Z M 10.375 22.550781 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(59.607843%,83.137255%,0%);fill-opacity:1;" d="M 20.519531 22.945312 L 16.207031 16.929688 L 17.875 16.929688 C 18.210938 16.929688 18.53125 16.742188 18.699219 16.441406 C 18.867188 16.121094 18.851562 15.765625 18.664062 15.464844 L 14.632812 9.429688 L 16 9.429688 C 16.355469 9.429688 16.675781 9.222656 16.84375 8.902344 C 16.992188 8.585938 16.957031 8.210938 16.75 7.929688 L 11.125 0.367188 C 10.9375 0.140625 10.65625 0.0117188 10.375 0.0117188 C 10.09375 0.0117188 9.8125 0.140625 9.625 0.367188 L 4 7.929688 C 3.792969 8.210938 3.757812 8.585938 3.90625 8.902344 C 4.078125 9.222656 4.394531 9.429688 4.75 9.429688 L 6.121094 9.429688 L 2.089844 15.464844 C 1.902344 15.765625 1.882812 16.121094 2.050781 16.441406 C 2.21875 16.742188 2.539062 16.929688 2.875 16.929688 L 4.542969 16.929688 L 0.171875 22.945312 C -0.0351562 23.226562 -0.0546875 23.601562 0.113281 23.921875 C 0.265625 24.238281 0.582031 24.425781 0.9375 24.425781 L 19.75 24.425781 C 20.105469 24.425781 20.425781 24.238281 20.574219 23.921875 C 20.742188 23.601562 20.726562 23.226562 20.519531 22.945312 Z M 20.519531 22.945312 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(40%,74.117647%,12.941176%);fill-opacity:1;" d="M 20.574219 23.921875 C 20.425781 24.238281 20.105469 24.425781 19.75 24.425781 L 10.375 24.425781 L 10.375 0.0117188 C 10.65625 0.0117188 10.9375 0.140625 11.125 0.367188 L 16.75 7.929688 C 16.957031 8.210938 16.992188 8.585938 16.84375 8.902344 C 16.675781 9.222656 16.355469 9.429688 16 9.429688 L 14.632812 9.429688 L 18.664062 15.464844 C 18.851562 15.765625 18.867188 16.121094 18.699219 16.441406 C 18.53125 16.742188 18.210938 16.929688 17.875 16.929688 L 16.207031 16.929688 L 20.519531 22.945312 C 20.726562 23.226562 20.742188 23.601562 20.574219 23.921875 Z M 20.574219 23.921875 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(59.607843%,83.137255%,0%);fill-opacity:1;" d="M 32 31.050781 C 32 31.578125 31.585938 31.988281 31.0625 31.988281 L 0.9375 31.988281 C 0.414062 31.988281 0 31.578125 0 31.050781 C 0 30.527344 0.414062 30.113281 0.9375 30.113281 L 31.0625 30.113281 C 31.585938 30.113281 32 30.527344 32 31.050781 Z M 32 31.050781 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(40%,74.117647%,12.941176%);fill-opacity:1;" d="M 32 31.050781 C 32 31.578125 31.585938 31.988281 31.0625 31.988281 L 16 31.988281 L 16 30.113281 L 31.0625 30.113281 C 31.585938 30.113281 32 30.527344 32 31.050781 Z M 32 31.050781 "/> | |||
</g> | |||
</svg> |
@ -0,0 +1,18 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32pt" height="32pt" viewBox="0 0 32 32" version="1.1"> | |||
<g id="surface1"> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(69.019608%,36.078431%,14.509804%);fill-opacity:1;" d="M 13.75 22.359375 L 17.835938 22.359375 L 17.835938 30.609375 L 13.75 30.609375 Z M 13.75 22.359375 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(55.686275%,29.019608%,12.156863%);fill-opacity:1;" d="M 15.792969 22.359375 L 17.835938 22.359375 L 17.835938 30.609375 L 15.792969 30.609375 Z M 15.792969 22.359375 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,51.764706%,52.54902%);fill-opacity:1;" d="M 26.207031 31.546875 C 25.6875 31.546875 25.265625 31.128906 25.265625 30.609375 L 25.265625 28.261719 C 25.265625 27.742188 25.6875 27.324219 26.207031 27.324219 C 26.726562 27.324219 27.144531 27.742188 27.144531 28.261719 L 27.144531 30.609375 C 27.144531 31.128906 26.726562 31.546875 26.207031 31.546875 Z M 26.207031 31.546875 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(56.470588%,92.156863%,47.843137%);fill-opacity:1;" d="M 4.410156 31.546875 C 3.894531 31.546875 3.472656 31.128906 3.472656 30.609375 L 3.472656 28.449219 C 3.472656 27.933594 3.894531 27.511719 4.410156 27.511719 C 4.929688 27.511719 5.351562 27.933594 5.351562 28.449219 L 5.351562 30.609375 C 5.351562 31.128906 4.929688 31.546875 4.410156 31.546875 Z M 4.410156 31.546875 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,67.843137%,58.431373%);fill-opacity:1;" d="M 8.335938 31.546875 C 7.820312 31.546875 7.398438 31.128906 7.398438 30.609375 L 7.398438 27.207031 C 7.398438 26.6875 7.820312 26.265625 8.335938 26.265625 C 8.855469 26.265625 9.277344 26.6875 9.277344 27.207031 L 9.277344 30.609375 C 9.277344 31.128906 8.855469 31.546875 8.335938 31.546875 Z M 8.335938 31.546875 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,67.843137%,58.431373%);fill-opacity:1;" d="M 26.105469 23.050781 L 21.050781 16.535156 L 21.644531 15.863281 C 21.992188 15.863281 22.191406 15.460938 21.980469 15.179688 L 18.117188 8.335938 L 19.722656 7.710938 C 20.074219 7.710938 20.273438 7.304688 20.054688 7.023438 L 16.285156 3.230469 C 16.035156 2.910156 15.550781 2.910156 15.300781 3.230469 L 11.132812 7.464844 C 10.917969 7.742188 11.113281 8.148438 11.460938 8.152344 L 13.472656 8.398438 L 12.488281 13.75 C 12.277344 14.03125 12.476562 14.433594 12.824219 14.433594 L 10.535156 16.535156 L 5.480469 23.050781 C 5.242188 23.355469 5.460938 23.804688 5.847656 23.804688 L 25.742188 23.804688 C 26.128906 23.804688 26.34375 23.355469 26.105469 23.050781 Z M 26.105469 23.050781 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,81.960784%,42.352941%);fill-opacity:1;" d="M 31.0625 31.546875 L 0.9375 31.546875 C 0.421875 31.546875 0 31.128906 0 30.609375 C 0 30.089844 0.421875 29.667969 0.9375 29.667969 L 31.0625 29.667969 C 31.578125 29.667969 32 30.089844 32 30.609375 C 32 31.128906 31.578125 31.546875 31.0625 31.546875 Z M 31.0625 31.546875 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,51.764706%,52.54902%);fill-opacity:1;" d="M 21.050781 16.535156 L 22.121094 16.042969 C 22.46875 16.042969 22.667969 15.640625 22.457031 15.359375 L 16.816406 7.84375 L 20.011719 7.855469 C 20.363281 7.855469 20.5625 7.445312 20.347656 7.167969 L 16.320312 1.8125 C 16.195312 1.648438 15.976562 1.867188 15.792969 1.867188 L 15.792969 23.804688 L 25.742188 23.804688 C 26.128906 23.804688 26.34375 23.355469 26.105469 23.050781 Z M 21.050781 16.535156 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,81.960784%,42.352941%);fill-opacity:1;" d="M 10.488281 16.535156 C 10.535156 16.535156 10.578125 16.554688 10.613281 16.585938 L 12.613281 18.429688 C 12.875 18.664062 13.269531 18.667969 13.535156 18.441406 L 15.527344 16.59375 C 15.609375 16.515625 15.71875 16.476562 15.832031 16.476562 C 15.945312 16.480469 16.050781 16.523438 16.128906 16.605469 L 17.921875 18.378906 C 18.179688 18.613281 18.566406 18.621094 18.835938 18.394531 L 20.914062 16.648438 C 21 16.574219 21.109375 16.535156 21.222656 16.535156 L 23.417969 16.535156 C 23.765625 16.535156 23.964844 16.136719 23.753906 15.855469 L 18.113281 8.335938 L 16.253906 10.207031 C 15.980469 10.480469 15.539062 10.480469 15.265625 10.207031 L 13.46875 8.398438 L 7.832031 15.855469 C 7.621094 16.132812 7.820312 16.535156 8.167969 16.535156 Z M 10.488281 16.535156 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,67.843137%,58.431373%);fill-opacity:1;" d="M 18.113281 8.335938 L 16.253906 10.207031 C 16.125 10.335938 15.960938 10.402344 15.792969 10.410156 L 15.792969 16.480469 C 15.808594 16.476562 15.820312 16.476562 15.832031 16.476562 C 15.945312 16.480469 16.050781 16.523438 16.128906 16.605469 L 17.917969 18.378906 C 18.179688 18.613281 18.566406 18.621094 18.835938 18.394531 L 20.914062 16.648438 C 21 16.574219 21.109375 16.535156 21.222656 16.535156 L 23.417969 16.535156 C 23.765625 16.535156 23.964844 16.136719 23.753906 15.855469 Z M 18.113281 8.335938 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,67.843137%,58.431373%);fill-opacity:1;" d="M 31.0625 29.667969 L 15.792969 29.667969 L 15.792969 31.546875 L 31.0625 31.546875 C 31.578125 31.546875 32 31.128906 32 30.609375 C 32 30.089844 31.578125 29.667969 31.0625 29.667969 Z M 31.0625 29.667969 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(56.470588%,92.156863%,47.843137%);fill-opacity:1;" d="M 17.894531 8.5625 L 16.199219 10.265625 C 15.960938 10.507812 15.574219 10.507812 15.335938 10.265625 L 13.695312 8.617188 C 13.554688 8.476562 13.363281 8.394531 13.164062 8.394531 L 10.265625 8.359375 C 9.914062 8.355469 9.722656 7.953125 9.9375 7.675781 L 15.304688 0.695312 C 15.554688 0.371094 16.042969 0.371094 16.292969 0.695312 L 21.652344 7.660156 C 21.867188 7.941406 21.667969 8.347656 21.316406 8.347656 L 18.4375 8.335938 C 18.234375 8.335938 18.039062 8.417969 17.894531 8.5625 Z M 17.894531 8.5625 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,81.960784%,42.352941%);fill-opacity:1;" d="M 16.292969 0.695312 C 16.164062 0.53125 15.980469 0.449219 15.792969 0.453125 L 15.792969 10.445312 C 15.941406 10.4375 16.089844 10.378906 16.199219 10.265625 L 17.894531 8.5625 C 18.039062 8.417969 18.234375 8.335938 18.4375 8.335938 L 21.316406 8.347656 C 21.667969 8.347656 21.867188 7.941406 21.652344 7.660156 Z M 16.292969 0.695312 "/> | |||
</g> | |||
</svg> |
@ -0,0 +1,33 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32pt" height="32pt" viewBox="0 0 32 32" version="1.1"> | |||
<g id="surface1"> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(71.372549%,94.117647%,100%);fill-opacity:1;" d="M 28.351562 29.484375 C 28.351562 28.09375 22.820312 26.96875 16 26.96875 C 9.179688 26.96875 3.648438 28.09375 3.648438 29.484375 C 3.648438 30.875 9.179688 32 16 32 C 22.820312 32 28.351562 30.875 28.351562 29.484375 Z M 28.351562 29.484375 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(86.27451%,99.607843%,100%);fill-opacity:1;" d="M 16 26.96875 C 13.875 26.96875 11.875 27.078125 10.128906 27.269531 C 9.632812 27.324219 9.257812 27.746094 9.257812 28.242188 C 9.257812 28.824219 9.761719 29.277344 10.339844 29.214844 C 12.0625 29.023438 14.015625 28.921875 16 28.921875 C 17.230469 28.921875 18.449219 28.960938 19.609375 29.035156 C 20.171875 29.074219 20.644531 28.625 20.644531 28.0625 C 20.644531 27.546875 20.246094 27.121094 19.734375 27.085938 C 18.554688 27.011719 17.300781 26.96875 16 26.96875 Z M 16 26.96875 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 12.777344 27.058594 C 12.664062 27.0625 12.550781 27.070312 12.4375 27.078125 C 11.925781 27.109375 11.523438 27.535156 11.523438 28.050781 C 11.523438 28.613281 11.996094 29.0625 12.558594 29.027344 C 12.667969 29.019531 12.777344 29.015625 12.882812 29.007812 C 13.402344 28.980469 13.808594 28.550781 13.808594 28.03125 C 13.808594 27.472656 13.335938 27.027344 12.777344 27.058594 Z M 12.777344 27.058594 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(85.882353%,46.27451%,35.294118%);fill-opacity:1;" d="M 14.734375 19.597656 L 17.265625 19.597656 L 17.265625 29.757812 L 14.734375 29.757812 Z M 14.734375 19.597656 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(70.980392%,32.941176%,20.392157%);fill-opacity:1;" d="M 17.265625 19.597656 L 17.265625 22.988281 C 16.800781 22.914062 16.371094 22.730469 16 22.46875 C 15.628906 22.730469 15.199219 22.914062 14.734375 22.988281 L 14.734375 19.597656 Z M 17.265625 19.597656 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(70.980392%,32.941176%,20.392157%);fill-opacity:1;" d="M 17.265625 26.050781 L 17.265625 29.757812 L 14.734375 29.757812 L 14.734375 28.085938 C 14.804688 28.089844 14.878906 28.09375 14.953125 28.09375 C 16.144531 28.09375 17.125 27.203125 17.265625 26.050781 Z M 17.265625 26.050781 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(95.686275%,65.098039%,59.607843%);fill-opacity:1;" d="M 14.734375 24.246094 L 14.734375 26.136719 C 14.734375 26.664062 15.160156 27.089844 15.6875 27.089844 C 16.214844 27.089844 16.640625 26.664062 16.640625 26.136719 L 16.640625 24.246094 C 16.640625 23.71875 16.214844 23.289062 15.6875 23.289062 C 15.160156 23.289062 14.734375 23.71875 14.734375 24.246094 Z M 14.734375 24.246094 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(7.058824%,67.843137%,70.980392%);fill-opacity:1;" d="M 16 2.042969 C 16 8.382812 7.035156 18.191406 5.570312 19.746094 C 5.429688 19.898438 5.367188 20.105469 5.40625 20.304688 C 5.566406 21.117188 6.285156 21.730469 7.144531 21.730469 C 8.121094 21.730469 8.914062 20.9375 8.914062 19.957031 C 8.914062 20.9375 9.707031 21.730469 10.6875 21.730469 C 11.664062 21.730469 12.457031 20.9375 12.457031 19.957031 C 12.457031 20.9375 13.25 21.730469 14.226562 21.730469 C 15.207031 21.730469 16 20.9375 16 19.957031 C 16 20.9375 16.792969 21.730469 17.769531 21.730469 C 18.75 21.730469 19.542969 20.9375 19.542969 19.957031 C 19.542969 20.9375 20.335938 21.730469 21.3125 21.730469 C 22.292969 21.730469 23.085938 20.9375 23.085938 19.957031 C 23.085938 20.9375 23.878906 21.730469 24.855469 21.730469 C 25.714844 21.730469 26.433594 21.117188 26.59375 20.304688 C 26.632812 20.105469 26.570312 19.898438 26.429688 19.746094 C 24.964844 18.191406 16 8.382812 16 2.042969 Z M 16 2.042969 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(5.098039%,54.509804%,62.745098%);fill-opacity:1;" d="M 26.429688 19.746094 C 24.96875 18.191406 16 8.382812 16 2.042969 C 16 6.5625 11.445312 12.839844 8.300781 16.640625 C 8.5 16.679688 8.703125 16.699219 8.914062 16.699219 C 9.574219 16.699219 10.183594 16.492188 10.683594 16.136719 C 10.695312 16.144531 10.707031 16.152344 10.71875 16.160156 C 10.988281 16.980469 11.757812 17.574219 12.667969 17.574219 C 13.507812 17.574219 14.234375 17.0625 14.546875 16.335938 C 14.980469 16.570312 15.476562 16.699219 16 16.699219 C 16.660156 16.699219 17.269531 16.492188 17.769531 16.136719 C 18.273438 16.492188 18.882812 16.699219 19.542969 16.699219 C 19.914062 16.699219 20.269531 16.636719 20.597656 16.515625 C 21.003906 16.367188 21.441406 16.652344 21.445312 17.082031 C 21.445312 17.085938 21.445312 17.089844 21.445312 17.09375 C 21.445312 18.65625 20.988281 20.113281 20.203125 21.335938 C 20.507812 21.582031 20.890625 21.730469 21.3125 21.730469 C 22.292969 21.730469 23.085938 20.9375 23.085938 19.957031 C 23.085938 20.9375 23.878906 21.730469 24.855469 21.730469 C 25.714844 21.730469 26.433594 21.117188 26.59375 20.304688 C 26.632812 20.105469 26.570312 19.898438 26.429688 19.746094 Z M 26.429688 19.746094 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(34.117647%,91.764706%,90.196078%);fill-opacity:1;" d="M 24.613281 13.410156 C 23.832031 12.707031 21.335938 10.320312 19.230469 6.921875 L 12.769531 6.921875 C 10.664062 10.320312 8.167969 12.707031 7.386719 13.410156 C 7.214844 13.570312 7.136719 13.808594 7.191406 14.039062 C 7.375 14.820312 8.078125 15.398438 8.914062 15.398438 C 9.890625 15.398438 10.6875 14.605469 10.6875 13.628906 C 10.6875 14.605469 11.480469 15.398438 12.457031 15.398438 C 13.433594 15.398438 14.226562 14.605469 14.226562 13.628906 C 14.226562 14.605469 15.023438 15.398438 16 15.398438 C 16.976562 15.398438 17.769531 14.605469 17.769531 13.628906 C 17.769531 14.605469 18.5625 15.398438 19.542969 15.398438 C 20.519531 15.398438 21.3125 14.605469 21.3125 13.628906 C 21.3125 14.605469 22.105469 15.398438 23.085938 15.398438 C 23.921875 15.398438 24.625 14.820312 24.808594 14.039062 C 24.863281 13.808594 24.785156 13.570312 24.613281 13.410156 Z M 24.613281 13.410156 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(23.529412%,82.745098%,82.745098%);fill-opacity:1;" d="M 24.808594 14.039062 C 24.625 14.820312 23.921875 15.398438 23.085938 15.398438 C 22.597656 15.398438 22.152344 15.203125 21.832031 14.878906 C 21.511719 14.558594 21.3125 14.117188 21.3125 13.628906 C 21.3125 14.605469 20.519531 15.398438 19.542969 15.398438 C 19.304688 15.398438 19.078125 15.351562 18.875 15.269531 C 19.332031 15.015625 19.730469 14.660156 20.035156 14.238281 C 20.230469 13.972656 20.039062 13.605469 19.710938 13.609375 L 19.703125 13.609375 C 18.875 13.609375 18.160156 13.113281 17.835938 12.40625 C 17.476562 12.722656 17.003906 12.914062 16.488281 12.914062 C 15.941406 12.914062 15.425781 12.699219 15.039062 12.3125 C 14.914062 12.1875 14.804688 12.046875 14.71875 11.898438 L 14.71875 14.847656 C 14.414062 14.53125 14.230469 14.101562 14.230469 13.628906 C 14.230469 14.605469 13.4375 15.398438 12.457031 15.398438 C 11.480469 15.398438 10.6875 14.605469 10.6875 13.628906 C 10.6875 13.796875 10.710938 10.472656 10.710938 10.472656 C 10.574219 10.46875 10.347656 10.457031 10.21875 10.4375 C 11.042969 9.453125 11.9375 8.265625 12.769531 6.921875 L 19.230469 6.921875 C 21.335938 10.320312 23.832031 12.703125 24.613281 13.410156 C 24.785156 13.570312 24.863281 13.808594 24.808594 14.039062 Z M 24.808594 14.039062 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(34.117647%,91.764706%,90.196078%);fill-opacity:1;" d="M 17.921875 30.078125 L 18.515625 29.484375 C 18.707031 29.292969 18.664062 29.046875 18.410156 28.957031 C 18.292969 28.917969 18.164062 28.949219 18.082031 29.03125 L 17.703125 29.410156 L 17.703125 28.636719 C 17.703125 28.464844 17.5625 28.324219 17.386719 28.324219 C 17.214844 28.324219 17.074219 28.464844 17.074219 28.636719 L 17.074219 29.410156 L 16.703125 29.039062 C 16.640625 28.980469 16.5625 28.941406 16.476562 28.941406 C 16.195312 28.9375 16.054688 29.277344 16.25 29.476562 L 16.851562 30.078125 C 16.996094 30.21875 17.1875 30.296875 17.390625 30.296875 C 17.589844 30.296875 17.78125 30.21875 17.921875 30.078125 Z M 17.921875 30.078125 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(7.058824%,67.843137%,70.980392%);fill-opacity:1;" d="M 23.828125 28.210938 L 24.421875 27.617188 C 24.613281 27.429688 24.566406 27.183594 24.3125 27.09375 C 24.195312 27.050781 24.070312 27.082031 23.988281 27.167969 L 23.605469 27.546875 L 23.605469 26.773438 C 23.605469 26.601562 23.464844 26.460938 23.292969 26.460938 C 23.121094 26.460938 22.980469 26.601562 22.980469 26.773438 L 22.980469 27.546875 L 22.605469 27.175781 C 22.546875 27.113281 22.464844 27.078125 22.382812 27.074219 C 22.101562 27.070312 21.957031 27.414062 22.15625 27.609375 L 22.757812 28.210938 C 22.898438 28.355469 23.09375 28.433594 23.292969 28.433594 C 23.492188 28.433594 23.6875 28.355469 23.828125 28.210938 Z M 23.828125 28.210938 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(7.058824%,67.843137%,70.980392%);fill-opacity:1;" d="M 15.339844 30.421875 L 15.933594 29.828125 C 16.125 29.640625 16.078125 29.390625 15.824219 29.304688 C 15.707031 29.261719 15.582031 29.292969 15.5 29.378906 L 15.117188 29.757812 L 15.117188 28.984375 C 15.117188 28.8125 14.976562 28.671875 14.804688 28.671875 C 14.632812 28.671875 14.492188 28.8125 14.492188 28.984375 L 14.492188 29.757812 L 14.117188 29.382812 C 14.058594 29.324219 13.976562 29.285156 13.894531 29.285156 C 13.613281 29.28125 13.46875 29.621094 13.667969 29.820312 L 14.269531 30.421875 C 14.410156 30.566406 14.605469 30.644531 14.804688 30.644531 C 15.003906 30.644531 15.199219 30.566406 15.339844 30.421875 Z M 15.339844 30.421875 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(23.529412%,82.745098%,82.745098%);fill-opacity:1;" d="M 7.785156 28.550781 L 8.378906 27.957031 C 8.566406 27.765625 8.523438 27.519531 8.269531 27.429688 C 8.152344 27.390625 8.027344 27.421875 7.941406 27.503906 L 7.5625 27.886719 L 7.5625 27.113281 C 7.5625 26.9375 7.421875 26.796875 7.25 26.796875 C 7.078125 26.796875 6.9375 26.9375 6.9375 27.113281 L 6.9375 27.886719 L 6.5625 27.511719 C 6.503906 27.453125 6.421875 27.414062 6.339844 27.414062 C 6.054688 27.410156 5.914062 27.75 6.113281 27.949219 L 6.714844 28.550781 C 6.855469 28.691406 7.050781 28.773438 7.25 28.773438 C 7.449219 28.773438 7.640625 28.691406 7.785156 28.550781 Z M 7.785156 28.550781 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(23.529412%,82.745098%,82.745098%);fill-opacity:1;" d="M 7.640625 17.425781 C 7.539062 17.546875 7.4375 17.660156 7.339844 17.773438 C 6.792969 18.40625 7.246094 19.386719 8.078125 19.386719 C 8.363281 19.386719 8.632812 19.265625 8.820312 19.050781 C 8.917969 18.933594 9.023438 18.8125 9.125 18.691406 C 9.667969 18.058594 9.214844 17.082031 8.382812 17.082031 C 8.097656 17.082031 7.824219 17.207031 7.640625 17.425781 Z M 7.640625 17.425781 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(64.705882%,97.647059%,95.294118%);fill-opacity:1;" d="M 9.5625 13.617188 C 10.09375 13.066406 10.722656 12.371094 11.382812 11.558594 C 11.808594 11.03125 11.433594 10.246094 10.757812 10.246094 C 10.519531 10.246094 10.292969 10.351562 10.140625 10.53125 C 9.472656 11.324219 8.855469 11.980469 8.355469 12.484375 C 8.011719 12.832031 8.050781 13.40625 8.445312 13.699219 C 8.449219 13.703125 8.453125 13.703125 8.460938 13.707031 C 8.796875 13.960938 9.269531 13.921875 9.5625 13.617188 Z M 9.5625 13.617188 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(71.372549%,94.117647%,100%);fill-opacity:1;" d="M 22.804688 7.234375 C 21.742188 6.402344 17.996094 3.320312 16.5625 0.351562 C 16.457031 0.136719 16.238281 0 16 0 C 15.761719 0 15.542969 0.136719 15.4375 0.351562 C 14.003906 3.320312 10.257812 6.402344 9.195312 7.234375 C 8.996094 7.390625 8.90625 7.652344 8.96875 7.898438 C 9.167969 8.660156 9.859375 9.226562 10.6875 9.226562 C 10.691406 9.226562 10.695312 9.226562 10.699219 9.226562 C 11.339844 9.21875 11.867188 9.722656 11.867188 10.363281 L 11.867188 15.523438 C 11.867188 15.964844 12.226562 16.324219 12.667969 16.324219 C 13.109375 16.324219 13.46875 15.964844 13.46875 15.523438 L 13.46875 10.101562 C 13.46875 9.566406 13.847656 9.101562 14.378906 9.003906 C 14.386719 9 14.398438 9 14.40625 9 C 15.070312 8.871094 15.6875 9.382812 15.6875 10.058594 L 15.6875 10.863281 C 15.6875 11.304688 16.046875 11.664062 16.488281 11.664062 C 16.929688 11.664062 17.289062 11.304688 17.289062 10.863281 L 17.289062 9.894531 C 17.289062 9.503906 17.574219 9.171875 17.960938 9.109375 C 17.96875 9.109375 17.976562 9.109375 17.984375 9.109375 C 18.464844 9.03125 18.902344 9.402344 18.902344 9.890625 L 18.902344 11.558594 C 18.902344 12 19.261719 12.359375 19.703125 12.359375 C 20.144531 12.359375 20.503906 12 20.503906 11.558594 L 20.503906 10.007812 C 20.503906 9.566406 20.863281 9.222656 21.304688 9.226562 L 21.3125 9.226562 C 22.140625 9.226562 22.832031 8.660156 23.027344 7.898438 C 23.09375 7.652344 23.003906 7.390625 22.804688 7.234375 Z M 22.804688 7.234375 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(45.098039%,88.235294%,100%);fill-opacity:1;" d="M 23.03125 7.898438 C 22.832031 8.660156 22.140625 9.226562 21.3125 9.226562 L 21.304688 9.226562 C 20.863281 9.222656 20.503906 9.566406 20.503906 10.007812 L 20.503906 11.558594 C 20.503906 11.777344 20.414062 11.980469 20.269531 12.125 C 20.125 12.269531 19.921875 12.359375 19.703125 12.359375 C 19.261719 12.359375 18.902344 12 18.902344 11.558594 L 18.902344 9.890625 C 18.902344 9.402344 18.464844 9.03125 17.984375 9.109375 C 17.976562 9.109375 17.96875 9.109375 17.960938 9.109375 C 17.574219 9.171875 17.289062 9.5 17.289062 9.894531 L 17.289062 10.863281 C 17.289062 11.082031 17.199219 11.285156 17.054688 11.429688 C 16.910156 11.574219 16.707031 11.664062 16.488281 11.664062 C 16.046875 11.664062 15.6875 11.304688 15.6875 10.863281 L 15.6875 10.058594 C 15.6875 9.769531 15.574219 9.511719 15.394531 9.320312 C 17.78125 9.019531 19.671875 7.117188 19.953125 4.722656 C 21.152344 5.90625 22.292969 6.832031 22.804688 7.234375 C 23.003906 7.390625 23.09375 7.652344 23.03125 7.898438 Z M 23.03125 7.898438 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(86.27451%,99.607843%,100%);fill-opacity:1;" d="M 13.46875 13.371094 L 13.46875 11.800781 C 13.46875 11.355469 13.109375 11 12.667969 11 C 12.226562 11 11.867188 11.355469 11.867188 11.800781 L 11.867188 13.371094 C 11.867188 13.8125 12.226562 14.171875 12.667969 14.171875 C 13.109375 14.171875 13.46875 13.8125 13.46875 13.371094 Z M 13.46875 13.371094 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(86.27451%,99.607843%,100%);fill-opacity:1;" d="M 17.945312 17.53125 C 17.527344 17.53125 17.1875 17.195312 17.1875 16.777344 L 17.1875 16.554688 C 17.1875 16.136719 17.527344 15.800781 17.945312 15.800781 C 18.363281 15.800781 18.699219 16.136719 18.699219 16.554688 L 18.699219 16.777344 C 18.699219 17.195312 18.363281 17.53125 17.945312 17.53125 Z M 17.945312 17.53125 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(86.27451%,99.607843%,100%);fill-opacity:1;" d="M 19.222656 8.246094 C 18.804688 8.246094 18.464844 7.910156 18.464844 7.492188 L 18.464844 7.273438 C 18.464844 6.855469 18.804688 6.515625 19.222656 6.515625 C 19.640625 6.515625 19.976562 6.855469 19.976562 7.273438 L 19.976562 7.492188 C 19.976562 7.910156 19.640625 8.246094 19.222656 8.246094 Z M 19.222656 8.246094 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(86.27451%,99.607843%,100%);fill-opacity:1;" d="M 16.898438 6.4375 C 16.480469 6.4375 16.140625 6.097656 16.140625 5.679688 L 16.140625 5.460938 C 16.140625 5.042969 16.480469 4.703125 16.898438 4.703125 C 17.316406 4.703125 17.652344 5.042969 17.652344 5.460938 L 17.652344 5.679688 C 17.652344 6.097656 17.316406 6.4375 16.898438 6.4375 Z M 16.898438 6.4375 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(86.27451%,99.607843%,100%);fill-opacity:1;" d="M 14.929688 14.085938 C 14.511719 14.085938 14.175781 13.746094 14.175781 13.328125 L 14.175781 13.109375 C 14.175781 12.691406 14.511719 12.355469 14.929688 12.355469 C 15.347656 12.355469 15.6875 12.691406 15.6875 13.109375 L 15.6875 13.328125 C 15.6875 13.746094 15.347656 14.085938 14.929688 14.085938 Z M 14.929688 14.085938 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(86.27451%,99.607843%,100%);fill-opacity:1;" d="M 11.867188 18.714844 C 11.449219 18.714844 11.109375 18.375 11.109375 17.957031 L 11.109375 17.738281 C 11.109375 17.320312 11.449219 16.984375 11.867188 16.984375 C 12.285156 16.984375 12.621094 17.320312 12.621094 17.738281 L 12.621094 17.957031 C 12.621094 18.375 12.285156 18.714844 11.867188 18.714844 Z M 11.867188 18.714844 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(86.27451%,99.607843%,100%);fill-opacity:1;" d="M 21.046875 19.914062 C 20.628906 19.914062 20.289062 19.574219 20.289062 19.15625 L 20.289062 18.9375 C 20.289062 18.519531 20.628906 18.183594 21.046875 18.183594 C 21.460938 18.183594 21.800781 18.519531 21.800781 18.9375 L 21.800781 19.15625 C 21.800781 19.574219 21.460938 19.914062 21.046875 19.914062 Z M 21.046875 19.914062 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(86.27451%,99.607843%,100%);fill-opacity:1;" d="M 14.988281 2.851562 C 14.984375 2.847656 14.980469 2.84375 14.976562 2.839844 C 14.582031 2.519531 14.007812 2.570312 13.679688 2.960938 C 12.960938 3.820312 12.167969 4.625 11.4375 5.308594 C 11.015625 5.703125 11.046875 6.378906 11.5 6.734375 C 11.507812 6.738281 11.511719 6.742188 11.515625 6.746094 C 11.871094 7.023438 12.375 7 12.703125 6.695312 C 13.492188 5.957031 14.339844 5.097656 15.113281 4.171875 C 15.445312 3.773438 15.390625 3.183594 14.988281 2.851562 Z M 14.988281 2.851562 "/> | |||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 12.464844 4.300781 C 12.460938 4.304688 12.457031 4.308594 12.453125 4.3125 C 12.117188 4.660156 12.113281 5.207031 12.441406 5.558594 C 12.457031 5.578125 12.472656 5.59375 12.492188 5.613281 C 12.84375 5.988281 13.4375 5.996094 13.796875 5.625 C 13.800781 5.621094 13.808594 5.613281 13.8125 5.609375 C 14.164062 5.25 14.152344 4.671875 13.789062 4.324219 C 13.769531 4.308594 13.753906 4.292969 13.734375 4.273438 C 13.378906 3.933594 12.8125 3.945312 12.464844 4.300781 Z M 12.464844 4.300781 "/> | |||
</g> | |||
</svg> |
@ -0,0 +1,93 @@ | |||
import axios from "axios"; | |||
import { readFileSync } from 'fs'; | |||
import { ShuishanTreeItem } from "./shuishan"; | |||
export class APIService{ | |||
private items:Array<ShuishanTreeItem> = [] | |||
// private domain: string = "http://113.31.111.149"; | |||
private domain: string = "http://127.0.0.1:5000"; | |||
async getPids():Promise<Array<ShuishanTreeItem>>{ | |||
const url = this.domain + "/get-problem-items/"; | |||
const response = await axios.get(url,{ | |||
headers:{ | |||
'content-type':"application/json" | |||
} | |||
}) | |||
for(let i=0; i < response.data.length; i++){ | |||
const pid = { | |||
pid:response.data[i].id, | |||
title:response.data[i].title | |||
} | |||
// console.log(response.data.pids[i]) | |||
this.items.push(new ShuishanTreeItem(pid)) | |||
} | |||
return this.items; | |||
} | |||
async getDes(pid:string):Promise<string>{ | |||
const url = this.domain + `/get-problem-description/${pid}/`; | |||
const response = await axios.get(url,{ | |||
headers:{ | |||
'content-type':"text/plain" | |||
} | |||
}) | |||
// console.log(response.data); | |||
return response.data; | |||
} | |||
async testSolution(filePath: string):Promise<string>{ | |||
filePath = filePath.toString().substring(7); | |||
let code = readFileSync(filePath).toString(); | |||
let pid:any = filePath.split('/'); | |||
pid = pid[pid.length-1].split('.')[0]; | |||
pid = pid.split('-')[0]; | |||
const url = this.domain + "/case_test/" | |||
const response = await axios.post(url,{ | |||
headers:{ | |||
'content-type':"application/json" | |||
}, | |||
pid: pid, | |||
code: code | |||
}) | |||
return response.data; | |||
} | |||
async checkSolution(filePath: string):Promise<String>{ | |||
filePath = filePath.toString().substring(7); | |||
let code = readFileSync(filePath).toString(); | |||
let pid:any = filePath.split('/'); | |||
pid = pid[pid.length-1].split('.')[0]; | |||
pid = pid.split('-')[0]; | |||
const url = this.domain + "/check-logic-error/" | |||
const response = await axios.post(url,{ | |||
headers:{ | |||
'content-type':"application/json" | |||
}, | |||
pid: pid, | |||
code: code | |||
}) | |||
return response.data; | |||
} | |||
async submitSolution(filePath: string):Promise<string>{ | |||
filePath = filePath.toString().substring(7); | |||
let code = readFileSync(filePath).toString(); | |||
let pid:any = filePath.split('/'); | |||
pid = pid[pid.length-1].split('.')[0]; | |||
pid = pid.split('-')[0]; | |||
const url = this.domain + "/submit/" | |||
const response = await axios.post(url,{ | |||
headers:{ | |||
'content-type':"application/json" | |||
}, | |||
pid: pid, | |||
code: code | |||
}) | |||
return response.data; | |||
} | |||
} |
@ -0,0 +1,21 @@ | |||
import { TreeItem, TreeItemCollapsibleState } from "vscode"; | |||
export interface Shuishan{ | |||
pid:string; | |||
title:string; | |||
} | |||
export class ShuishanTreeItem extends TreeItem{ | |||
constructor(info:Shuishan){ | |||
super("",TreeItemCollapsibleState.None); | |||
this.label = info.pid + ". " + info.title; | |||
this.id = info.pid; | |||
// this.description = ''; | |||
// this.tooltip = ''; | |||
this.command = { | |||
title:"查看题目描述", | |||
command:"ShuiShan.click", | |||
arguments:[info.pid, info.title] | |||
} | |||
} | |||
} |
@ -0,0 +1,23 @@ | |||
import { TreeView, TreeDataProvider } from "vscode"; | |||
import { APIService } from "./service"; | |||
import { Shuishan, ShuishanTreeItem } from "./shuishan"; | |||
export class ShuishanDataProvider implements TreeDataProvider<ShuishanTreeItem> { | |||
private service: APIService; | |||
constructor(service:APIService){ | |||
this.service = service | |||
} | |||
getTreeItem(element: ShuishanTreeItem){ | |||
return element; | |||
} | |||
getChildren(element: ShuishanTreeItem){ | |||
return this.service.getPids() | |||
} | |||
getParent(element: ShuishanTreeItem){ | |||
return null; | |||
} | |||
} |
@ -0,0 +1,23 @@ | |||
import * as path from 'path'; | |||
import { runTests } from 'vscode-test'; | |||
async function main() { | |||
try { | |||
// The folder containing the Extension Manifest package.json | |||
// Passed to `--extensionDevelopmentPath` | |||
const extensionDevelopmentPath = path.resolve(__dirname, '../../'); | |||
// The path to test runner | |||
// Passed to --extensionTestsPath | |||
const extensionTestsPath = path.resolve(__dirname, './suite/index'); | |||
// Download VS Code, unzip it and run the integration test | |||
await runTests({ extensionDevelopmentPath, extensionTestsPath }); | |||
} catch (err) { | |||
console.error('Failed to run tests'); | |||
process.exit(1); | |||
} | |||
} | |||
main(); |
@ -0,0 +1,15 @@ | |||
import * as assert from 'assert'; | |||
// You can import and use all API from the 'vscode' module | |||
// as well as import your extension to test it | |||
import * as vscode from 'vscode'; | |||
// import * as myExtension from '../../extension'; | |||
suite('Extension Test Suite', () => { | |||
vscode.window.showInformationMessage('Start all tests.'); | |||
test('Sample test', () => { | |||
assert.equal(-1, [1, 2, 3].indexOf(5)); | |||
assert.equal(-1, [1, 2, 3].indexOf(0)); | |||
}); | |||
}); |
@ -0,0 +1,38 @@ | |||
import * as path from 'path'; | |||
import * as Mocha from 'mocha'; | |||
import * as glob from 'glob'; | |||
export function run(): Promise<void> { | |||
// Create the mocha test | |||
const mocha = new Mocha({ | |||
ui: 'tdd', | |||
color: true | |||
}); | |||
const testsRoot = path.resolve(__dirname, '..'); | |||
return new Promise((c, e) => { | |||
glob('**/**.test.js', { cwd: testsRoot }, (err, files) => { | |||
if (err) { | |||
return e(err); | |||
} | |||
// Add files to the test suite | |||
files.forEach(f => mocha.addFile(path.resolve(testsRoot, f))); | |||
try { | |||
// Run the mocha test | |||
mocha.run(failures => { | |||
if (failures > 0) { | |||
e(new Error(`${failures} tests failed.`)); | |||
} else { | |||
c(); | |||
} | |||
}); | |||
} catch (err) { | |||
console.error(err); | |||
e(err); | |||
} | |||
}); | |||
}); | |||
} |
@ -0,0 +1,21 @@ | |||
{ | |||
"compilerOptions": { | |||
"module": "commonjs", | |||
"target": "es6", | |||
"outDir": "out", | |||
"lib": [ | |||
"es6" | |||
], | |||
"sourceMap": true, | |||
"rootDir": "src", | |||
"strict": true /* enable all strict type-checking options */ | |||
/* Additional Checks */ | |||
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ | |||
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ | |||
// "noUnusedParameters": true, /* Report errors on unused parameters. */ | |||
}, | |||
"exclude": [ | |||
"node_modules", | |||
".vscode-test" | |||
] | |||
} |
@ -0,0 +1,133 @@ | |||
id,node_type | |||
3,LOCAL DOWN | |||
9,<operator>.assignment UP | |||
52,<operator>.lessThan DOWN | |||
61,ForStatement UP | |||
128,<operator>.preDecrement DOWN | |||
53,<operator>.computedMemberAccess UP | |||
4,TYPE_FULL_NAME DOWN | |||
60,GotoStatement UP | |||
103,COMMENT DOWN | |||
34,<operator>.equals UP | |||
67,<operator>.lessEqualsThan UP | |||
46,METHOD_PARAMETER_IN DOWN | |||
94,ContinueStatement DOWN | |||
16,BLOCK UP | |||
72,<operator>.greaterEqualsThan DOWN | |||
120,<operator>.assignmentDivision DOWN | |||
132,TryStatement UP | |||
43,WhileStatement DOWN | |||
109,ConditionalExpression UP | |||
69,BreakStatement DOWN | |||
78,NAMESPACE_BLOCK DOWN | |||
108,<operator>.logicalOr DOWN | |||
82,TYPE_DECL DOWN | |||
102,FILE DOWN | |||
66,<operator>.division DOWN | |||
114,<operator>.and UP | |||
14,<operator>.addressOf DOWN | |||
106,<operator>.assignmentMultiplication DOWN | |||
26,<operator>.cast UP | |||
80,MEMBER UP | |||
21,METHOD UP | |||
49,<operator>.greaterThan UP | |||
96,RETURN UP | |||
112,<operator>.preIncrement DOWN | |||
110,ConditionalExpression DOWN | |||
111,ALIAS_TYPE_FULL_NAME DOWN | |||
12,CALL UP | |||
23,<operator>.sizeOf DOWN | |||
44,<operator>.minus UP | |||
100,SwitchStatement DOWN | |||
92,<operator>.indirection UP | |||
124,<operator>.logicalNot UP | |||
71,<operator>.greaterEqualsThan UP | |||
17,BLOCK DOWN | |||
105,<operator>.assignmentMultiplication UP | |||
6,IDENTIFIER UP | |||
15,LITERAL UP | |||
33,<operator>.minus DOWN | |||
11,CALL DOWN | |||
28,CastTarget DOWN | |||
122,<operator>.or DOWN | |||
99,SwitchStatement UP | |||
123,<operator>.logicalNot DOWN | |||
41,<operator>.sizeOf UP | |||
50,<operator>.greaterThan DOWN | |||
37,IfStatement DOWN | |||
116,ALIAS_TYPE_FULL_NAME UP | |||
32,<operator>.notEquals DOWN | |||
121,<operator>.or UP | |||
25,CastTarget UP | |||
119,<operator>.assignmentDivision UP | |||
64,<operator>.postIncrement UP | |||
63,<operator>.postIncrement DOWN | |||
85,<operator>.memberAccess DOWN | |||
31,<operator>.notEquals UP | |||
58,<operator>.addition DOWN | |||
7,IDENTIFIER DOWN | |||
57,<operator>.addition UP | |||
95,ContinueStatement UP | |||
1,NAME UP | |||
2,LOCAL UP | |||
59,GotoStatement DOWN | |||
56,<operator>.subtraction DOWN | |||
75,<operator>.postDecrement DOWN | |||
42,WhileStatement UP | |||
36,IfStatement UP | |||
84,<operator>.memberAccess UP | |||
98,Label DOWN | |||
125,<operator>.plus DOWN | |||
8,NAME DOWN | |||
77,NAMESPACE_BLOCK UP | |||
10,<operator>.assignment DOWN | |||
70,BreakStatement UP | |||
87,<operator>.modulo DOWN | |||
127,<operator>.preDecrement UP | |||
54,<operator>.computedMemberAccess DOWN | |||
104,COMMENT UP | |||
73,<operator>.assignmentMinus UP | |||
83,MEMBER DOWN | |||
19,RETURN DOWN | |||
113,<operator>.preIncrement UP | |||
13,LITERAL DOWN | |||
22,METHOD DOWN | |||
18,<operator>.addressOf UP | |||
65,<operator>.division UP | |||
45,METHOD_PARAMETER_IN UP | |||
90,<operator>.assignmentPlus UP | |||
101,FILE UP | |||
107,<operator>.logicalOr UP | |||
93,<operator>.indirection DOWN | |||
74,<operator>.assignmentMinus DOWN | |||
27,<operator>.cast DOWN | |||
30,<operator>.indirectMemberAccess DOWN | |||
79,METHOD_RETURN DOWN | |||
86,<operator>.modulo UP | |||
129,<operator>.arithmeticShiftRight UP | |||
131,TryStatement DOWN | |||
47,<operator>.logicalAnd UP | |||
91,<operator>.assignmentPlus DOWN | |||
29,<operator>.indirectMemberAccess UP | |||
48,<operator>.logicalAnd DOWN | |||
117,DoStatement UP | |||
81,TYPE_DECL UP | |||
97,Label UP | |||
5,TYPE_FULL_NAME UP | |||
40,SizeofOperand UP | |||
62,ForStatement DOWN | |||
115,<operator>.and DOWN | |||
89,<operator>.multiplication DOWN | |||
130,<operator>.arithmeticShiftRight DOWN | |||
55,<operator>.subtraction UP | |||
76,<operator>.postDecrement UP | |||
24,SizeofOperand DOWN | |||
35,<operator>.equals DOWN | |||
38,ElseStatement DOWN | |||
88,<operator>.multiplication UP | |||
68,<operator>.lessEqualsThan DOWN | |||
51,<operator>.lessThan UP | |||
118,DoStatement DOWN | |||
20,METHOD_RETURN UP | |||
39,ElseStatement UP | |||
126,<operator>.plus UP |
@ -0,0 +1,39 @@ | |||
from math import ceil | |||
from typing import Optional | |||
import logging | |||
from argparse import ArgumentParser | |||
import sys | |||
import os | |||
class Config: | |||
def __init__(self): | |||
self.__logger: Optional[logging.Logger] = None | |||
self.set_defaults() | |||
def set_defaults(self): | |||
self.NUM_TRAIN_EPOCHS = 100 | |||
self.SAVE_EVERY_EPOCHS = 5 | |||
self.TRAIN_BATCH_SIZE = 64 | |||
# model hyper-params | |||
self.categories = 10 | |||
# self.learning_rate=0.001 | |||
# self.decay_rate=0.9 | |||
self.path_vocab_size = 27500 | |||
self.token_vocab_size = 1500 | |||
self.MAX_CONTEXTS = 200 | |||
self.MAX_TOKEN_VOCAB_SIZE = 1301136 | |||
self.MAX_PATH_VOCAB_SIZE = 911417 | |||
self.DEFAULT_EMBEDDINGS_SIZE = 64 | |||
self.TOKEN_EMBEDDINGS_SIZE = self.DEFAULT_EMBEDDINGS_SIZE | |||
self.PATH_EMBEDDINGS_SIZE = self.DEFAULT_EMBEDDINGS_SIZE | |||
self.CODE_VECTOR_SIZE = self.context_vector_size | |||
self.TARGET_EMBEDDINGS_SIZE = self.CODE_VECTOR_SIZE | |||
self.DROPOUT_KEEP_RATE = 0.5 | |||
@property | |||
def context_vector_size(self) -> int: | |||
# The context vector is actually a concatenation of the embedded | |||
# source & target vectors and the embedded path vector. | |||
return self.PATH_EMBEDDINGS_SIZE + 2 * self.TOKEN_EMBEDDINGS_SIZE |
@ -0,0 +1,80 @@ | |||
import tensorflow as tf | |||
try: | |||
import tensorflow.python.keras as keras | |||
from tensorflow.python.keras import layers | |||
from tensorflow.python.keras import backend as K | |||
except: | |||
import tensorflow.keras as keras | |||
from tensorflow.keras import layers | |||
from tensorflow.keras import backend as K | |||
class Attention_layer(layers.Layer): | |||
def __init__(self, **kwargs): | |||
super(Attention_layer, self).__init__(**kwargs) | |||
def build(self, inputs_shape): | |||
assert isinstance(inputs_shape, list) | |||
# inputs: --> size | |||
# [(None,max_contents,code_vector_size),(None,max_contents)] | |||
# the second input is optional | |||
if (len(inputs_shape) < 1 or len(inputs_shape) > 2): | |||
raise ValueError("AttentionLayer expect one or two inputs.") | |||
# (None,max_contents,code_vector_size) | |||
input_shape = inputs_shape[0] | |||
if (len(input_shape) != 3): | |||
raise ValueError("Input shape for AttentionLayer shoud be of 3 dimensions.") | |||
self.input_length = int(input_shape[1]) | |||
self.input_dim = int(input_shape[2]) | |||
attention_param_shape = (self.input_dim, 1) | |||
self.attention_param = self.add_weight( | |||
name='attention_param', | |||
shape=attention_param_shape, | |||
initializer='uniform', | |||
trainable=True, | |||
dtype=tf.float32 | |||
) | |||
super(Attention_layer, self).build(input_shape) | |||
def call(self, inputs, **kwargs): | |||
assert isinstance(inputs, list) | |||
# inputs: | |||
# [(None,max_contents,code_vector_size),(None,max_contents)] | |||
# the second input is optional | |||
if (len(inputs) < 1 or len(inputs) > 2): | |||
raise ValueError("AttentionLayer expect one or two inputs.") | |||
actual_input = inputs[0] | |||
mask = inputs[1] if (len(inputs) > 1) else None | |||
if mask is not None and not (((len(mask.shape) == 3 and mask.shape[2] == 1) or (len(mask.shape) == 2)) and ( | |||
mask.shape[1] == self.input_length)): | |||
raise ValueError( | |||
"`mask` shoud be of shape (batch, input_length) or (batch, input_length, 1) when calling AttentionLayer.") | |||
assert actual_input.shape[-1] == self.attention_param.shape[0] | |||
# (batch, input_length, input_dim) * (input_dim, 1) ==> (batch, input_length, 1) | |||
attention_weights = K.dot(actual_input, self.attention_param) | |||
if mask is not None: | |||
if (len(mask.shape) == 2): | |||
mask = K.expand_dims(mask, axis=2) # (batch, input_dim, 1) | |||
mask = K.log(mask) # e.g. K.exp(K.log(0.)) = 0 K.exp(K.log(1.)) =1 | |||
attention_weights += mask | |||
attention_weights = K.softmax(attention_weights, axis=1) | |||
result = K.sum(actual_input * attention_weights, axis=1) | |||
return result, attention_weights | |||
def compute_output_shape(self, input_shape): | |||
return input_shape[0], input_shape[2] # (batch,input_length,input_dim) --> (batch,input_dim) |
@ -0,0 +1,203 @@ | |||
import sys | |||
sys.path.append('../') | |||
import tensorflow as tf | |||
try: | |||
import tensorflow.python.keras as keras | |||
from tensorflow.python.keras import layers | |||
import tensorflow.python.keras.backend as K | |||
except: | |||
import tensorflow.keras as keras | |||
from tensorflow.keras import layers | |||
import tensorflow.keras.backend as K | |||
from typing import Optional | |||
from PIPE.config import Config | |||
from PIPE.keras_attention_layer import Attention_layer | |||
class Code2VecModel(): | |||
def __init__(self,config: Config): | |||
self.keras_train_model: Optional[keras.Model] = None | |||
self.config = config | |||
##################################################搭建模型结构函数######################################################## | |||
def _create_keras_model(self): | |||
path_source_token_input = layers.Input((self.config.MAX_CONTEXTS,), dtype=tf.int32) | |||
path_input = layers.Input((self.config.MAX_CONTEXTS,), dtype=tf.int32) | |||
path_target_token_input = layers.Input((self.config.MAX_CONTEXTS,), dtype=tf.int32) | |||
context_valid_mask = layers.Input((self.config.MAX_CONTEXTS,)) | |||
# path embedding layer | |||
# (None, max_contents) -> (None,max_contents,path_embedding_size) | |||
paths_embedded = layers.Embedding( | |||
self.config.path_vocab_size, self.config.PATH_EMBEDDINGS_SIZE, name = 'path_embedding' | |||
)(path_input) | |||
# terminal embedding layer | |||
# (None, max_contents) -> (None,max_contents,token_embedding_size) | |||
token_embedding_shared_layer = layers.Embedding( | |||
self.config.token_vocab_size, self.config.TOKEN_EMBEDDINGS_SIZE, name = 'token_embedding' | |||
) | |||
path_source_token_embedded = token_embedding_shared_layer(path_source_token_input) | |||
path_target_token_embedded = token_embedding_shared_layer(path_target_token_input) | |||
# concatenate layer: paths -> [source, path, target] | |||
# [3 * (None,max_contents, token_embedding_size)] -> (None, max_contents,3*embedding_size) | |||
context_embedded = layers.Concatenate()([path_source_token_embedded, paths_embedded, path_target_token_embedded]) | |||
context_embedded = layers.Dropout(1 - self.config.DROPOUT_KEEP_RATE)(context_embedded) | |||
# Dense layer: (None,max_contents,3*embedding_size) -> (None,max_contents, code_vector_size) | |||
context_after_dense = layers.TimeDistributed( | |||
layers.Dense(self.config.CODE_VECTOR_SIZE, use_bias=False, activation='tanh') | |||
)(context_embedded) | |||
# attention layer: (None, max_contents,code_vector_size) -> (None,code_vector_size) | |||
code_vectors, attention_weights = Attention_layer(name='attention')( | |||
[context_after_dense, context_valid_mask] | |||
) | |||
""" | |||
下面是用C2AE分类器进行分类的模型 | |||
""" | |||
Fx = layers.Dense( | |||
186 , use_bias=True,activation=None,name='Fx' | |||
)(code_vectors) | |||
Fx_relu = tf.tanh(Fx) | |||
Fx_dropout = layers.Dropout(0.5)(Fx_relu) | |||
targets_input = layers.Input((self.config.categories,), dtype=tf.float32) | |||
targets_hidden = layers.Dense( | |||
186, use_bias=True,activation=None,name='targets_hidden' | |||
)(targets_input) | |||
targets_hidden_relu = tf.tanh(targets_hidden) | |||
targets_hidden_dropout = layers.Dropout(0.5)(targets_hidden_relu) | |||
targets_output = layers.Dense( | |||
186, use_bias=True,activation=None,name='targets_embedding' | |||
)(targets_hidden_dropout) | |||
targets_output_relu = tf.tanh(targets_output) | |||
targets_output_dropout = layers.Dropout(0.5)(targets_output_relu) | |||
targets_loss = layers.subtract([targets_output_dropout,Fx_dropout],name='targets_loss') | |||
Fd1 = layers.Dense( | |||
186, use_bias=True,activation=None,name='Fd1' | |||
)(Fx_dropout) | |||
Fd_relu1 = tf.tanh(Fd1) | |||
Fd_dropout1 = layers.Dropout(0.5)(Fd_relu1) | |||
Fd = layers.Dense( | |||
186, use_bias=True, activation=None, name='Fd' | |||
)(Fd_dropout1) | |||
Fd_relu = tf.tanh(Fd) | |||
Fd_dropout = layers.Dropout(0.5)(Fd_relu) | |||
target_index_3 = layers.Dense( | |||
self.config.categories, use_bias=True,activation='sigmoid',name='target_index_3' | |||
)(Fd_dropout) | |||
inputs = [path_source_token_input, path_input, path_target_token_input, context_valid_mask, targets_input] | |||
self.keras_train_model = keras.Model(inputs = inputs, outputs = [target_index_3,targets_loss]) | |||
print("------------------create_keras_model Done.-------------------------") | |||
@classmethod | |||
def _create_optimizer(self): | |||
return tf.keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0) | |||
def _comile_keras_model(self, optimizer=None): | |||
if optimizer is None: | |||
optimizer = self._create_optimizer() | |||
################################评估指标############################## | |||
def exactMatch(y_true, y_pred): | |||
y_pred1 = y_pred | |||
row_dif = K.cast(K.sum(K.round(K.clip(y_true * (1 - y_pred1) + (1-y_true) * y_pred1,0,1)), axis=1) > K.epsilon(),'float32') | |||
dif = K.sum(K.round(row_dif)) | |||
row_equ = K.cast(K.abs(K.sum(K.round(K.clip(y_true * y_pred1 + (1-y_true) * (1 - y_pred1),0,1)), axis=1) - self.config.categories) < K.epsilon(),'float32') | |||
equ = K.sum(K.round(row_equ)) | |||
return equ / (equ + dif + K.epsilon()) | |||
def micro_getPrecsion(y_true, y_pred): | |||
TP = tf.reduce_sum(y_true * tf.round(y_pred)) | |||
TN = tf.reduce_sum((1 - y_true) * (1 - tf.round(y_pred))) | |||
FP = tf.reduce_sum((1 - y_true) * tf.round(y_pred)) | |||
FN = tf.reduce_sum(y_true * (1 - tf.round(y_pred))) | |||
precision = TP / (TP + FP) | |||
return precision | |||
def micro_getRecall(y_true, y_pred): | |||
TP = tf.reduce_sum(y_true * tf.round(y_pred)) | |||
TN = tf.reduce_sum((1 - y_true) * (1 - tf.round(y_pred))) | |||
FP = tf.reduce_sum((1 - y_true) * tf.round(y_pred)) | |||
FN = tf.reduce_sum(y_true * (1 - tf.round(y_pred))) | |||
precision = TP / (TP + FP) | |||
recall = TP / (TP + FN) | |||
return recall | |||
# F1-score评价指标 | |||
def micro_F1score(y_true, y_pred): | |||
TP = tf.reduce_sum(y_true * tf.round(y_pred)) | |||
TN = tf.reduce_sum((1 - y_true) * (1 - tf.round(y_pred))) | |||
FP = tf.reduce_sum((1 - y_true) * tf.round(y_pred)) | |||
FN = tf.reduce_sum(y_true * (1 - tf.round(y_pred))) | |||
precision = TP / (TP + FP) | |||
recall = TP / (TP + FN) | |||
F1score = 2 * precision * recall / (precision + recall) | |||
return F1score | |||
def macro_getPrecison(y_true, y_pred): | |||
col_TP = K.sum(y_true * K.round(y_pred), axis=0) | |||
col_TN = K.sum((1 - y_true) * (1 - K.round(y_pred)), axis=0) | |||
col_FP = K.sum((1 - y_true) * K.round(y_pred), axis=0) | |||
col_FN = K.sum(y_true * (1 - K.round(y_pred)), axis=0) | |||
precsion = K.mean(col_TP / (col_TP + col_FP + K.epsilon())) | |||
return precsion | |||
def macro_getRecall(y_true, y_pred): | |||
# print(y_true) | |||
row_TP = K.sum(y_true * K.round(y_pred), axis=0) | |||
row_TN = K.sum((1 - y_true) * (1 - K.round(y_pred)), axis=0) | |||
row_FP = K.sum((1 - y_true) * K.round(y_pred), axis=0) | |||
row_FN = K.sum(y_true * (1 - K.round(y_pred)), axis=0) | |||
recall = K.mean(row_TP / (row_TP + row_FN + K.epsilon())) | |||
return recall | |||
def macro_getF1score(y_true, y_pred): | |||
precision = macro_getPrecison(y_true, y_pred) | |||
recall = macro_getRecall(y_true, y_pred) | |||
F1score = 2 * precision * recall / (precision + recall) | |||
return F1score | |||
""" | |||
C2AE损失函数: | |||
custom_loss: | |||
返回模型最后一层target_loss的平方和,这里y_true是随机设的 | |||
a_cross_loss: | |||
返回输出的二分类交叉熵 | |||
""" | |||
def custom_loss(y_true,y_pred): | |||
return 1*tf.reduce_mean(tf.square(y_pred)) | |||
def a_cross_loss(y_true, y_pred): | |||
cross_loss = tf.add(tf.log(1e-10 + y_pred) * y_true, tf.log(1e-10 + (1 - y_pred)) * (1 - y_true)) | |||
cross_entropy_label = -1 * tf.reduce_mean(tf.reduce_sum(cross_loss, 1)) | |||
return 0.1*cross_entropy_label | |||
self.keras_train_model.compile( | |||
loss = {'target_index_3':a_cross_loss,'targets_loss':custom_loss}, | |||
optimizer=optimizer, | |||
metrics={'target_index_3':[exactMatch, micro_getPrecsion, micro_getRecall,micro_F1score,macro_getPrecison,macro_getRecall,macro_getF1score]} | |||
) | |||
if __name__ == "__main__": | |||
config = Config(set_defaults=True, load_from_args=True, verify=False) | |||
model = Code2VecModel(config) | |||
model._create_keras_model() | |||
@ -0,0 +1,250 @@ | |||
import sys | |||
sys.path.append('../') | |||
from PIPE.config import Config | |||
from PIPE.keras_model import Code2VecModel | |||
# from data_process import Code2tags | |||
import pandas as pd | |||
import os | |||
os_path = '/'.join(os.path.abspath(__file__).split('/')[:-1]) | |||
# print(os_path) | |||
import numpy as np | |||
import tensorflow as tf | |||
from tensorflow.keras.callbacks import TensorBoard | |||
class PIPEModel(): | |||
def __init__(self): | |||
self.config = Config() | |||
self.model = Code2VecModel(self.config) | |||
self.modelSaved_path = os_path + '/training' | |||
self.base_path = os_path + "/codeData/" | |||
self.parsed_code_path=os_path + '/predict/parsedCode/' | |||
self.predict_code_path = os_path + '/predict/predictCode/' | |||
self.outData_path = self.base_path + 'outData/' | |||
#################################模型训练################################################################# | |||
def train(self, x_inputs,y_inputs): | |||
self.model._create_keras_model() | |||
self.model._comile_keras_model() | |||
cur_model = self.model.keras_train_model | |||
modelSaved_path = os.path.join(self.modelSaved_path, 'C2AE_model') | |||
if not os.path.exists(modelSaved_path): | |||
os.mkdir(modelSaved_path) | |||
# keras.utils.plot_model(cur_model, os.path.join(modelSaved_path, 'model.png'), show_shapes=True) | |||
checkpoint_path = os.path.join(modelSaved_path, "cp-{epoch:04d}.ckpt") | |||
cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_path, verbose=1, | |||
save_weights_only=True, | |||
period=self.config.SAVE_EVERY_EPOCHS) | |||
cur_model.save_weights(checkpoint_path.format(epoch=0)) | |||
tensorboard = TensorBoard(log_dir=os.path.join(modelSaved_path, "logs")) | |||
history = cur_model.fit(x_inputs, y_inputs, | |||
batch_size=self.config.TRAIN_BATCH_SIZE, | |||
epochs=self.config.NUM_TRAIN_EPOCHS, callbacks=[cp_callback, tensorboard], | |||
validation_split=1/4) | |||
print("History:") | |||
print(history.history) | |||
self.cur_model = cur_model | |||
###########################################加载模型############################################ | |||
def load_savedModel(self): | |||
self.model._create_keras_model() | |||
self.model._comile_keras_model() | |||
cur_model = self.model.keras_train_model | |||
checkpoint_path = self.modelSaved_path + '/C2AE_model/cp-0015.ckpt' | |||
cur_model.load_weights(checkpoint_path) | |||
self.cur_model = cur_model | |||
######################################预测##################################################### | |||
def predict(self, inputs): | |||
if self.cur_model == None: | |||
raise Exception("model not loaded") | |||
return self.cur_model.predict(inputs) | |||
def evaluate(self, inputs, targets): | |||
if self.cur_model == None: | |||
raise Exception("model not loaded") | |||
return self.cur_model.evaluate(inputs, targets) | |||
def get_hashed_table(self): | |||
node_types_dict = {} | |||
paths_dict = {} | |||
tokens_dict = {} | |||
node_types_path = os.path.join(self.outData_path, "node_types.csv") | |||
paths_path = os.path.join(self.outData_path, "paths.csv") | |||
tokens_path = os.path.join(self.outData_path, "tokens.csv") | |||
file1 = pd.read_csv(node_types_path) | |||
def node_types2dict(row): | |||
node_types_dict[row['node_type']] = row['id'] | |||
file1.apply(node_types2dict, axis=1) | |||
file2 = pd.read_csv(paths_path) | |||
def paths2dict(row): | |||
paths_dict[row['path']] = row['id'] | |||
file2.apply(paths2dict, axis=1) | |||
file3 = pd.read_csv(tokens_path) | |||
def tokens2dict(row): | |||
tokens_dict[row['token']] = row['id'] | |||
file3.apply(tokens2dict, axis=1) | |||
self.node_types_dict = node_types_dict | |||
self.paths_dict = paths_dict | |||
self.tokens_dict = tokens_dict | |||
##############################################对代码文本进行预测############################################ | |||
def predict_code(self, code=''): | |||
self.get_hashed_table() | |||
self.already_get_hashed_table = True | |||
code_name = "main.c" | |||
code_path = os.path.join(self.predict_code_path, code_name) | |||
with open(code_path, 'w') as f: | |||
f.write(code) | |||
cur_order = r'java -jar ' + os_path + r'/cli.jar pathContexts --lang c --project ' + self.predict_code_path + ' --output ' + self.parsed_code_path + \ | |||
r' --maxH 8 --maxW 2 --maxContexts ' + str(self.config.MAX_CONTEXTS) + ' --maxTokens ' + str( | |||
self.config.MAX_TOKEN_VOCAB_SIZE) + \ | |||
' --maxPaths ' + str(self.config.MAX_PATH_VOCAB_SIZE) | |||
ret = os.system(cur_order) | |||
assert ret == 0 | |||
node_types_path = os.path.join(self.parsed_code_path, "node_types.csv") | |||
paths_path = os.path.join(self.parsed_code_path, "paths.csv") | |||
tokens_path = os.path.join(self.parsed_code_path, "tokens.csv") | |||
code_path = os.path.join(self.parsed_code_path, "path_contexts_0.csv") | |||
file1 = pd.read_csv(node_types_path) | |||
file2 = pd.read_csv(paths_path) | |||
file3 = pd.read_csv(tokens_path) | |||
temp_node_types_dict = {} | |||
temp_paths_dict = {} | |||
temp_tokens_dict = {} | |||
def node_types2dict(row): | |||
temp_node_types_dict[row['id']] = row['node_type'] | |||
file1.apply(node_types2dict, axis=1) | |||
def paths2dict(row): | |||
temp_paths_dict[row['id']] = row['path'] | |||
file2.apply(paths2dict, axis=1) | |||
def tokens2dict(row): | |||
temp_tokens_dict[row['id']] = row['token'] | |||
file3.apply(tokens2dict, axis=1) | |||
source_input = [] | |||
path_input = [] | |||
target_input = [] | |||
context_valid_input = [] | |||
file4 = open(code_path, "r") | |||
code = file4.readline().split(' ')[1:] | |||
cnt = 0 | |||
for path in code: | |||
temp_source, temp_path, temp_target = map(int, path.split(',')) | |||
try: | |||
real_source = self.tokens_dict[temp_tokens_dict[temp_source]] | |||
real_target = self.tokens_dict[temp_tokens_dict[temp_target]] | |||
real_path = self.paths_dict[' '.join(list(map(lambda x: str(self.node_types_dict[x]), | |||
list(map(lambda x: temp_node_types_dict[int(x)], | |||
temp_paths_dict[temp_path].split(' '))))))] | |||
context_valid_input.append(1) | |||
except: | |||
# if the path cannot map into the vocabulary due to dataset reason or unknown cli.jar technical stargety | |||
# I currently choose to set value to zero to delete the path | |||
real_path = 0 | |||
context_valid_input.append(0) | |||
real_source = 0 | |||
real_target = 0 | |||
source_input.append(real_source) | |||
path_input.append(real_path) | |||
target_input.append(real_target) | |||
cnt = cnt + 1 | |||
file4.close() | |||
source_input = [np.pad(source_input, (0, self.config.MAX_CONTEXTS - cnt), 'constant', constant_values=(0, 0))] | |||
path_input = [np.pad(path_input, (0, self.config.MAX_CONTEXTS - cnt), 'constant', constant_values=(0, 0))] | |||
target_input = [np.pad(target_input, (0, self.config.MAX_CONTEXTS - cnt), 'constant', constant_values=(0, 0))] | |||
context_valid_input = [ | |||
np.pad(context_valid_input, (0, self.config.MAX_CONTEXTS - cnt), 'constant', constant_values=(0, 0))] | |||
lab = [np.array([0] * 10)] | |||
inputs = (source_input, path_input, target_input, context_valid_input, lab) | |||
index2str = ['输入变量错误', '无输出', '输出格式错误', '初始化错误','数据类型错误', | |||
'数据精度错误', '循环错误',"分支错误","逻辑错误","运算符错误"] | |||
result = self.predict(inputs) | |||
results = result[0][0].tolist() | |||
final="" | |||
dict = {} | |||
for i in range(self.config.categories): | |||
dict[index2str[i]]=results[i] | |||
#降序输出结果 | |||
sorted_prob=sorted(dict.items(),key=lambda kv:(kv[1], kv[0]),reverse=True) | |||
for x in sorted_prob: | |||
final=final+str(x[0])+':'+str("%.2f%%" % (x[1] * 100))+'\n' | |||
# print(final) | |||
return final | |||
# if __name__ == '__main__': | |||
######################训练模型##################################################### | |||
# data=Code2tags() | |||
# train_inputs=np.load(data.sourceData_path+"train_inputs.npy",allow_pickle=True).tolist() | |||
# test_inputs=np.load(data.sourceData_path+"test_inputs.npy",allow_pickle=True).tolist() | |||
# | |||
# x_train=train_inputs[:-2] | |||
# y_train=train_inputs[-2:] | |||
# | |||
# model=PIPEModel() | |||
# model.train(x_train,y_train) | |||
# # modelSaved_path = os.path.join(model.modelSaved_path,"C2AE_model") | |||
# # model.load_savedModel(os.path.join(modelSaved_path,"cp-0080.ckpt")) | |||
# answer = model.evaluate(test_inputs[:-2],test_inputs[-2:]) | |||
# print(answer) | |||
#######################对代码进行预测############################################ | |||
# model=PIPEModel() | |||
# modelSaved_path = os.path.join(model.modelSaved_path,"C2AE_model") | |||
# model.load_savedModel(os.path.join(modelSaved_path,"cp-0015.ckpt")) | |||
#############################传入code文本######################################## | |||
# code_text=open("./predict/predictCode/code.txt","r").read() | |||
# code_text = '' | |||
# include <stdio.h> | |||
# | |||
# int | |||
# main() | |||
# { | |||
# return 0; | |||
# } | |||
# answer = model.predict_code(code=code_text) | |||
# answer = model.predict_code() | |||
# print(answer) | |||
@ -0,0 +1,10 @@ | |||
id,node_type | |||
2,METHOD_RETURN UP | |||
3,METHOD UP | |||
4,METHOD DOWN | |||
5,NAME DOWN | |||
9,NAME UP | |||
7,RETURN DOWN | |||
6,BLOCK DOWN | |||
8,LITERAL DOWN | |||
1,TYPE_FULL_NAME UP |
@ -0,0 +1 @@ | |||
/home/liyuxin/桌面/shuishan/be/PIPE/predict/predictCode/main.c 1,1,2 1,2,3 2,3,3 |
@ -0,0 +1,4 @@ | |||
id,path | |||
3,9 3 4 6 7 8 | |||
1,1 2 3 4 5 | |||
2,1 2 3 4 6 7 8 |
@ -0,0 +1,4 @@ | |||
id,token | |||
3,0 | |||
2,main | |||
1,int |
@ -0,0 +1,16 @@ | |||
#include <stdio.h> | |||
int main() | |||
{ | |||
int a,b,c,d; | |||
float sum=0,ave; | |||
printf("input 4 int data:\n"); | |||
scanf("%d %d %d %d", &a, &b, &c, &d); | |||
sum=a+b+c+d; | |||
ave=((int)(sum / 4.0*10))/10.0; | |||
printf("sum=%d mean=%.1f\n",sum,ave); | |||
return 0; | |||
} |
@ -0,0 +1,7 @@ | |||
#include <stdio.h> | |||
int main() | |||
{ | |||
return 0; | |||
} | |||
@ -0,0 +1,2 @@ | |||
model_checkpoint_path: "cp-0100.ckpt" | |||
all_model_checkpoint_paths: "cp-0100.ckpt" |
@ -0,0 +1,3 @@ | |||
create user 'shuishan'@'%' identified with mysql_native_password by 'Shuishan@2020'; | |||
grant all on *.* to 'shuishan'@'%' with grant option; |
@ -0,0 +1,108 @@ | |||
from flask import Flask | |||
from flask import jsonify | |||
from flask import request | |||
import json | |||
import pymysql | |||
import sys | |||
sys.path.append('../') | |||
from PIPE.main import PIPEModel | |||
app = Flask(__name__) | |||
app.config['JSON_AS_ASCII'] = False | |||
db = pymysql.connect(host='127.0.0.1', | |||
port=3306, | |||
user='shuishan', | |||
password='Shuishan@2020', | |||
db='shuishan', | |||
charset='utf8') | |||
@app.route('/get-problem-items/') | |||
def get_problem_items(): | |||
db.ping(reconnect=True) | |||
cursor = db.cursor() | |||
cursor.execute("select id, title from problem") | |||
data = cursor.fetchall() | |||
pids = [] | |||
for d in data: | |||
pids.append({"id": d[0], "title": d[1]}) | |||
pids = sorted(pids, key=lambda x: x.__getitem__('id'), reverse=False) | |||
for i in range(len(pids)): | |||
pids[i]['id'] = str(pids[i]['id']) | |||
return jsonify(pids), 200 | |||
@app.route('/get-problem-description/<_id>/') | |||
def get_problem_description(_id: str): | |||
db.ping(reconnect=True) | |||
cursor = db.cursor() | |||
cursor.execute("select title, description, input_description, output_description, samples " | |||
"from problem where id = %d" % int(_id)) | |||
des = cursor.fetchone() | |||
# print(des) | |||
title = '<div><strong style="font-size:22px;color:blue;">%s. %s</strong></div><br/>' % (_id, des[0]) | |||
description = '<div><strong style="font-size:20px;color:blue;">Description</strong></div><div>%s</div><br/>' % des[1] | |||
input_description = '<div><strong style="font-size:20px;color:blue;">Input Description</strong></div><div>%s</div><br/>' \ | |||
% des[2] | |||
output_description = '<div><strong style="font-size:20px;color:blue;">Output Description</strong></div><div>%s</div><br/>' \ | |||
% des[3] | |||
samples = json.loads(des[-1].replace("\n", "\\n")) | |||
samples_html = '' | |||
for s in samples: | |||
_input = s["input"].strip().replace(" ", " ").replace("\n", "<br/> ") | |||
_output = s["output"].strip().replace(" ", " ").replace("\n", "<br/> ") | |||
# _input = s["input"].strip().replace(" ", " ") | |||
# _output = s["output"].strip().replace(" ", " ") | |||
stra = '<div>' | |||
strb = '<div style="width:100%;">' | |||
strc = '<div style="display:inline-block;width:45%;vertical-align:top;"><strong style="font-size:20px;color:blue;">Input</strong></div>' | |||
strd = '<div style="display:inline-block;width:2%;vertical-align:top;"></div>' | |||
stre = '<div style="display:inline-block;width:45%;vertical-align:top;"><strong style="font-size:20px;color:blue;">Output</strong></div>' | |||
strf = '</div><br/>' | |||
strg = '<div style="width:100%;">' | |||
strh = '<div style="display:inline-block;width:45%;height:100%;vertical-align:top;border:0.5px solid;border-radius:5px;"><br/> ' + _input + '<br/> </div>' | |||
stri = '<div style="display:inline-block;width:2%;height:100%;vertical-align:top;"></div>' | |||
strj = '<div style="display:inline-block;width:45%;height:100%;vertical-align:top;border:0.5px solid;border-radius:5px;"><br/> ' + _output + '<br/> </div>' | |||
strk = '</div>' | |||
strl = '</div><br/>' | |||
samples_html = samples_html + stra + strb + strc + strd + stre + strf + strg + strh + stri + strj + strk + strl | |||
return title + description + input_description + output_description + samples_html, 200 | |||
@app.route('/case_test/', methods=['POST']) | |||
def case_test_(): | |||
pid: str = request.json.get("pid") | |||
code: str = request.json.get("code") | |||
print(pid) | |||
print(code) | |||
return 'pass', 200 | |||
@app.route('/check-logic-error/', methods=['POST']) | |||
def check_logic_error(): | |||
pid: str = request.json.get("pid") | |||
code: str = request.json.get("code") | |||
print(pid) | |||
print(code) | |||
model = PIPEModel() | |||
model.load_savedModel() | |||
answer = model.predict_code(code=code) | |||
del model | |||
# results = 'check_logic_error' | |||
return answer, 200 | |||
@app.route('/submit/', methods=['POST']) | |||
def submit(): | |||
pid: str = request.json.get("pid") | |||
code: str = request.json.get("code") | |||
print(pid) | |||
print(code) | |||
# results = check_logic_error(pid, code) | |||
results = 'submit' | |||
return results, 200 | |||
if __name__ == '__main__': | |||
app.run() |
@ -0,0 +1,8 @@ | |||
home = /usr/lib/python3.7 | |||
implementation = CPython | |||
version_info = 3.7.4.final.0 | |||
virtualenv = 20.1.0 | |||
include-system-site-packages = false | |||
base-prefix = /usr/lib/python3.7 | |||
base-exec-prefix = /usr/lib/python3.7 | |||
base-executable = /usr/bin/python3.7 |
@ -0,0 +1,5 @@ | |||
numpy==1.19.4 | |||
pandas==1.1.5 | |||
tensorflow==1.14.0 | |||
Flask==1.1.2 | |||
PyMySQL==0.10.1 |
@ -0,0 +1,4 @@ | |||
from app import app | |||
if __name__ == '__main__': | |||
app.run() |
@ -0,0 +1,46 @@ | |||
后端服务器: | |||
IP: 106.75.225.90 / 10.23.152.3 | |||
user: ubuntu | |||
passwd: 1234qwer | |||
(后段代码只能向 case_test.py 和 check.py 中添加,接口不要更改,代码在 /home/ubuntu/be 中,修改之后通过 sudo systemctl restart be 重启服务) | |||
数据库: | |||
服务器中通过 mysql -h10.23.211.165 -uroot -p1234qwer 连接,使用shuishan这个数据库 | |||
插件: | |||
上传到 106.75.251.241 code-server所在的服务器的 /home/ubuntu/ShuiShan 目录下,目前上传的为以 vscode 1.51.1 为基础的版本,如果需要其他的我再行上传 | |||
code-server: | |||
http://106.75.251.241:8080 | |||
passwd: aZ720217 | |||
user: ubuntu | |||
code-server-passwd: 123456789 | |||
前端服务器 | |||
113.31.118.137 / 10.23.179.109 pw: 1234qwer | |||
106.75.251.241 pw: aZ720217 | |||
user: ubuntu | |||
后端服务器 | |||
106.75.209.55 / 10.23.106.22 | |||
10.23.14.54 | |||
10.23.31.251 | |||
10.23.245.143 | |||
passwd: 1234qwer | |||
user: ubuntu | |||
负载均衡 | |||
113.31.111.149 | |||
云数据库 | |||
10.23.211.165 | |||
user: root | |||
passwd: 1234qwer |
@ -0,0 +1,224 @@ | |||
一、在Ubuntu上安装Python3.7 | |||
```shell | |||
# 升级包索引和软件 | |||
sudo apt update | |||
sudo apt upgrade -y | |||
# 安装编译所需包 | |||
sudo apt install -y build-essential zlib1g-dev libbz2-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev wget | |||
# 官网下载 Python3.7 | |||
wget https://www.python.org/ftp/python/3.7.4/Python-3.7.4.tgz | |||
# 解压 | |||
tar -xzvf Python-3.7.4.tgz | |||
# 查看已安装 Python 的位置 | |||
whereis python | |||
# 编译安装 | |||
cd Python-3.7.4 | |||
./configure --prefix=/usr/lib/python3.7 # 配置安装位置 | |||
sudo make | |||
sudo make install | |||
# 建立软链接 | |||
sudo ln -s /usr/lib/python3.7/bin/python3.7 /usr/bin/python3.7 | |||
sudo ln -s /usr/lib/python3.7/bin/pip3.7 /usr/bin/pip3.7 | |||
# 替换系统默认(建议不要替换,会使系统发生改变,使得ufw无法使用) | |||
sudo rm -rf /usr/bin/python3 | |||
sudo ln -s /usr/lib/python3.7/bin/python3.7 /usr/bin/python3 | |||
# 默认ubuntu系统中没有pip3,直接建立软连接即可, 如果有先删除 | |||
sudo ln -s /usr/lib/python3.7/bin/pip3.7 /usr/bin/pip3 | |||
# pip 换源 | |||
sudo mkdir ~/.pip | |||
sudo vi ~/.pip/pip.conf | |||
# 写入 | |||
[global] | |||
index-url = http://mirrors.aliyun.com/pypi/simple/ | |||
[install] | |||
trusted-host=mirrors.aliyun.com | |||
# 保存并关闭 | |||
``` | |||
二、安装 JDK-11 | |||
```shell | |||
sudo apt update | |||
sudo apt install -y openjdk-11-jdk | |||
java -version | |||
sudo update-alternatives --config java | |||
sudo nano /etc/environment | |||
JAVA_HOME="/usr/lib/jvm/java-11-openjdk-amd64" | |||
source /etc/environment | |||
echo $JAVA_HOME | |||
三、创建 Python 虚拟环境 | |||
```shell | |||
# 更新并安装组件 | |||
sudo apt update | |||
sudo apt install -y python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools | |||
# 安装 python3-venv 软件包 | |||
sudo apt install -y python3-venv | |||
# 创建虚拟环境 | |||
cd ~ | |||
python3.7 -m venv be | |||
# 激活虚拟环境 | |||
source ~/be/bin/activate | |||
# 上传代码 | |||
# 从本地向云主机上传代码 | |||
# scp ... | |||
# 安装依赖(激活虚拟环境时都应该使用pip而不是pip3) | |||
pip install -r requirements.txt | |||
# 安装 uwsgi | |||
pip install uwsgi | |||
# 创建 wsgi.py 作为程序入口点,告诉 uWSGI 服务器如何与程序进行交互 | |||
``` | |||
四、安装 Nginx | |||
```shell | |||
sudo apt-get install -y nginx | |||
# 启动 | |||
sudo /etc/init.d/nginx start | |||
sudo systemctl restart nginx | |||
sudo systemctl start nginx | |||
sudo systemctl stop nginx | |||
sudo systemctl status nginx | |||
五、配置 uWSGI | |||
```shell | |||
# 启用UFW防火墙,允许访问端口5000 | |||
sudo ufw allow 5000 | |||
# 测试 uWSGI 服务(若本地开启了代理注意关闭,在虚拟环境下执行) | |||
uwsgi --socket 0.0.0.0:5000 --protocol=http -w wsgi:app | |||
# 从本地浏览器输入 http://<IP address>:5000 | |||
# 关闭虚拟环境 | |||
deactivate | |||
# 创建 uWSGI 配置文件 | |||
nano ~/be/be.ini | |||
# 从 [uwsgi] 标头开始,以便 uWSGI 知道应用设置 | |||
# 需要指定两件事:模块本神,通过引用 wsgi.py 减去扩展名,以及文件中的 callable 对象,即 app | |||
[uwsgi] | |||
module = wsgi:app | |||
# 接下来,告诉 uWSGI 以主模式启动并生成5个工作进程提供实际请求 | |||
[uwsgi] | |||
module = wsgi:app | |||
master = true | |||
processes = 5 | |||
# 接下来 | |||
[uwsgi] | |||
module = wsgi:app | |||
master = true | |||
processes = 5 | |||
socket = be.sock | |||
chmod-socket = 660 | |||
vacuum = true | |||
die-on-term = true | |||
# 保存并关闭 | |||
``` | |||
六、创建 systemd 单元文件 | |||
```shell | |||
sudo nano /etc/systemd/system/be.service | |||
[Unit] | |||
Description=uWSGI instance to serve be | |||
After=network.target | |||
[Service] | |||
User=ubuntu | |||
Group=www-data | |||
WorkingDirectory=/home/ubuntu/be | |||
Environment="PATH=/home/ubuntu/be/bin" | |||
ExecStart=/home/ubuntu/be/bin/uwsgi --ini be.ini | |||
[Install] | |||
WantedBy=multi-user.target | |||
# 保存并关闭 | |||
# 现在可以启动创建的 uWSGI 服务并启用它,以便它在启动时启动 | |||
sudo systemctl start be | |||
sudo systemctl enable be | |||
# 查看状态 | |||
sudo systemctl status be | |||
``` | |||
七、将 Nginx 配置为代理请求 | |||
```shell | |||
sudo nano /etc/nginx/sites-available/be | |||
# 写入 | |||
server { | |||
listen 80; | |||
server_name <公网IP>; | |||
location / { | |||
include uwsgi_params; | |||
uwsgi_pass unix:/home/ubuntu/be/be.sock; | |||
} | |||
} | |||
# 保存并关闭 | |||
# 若要启用该配置,需将文件链接至 sites-enabled 目录 | |||
sudo ln -s /etc/nginx/sites-available/be /etc/nginx/sites-enabled | |||
# 通过如下命令测试语法错误 | |||
sudo nginx -t | |||
# 返回成功则重启 Nginx 进程以读取新配置 | |||
sudo systemctl restart nginx | |||
# 再次调整防火墙,不再需要通过5000端口访问,可以删除该规则,最后可以允许访问Nginx服务器 | |||
sudo ufw delete allow 5000 | |||
sudo ufw allow 'Nginx Full' | |||
# 现在可以直接通过 IP 地址访问 | |||
# 遇到错误使用如下方式检查 | |||
sudo less /var/log/nginx/error.log # 检查Nginx错误日志 | |||
sudo less /var/log/nginx/access.log # 检查Nginx访问日志 | |||
sudo journalctl -u nginx # 检查Nginx进程日志 | |||
sudo journalctl -u be # 检查你的Flask应用程序的uWSGI日志 | |||
``` | |||