[mod] port to sanic for perfs
This commit is contained in:
parent
6ea4acaab2
commit
b68fb5988e
2 changed files with 47 additions and 21 deletions
|
@ -1,4 +1,2 @@
|
||||||
argparse
|
|
||||||
jinja2
|
jinja2
|
||||||
github-webhook==1.0.4
|
sanic
|
||||||
gunicorn==20.1.0
|
|
||||||
|
|
|
@ -1,15 +1,19 @@
|
||||||
import subprocess
|
|
||||||
import os
|
import os
|
||||||
|
import hmac
|
||||||
|
import shlex
|
||||||
|
import hashlib
|
||||||
|
import asyncio
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
from github_webhook import Webhook
|
from sanic import Sanic
|
||||||
from flask import Flask
|
from sanic.response import text
|
||||||
|
from sanic.exceptions import abort
|
||||||
|
|
||||||
from make_readme import generate_READMEs
|
from make_readme import generate_READMEs
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Sanic(__name__)
|
||||||
|
|
||||||
github_webhook_secret = open("github_webhook_secret", "r").read().strip()
|
github_webhook_secret = open("github_webhook_secret", "r").read().strip()
|
||||||
webhook = Webhook(app, endpoint="/github", secret=github_webhook_secret)
|
|
||||||
|
|
||||||
login = open("login").read().strip()
|
login = open("login").read().strip()
|
||||||
token = open("token").read().strip()
|
token = open("token").read().strip()
|
||||||
|
@ -22,39 +26,63 @@ my_env["GIT_COMMITTER_NAME"] = "Yunohost-Bot"
|
||||||
my_env["GIT_COMMITTER_EMAIL"] = "yunohost@yunohost.org"
|
my_env["GIT_COMMITTER_EMAIL"] = "yunohost@yunohost.org"
|
||||||
|
|
||||||
|
|
||||||
def git(cmd, in_folder=None):
|
async def git(cmd, in_folder=None):
|
||||||
|
|
||||||
if not isinstance(cmd, list):
|
if not isinstance(cmd, list):
|
||||||
cmd = cmd.split()
|
cmd = cmd.split()
|
||||||
if in_folder:
|
if in_folder:
|
||||||
cmd = ["-C", in_folder] + cmd
|
cmd = ["-C", in_folder] + cmd
|
||||||
cmd = ["git"] + cmd
|
cmd = ["git"] + cmd
|
||||||
return subprocess.check_output(cmd, env=my_env).strip().decode("utf-8")
|
cmd = " ".join(map(shlex.quote, cmd))
|
||||||
|
command = await asyncio.create_subprocess_shell(cmd, env=my_env, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.STDOUT)
|
||||||
|
data = await command.stdout.read()
|
||||||
|
return data.decode().strip()
|
||||||
|
|
||||||
|
|
||||||
@app.route("/github")
|
@app.route("/github", methods=["GET"])
|
||||||
def main_route():
|
def main_route(request):
|
||||||
return "You aren't supposed to go on this page using a browser, it's for webhooks push instead."
|
return text("You aren't supposed to go on this page using a browser, it's for webhooks push instead.")
|
||||||
|
|
||||||
|
|
||||||
@webhook.hook()
|
@app.route("/github", methods=["POST"])
|
||||||
def on_push(data):
|
async def on_push(request):
|
||||||
|
header_signature = request.headers.get("X-Hub-Signature")
|
||||||
|
if header_signature is None:
|
||||||
|
print("no header X-Hub-Signature")
|
||||||
|
abort(403)
|
||||||
|
|
||||||
|
sha_name, signature = header_signature.split("=")
|
||||||
|
if sha_name != "sha1":
|
||||||
|
print("signing algo isn't sha1, it's '%s'" % sha_name)
|
||||||
|
abort(501)
|
||||||
|
|
||||||
|
# HMAC requires the key to be bytes, but data is string
|
||||||
|
mac = hmac.new(github_webhook_secret.encode(), msg=request.body, digestmod=hashlib.sha1)
|
||||||
|
|
||||||
|
if not hmac.compare_digest(str(mac.hexdigest()), str(signature)):
|
||||||
|
abort(403)
|
||||||
|
|
||||||
|
data = request.json
|
||||||
|
|
||||||
repository = data["repository"]["full_name"]
|
repository = data["repository"]["full_name"]
|
||||||
branch = data["ref"].split("/", 2)[2]
|
branch = data["ref"].split("/", 2)[2]
|
||||||
|
|
||||||
with tempfile.TemporaryDirectory() as folder:
|
with tempfile.TemporaryDirectory() as folder:
|
||||||
git(["clone", f"https://{login}:{token}@github.com/{repository}", "--single-branch", "--branch", branch, folder])
|
await git(["clone", f"https://{login}:{token}@github.com/{repository}", "--single-branch", "--branch", branch, folder])
|
||||||
generate_READMEs(folder)
|
generate_READMEs(folder)
|
||||||
|
|
||||||
git(["add", "README*.md"], in_folder=folder)
|
await git(["add", "README*.md"], in_folder=folder)
|
||||||
|
|
||||||
diff_not_empty = bool(subprocess.check_output(["git", "diff", "HEAD", "--compact-summary"], cwd=folder).strip().decode("utf-8"))
|
diff_not_empty = await asyncio.create_subprocess_shell(" ".join(["git", "diff", "HEAD", "--compact-summary"]), cwd=folder, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.STDOUT)
|
||||||
|
diff_not_empty = await diff_not_empty.stdout.read()
|
||||||
|
diff_not_empty = diff_not_empty.decode().strip()
|
||||||
if not diff_not_empty:
|
if not diff_not_empty:
|
||||||
return
|
return text("nothing to do")
|
||||||
|
|
||||||
git(["commit", "-a", "-m", "Auto-update README", "--author='Yunohost-Bot <>'"], in_folder=folder)
|
await git(["commit", "-a", "-m", "Auto-update README", "--author='Yunohost-Bot <>'"], in_folder=folder)
|
||||||
git(["push", "origin", branch, "--quiet"], in_folder=folder)
|
await git(["push", "origin", branch, "--quiet"], in_folder=folder)
|
||||||
|
|
||||||
|
return text("ok")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
Loading…
Reference in a new issue