mirror of https://github.com/chriskiehl/Gooey.git
1 changed files with 80 additions and 0 deletions
Unified 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