Removed aux.Command and friends. Functionality provided by over.core.cmd.
This commit is contained in:
parent
3103e577ad
commit
f418f28acf
2 changed files with 6 additions and 145 deletions
146
aux.py
146
aux.py
|
@ -3,152 +3,12 @@
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import pathlib
|
import pathlib
|
||||||
import queue
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
import threading
|
|
||||||
|
|
||||||
# --------------------------------------------------
|
|
||||||
|
|
||||||
def capture_output(stream, fifo):
|
|
||||||
while True:
|
|
||||||
chunk = stream.read1(128)
|
|
||||||
|
|
||||||
if chunk:
|
|
||||||
fifo.put(chunk)
|
|
||||||
else:
|
|
||||||
fifo.put(None) # indicates a process has terminated
|
|
||||||
break
|
|
||||||
|
|
||||||
stream.close()
|
|
||||||
|
|
||||||
class Command:
|
|
||||||
"""
|
|
||||||
A shell command with argument substitution and output capture.
|
|
||||||
|
|
||||||
>>> c = Command(["process.sh", "-x", "ARGUMENT"])
|
|
||||||
>>> c.ARGUMENT = "file.txt"
|
|
||||||
>>> c.dump()
|
|
||||||
['process.sh', '-x', 'file.txt']
|
|
||||||
>>> c.run(stderr=False) # capture stdout
|
|
||||||
>>> c.get_output()
|
|
||||||
b'some output'
|
|
||||||
>>> c.get_output()
|
|
||||||
b'' # there was no output since the last call
|
|
||||||
>>> c.get_output()
|
|
||||||
b'more of it\nand some more'
|
|
||||||
>>> c.get_output()
|
|
||||||
None # indicates the process ended and there is no more output
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, *sequence):
|
|
||||||
self.__dict__["sequence_original"] = list(sequence)
|
|
||||||
self.reset()
|
|
||||||
|
|
||||||
def __setattr__(self, name, value):
|
|
||||||
found = False
|
|
||||||
|
|
||||||
for i, word in enumerate(self.sequence):
|
|
||||||
if word == name:
|
|
||||||
self.sequence[i] = value
|
|
||||||
found = True
|
|
||||||
|
|
||||||
#if not found:
|
|
||||||
#raise AttributeError("Command has no attribute \'%s\'" %(name))
|
|
||||||
|
|
||||||
def reset(self):
|
|
||||||
self.__dict__["sequence"] = list(self.sequence_original)
|
|
||||||
self.__dict__["thread"] = None
|
|
||||||
self.__dict__["fifo"] = None
|
|
||||||
self.__dict__["terminated"] = False
|
|
||||||
|
|
||||||
def dump(self, sequence=None, pretty=False):
|
|
||||||
out = []
|
|
||||||
|
|
||||||
if not sequence:
|
|
||||||
sequence = self.sequence
|
|
||||||
|
|
||||||
for item in sequence:
|
|
||||||
if type(item) is list:
|
|
||||||
out += self.dump(item)
|
|
||||||
elif type(item) is Command:
|
|
||||||
out += item.dump()
|
|
||||||
elif item is not None:
|
|
||||||
out.append(str(item))
|
|
||||||
|
|
||||||
if pretty:
|
|
||||||
return [('"%s"' %(a) if ' ' in a else a) for a in out]
|
|
||||||
else:
|
|
||||||
return out
|
|
||||||
|
|
||||||
def run(self, stderr=False):
|
|
||||||
"""
|
|
||||||
Executes the command in the current environment.
|
|
||||||
|
|
||||||
stderr capture stderr instead of stdout
|
|
||||||
"""
|
|
||||||
|
|
||||||
self.__dict__["process"] = subprocess.Popen(self.dump(), stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=1)
|
|
||||||
self.__dict__["fifo"] = queue.Queue()
|
|
||||||
self.__dict__["thread"] = threading.Thread(
|
|
||||||
target=capture_output,
|
|
||||||
args=(self.process.stderr if stderr else self.process.stdout, self.fifo)
|
|
||||||
)
|
|
||||||
self.__dict__["terminated"] = False
|
|
||||||
self.thread.daemon = True # thread dies with the program
|
|
||||||
self.thread.start()
|
|
||||||
|
|
||||||
def get_output(self, blocking=False):
|
|
||||||
"""
|
|
||||||
Returns the output of a currently running process and clears the buffer.
|
|
||||||
|
|
||||||
Returns None if no process is running and no more output is available.
|
|
||||||
|
|
||||||
blocking block until some output is available or the process terminates
|
|
||||||
"""
|
|
||||||
|
|
||||||
buffer = []
|
|
||||||
|
|
||||||
if self.terminated:
|
|
||||||
return None
|
|
||||||
|
|
||||||
if blocking:
|
|
||||||
buffer.append(self.fifo.get())
|
|
||||||
|
|
||||||
while not self.fifo.empty():
|
|
||||||
buffer.append(self.fifo.get_nowait()) # FIXME nowait needed?
|
|
||||||
|
|
||||||
if None in buffer:
|
|
||||||
self.__dict__["terminated"] = True
|
|
||||||
self.__dict__["returncode"] = self.process.poll()
|
|
||||||
|
|
||||||
if len(buffer) == 1:
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
assert(buffer[-1] is None)
|
|
||||||
del buffer[-1]
|
|
||||||
|
|
||||||
return b"".join(buffer)
|
|
||||||
|
|
||||||
def get_all_output(self):
|
|
||||||
buffer = []
|
|
||||||
|
|
||||||
while True:
|
|
||||||
chunk = self.get_output(blocking=True)
|
|
||||||
|
|
||||||
if chunk is None:
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
buffer.append(chunk)
|
|
||||||
|
|
||||||
return b''.join(buffer) if buffer else None
|
|
||||||
|
|
||||||
# --------------------------------------------------
|
# --------------------------------------------------
|
||||||
|
|
||||||
def parse_fps(raw):
|
def parse_fps(raw):
|
||||||
if "/" in raw:
|
if '/' in raw:
|
||||||
num, den = (int(x) for x in raw.split("/"))
|
num, den = (int(x) for x in raw.split('/'))
|
||||||
|
|
||||||
return float(num) / float(den)
|
return float(num) / float(den)
|
||||||
|
|
||||||
|
@ -158,7 +18,7 @@ def parse_fps(raw):
|
||||||
|
|
||||||
def to_Path(raw_path):
|
def to_Path(raw_path):
|
||||||
'''
|
'''
|
||||||
Returns pathlib.Path pointing to raw_path, handling "~/" correctly.
|
Returns pathlib.Path pointing to raw_path, handling '~/' correctly.
|
||||||
|
|
||||||
To be removed after python:3.5 move.
|
To be removed after python:3.5 move.
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -6,13 +6,14 @@ import os
|
||||||
import over
|
import over
|
||||||
import pathlib
|
import pathlib
|
||||||
import re
|
import re
|
||||||
import subprocess
|
|
||||||
import tempfile
|
import tempfile
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from aux import Command, parse_fps, to_Path
|
from aux import parse_fps, to_Path
|
||||||
from version import _version
|
from version import _version
|
||||||
|
|
||||||
|
Command = over.core.cmd.Command
|
||||||
|
|
||||||
# --------------------------------------------------
|
# --------------------------------------------------
|
||||||
|
|
||||||
prefix = over.core.textui.prefix
|
prefix = over.core.textui.prefix
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue