diff --git a/aux.py b/aux.py index f651bf8..f259a7c 100644 --- a/aux.py +++ b/aux.py @@ -3,152 +3,12 @@ import os 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): - if "/" in raw: - num, den = (int(x) for x in raw.split("/")) + if '/' in raw: + num, den = (int(x) for x in raw.split('/')) return float(num) / float(den) @@ -158,7 +18,7 @@ def parse_fps(raw): 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. ''' diff --git a/over-video.py b/over-video.py index bb59a9f..f541ae0 100755 --- a/over-video.py +++ b/over-video.py @@ -6,13 +6,14 @@ import os import over import pathlib import re -import subprocess import tempfile import time -from aux import Command, parse_fps, to_Path +from aux import parse_fps, to_Path from version import _version +Command = over.core.cmd.Command + # -------------------------------------------------- prefix = over.core.textui.prefix