from flask import render_template, request, jsonify, stream_with_context, Response
from app import app

from pygments import highlight
from pygments.lexers import BashLexer
from pygments.formatters import HtmlFormatter

import subprocess


@app.route('/')
@app.route('/index')
def index():
    return render_template('index.html')


## Include scripts with AJAX
@app.route('/_exec')
def exec_script():
    """ Executes given script """
    script = request.args.get('script', None, type=str)

    if script:
        path = "scripts/"
        cmd = ["python3", path + script]
        p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
                                  stderr=subprocess.PIPE,
                                  stdin=subprocess.PIPE)
        out, err = p.communicate()

        # If there is any response, format it for HTML
        if out:
            out = highlight(out, BashLexer(), HtmlFormatter())

        err = err.decode("utf-8")

        if err.startswith("python3: can't open file '"):
            err = "Das Skript <strong>'" + script + "'</strong> konnte nicht gefunden werden."
        elif err:
            err = highlight(err, BashLexer(), HtmlFormatter())

    else:
        out = None
        err = "Es wurde kein Skript angegeben."

    return jsonify(out=str(out), err=str(err))


@app.route('/stream/<script>')
def execute(script):
    def inner():
        path = "scripts/"
        exec_path = path + script + ".py"

        cmd = ["/usr/bin/env", "python3", "-u", exec_path]

        proc = subprocess.Popen(
            cmd,
            stdout=subprocess.PIPE,
        )
        #out, err = proc.communicate()
        print("hello")
        for line in iter(proc.stdout.readline, ''):
            #print(proc.returncode)
            yield highlight(line, BashLexer(), HtmlFormatter())

    return Response(stream_with_context(inner()), mimetype='text/html')  # text/html is required for most browsers to show the partial page immediately
@@ -31,26 +31,8 @@
 ate,
- request, jsonify,
  str
@@ -213,16 +213,43 @@
 process%0A
+import psutil%0A%0A%0Apid = None%0A
 %0A%0A@app.r
@@ -339,990 +339,8 @@
 )%0A%0A%0A
-## Include scripts with AJAX%0A@app.route('/_exec')%0Adef exec_script():%0A    %22%22%22 Executes given script %22%22%22%0A    script = request.args.get('script', None, type=str)%0A%0A    if script:%0A        path = %22scripts/%22%0A        cmd = %5B%22python3%22, path + script%5D%0A        p = subprocess.Popen(cmd, stdout=subprocess.PIPE,%0A                                  stderr=subprocess.PIPE,%0A                                  stdin=subprocess.PIPE)%0A        out, err = p.communicate()%0A%0A        # If there is any response, format it for HTML%0A        if out:%0A            out = highlight(out, BashLexer(), HtmlFormatter())%0A%0A        err = err.decode(%22utf-8%22)%0A%0A        if err.startswith(%22python3: can't open file '%22):%0A            err = %22Das Skript %3Cstrong%3E'%22 + script + %22'%3C/strong%3E konnte nicht gefunden werden.%22%0A        elif err:%0A            err = highlight(err, BashLexer(), HtmlFormatter())%0A%0A    else:%0A        out = None%0A        err = %22Es wurde kein Skript angegeben.%22%0A%0A    return jsonify(out=str(out), err=str(err))%0A%0A%0A
 @app
@@ -400,24 +400,44 @@
 ef inner():%0A
+        global pid%0A%0A
         path
@@ -492,17 +492,16 @@
 + %22.py%22%0A
-%0A
         
@@ -660,61 +660,23 @@
     
-#out, err = proc.communicate()%0A        print(%22hello%22)
+pid = proc.pid%0A
 %0A   
@@ -741,243 +741,568 @@
    #
-print(proc.returncode)%0A            yield highlight(line, BashLexer(), HtmlFormatter())%0A%0A    return Response(stream_with_context(inner()), mimetype='text/html')  # text/html is required for most browsers to show the partial page immediately
+ If process is done, break loop%0A            if not proc.poll() == 0:%0A                yield highlight(line, BashLexer(), HtmlFormatter())%0A            else:%0A                pid = None%0A                break%0A%0A    return Response(stream_with_context(inner()), mimetype='text/html')  # text/html is required for most browsers to show the partial page immediately%0A%0A@app.route('/kill-pid')%0Adef kill_pid():%0A    global pid%0A%0A    if pid:%0A        process = psutil.Process(pid)%0A        for proc in process.children(recursive=True):%0A            proc.kill()%0A        process.kill()

Break loop when subprocess is done