Reorganized code, added Wallaby hostnames, added sync, added compile view, improved window handling

This commit is contained in:
PhilipTrauner 2016-03-29 23:48:23 +02:00
parent 2ef7a5c1c1
commit 23c937b356

View file

@ -19,34 +19,30 @@ import sublime_plugin
import socket import socket
from ESock import ESock from ESock import ESock
from Utils import capture_trace from Utils import capture_trace
from Sync import SyncClient
import Routing import Routing
from SublimeMenu import * from SublimeMenu import *
import Logging import Logging
import webbrowser import webbrowser
CHANNEL = "s"
def plugin_unloaded(): def plugin_unloaded():
observer.stop()
try:
for window in windows: for window in windows:
if hasattr(window, "fl0w"): if hasattr(window, "fl0w"):
window.fl0w.invoke_disconnect() window.fl0w.invoke_disconnect()
except:
print("Error while unloading fl0w for %s" % window.folders())
print("Observer stopped!")
def sock_handler(sock, routes, handler): def sock_handler(sock, routes, handler):
sock.send("st", "set_type")
while 1: while 1:
try: try:
data = sock.recv() data = sock.recv()
if data[1] in routes: if data[1] in routes:
routes[data[1]].run(data[0], handler) routes[data[1]].run(data[0], handler)
except (OSError, socket.error, Exception) as e: except (OSError, socket.error, Exception) as e:
if e is Exception: if str(e) != "[Errno 9] Bad file descriptor":
Logging.info("Exception occured in network thread.")
capture_trace() capture_trace()
handler.invoke_disconnect() handler.invoke_disconnect()
break break
@ -62,6 +58,7 @@ class ReloadHandler(FileSystemEventHandler):
def on_deleted(self, event): def on_deleted(self, event):
print("Deleted: %s" % event) print("Deleted: %s" % event)
class Fl0w: class Fl0w:
def __init__(self, window): def __init__(self, window):
self.connected = False self.connected = False
@ -79,23 +76,95 @@ class Fl0w:
self.main_menu.add(Entry("Disconnect", "Disconnect from server", action=self.invoke_disconnect)) self.main_menu.add(Entry("Disconnect", "Disconnect from server", action=self.invoke_disconnect))
def invoke_about(self):
if sublime.ok_cancel_dialog("fl0w by @robot0nfire", "robot0nfire.com"):
webbrowser.open("http://robot0nfire.com")
def invoke_info(self):
self.sock.send("", "info")
class Info(Routing.ClientRoute):
def run(self, data, handler):
sublime.message_dialog(data)
handler.main_menu.invoke(handler.window)
class GetInfo(Routing.ClientRoute):
def run(self, data, handler):
if data == "":
handler.sock.send({"type" : CHANNEL}, "get_info")
class ErrorReport(Routing.ClientRoute): class ErrorReport(Routing.ClientRoute):
def run(self, data, handler): def run(self, data, handler):
sublime.error_message(data) sublime.error_message(data)
class Compile(Routing.ClientRoute):
def run(self, data, handler):
status = ""
if data["failed"]:
status = "Compile failed (%s)." % data["relpath"]
else:
status = "Compile completed successfully. (%s)." % data["relpath"]
view = handler.window.create_output_panel('compile_panel')
view.set_syntax_file("Packages/fl0w/CompileHighlight.sublime-syntax")
view.settings().set("draw_white_space", "none")
view.settings().set("draw_indent_guides", False)
view.settings().set("gutter", False)
view.settings().set("line_numbers", False)
view.set_read_only(False)
view.run_command("append", {"characters": data["returned"] + status})
view.set_read_only(True)
handler.window.run_command("show_panel", {"panel": "output.compile_panel"})
def connect(self, connect_details):
connect_details_raw = connect_details
connect_details = connect_details.split(":")
if len(connect_details) == 2:
try:
# Establish connection to the server
self.sock = ESock(socket.create_connection((connect_details[0], int(connect_details[1]))), disconnect_callback=self.invoke_disconnect, debug=False)
sublime.status_message("Connected to %s:%s." % (connect_details[0], connect_details[1]))
self.connected = True
# Initialize all routes
error_report = Fl0w.ErrorReport()
info = Fl0w.Info()
wallaby_control = Fl0w.WallabyControl()
get_info = Fl0w.GetInfo()
self.s_sync = SyncClient(self.sock, self.folder, "s_sync")
compile = Fl0w.Compile()
_thread.start_new_thread(sock_handler, (self.sock, {"error_report": error_report,
"info" : info, "wallaby_control" : wallaby_control, "get_info" : get_info,
"s_sync" : self.s_sync, "compile" : compile}, self))
self.s_sync.start()
# Saving last server address
sublime.load_settings("fl0w.sublime-setting").set("server_address", connect_details_raw)
sublime.save_settings("fl0w.sublime-setting")
except OSError as e:
sublime.error_message("Error during connection creation:\n %s" % str(e))
else:
sublime.error_message("Invalid input.")
# Input invokers # Input invokers
def invoke_connect(self): def invoke_connect(self):
address = sublime.load_settings("fl0w.sublime-setting").get("server_address") address = sublime.load_settings("fl0w.sublime-setting").get("server_address")
address = "" if type(address) is not str else address address = "" if type(address) is not str else address
Input("Address:Port", initial_text=address, on_done=self.connect).invoke(self.window) Input("Address:Port", initial_text=address, on_done=self.connect).invoke(self.window)
def invoke_about(self):
if sublime.ok_cancel_dialog("fl0w by @robot0nfire", "robot0nfire.com"): def invoke_disconnect(self):
webbrowser.open("http://robot0nfire.com") if self.connected:
sublime.message_dialog("Connection closed ('%s')" % ", ".join(self.folder))
if hasattr(self, "s_sync"):
self.s_sync.observer.stop()
self.connected = False
self.sock.close()
def invoke_wallaby_control(self): def invoke_wallaby_control(self):
self.sock.send("list", "wallaby_control") self.sock.send("list", "wallaby_control")
@ -103,21 +172,25 @@ class Fl0w:
class WallabyControl(Routing.ClientRoute): class WallabyControl(Routing.ClientRoute):
def run(self, data, handler): def run(self, data, handler):
wallaby_menu = Menu(subtitles=False) wallaby_menu = Menu()
entry_count = 0 entry_count = 0
for wallaby in data: for wallaby in data:
wallaby_menu.add(Entry(wallaby, action=handler.wallaby_control_submenu, kwargs={"wallaby" : wallaby})) wallaby_menu.add(Entry(wallaby, str(data[wallaby]), action=handler.wallaby_control_submenu, kwargs={"wallaby" : wallaby}))
entry_count += 1 entry_count += 1
if entry_count != 0: if entry_count != 0:
wallaby_menu.invoke(handler.window, back=handler.main_menu) wallaby_menu.invoke(handler.window, back=handler.main_menu)
else: else:
sublime.error_message("No Wallabies connected.") sublime.error_message("No Wallaby Controllers connected.")
def wallaby_control_submenu(self, wallaby): def wallaby_control_submenu(self, wallaby):
menu = Menu(subtitles=False) menu = Menu(subtitles=False)
for command in ("Stop", "Restart", "Shutdown", "Reboot", "Disconnect"): for action in ("Run", "Stop"):
menu.add(Entry(command, action=self.sock.send, kwargs={"data" : {wallaby : command.lower()}, "route" : "wallaby_control"})) menu.add(Entry(action, action=self.sock.send, kwargs={"data" : {wallaby : action.lower()}, "route" : "wallaby_control"}))
for action in ("Restart", "Shutdown", "Reboot", "Disconnect"):
menu.add(Entry(action, action=self.sock.send, kwargs={"data" : {wallaby : action.lower()}, "route" : "wallaby_control"}))
menu.invoke(self.window) menu.invoke(self.window)
@ -133,48 +206,8 @@ class Fl0w:
self.sock.debug = debug self.sock.debug = debug
def invoke_info(self):
self.sock.send("", "info")
class Info(Routing.ClientRoute):
def run(self, data, handler):
sublime.message_dialog(data)
handler.main_menu.invoke(handler.window)
def invoke_disconnect(self):
if self.connected:
sublime.message_dialog("Connection closed ('%s')" % ", ".join(self.window.folders()))
self.connected = False
self.sock.close()
def connect(self, connect_details):
connect_details_raw = connect_details
connect_details = connect_details.split(":")
if len(connect_details) == 2:
try:
# Establish connection to the server
self.sock = ESock(socket.create_connection((connect_details[0], int(connect_details[1]))), disconnect_callback=self.invoke_disconnect, debug=True)
sublime.status_message("Connected to %s:%s." % (connect_details[0], connect_details[1]))
self.connected = True
_thread.start_new_thread(sock_handler, (self.sock, {"error_report": Fl0w.ErrorReport(),
"info" : Fl0w.Info(), "wallaby_control" : Fl0w.WallabyControl()}, self))
# Saving last server address
sublime.load_settings("fl0w.sublime-setting").set("server_address", connect_details_raw)
sublime.save_settings("fl0w.sublime-setting")
self.main_menu.invoke(self.window)
except OSError as e:
sublime.error_message("Error during connection creation:\n %s" % str(e))
else:
sublime.error_message("Invalid input.")
class Fl0wCommand(sublime_plugin.WindowCommand): class Fl0wCommand(sublime_plugin.WindowCommand):
def run(self, menu=None, action=None): def run(self):
valid_window_setup = True valid_window_setup = True
folder_count = len(self.window.folders()) folder_count = len(self.window.folders())
if folder_count > 1: if folder_count > 1:
@ -188,7 +221,7 @@ class Fl0wCommand(sublime_plugin.WindowCommand):
folder = self.window.folders()[0] folder = self.window.folders()[0]
files = os.listdir(folder) files = os.listdir(folder)
if not ".no-fl0w" in files: if not ".no-fl0w" in files:
if not ".flow" in files: if not ".fl0w" in files:
if sublime.ok_cancel_dialog("""We've detected that this is your first time using fl0w in your current directory. if sublime.ok_cancel_dialog("""We've detected that this is your first time using fl0w in your current directory.
We don't want to be responsible for any lost work so please backup your files before proceding. We don't want to be responsible for any lost work so please backup your files before proceding.
(An empty project directory is recommended but not necessary.)""", "Yes"): (An empty project directory is recommended but not necessary.)""", "Yes"):
@ -201,6 +234,7 @@ class Fl0wCommand(sublime_plugin.WindowCommand):
else: else:
self.window.fl0w = Fl0w(self.window) self.window.fl0w = Fl0w(self.window)
windows.append(self.window) windows.append(self.window)
self.window.fl0w.start_menu.invoke(self.window)
else: else:
sublime.error_message("fl0w can't be opened in your current directory (.no-fl0w file exists)") sublime.error_message("fl0w can't be opened in your current directory (.no-fl0w file exists)")
else: else:
@ -210,11 +244,15 @@ class Fl0wCommand(sublime_plugin.WindowCommand):
self.window.fl0w.main_menu.invoke(self.window) self.window.fl0w.main_menu.invoke(self.window)
else: else:
if hasattr(self.window, "fl0w"): if hasattr(self.window, "fl0w"):
sublime.error_message("Window setup was invalidated (Don't close or open any additional folders in a fl0w window)")
if self.window.fl0w.connected: if self.window.fl0w.connected:
self.window.fl0w.invoke_disconnect() self.window.fl0w.invoke_disconnect()
def description(self):
print("description accessed")
if hasattr(self.windows, "fl0w"):
return "Connected."
return None
windows = [] windows = []
observer = Observer()
observer.schedule(ReloadHandler(), path=".", recursive=True)
#observer.start()