|
@@ -36,84 +36,78 @@ import beewatch
|
|
import beewatch.pinapi
|
|
import beewatch.pinapi
|
|
|
|
|
|
log = logging.getLogger(__name__+"")
|
|
log = logging.getLogger(__name__+"")
|
|
-lapi = logging.getLogger(__name__+".api")
|
|
|
|
-lchat = logging.getLogger(__name__+".chat")
|
|
|
|
|
|
+# lapi = logging.getLogger(__name__+".api")
|
|
|
|
+# lschat = logging.getLogger(__name__+".schat")
|
|
|
|
+lch = logging.getLogger(__name__+".chandler")
|
|
lserver = logging.getLogger(__name__+".server")
|
|
lserver = logging.getLogger(__name__+".server")
|
|
|
|
|
|
class BeeWatchServer(digilib.network.Server):
|
|
class BeeWatchServer(digilib.network.Server):
|
|
- """docstring for Server."""
|
|
|
|
|
|
+ """
|
|
|
|
+ BeeWatchServer is a subclass of digilib.network.Server. It connects to
|
|
|
|
+ the gpio control socket and adds protetction by requireing user
|
|
|
|
+ authentification. This isn't implemented yet.
|
|
|
|
+ """
|
|
|
|
|
|
def __init__(self,*args,**kwargs):
|
|
def __init__(self,*args,**kwargs):
|
|
super(BeeWatchServer, self).__init__(
|
|
super(BeeWatchServer, self).__init__(
|
|
*args,
|
|
*args,
|
|
- **kwargs,
|
|
|
|
handler_class=beewatch.server.ConnHandlerBeeWatch,
|
|
handler_class=beewatch.server.ConnHandlerBeeWatch,
|
|
|
|
+ **kwargs,
|
|
)
|
|
)
|
|
|
|
|
|
def make_socket(self):
|
|
def make_socket(self):
|
|
s = super(BeeWatchServer,self).make_socket()
|
|
s = super(BeeWatchServer,self).make_socket()
|
|
|
|
+ # only for debugging because I'm impatient and don't want to wait
|
|
|
|
+ lch.warning("setting sokopt SO_REUSEADDR to 1. DEBUGGING ONLY")
|
|
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
return s
|
|
return s
|
|
|
|
|
|
class ConnHandlerBeeWatch(digilib.network.ConnHandlerBase):
|
|
class ConnHandlerBeeWatch(digilib.network.ConnHandlerBase):
|
|
-
|
|
|
|
|
|
+ """
|
|
|
|
+ Connection handler for the beewatch server. Applies permission system,
|
|
|
|
+ parses commands and tells apis what to do.
|
|
|
|
+ """
|
|
def __init__(self, socket, addr, server):
|
|
def __init__(self, socket, addr, server):
|
|
super(ConnHandlerBeeWatch, self).__init__(socket, addr, server)
|
|
super(ConnHandlerBeeWatch, self).__init__(socket, addr, server)
|
|
- self.engines_ctrl = beewatch._controllers["engines_ctrl"]
|
|
|
|
- # digilib.pin.EnginesController(
|
|
|
|
- # left=[4,17],
|
|
|
|
- # right=[27,22],
|
|
|
|
- # )
|
|
|
|
- self.text_to_func = {
|
|
|
|
- "turn":self.engines_ctrl.turn
|
|
|
|
- }
|
|
|
|
|
|
|
|
async def handle(self, data):
|
|
async def handle(self, data):
|
|
|
|
+ """
|
|
|
|
+ The handle method parses commands and responds if a command was not
|
|
|
|
+ found. It executes synchronous and asynchronous methods correctly and
|
|
|
|
+ logs the traceback if an exception occured.
|
|
|
|
+ """
|
|
data = data.strip()
|
|
data = data.strip()
|
|
data = data.split(" ")
|
|
data = data.split(" ")
|
|
cmd,*args = data
|
|
cmd,*args = data
|
|
- kwargs = {"args":args,"command":cmd,"respond":self.respond}
|
|
|
|
func = beewatch._commands.get(cmd,False)
|
|
func = beewatch._commands.get(cmd,False)
|
|
- task = None
|
|
|
|
- if func == False:
|
|
|
|
|
|
+ if not func:
|
|
await self.respond("Unknown command")
|
|
await self.respond("Unknown command")
|
|
return
|
|
return
|
|
|
|
+ kwargs = {"args":args,"command":cmd,"respond":self.respond}
|
|
|
|
+ task = None
|
|
try:
|
|
try:
|
|
coro = func(**kwargs)
|
|
coro = func(**kwargs)
|
|
if hasattr(coro,"__await__"):
|
|
if hasattr(coro,"__await__"):
|
|
task = await coro
|
|
task = await coro
|
|
except Exception as e:
|
|
except Exception as e:
|
|
- lserver.error("api_func raised an error:",exc_info=e)
|
|
|
|
|
|
+ lch.error("api_func raised an error:",exc_info=e)
|
|
tb = traceback.format_exc()
|
|
tb = traceback.format_exc()
|
|
await self.respond(tb,log_msg="traceback of '{}'"
|
|
await self.respond(tb,log_msg="traceback of '{}'"
|
|
.format(e.__cause__))
|
|
.format(e.__cause__))
|
|
finally:
|
|
finally:
|
|
pass
|
|
pass
|
|
if task:
|
|
if task:
|
|
- lserver.debug("exec: "+task.exception.__cause__)
|
|
|
|
|
|
+ lch.debug("exec: "+task.exception.__cause__)
|
|
# task joins iself to suppress the "task not joined" warning
|
|
# task joins iself to suppress the "task not joined" warning
|
|
cur_task = await curio.current_task()
|
|
cur_task = await curio.current_task()
|
|
await curio.ignore_after(0,cur_task.wait)
|
|
await curio.ignore_after(0,cur_task.wait)
|
|
|
|
|
|
async def respond(self,text,*args,log_msg=False):
|
|
async def respond(self,text,*args,log_msg=False):
|
|
|
|
+ """
|
|
|
|
+ this method is passed to apis so they can give feedback to the user
|
|
|
|
+ """
|
|
await self.send(text,log_msg)
|
|
await self.send(text,log_msg)
|
|
|
|
|
|
- # async def wait_for_func(self,coro):
|
|
|
|
- # try:
|
|
|
|
- # task = await curio.spawn(coro)
|
|
|
|
- # try:
|
|
|
|
- # await task.join()
|
|
|
|
- # except Exception as e:
|
|
|
|
- # lserver.error("error during api_func execution",exc_info=e)
|
|
|
|
- # # we do this so we don't get an "task was not joined" error
|
|
|
|
- # cur_task = await curio.current_task()
|
|
|
|
- # await curio.ignore_after(0,cur_task.wait)
|
|
|
|
- # except Exception as e:
|
|
|
|
- # lserver.error("error",exc_info=e)
|
|
|
|
-
|
|
|
|
- async def welcome_client(self):
|
|
|
|
- await self.send("this is the server speaking, hello new client!")
|
|
|
|
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|