From bba190a782d61995eb4717e441a0c676cefa372f Mon Sep 17 00:00:00 2001 From: nefrace Date: Thu, 19 May 2022 12:18:00 +0300 Subject: [PATCH] Initial commit --- .gitignore | 3 ++ bot/.dockerignore | 2 + bot/Dockerfile | 10 +++++ bot/main.py | 38 ++++++++++++++++ bot/requirements.txt | 21 +++++++++ docker-compose.yml | 11 +++++ server/Dockerfile | 67 +++++++++++++++++++++++++++++ server/go.mod | 24 +++++++++++ server/go.sum | 100 +++++++++++++++++++++++++++++++++++++++++++ server/main.go | 99 ++++++++++++++++++++++++++++++++++++++++++ server/template | 16 +++++++ 11 files changed, 391 insertions(+) create mode 100644 .gitignore create mode 100644 bot/.dockerignore create mode 100644 bot/Dockerfile create mode 100644 bot/main.py create mode 100644 bot/requirements.txt create mode 100644 docker-compose.yml create mode 100644 server/Dockerfile create mode 100644 server/go.mod create mode 100644 server/go.sum create mode 100644 server/main.go create mode 100644 server/template diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7efe06d --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +env +.env +*.log \ No newline at end of file diff --git a/bot/.dockerignore b/bot/.dockerignore new file mode 100644 index 0000000..3b23b18 --- /dev/null +++ b/bot/.dockerignore @@ -0,0 +1,2 @@ +env +Dockerfile \ No newline at end of file diff --git a/bot/Dockerfile b/bot/Dockerfile new file mode 100644 index 0000000..33b828e --- /dev/null +++ b/bot/Dockerfile @@ -0,0 +1,10 @@ +FROM python:3-buster + +WORKDIR /app + +COPY requirements.txt ./ +RUN pip install --no-cache-dir -r requirements.txt + +COPY . . + +CMD [ "python", "./main.py"] \ No newline at end of file diff --git a/bot/main.py b/bot/main.py new file mode 100644 index 0000000..37935c9 --- /dev/null +++ b/bot/main.py @@ -0,0 +1,38 @@ +from urllib import response +from aiogram import types, Bot, Dispatcher +import requests +from dotenv import load_dotenv +import os + +load_dotenv() +TOKEN = os.getenv("TOKEN") +HOST = os.getenv("HOST", "http://127.0.0.1:8080") +if not TOKEN: + print("Token not specified") + exit(1) + +bot: Bot = Bot(TOKEN) + +dp: Dispatcher = Dispatcher() + +@dp.message(commands=['run']) +async def message_handler(message: types.Message): + if not message.reply_to_message: return + msg = message.reply_to_message + if not msg.entities: return + print(msg.text) + + for entity in msg.entities: + if entity.type != "pre" and entity.type != "code": continue + code = entity.extract(msg.text) + resp = requests.post(HOST+"/run", data={'code': code}) + json = resp.json() + if resp.status_code != 200: + return await msg.answer("Произошла ошибка:\n" + json["stderr"]) + await msg.reply(f"Резульат\n```gd\n{json['result']}\n```", parse_mode="MarkdownV2") + +def main(): + dp.run_polling(bot) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/bot/requirements.txt b/bot/requirements.txt new file mode 100644 index 0000000..1fdfb64 --- /dev/null +++ b/bot/requirements.txt @@ -0,0 +1,21 @@ +aiofiles==0.8.0 +aiogram==3.0.0b3 +aiohttp==3.8.1 +aiosignal==1.2.0 +async-timeout==4.0.2 +attrs==21.4.0 +Babel==2.9.1 +certifi==2022.5.18 +charset-normalizer==2.0.12 +frozenlist==1.3.0 +idna==3.3 +magic-filter==1.0.7 +multidict==6.0.2 +pydantic==1.9.0 +Pygments==2.12.0 +python-dotenv==0.20.0 +pytz==2022.1 +requests==2.27.1 +typing_extensions==4.2.0 +urllib3==1.26.9 +yarl==1.7.2 diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..12f5d3a --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,11 @@ +version: '3' + +services: + godot: + build: ./server + volumes: + - ./data/scripts:/app/scripts + - ./data/logs:/app/logs + bot: + build: ./bot + \ No newline at end of file diff --git a/server/Dockerfile b/server/Dockerfile new file mode 100644 index 0000000..50a6a88 --- /dev/null +++ b/server/Dockerfile @@ -0,0 +1,67 @@ +##################################################### +# Dockerfile +# +# Creates an image with the Godot headless app. +# +# Build Args: +# - GODOT_VERSION: The version of Godot +# - EXPORT_TEMPLATES: Included export templates +# examples "all", "none", "win" +# + +ARG EXPORT_TEMPLATES=all + +#------------------------------ +# Alias for the root image +FROM debian:stable-slim AS base + +ARG GODOT_VERSION=3.4.2 + +#------------------------------ +# Installs packages to use wget +FROM base as wget + +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + wget \ + unzip + +#---------------- +# Downloads Godot +FROM wget AS godot + +RUN wget https://downloads.tuxfamily.org/godotengine/3.4.4/Godot_v3.4.4-stable_linux_headless.64.zip +RUN unzip Godot_v3.4.4-stable_linux_headless.64.zip +RUN mv Godot_v3.4.4-stable_linux_headless.64 /usr/local/bin/godot + +#---------------- +# Build web-server + +FROM golang:1.18.2 as web + +WORKDIR /app +COPY go.mod ./ +COPY go.sum ./ +RUN go mod download +COPY *.go ./ +RUN go build -o ./server + +#------------------------------ +# Clean setup with no templates + +FROM base AS export-none + +ENV XDG_DATA_HOME /usr/local/share + +RUN mkdir -p /root/.cache +RUN mkdir -p /root/.config/godot + +WORKDIR /app +COPY --from=godot /usr/local/bin/godot /usr/local/bin/godot +COPY --from=web /app/server /usr/local/bin/server +COPY template ./ +# EXPOSE 8080 +ENV SCRIPTS=/app/scripts + +ENTRYPOINT ["server"] +CMD ["--help"] \ No newline at end of file diff --git a/server/go.mod b/server/go.mod new file mode 100644 index 0000000..14db0df --- /dev/null +++ b/server/go.mod @@ -0,0 +1,24 @@ +module go-godot-repl + +go 1.18 + +require ( + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/gin-gonic/gin v1.7.7 // indirect + github.com/go-playground/locales v0.14.0 // indirect + github.com/go-playground/universal-translator v0.18.0 // indirect + github.com/go-playground/validator/v10 v10.11.0 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/leodido/go-urn v1.2.1 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/ugorji/go/codec v1.2.7 // indirect + golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898 // indirect + golang.org/x/sys v0.0.0-20220517195934-5e4e11fc645e // indirect + golang.org/x/text v0.3.7 // indirect + google.golang.org/protobuf v1.28.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect +) diff --git a/server/go.sum b/server/go.sum new file mode 100644 index 0000000..afbaddd --- /dev/null +++ b/server/go.sum @@ -0,0 +1,100 @@ +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs= +github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= +github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= +github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= +github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= +github.com/go-playground/validator/v10 v10.11.0 h1:0W+xRM511GY47Yy3bZUbJVitCNg2BOGlCyvTqsp/xIw= +github.com/go-playground/validator/v10 v10.11.0/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= +github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo= +github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= +github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898 h1:SLP7Q4Di66FONjDJbCYrCRrh97focO6sLogHO7/g8F0= +golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220517195934-5e4e11fc645e h1:w36l2Uw3dRan1K3TyXriXvY+6T56GNmlKGcqiQUJDfM= +golang.org/x/sys v0.0.0-20220517195934-5e4e11fc645e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/server/main.go b/server/main.go new file mode 100644 index 0000000..5b522e9 --- /dev/null +++ b/server/main.go @@ -0,0 +1,99 @@ +package main + +import ( + "bytes" + "context" + "log" + "net/http" + "os" + "os/exec" + "strings" + "text/template" + "time" + + "github.com/gin-gonic/gin" + "github.com/google/uuid" +) + +type CodeStruct struct { + Code []string + Id string +} + +func main() { + r := gin.Default() + var godot_path string + godot_path, exists := os.LookupEnv("GODOT") + if !exists { + godot_path = "godot" + } + scripts_path, exists := os.LookupEnv("SCRIPTS") + if !exists { + scripts_path = "./" + } + r.POST("/run", func(c *gin.Context) { + code := c.DefaultPostForm("code", "") + if code == "" { + c.JSON(http.StatusBadRequest, gin.H{"status": "Empty body"}) + return + } + lines := strings.Split(code, "\n") + log.Printf("%v", lines) + file_uuid := uuid.New() + file_uuid_clean := strings.Replace(file_uuid.String(), "-", "", -1) + filename := scripts_path + file_uuid_clean + ".gd" + // err := os.WriteFile(filename, code_bytes, 0644) + tmpl, err := template.ParseFiles("template") + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"status": "could not parse template", "error": err.Error()}) + return + } + file, err := os.Create(filename) + defer file.Close() + defer os.Remove(filename) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"status": "could not create file", "error": err.Error()}) + return + } + err = tmpl.Execute(file, CodeStruct{Code: lines, Id: file_uuid_clean}) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"status": "could not write file", "error": err.Error()}) + return + } + var stdout bytes.Buffer + var stderr bytes.Buffer + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + cmd := exec.CommandContext(ctx, godot_path, "-s", filename, "--no-window") + cmd.Stdout = &stdout + cmd.Stderr = &stderr + err = cmd.Run() + out_str := stdout.String() + err_str := stderr.String() + separator := "=== " + file_uuid_clean + " ===" + out_sep := strings.Split(out_str, separator) + err_sep := strings.Split(err_str, separator) + if len(out_sep) == 1 { + out_sep = append(out_sep, "") + } + if len(err_sep) == 1 { + err_sep = append(err_sep, "") + } + if ctx.Err() == context.DeadlineExceeded { + c.JSON(http.StatusRequestTimeout, gin.H{"status": "script timeout", "stdout": out_sep[1], "stderr": err_sep[1]}) + return + } + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"status": err.Error()}) + return + } + + out_separated := strings.Split(out_str, separator) + if len(out_separated) < 2 { + c.JSON(http.StatusBadRequest, gin.H{"status": "runtime error", "stdout": out_str, "stderr": err_str}) + return + } + c.JSON(http.StatusOK, gin.H{"result": out_separated[1]}) + }) + log.Fatal(r.Run(":8080").Error()) +} diff --git a/server/template b/server/template new file mode 100644 index 0000000..94936e6 --- /dev/null +++ b/server/template @@ -0,0 +1,16 @@ +extends SceneTree + + +func _init(): + var Executor = null + var OS = null + var Directory = null + var ConfigFile = null + var File = null + print("=== {{ .Id }} ===") + printerr("=== {{ .Id }} === ") + + {{ range .Code }}{{ . }} + {{end}} + + quit() \ No newline at end of file