diff --git a/paternoster.py b/paternoster.py index 447d9cb..9a34fca 100755 --- a/paternoster.py +++ b/paternoster.py @@ -9,10 +9,10 @@ import re import sys import argparse import subprocess +import queue -def call( cmd, text, nowait=False ): - +def run( cmd, text, nowait=False ): # If there is a string formatting mark try: # put the matching text in it @@ -28,14 +28,21 @@ def call( cmd, text, nowait=False ): subprocess.call( behest, stdout=sys.stdout, stderr=dev_null, shell=True ) -def parse( text, pattern, cmd=[""], nowait=False ): +def call( cmd, text, nowait=False, queue=None ): + if queue: + queue.put( (cmd, text, nowait) ) + else: + run( cmd, text, nowait ) + + +def parse( text, pattern, cmd=[""], nowait=False, queue=None ): regex = re.compile(pattern) for match in regex.finditer(text): # If no groups are specified if not match.groups(): - call( cmd[0], text, nowait ) + call( cmd[0], text, nowait, queue ) else: nb_groups = len(match.groups()) @@ -51,7 +58,7 @@ def parse( text, pattern, cmd=[""], nowait=False ): for group in range(1, nb_groups+1): # If a group didn't match, there's nothing to do if match.group(group) is not None: - call( group_cmds[group-1], text[match.start(group):match.end(group)], nowait ) + call( group_cmds[group-1], text[match.start(group):match.end(group)], nowait, queue ) def write( text, stream = sys.stdout): @@ -70,7 +77,7 @@ def write( text, stream = sys.stdout): pass -def map_write( stream_in, stream_out, function, *args ): +def read_parse( stream_in, stream_out, pattern, cmd, nowait = False, at_end = False ): """ Read the given file-like object as a non-blocking stream and call the function on each item (line), @@ -81,6 +88,12 @@ def map_write( stream_in, stream_out, function, *args ): for item in sys.stdin.readlines(): write( function( *args ) ) """ + + if at_end: + events = queue.Queue(0) + else: + events = None + while True: try: item = stream_in.readline() @@ -93,8 +106,16 @@ def map_write( stream_in, stream_out, function, *args ): # Write the line being processed write( item, stream_out ) - # Then do something (blocking) - function(item, *args) + # Then do something + parse(item, pattern, cmd, nowait, events) + + if at_end: + while events.not_empty: + try: + run( *events.get_nowait() ) + except queue.Empty: + break + if __name__ == "__main__": @@ -116,7 +137,10 @@ if __name__ == "__main__": parser.add_argument("-w", "--no-wait", action="store_true", help="Don't wait for the end of the current command before calling the next one.") + parser.add_argument("-e", "--end", action="store_true", + help="Run commands at the end of the input stream.") + args = parser.parse_args() - map_write( sys.stdin, sys.stdout, parse, args.pattern[0], args.commands, args.no_wait ) + read_parse( sys.stdin, sys.stdout, args.pattern[0], args.commands, args.no_wait, args.end )