Skip to content
Snippets Groups Projects
Commit 541ac22a authored by Yingzhou Li's avatar Yingzhou Li
Browse files

Updated exec to be compatible with current mautrix library and python 3.8+

parent 270c6f55
No related branches found
No related tags found
No related merge requests found
name: tag-release
on:
push:
tags:
- 'v*'
jobs:
build:
name: tag-release
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Zip
run: |
zip -9r smartpoll.mbp polls maubot.yaml upload.py
- name: Get the version
id: get_version
run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{steps.get_version.outputs.VERSION}}
release_name: Release ${{steps.get_version.outputs.VERSION}}
draft: false
prerelease: false
- name: Upload Release Asset
id: upload-release-asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./smartpoll.mbp
asset_name: smartpoll-${{steps.get_version.outputs.VERSION}}.mbp
asset_content_type: application/zip
image: dock.mau.dev/maubot/maubot
stages:
- build
variables:
PYTHONPATH: /opt/maubot
build:
stage: build
except:
- tags
script:
- python3 -m maubot.cli build -o xyz.maubot.$CI_PROJECT_NAME-$CI_COMMIT_REF_NAME-$CI_COMMIT_SHORT_SHA.mbp
artifacts:
paths:
- "*.mbp"
build tags:
stage: build
only:
- tags
script:
- python3 -m maubot.cli build -o xyz.maubot.$CI_PROJECT_NAME-$CI_COMMIT_TAG.mbp
artifacts:
paths:
- "*.mbp"
# exec
A [maubot](https://github.com/maubot/maubot) that executes code.
exec is updated to be compatible with python 3.8+.
## Usage
The bot is triggered by a specific message prefix (defaults to `!exec`) and
......@@ -34,3 +35,12 @@ If running in userbot mode, the bot will edit your original message instead of
making a new reply message.
Currently, the bot supports `python` and `shell` as languages.
## Contributors
<a href="https://github.com/YingzhouLi/exec/graphs/contributors">
<img src="https://contrib.rocks/image?repo=YingzhouLi/exec" />
</a>
Made with [contrib.rocks](https://contrib.rocks).
......@@ -19,13 +19,15 @@ from io import IOBase, StringIO
import contextlib
import traceback
import asyncio
import inspect
import ast
import sys
from mautrix.util.manhole import asyncify
from mautrix.util.manhole import compile_async
from .base import Runner, OutputType, AsyncTextOutput
TOP_LEVEL_AWAIT = sys.version_info >= (3, 8)
class SyncTextProxy(AsyncTextOutput):
writers: Dict[OutputType, 'ProxyWriter']
......@@ -116,7 +118,7 @@ class PythonRunner(Runner):
line: traceback.FrameSummary
for i, line in enumerate(tb):
if line.filename == "<input>":
line.name = "<module>"
line.name = "<node>"
tb = tb[i:]
break
......@@ -127,17 +129,34 @@ class PythonRunner(Runner):
async def run(self, code: str, stdin: str = "", loop: Optional[asyncio.AbstractEventLoop] = None
) -> AsyncGenerator[Tuple[OutputType, Any], None]:
loop = loop or asyncio.get_event_loop()
codeobj = asyncify(compile(code, "<input>", "exec", optimize=1, flags=ast.PyCF_ONLY_AST),
module="<input>")
codeobj = compile_async(code)
namespace = {**self.namespace} if self.per_run_namespace else self.namespace
exec(codeobj, namespace)
with self._redirect_io(SyncTextProxy(loop), StringIO(stdin)) as output:
task = asyncio.ensure_future(self._wait_task(namespace, output), loop=loop)
async for part in output:
yield part
try:
return_value = await task
except Exception:
yield (OutputType.EXCEPTION, ExcInfo(*sys.exc_info()))
else:
yield (OutputType.RETURN, return_value)
if TOP_LEVEL_AWAIT:
with self._redirect_io(SyncTextProxy(loop), StringIO(stdin)) as output:
try:
value = eval(codeobj, namespace)
finally:
output.close()
async for part in output:
yield part
try:
if codeobj.co_flags & inspect.CO_COROUTINE:
return_value = await value
else:
return_value = value
except Exception:
yield (OutputType.EXCEPTION, ExcInfo(*sys.exc_info()))
else:
yield (OutputType.RETURN, return_value)
else:
exec(codeobj, namespace)
with self._redirect_io(SyncTextProxy(loop), StringIO(stdin)) as output:
task = asyncio.create_task(self._wait_task(namespace, output))
async for part in output:
yield part
try:
return_value = await task
except Exception:
yield (OutputType.EXCEPTION, ExcInfo(*sys.exc_info()))
else:
yield (OutputType.RETURN, return_value)
\ No newline at end of file
maubot: 0.1.0
id: xyz.maubot.exec
version: 0.1.0
version: 0.2.0
license: AGPL-3.0-or-later
modules:
- exec
......
zip -9r exec-develop.mbp exec maubot.yaml base-config.yaml
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment