| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- #!/usr/bin/python
- # Copyright (c) 2013 Daniele Bartolini, Michele Rossi
- # Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
- #
- # Permission is hereby granted, free of charge, to any person
- # obtaining a copy of this software and associated documentation
- # files (the "Software"), to deal in the Software without
- # restriction, including without limitation the rights to use,
- # copy, modify, merge, publish, distribute, sublicense, and/or sell
- # copies of the Software, and to permit persons to whom the
- # Software is furnished to do so, subject to the following
- # conditions:
- #
- # The above copyright notice and this permission notice shall be
- # included in all copies or substantial portions of the Software.
- #
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- # OTHER DEALINGS IN THE SOFTWARE.
- import sys
- import os
- import socket
- import threading
- from gi.repository import Gtk
- # Client Console commands
- CMD_CLEAR = "clear" # Clear console output
- CMD_EXIT_1 = "exit" # Close console
- CMD_EXIT_2 = "Device.stop()" # Close console
- CMD_HELP = "help" # Console help
- CMD_HISTORY = "history" # History
- CMD_VOID = ""
- class ReaderThread(threading.Thread):
- #------------------------------------------------------------------------------
- def __init__(self, console):
- threading.Thread.__init__(self)
- self.t_console = console
- self.t_stop = threading.Event()
- self.t_is_running = True
- #------------------------------------------------------------------------------
- def stop(self):
- self.t_stop.set()
- self.t_is_running = False
- #------------------------------------------------------------------------------
- def stopped(self):
- return self.t_stop.isSet()
- #------------------------------------------------------------------------------
- def run(self):
- while self.t_is_running:
- self.t_tmp = self.t_console.m_sock.recv(1024)
- if self.t_tmp != "":
- self.t_tmp = self.t_tmp.decode("utf-8")
- self.t_error = self.t_tmp.split('\x00', 1)[0]
- self.t_console.print_error(self.t_error)
- class ConsoleHistory:
- #------------------------------------------------------------------------------
- def __init__(self):
- self.m_list = list()
- self.m_count = 0
- self.m_index = 0
- #------------------------------------------------------------------------------
- def add(self, cmd):
- self.m_list.append(cmd)
- self.m_count += 1
- self.m_index = self.m_count
- #------------------------------------------------------------------------------
- def previous(self):
- if self.m_count != 0:
- self.m_index -= 1
- if self.m_index < 0:
- self.m_index = 0
- return self.m_list[self.m_index]
- return ""
- #------------------------------------------------------------------------------
- def following(self):
- if self.m_count != 0:
- self.m_index += 1
- if self.m_index > self.m_count-1:
- self.m_index = self.m_count - 1
- return self.m_list[self.m_index]
- return ""
- class Console:
- #------------------------------------------------------------------------------
- def __init__(self, address):
- builder = Gtk.Builder()
- builder.add_from_file("ui/console.glade")
-
- self.m_view = builder.get_object("textview1")
- self.m_buffer = builder.get_object("textbuffer1")
- self.m_entry = builder.get_object("entry1")
-
- self.m_window = builder.get_object('window1')
- self.m_window.set_title("Crown Console")
- self.m_window.show_all()
- builder.connect_signals(self)
- self.m_address = address
- self.m_error_buffer = ""
- self.history = ConsoleHistory()
- self.m_sock = socket.create_connection((self.m_address, 10000))
- self.m_thread = ReaderThread(self)
- self.m_thread.start()
- self.m_formatter = self.m_buffer.create_tag("console", foreground="green")
- Gtk.main()
- #------------------------------------------------------------------------------
- def on_destroy(self, *args):
- self.m_sock.close()
- self.m_thread.stop()
- Gtk.main_quit(*args)
- #------------------------------------------------------------------------------
- def on_key_pressed(self, entry, event):
- # If return is pressed, run command
- if event.keyval == 0xff0d:
- cmd = entry.get_text()
- self.parse_command(cmd)
- return True
- if event.keyval == 0xff52:
- cmd = self.history.previous()
- self.print_to_entry(cmd)
- return True
- if event.keyval == 0xff54:
- cmd = self.history.following()
- self.print_to_entry(cmd)
- return True
- #------------------------------------------------------------------------------
- def parse_command(self, cmd):
- self.history.add(cmd)
- if cmd == CMD_CLEAR:
- self.m_buffer.set_text("")
- self.m_entry.set_text("")
- elif cmd == CMD_EXIT_1:
- self.on_destroy()
- elif cmd == CMD_EXIT_2:
- self.run_command(cmd)
- self.on_destroy()
- elif cmd == CMD_HELP:
- self.print_help()
- elif cmd == CMD_VOID:
- self.print_command("");
- else:
- self.run_command(cmd)
- #------------------------------------------------------------------------------
- def run_command(self, cmd):
- self.m_sock.send(cmd.encode('utf-8'))
- self.print_command(cmd)
- #------------------------------------------------------------------------------
- def print_command(self, text):
- # Print command to console
- start_iter = self.m_buffer.get_end_iter()
- a_string = "> " + text + "\n"
- # Append command to the end of buffer
- self.m_buffer.insert(start_iter, a_string, len(a_string))
- self.m_view.scroll_mark_onscreen(self.m_buffer.get_insert())
- # Reset entry
- self.print_to_entry("")
- #------------------------------------------------------------------------------
- def print_error(self, text):
- start_iter = self.m_buffer.get_end_iter()
- a_string = "> " + text + "\n"
- self.m_buffer.insert(start_iter, a_string, len(a_string))
- self.m_view.scroll_mark_onscreen(self.m_buffer.get_insert())
- #------------------------------------------------------------------------------
- def print_to_entry(self, text):
- self.m_entry.set_text(text)
- #------------------------------------------------------------------------------
- # def popup_dialog(self, message, expl):
- # dialog = Gtk.MessageDialog(self.m_window, 0, Gtk.MessageType.INFO, Gtk.ButtonsType.OK, message)
- # dialog.format_secondary_text(expl)
- # dialog.run()
- # dialog.destroy()
- #------------------------------------------------------------------------------
- #------------------------------------------------------------------------------
- def main():
- if len(sys.argv) != 2:
- print("Usage: console.py <ip-address>")
- exit(-1)
- address = sys.argv[1]
- console = Console(address)
- main()
-
|