Пример #1
0
    def process_run(self, options):
        '''Run an assistant/action'''
        logger.info('Serving a run request')
        path = options['path']
        run_id = str(uuid.uuid4()).replace('-', '')

        da_args = options['arguments']
        da_args['__ui__'] = 'json'

        to_run = api.DevAssistantAdaptor.get_runnable_to_run(path, da_args)
        dalogger = api.DevAssistantAdaptor.get_logger()

        try:
            self.set_dialoghelper_contex(run_id)  # TODO: solve this in some less smelly way
            self.send(api.APIFormatter.format_run_ack(run_id))
            dalogger.handlers = []
            dalogger.addHandler(JSONHandler(self, run_id))
            dalogger.setLevel(options.get('loglevel', "INFO").upper())
            logger.info('Running with args: {}'.format(da_args))
            to_run.run()
            self.send(api.APIFormatter.format_run_finished(run_id, 'ok'))
        except BaseException as e:
            logger.error(traceback.format_exc())
            raise exceptions.ProcessingError(str(e), run_id=run_id)
        finally:
            dalogger.handlers = []
            self.clean_dialoghelper()
            api.DevAssistantAdaptor.reload_command_runners()  # see https://github.com/tradej/devassistant-c2s/issues/3
Пример #2
0
 def process_shutdown(self):
     '''Shutdown the server if it was invoked with --client-stoppable'''
     logger.info('Serving a shutdown request')
     if self.handler.server.context.get('client_stoppable', False):
         raise SystemExit('Stopped by client')
     else:
         raise exceptions.ProcessingError('Server was not invoked with --client-stoppable')
Пример #3
0
 def process_tree(self, args):
     '''Get a tree of runnables'''
     logger.info('Serving a tree request')
     runnables = api.DevAssistantAdaptor.get_top_runnables()
     tree = [api.APISerializer.serialize_runnable(runnable,
                                                  '/',
                                                  get_icons = args.get('icons', False),
                                                  get_arguments = args.get('arguments', False),
                                                  ) for runnable in runnables]
     self.send_json({'tree': tree})
Пример #4
0
 def process_detail(self, args):
     '''Get a detail of a runnable'''
     logger.info('Serving a detail request')
     path = args['path']
     runnable = api.DevAssistantAdaptor.get_runnable_by_path(args['path'])
     detail = api.APISerializer.serialize_runnable(runnable,
                                                   path[:path.rfind('/')],
                                                   get_icons=args.get('icons', False),
                                                   get_arguments=args.get('arguments', False),
                                                   names_only=True)
     self.send_json({"detail": detail})
Пример #5
0
def run():
    ap = argparse.ArgumentParser(usage='DevAssistant server. If no arguments are provided, the UNIX server is started',
                                 argument_default=argparse.SUPPRESS)
    ap.add_argument('-u', '--unix',
                    nargs='?',
                    metavar='FILENAME',
                    help='Run a UNIX socket server listening on a filename (default: {})'.format(settings.SOCKET_FILENAME))
    ap.add_argument('-t', '--tcp',
                    nargs='?',
                    metavar='HOST:PORT',
                    help='Run a TCP server listening on HOST:PORT (default: {}:{})'.format(settings.SOCKET_HOST, settings.SOCKET_PORT))
    ap.add_argument('-s', '--client-stoppable', action='store_true', help='Clients may stop the server via an API call')
    ap.add_argument('-d', '--debug', action='store_true', help='Display debug log messages on stdout')
    ap.add_argument('-v', '--verbose', action='store_true', help='Display informative log messages on stdout')
    args = vars(ap.parse_args())

    if args.get('verbose'):
        logger.setLevel(logging.INFO)
    elif args.get('debug'):
        logger.setLevel(logging.DEBUG)
    else:
        logger.setLevel(logging.WARNING)

    if 'tcp' in args and 'unix' in args:
        logger.error('Can not specify both UNIX and TCP at once!')
        sys.exit(1)

    if 'tcp' in args:
        try:
            host, port = args.get('tcp', '').split(':')
            port = int(port)
        except AttributeError:
            host, port = (settings.SOCKET_HOST, settings.SOCKET_PORT)
        server = servers.TCPServer((host, port), handlers.DARequestHandler)
        logger.info('TCP server started on {}:{}'.format(host, port))

    else: # UNIX server is default
        filename = args.get('unix') or settings.SOCKET_FILENAME
        helpers.prepare_socket(filename)
        server = servers.UNIXServer(filename, handlers.DARequestHandler)
        logger.info('UNIX server started at ' + filename)

    server.set_context({'client_stoppable': args.get('client_stoppable')})
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        logger.info('Killed by user')
        sys.exit(130)
    except SystemExit:
        logger.info('Killed by API call')
        sys.exit(0)
Пример #6
0
    def handle(self):
        logger.info('Incoming connection')
        cwd = os.getcwd()
        try:
            while True: # Wait for client
                data = self.receive()
                if not data:
                    logger.info('Client disconnected (EOF)')
                    break
                processor = helpers.QueryProcessor(handler=self)
                processor.process_query(data)

        # Trouble communicating with the client
        except IOError as e:
            if e.errno == errno.EPIPE:
                logger.info('Client disconnected (broken pipe)')
            else:
                raise
        # Other exceptions
        except Exception as e:
            try:
                self.send(api.APIFormatter.format_error('Unexpected server error'))
            except:
                pass
            raise
        # Return to original CWD
        finally:
            os.chdir(cwd)
Пример #7
0
    def handle(self):
        logger.info('Incoming connection')
        cwd = os.getcwd()
        try:
            while True:  # Wait for client
                data = self.receive()
                if not data:
                    logger.info('Client disconnected (EOF)')
                    break
                processor = helpers.QueryProcessor(handler=self)
                processor.process_query(data)

        # Trouble communicating with the client
        except IOError as e:
            if e.errno == errno.EPIPE:
                logger.info('Client disconnected (broken pipe)')
            else:
                raise
        # Other exceptions
        except Exception as e:
            try:
                self.send(
                    api.APIFormatter.format_error('Unexpected server error'))
            except:
                pass
            raise
        # Return to original CWD
        finally:
            os.chdir(cwd)
Пример #8
0
 def process_query(self, data):
     try:
         query = json.loads(data)['query']
         if query['request'] == 'get_tree':
             self.process_tree(query['options'])
         elif query['request'] == 'get_detail':
             self.process_detail(query['options'])
         elif query['request'] == 'run':
             self.process_run(query['options'])
         elif query['request'] == 'shutdown':
             self.process_shutdown()
         else:
             raise KeyError('Not a valid request')
         logger.info('Done')
     except ValueError as e:
         logger.info('Request not valid JSON: "{data}" ({e}) '.format(data=data, e=e))
         self.send_error('Request not valid JSON')
     except KeyError as e:
         logger.info('Request not valid DA API call: "{data}" ({e}) '.format(data=data, e=e))
         self.send_error('Request not valid API call')
     except exceptions.ProcessingError as e:
         logger.error('Error processing request: "{data}" ({e}) '.format(data=data, e=e))
         try:
             run_id = e.run_id
             self.send_error('Error processing request: ' + str(e), run_id)
             self.send(api.APIFormatter.format_run_finished(run_id, 'error'))
         except AttributeError:
             self.send_error('Error processing request: ' + str(e))
Пример #9
0
 def get_answer(self):
     '''Wait for client to provide input'''
     logger.info('Asking client...')
     msg = self.receive()
     logger.debug('Answer received: ' + msg)
     return msg
Пример #10
0
 def get_answer(self):
     '''Wait for client to provide input'''
     logger.info('Asking client...')
     msg = self.receive()
     logger.debug('Answer received: ' + msg)
     return msg