[color=#408080][i]#!/usr/bin/env python[/i][/color] [color=#008000][b]import[/b][/color] [color=#0000FF][b]subprocess[/b][/color] [color=#008000][b]from[/b][/color] [color=#0000FF][b]twisted.internet[/b][/color] [color=#008000][b]import[/b][/color] defer, stdio, protocol, reactor [color=#008000][b]from[/b][/color] [color=#0000FF][b]twisted.protocols[/b][/color] [color=#008000][b]import[/b][/color] basic [color=#008000][b]class[/b][/color] [color=#0000FF][b]Repl[/b][/color](basic[color=#666666].[/color]LineReceiver): delimiter [color=#666666]=[/color] [color=#BA2121]'[/color][color=#BB6622][b]\n[/b][/color][color=#BA2121]'[/color] prompt_string [color=#666666]=[/color] [color=#BA2121]'>>> '[/color] [color=#008000][b]def[/b][/color] [color=#0000FF]prompt[/color]([color=#008000]self[/color]): [color=#008000]self[/color][color=#666666].[/color]transport[color=#666666].[/color]write([color=#008000]self[/color][color=#666666].[/color]prompt_string) [color=#008000][b]def[/b][/color] [color=#0000FF]connectionMade[/color]([color=#008000]self[/color]): [color=#008000]self[/color][color=#666666].[/color]sendLine([color=#BA2121]'Welcome to Repl'[/color]) [color=#408080][i]# store factory and connector upon connection to the stdout[/i][/color] [color=#008000]self[/color][color=#666666].[/color]factory [color=#666666]=[/color] CFactory() [color=#008000]self[/color][color=#666666].[/color]connector [color=#666666]=[/color] reactor[color=#666666].[/color]connectTCP( [color=#BA2121]'127.0.0.1'[/color], [color=#666666]1234[/color], [color=#008000]self[/color][color=#666666].[/color]factory) [color=#008000]self[/color][color=#666666].[/color]prompt() [color=#008000][b]def[/b][/color] [color=#0000FF]lineReceived[/color]([color=#008000]self[/color], line): [color=#008000][b]if[/b][/color] [color=#AA22FF][b]not[/b][/color] line: [color=#008000]self[/color][color=#666666].[/color]prompt() [color=#008000][b]return[/b][/color] [color=#008000]self[/color][color=#666666].[/color]issueCommand(line) [color=#008000][b]def[/b][/color] [color=#0000FF]issueCommand[/color]([color=#008000]self[/color], command): [color=#408080][i]# write to the connector's transport, not the one writing on stdout[/i][/color] [color=#008000]self[/color][color=#666666].[/color]connector[color=#666666].[/color]transport[color=#666666].[/color]write([color=#BA2121]"[/color][color=#BB6688][b]%s%s[/b][/color][color=#BA2121]"[/color] [color=#666666]%[/color] (command, [color=#008000]self[/color][color=#666666].[/color]delimiter)) [color=#408080][i]# register the callback on the factory's deferred[/i][/color] [color=#008000]self[/color][color=#666666].[/color]factory[color=#666666].[/color]deferred[color=#666666].[/color]addCallback([color=#008000]self[/color][color=#666666].[/color]_checkResponse) [color=#008000][b]def[/b][/color] [color=#0000FF]_checkResponse[/color]([color=#008000]self[/color], args): success, num_lines, data [color=#666666]=[/color] args [color=#008000][b]if[/b][/color] num_lines [color=#666666]>[/color] [color=#666666]20[/color]: [color=#008000]self[/color][color=#666666].[/color]lessify(data) [color=#008000][b]else[/b][/color]: [color=#008000]self[/color][color=#666666].[/color]sendLine(data) [color=#008000]self[/color][color=#666666].[/color]prompt() [color=#408080][i]# recreate the deferred each time we have the response[/i][/color] [color=#008000]self[/color][color=#666666].[/color]factory[color=#666666].[/color]deferred [color=#666666]=[/color] defer[color=#666666].[/color]Deferred() [color=#008000][b]def[/b][/color] [color=#0000FF]lessify[/color]([color=#008000]self[/color], data): p [color=#666666]=[/color] subprocess[color=#666666].[/color]Popen([[color=#BA2121]"less"[/color]], stdin[color=#666666]=[/color]subprocess[color=#666666].[/color]PIPE) p[color=#666666].[/color]stdin[color=#666666].[/color]write(data) p[color=#666666].[/color]stdin[color=#666666].[/color]close() p[color=#666666].[/color]wait() [color=#008000][b]class[/b][/color] [color=#0000FF][b]Client[/b][/color](basic[color=#666666].[/color]LineReceiver): delimiter [color=#666666]=[/color] [color=#BA2121]'[/color][color=#BB6622][b]\n[/b][/color][color=#BA2121]'[/color] [color=#008000][b]def[/b][/color] [color=#0000FF]connectionMade[/color]([color=#008000]self[/color]): [color=#008000]self[/color][color=#666666].[/color]buffer [color=#666666]=[/color] [] [color=#008000]self[/color][color=#666666].[/color]cmd_success [color=#666666]=[/color] [color=#008000]True[/color] [color=#008000][b]def[/b][/color] [color=#0000FF]lineReceived[/color]([color=#008000]self[/color], line): [color=#008000][b]if[/b][/color] line[color=#666666].[/color]startswith([color=#BA2121]'OK'[/color]): [color=#008000][b]return[/b][/color] [color=#008000][b]if[/b][/color] line[color=#666666].[/color]startswith([color=#BA2121]'ERR'[/color]): [color=#008000]self[/color][color=#666666].[/color]cmd_success [color=#666666]=[/color] [color=#008000]False[/color] [color=#008000][b]return[/b][/color] [color=#008000][b]if[/b][/color] line [color=#666666]==[/color] [color=#BA2121]'END'[/color]: [color=#008000]self[/color][color=#666666].[/color]responseFinished( [color=#008000]len[/color]([color=#008000]self[/color][color=#666666].[/color]buffer), [color=#BA2121]"[/color][color=#BB6622][b]\n[/b][/color][color=#BA2121]"[/color][color=#666666].[/color]join([color=#008000]self[/color][color=#666666].[/color]buffer)) [color=#008000]self[/color][color=#666666].[/color]buffer [color=#666666]=[/color] [] [color=#008000][b]else[/b][/color]: [color=#008000]self[/color][color=#666666].[/color]buffer[color=#666666].[/color]append(line) [color=#008000][b]def[/b][/color] [color=#0000FF]responseFinished[/color]([color=#008000]self[/color], num_lines, data): [color=#408080][i]# just fire the callback[/i][/color] [color=#008000]self[/color][color=#666666].[/color]factory[color=#666666].[/color]deferred[color=#666666].[/color]callback(( [color=#008000]self[/color][color=#666666].[/color]cmd_success, num_lines, data)) [color=#008000][b]def[/b][/color] [color=#0000FF]connectionLost[/color]([color=#008000]self[/color], reason): reactor[color=#666666].[/color]stop() [color=#008000][b]class[/b][/color] [color=#0000FF][b]CFactory[/b][/color](protocol[color=#666666].[/color]ClientFactory): protocol [color=#666666]=[/color] Client [color=#008000][b]def[/b][/color] [color=#0000FF]__init__[/color]([color=#008000]self[/color]): [color=#008000]self[/color][color=#666666].[/color]deferred [color=#666666]=[/color] defer[color=#666666].[/color]Deferred() [color=#008000][b]if[/b][/color] __name__ [color=#666666]==[/color] [color=#BA2121]"__main__"[/color]: stdio[color=#666666].[/color]StandardIO(Repl()) reactor[color=#666666].[/color]run()