mirror of https://github.com/chriskiehl/Gooey.git
1 changed files with 80 additions and 0 deletions
Split View
Diff Options
@ -0,0 +1,80 @@ |
|||
import os |
|||
import re |
|||
import subprocess |
|||
|
|||
from functools import partial |
|||
from multiprocessing.dummy import Pool |
|||
|
|||
from gooey.gui.pubsub import pub |
|||
from gooey.gui.util.casting import safe_float |
|||
from gooey.gui.util.functional import unit, bind |
|||
|
|||
|
|||
class ProcessController(object): |
|||
def __init__(self, progress_regex, progress_expr): |
|||
self._process = None |
|||
self.progress_regex = progress_regex |
|||
self.progress_expr = progress_expr |
|||
|
|||
def was_success(self): |
|||
self._process.communicate() |
|||
return self._process.returncode == 0 |
|||
|
|||
def poll(self): |
|||
if not self._process: |
|||
raise Exception('Not started!') |
|||
self._process.poll() |
|||
|
|||
def run(self, command): |
|||
env = os.environ.copy() |
|||
env["GOOEY"] = "1" |
|||
self._process = subprocess.Popen(command, bufsize=1, stdout=subprocess.PIPE, |
|||
stderr=subprocess.STDOUT, shell=True, env=env) |
|||
Pool(1).apply_async(self._forward_stdout, (self._process,)) |
|||
|
|||
def _forward_stdout(self, process): |
|||
''' |
|||
Reads the stdout of `process` and forwards lines and progress |
|||
to any interested subscribers |
|||
''' |
|||
while True: |
|||
line = process.stdout.readline() |
|||
if not line: |
|||
break |
|||
pub.send_message('console_update', msg=line) |
|||
pub.send_message('progress_update', progress=self._extract_progress(line)) |
|||
pub.send_message('execution_complete') |
|||
|
|||
def _extract_progress(self, text): |
|||
''' |
|||
Finds progress information in the text using the |
|||
user-supplied regex and calculation instructions |
|||
''' |
|||
# monad-ish dispatch to avoid the if/else soup |
|||
find = partial(re.search, string=text.strip()) |
|||
regex = unit(self.progress_regex) |
|||
match = bind(regex, find) |
|||
result = bind(match, self._calculate_progress) |
|||
return result |
|||
|
|||
def _calculate_progress(self, match): |
|||
''' |
|||
Calculates the final progress value found by the regex |
|||
''' |
|||
if not self.progress_expr: |
|||
return safe_float(match.group(1)) |
|||
else: |
|||
return self._eval_progress(match) |
|||
|
|||
def _eval_progress(self, match): |
|||
''' |
|||
Runs the user-supplied progress calculation rule |
|||
''' |
|||
_locals = {k: safe_float(v) for k, v in match.groupdict().items()} |
|||
if "x" not in _locals: |
|||
_locals["x"] = [safe_float(x) for x in match.groups()] |
|||
try: |
|||
return int(eval(self.progress_expr, {}, _locals)) |
|||
except: |
|||
return None |
|||
|
Write
Preview
Loading…
Cancel
Save