def do_cli(manager, options): if not options.url: # Determine if first positional argument is a URL or a title if '://' in options.title: options.url = options.title options.title = None if options.url and not options.title: # Attempt to get a title from the URL response's headers try: value, params = cgi.parse_header(requests.head(options.url).headers['Content-Disposition']) options.title = params['filename'] except KeyError: console('No title given, and couldn\'t get one from the URL\'s HTTP response. Aborting.') return entry = Entry(title=options.title) if options.url: entry['url'] = options.url else: entry['url'] = 'http://localhost/inject/%s' % ''.join(random.sample(string.letters + string.digits, 30)) if options.force: entry['immortal'] = True if options.accept: entry.accept(reason='accepted by CLI inject') if options.fields: for key, value in options.fields: entry[key] = value options.inject = [entry] manager.execute_command(options)
def do_cli(manager, options): if not options.url: # Determine if first positional argument is a URL or a title if '://' in options.title: options.url = options.title options.title = None if options.url and not options.title: # Attempt to get a title from the URL response's headers try: value, params = cgi.parse_header( requests.head(options.url).headers['Content-Disposition']) options.title = params['filename'] except KeyError: console( 'No title given, and couldn\'t get one from the URL\'s HTTP response. Aborting.' ) return entry = Entry(title=options.title) if options.url: entry['url'] = options.url else: entry['url'] = 'http://localhost/inject/%s' % ''.join( random.sample(string.letters + string.digits, 30)) if options.force: entry['immortal'] = True if options.accept: entry.accept(reason='accepted by CLI inject') if options.fields: for key, value in options.fields: entry[key] = value options.inject = [entry] manager.execute_command(options)
def post(self, session: Session = None) -> Response: """ Execute task and stream results """ data = request.json for task in data.get('tasks'): if task.lower() not in [ t.lower() for t in self.manager.user_config.get('tasks', {}).keys() ]: raise NotFoundError(f'task {task} does not exist') queue = ExecuteLog() output = queue if data.get('loglevel') else None stream = (True if any( arg[0] in ['progress', 'summary', 'loglevel', 'entry_dump'] for arg in data.items() if arg[1]) else False) loglevel = data.pop('loglevel', None) if loglevel: loglevel = loglevel.upper() # This emulates the CLI command of using `--now` and `no-cache` options = { 'interval_ignore': data.pop('now', None), 'nocache': data.pop('no_cache', None), 'allow_manual': True, } for option, value in data.items(): options[option] = value if data.get('inject'): entries = [] for item in data.get('inject'): entry = Entry() entry['url'] = item['url'] if not item.get('title'): try: value, params = cgi.parse_header( requests.head( item['url']).headers['Content-Disposition']) entry['title'] = params['filename'] except KeyError: raise BadRequest( 'No title given, and couldn\'t get one from the URL\'s HTTP response' ) else: entry['title'] = item.get('title') if item.get('force'): entry['immortal'] = True if item.get('accept'): entry.accept(reason='accepted by API inject') if item.get('fields'): for key, value in item.get('fields').items(): entry[key] = value entries.append(entry) options['inject'] = entries if output: with capture_console(output), capture_logs(output, level=loglevel): executed_tasks = self.manager.execute(options=options) else: executed_tasks = self.manager.execute(options=options) tasks_queued = [] for task_id, task_name, task_event in executed_tasks: tasks_queued.append({ 'id': task_id, 'name': task_name, 'event': task_event }) _streams[task_id] = { 'queue': queue, 'last_update': datetime.now(), 'args': data } if not stream: return jsonify({ 'tasks': [{ 'id': task['id'], 'name': task['name'] } for task in tasks_queued] }) def stream_response(): # First return the tasks to execute yield '{"stream": [' yield json.dumps({ 'tasks': [{ 'id': task['id'], 'name': task['name'] } for task in tasks_queued] }) + ',\n' while True: try: yield queue.get(timeout=1) + ',\n' continue except Empty: pass if queue.empty() and all( [task['event'].is_set() for task in tasks_queued]): for task in tasks_queued: del _streams[task['id']] break yield '{}]}' return Response(stream_response(), mimetype='text/event-stream')
def post(self, session=None): """ Execute task and stream results """ data = request.json for task in data.get('tasks'): if task.lower() not in [t.lower() for t in self.manager.user_config.get('tasks', {}).keys()]: return {'error': 'task %s does not exist' % task}, 404 queue = ExecuteLog() output = queue if data.get('loglevel') else None stream = True if any( arg[0] in ['progress', 'summary', 'loglevel', 'entry_dump'] for arg in data.items() if arg[1]) else False loglevel = data.get('loglevel') options = {'tasks': data.get('tasks')} if data.get('inject'): entries = [] for item in data.get('inject'): entry = Entry() entry['url'] = item['url'] if not item.get('title'): try: value, params = cgi.parse_header(requests.head(item['url']).headers['Content-Disposition']) entry['title'] = params['filename'] except KeyError: return {'status': 'error', 'message': 'No title given, and couldn\'t get one from the URL\'s HTTP response'}, 500 else: entry['title'] = item.get('title') if item.get('force'): entry['immortal'] = True if item.get('accept'): entry.accept(reason='accepted by API inject') if item.get('fields'): for key, value in item.get('fields').items(): entry[key] = value entries.append(entry) options['inject'] = entries executed_tasks = self.manager.execute(options=options, output=output, loglevel=loglevel) tasks_queued = [] for task_id, task_name, task_event in executed_tasks: tasks_queued.append({'id': task_id, 'name': task_name, 'event': task_event}) _streams[task_id] = { 'queue': queue, 'last_update': datetime.now(), 'args': data } if not stream: return jsonify({'tasks': [{'id': task['id'], 'name': task['name']} for task in tasks_queued]}) def stream_response(): # First return the tasks to execute yield '{"stream": [' yield json.dumps({'tasks': [{'id': task['id'], 'name': task['name']} for task in tasks_queued]}) + ',\n' while True: try: yield queue.get(timeout=1) + ',\n' continue except Empty: pass if queue.empty() and all([task['event'].is_set() for task in tasks_queued]): for task in tasks_queued: del _streams[task['id']] break yield '{}]}' return Response(stream_response(), mimetype='text/event-stream')
def post(self, session=None): """ Execute task and stream results """ data = request.json for task in data.get('tasks'): if task.lower() not in [ t.lower() for t in self.manager.user_config.get('tasks', {}).keys() ]: return {'error': 'task %s does not exist' % task}, 404 queue = ExecuteLog() output = queue if data.get('loglevel') else None stream = True if any( arg[0] in ['progress', 'summary', 'loglevel', 'entry_dump'] for arg in data.items() if arg[1]) else False loglevel = data.get('loglevel') options = {'tasks': data.get('tasks')} if data.get('inject'): entries = [] for item in data.get('inject'): entry = Entry() entry['url'] = item['url'] if not item.get('title'): try: value, params = cgi.parse_header( requests.head( item['url']).headers['Content-Disposition']) entry['title'] = params['filename'] except KeyError: return { 'status': 'error', 'message': 'No title given, and couldn\'t get one from the URL\'s HTTP response' }, 500 else: entry['title'] = item.get('title') if item.get('force'): entry['immortal'] = True if item.get('accept'): entry.accept(reason='accepted by API inject') if item.get('fields'): for key, value in item.get('fields').items(): entry[key] = value entries.append(entry) options['inject'] = entries executed_tasks = self.manager.execute(options=options, output=output, loglevel=loglevel) tasks_queued = [] for task_id, task_name, task_event in executed_tasks: tasks_queued.append({ 'id': task_id, 'name': task_name, 'event': task_event }) _streams[task_id] = { 'queue': queue, 'last_update': datetime.now(), 'args': data } if not stream: return jsonify({ 'tasks': [{ 'id': task['id'], 'name': task['name'] } for task in tasks_queued] }) def stream_response(): # First return the tasks to execute yield '{"stream": [' yield json.dumps({ 'tasks': [{ 'id': task['id'], 'name': task['name'] } for task in tasks_queued] }) + ',\n' while True: try: yield queue.get(timeout=1) + ',\n' continue except Empty: pass if queue.empty() and all( [task['event'].is_set() for task in tasks_queued]): for task in tasks_queued: del _streams[task['id']] break yield '{}]}' return Response(stream_response(), mimetype='text/event-stream')
def post(self, task, session=None): """ Execute task and stream results """ data = request.json if task.lower() not in [t.lower() for t in self.manager.user_config.get('tasks', {}).keys()]: return {'error': 'task does not exist'}, 404 queue = ExecuteLog() output = queue if data.get('log') else None stream = True if any( arg[0] in ['progress', 'summary', 'log', 'entry_dump'] for arg in data.items() if arg[1]) else False loglevel = data.get('loglevel') options = {'tasks': [task]} if data.get('inject'): entries = [] for item in data.get('inject'): entry = Entry() entry['url'] = item['url'] if not item.get('title'): try: value, params = cgi.parse_header(requests.head(item['url']).headers['Content-Disposition']) entry['title'] = params['filename'] except KeyError: return {'status': 'error', 'message': 'No title given, and couldn\'t get one from the URL\'s HTTP response'}, 500 else: entry['title'] = item.get('title') if item.get('force'): entry['immortal'] = True if item.get('accept'): entry.accept(reason='accepted by API inject') if item.get('fields'): for key, value in item.get('fields').items(): entry[key] = value entries.append(entry) options['inject'] = entries task_id, __, task_event = self.manager.execute(options=options, output=output, loglevel=loglevel)[0] if not stream: return {'task': {'id': task_id, 'name': task}} _streams[task_id] = { 'queue': queue, 'last_update': datetime.now(), 'args': data } def stream_response(): yield '{"task": {"id": "%s", "name": "%s", "stream": [' % (task_id, task) while True: # If the server is shutting down then end the stream nicely if cherrypy.engine.state != cherrypy.engine.states.STARTED: break try: yield queue.get(timeout=1) + ',\n' continue except Empty: pass if queue.empty() and task_event.is_set(): del _streams[task_id] break yield '{}]}}' return Response(stream_response(), mimetype='text/event-stream')
def post(self, session=None): """ Execute task and stream results """ data = request.json for task in data.get("tasks"): if task.lower() not in [t.lower() for t in self.manager.user_config.get("tasks", {}).keys()]: return {"error": "task %s does not exist" % task}, 404 queue = ExecuteLog() output = queue if data.get("loglevel") else None stream = ( True if any(arg[0] in ["progress", "summary", "loglevel", "entry_dump"] for arg in data.items() if arg[1]) else False ) loglevel = data.pop("loglevel", None) # This emulates the CLI command of using `--now` options = {"interval_ignore": data.pop("now", None)} for option, value in data.items(): options[option] = value if data.get("inject"): entries = [] for item in data.get("inject"): entry = Entry() entry["url"] = item["url"] if not item.get("title"): try: value, params = cgi.parse_header(requests.head(item["url"]).headers["Content-Disposition"]) entry["title"] = params["filename"] except KeyError: return ( { "status": "error", "message": "No title given, and couldn't get one from the URL's HTTP response", }, 500, ) else: entry["title"] = item.get("title") if item.get("force"): entry["immortal"] = True if item.get("accept"): entry.accept(reason="accepted by API inject") if item.get("fields"): for key, value in item.get("fields").items(): entry[key] = value entries.append(entry) options["inject"] = entries executed_tasks = self.manager.execute(options=options, output=output, loglevel=loglevel) tasks_queued = [] for task_id, task_name, task_event in executed_tasks: tasks_queued.append({"id": task_id, "name": task_name, "event": task_event}) _streams[task_id] = {"queue": queue, "last_update": datetime.now(), "args": data} if not stream: return jsonify({"tasks": [{"id": task["id"], "name": task["name"]} for task in tasks_queued]}) def stream_response(): # First return the tasks to execute yield '{"stream": [' yield json.dumps({"tasks": [{"id": task["id"], "name": task["name"]} for task in tasks_queued]}) + ",\n" while True: try: yield queue.get(timeout=1) + ",\n" continue except Empty: pass if queue.empty() and all([task["event"].is_set() for task in tasks_queued]): for task in tasks_queued: del _streams[task["id"]] break yield "{}]}" return Response(stream_response(), mimetype="text/event-stream")