Python Twisted Cmd Module Integration

I like Python Twisted and Cmd . I want to use them together.

I have something working, but so far I have not figured out how to do the work of completing the work, because I do not see how to immediately receive tab keypres events (without pressing Enter) in Twisted LineReceiver.

Here is my code:

#!/usr/bin/env python from cmd import Cmd from twisted.internet import reactor from twisted.internet.stdio import StandardIO from twisted.protocols.basic import LineReceiver class CommandProcessor(Cmd): def do_EOF(self, line): return True class LineProcessor(LineReceiver): from os import linesep as delimiter # makes newline work def __init__(self): self.processor = CommandProcessor() self.setRawMode() def connectionMade(self): self.transport.write('>>> ') def rawDataReceived(self, data): self.processor.onecmd(data) self.transport.write('>>> ') StandardIO(LineProcessor()) reactor.run() 

Besides completing the tab, this works somewhat. I can enter the command as "help" and the Cmd module will print the results. But I have lost the excellent functionality of the Cmd module, since Twisted buffers one line at a time. I tried setting LineProcessor.delimiter to an empty string, but to no avail. Maybe I need to find another part of Twisted to use instead of LineReceiver? Or maybe there is a simpler approach that will allow me not to process each character one by one?

I canโ€™t use only Cmd, because I want to make it a network application, when some commands lead to sending data, and receiving data from the network will occur asynchronously (and will be displayed to the user).

So, regardless of whether we start with the above code or something completely different, I would like to create a nice friendly Python terminal application that responds to network events, as well as to the completion of the tab. I hope that I can use what is already there, and I donโ€™t need to realize myself too much.

+6
source share
1 answer

You have a couple of difficulties with this approach:

  • Cmd.onecmd will not handle the tab.
  • Even so, your terminal must be in cbreak mode so that individual keystrokes can go to the Python interpreter ( tty.setcbreak can take care of this).
  • As you know, Cmd.cmdloop does not know about the reactor and blocks waiting for input.
  • However, in order to get all the great line editing, Cmd (actually readline) must have direct access to stdin and stdout.

Given all these difficulties, you might want to run CommandProcessor in your thread. For instance:

 #!/usr/bin/env python from cmd import Cmd from twisted.internet import reactor class CommandProcessor(Cmd): def do_EOF(self, line): return True def do_YEP(self, line): reactor.callFromThread(on_main_thread, "YEP") def do_NOPE(self, line): reactor.callFromThread(on_main_thread, "NOPE") def on_main_thread(item): print "doing", item def heartbeat(): print "heartbeat" reactor.callLater(1.0, heartbeat) reactor.callLater(1.0, heartbeat) reactor.callInThread(CommandProcessor().cmdloop) reactor.run() 
+9
source

Source: https://habr.com/ru/post/904117/


All Articles