__init__.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. #! /usr/bin/env python3.5
  2. # Copyright 2017 Digital
  3. #
  4. # This file is part of BeeWatch.
  5. #
  6. # BeeWatch is free software: you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation, either version 3 of the License, or
  9. # (at your option) any later version.
  10. #
  11. # BeeWatch is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with BeeWatch. If not, see <http://www.gnu.org/licenses/>.
  18. import curio
  19. import blinker
  20. import logging
  21. import logging.handlers
  22. import digilib.network
  23. import os
  24. import queue
  25. import select
  26. import socket
  27. import sys
  28. import threading
  29. import time
  30. import traceback
  31. import digilib.pin
  32. import digilib.network
  33. import beewatch
  34. import beewatch.pinapi
  35. log = logging.getLogger(__name__+"")
  36. lapi = logging.getLogger(__name__+".api")
  37. lchat = logging.getLogger(__name__+".chat")
  38. lserver = logging.getLogger(__name__+".server")
  39. class BeeWatchServer(digilib.network.Server):
  40. """docstring for Server."""
  41. def __init__(self,*args,**kwargs):
  42. super(BeeWatchServer, self).__init__(
  43. *args,
  44. **kwargs,
  45. handler=beewatch.server.ConnHandlerBeeWatch,
  46. )
  47. def make_socket(self):
  48. s = super(BeeWatchServer,self).make_socket()
  49. s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  50. return s
  51. class ConnHandlerBeeWatch(digilib.network.ConnHandlerBase):
  52. def __init__(self, socket, addr, server):
  53. super(ConnHandlerBeeWatch, self).__init__(socket, addr, server)
  54. self.engines_ctrl = beewatch._controllers["engines_ctrl"]
  55. # digilib.pin.EnginesController(
  56. # left=[4,17],
  57. # right=[27,22],
  58. # )
  59. self.text_to_func = {
  60. "turn":self.engines_ctrl.turn
  61. }
  62. async def handle(self, data):
  63. data = data.strip()
  64. data = data.split(" ")
  65. cmd,*args = data
  66. kwargs = {"args":args,"command":cmd,"respond":self.respond}
  67. func = beewatch._commands.get(cmd,False)
  68. if func == False:
  69. await self.respond("Unknown command")
  70. return
  71. try:
  72. retval = func(**kwargs)
  73. if hasattr(retval,"__await__"):
  74. await curio.spawn(self.wait_for_func,retval)
  75. # task = await curio.spawn(retval)
  76. # task.join(0)
  77. except Exception as e:
  78. lserver.error("Error while calling api func",exc_info=e)
  79. tb = traceback.format_exc()
  80. await self.respond(tb)
  81. async def respond(self,text,*args):
  82. await self.send(text)
  83. async def wait_for_func(self,coro):
  84. try:
  85. task = await curio.spawn(coro)
  86. try:
  87. await task.join()
  88. except Exception as e:
  89. lserver.error("error during api_func execution",exc_info=e)
  90. # we do this so we don't get an "task was not joined" error
  91. cur_task = await curio.current_task()
  92. await curio.ignore_after(0,cur_task.join)
  93. except Exception as e:
  94. lserver.error("error",exc_info=e)
  95. async def welcome_client(self):
  96. await self.send("this is the server speaking, hello new client!")
  97. #