mirror of https://github.com/MISP/misp-modules
				
				
				
			add: [website] tree view history
Flask session store history and after save it's store in DBpull/659/head
							parent
							
								
									b38e4feb37
								
							
						
					
					
						commit
						0364deccaa
					
				|  | @ -1,3 +1,4 @@ | |||
| import json | ||||
| from .. import db | ||||
| 
 | ||||
| 
 | ||||
|  | @ -32,13 +33,38 @@ class Session_db(db.Model): | |||
|     query_date = db.Column(db.DateTime, index=True) | ||||
| 
 | ||||
|     def to_json(self): | ||||
|         return | ||||
|         json_dict = { | ||||
|             "id": self.id, | ||||
|             "uuid": self.uuid, | ||||
|             "modules": json.loads(self.modules_list), | ||||
|             "query_enter": self.query_enter, | ||||
|             "input_query": self.input_query, | ||||
|             "config_module": json.loads(self.config_module), | ||||
|             "result": json.loads(self.result), | ||||
|             "nb_errors": self.nb_errors, | ||||
|             "query_date": self.query_date.strftime('%Y-%m-%d') | ||||
|         } | ||||
|         return json_dict | ||||
|      | ||||
|     def history_json(self): | ||||
|         json_dict = { | ||||
|             "uuid": self.uuid, | ||||
|             "modules": json.loads(self.modules_list), | ||||
|             "query": self.query_enter, | ||||
|             "input": self.input_query, | ||||
|             "query_date": self.query_date.strftime('%Y-%m-%d') | ||||
|         } | ||||
|         return json_dict | ||||
| 
 | ||||
| 
 | ||||
| class History(db.Model): | ||||
|     id = db.Column(db.Integer, primary_key=True, autoincrement=True) | ||||
|     session_id = db.Column(db.Integer, index=True) | ||||
| 
 | ||||
| class History_Tree(db.Model): | ||||
|     id = db.Column(db.Integer, primary_key=True, autoincrement=True) | ||||
|     session_uuid = db.Column(db.String(36), index=True) | ||||
|     tree = db.Column(db.String) | ||||
| 
 | ||||
| class Config(db.Model): | ||||
|     id = db.Column(db.Integer, primary_key=True, autoincrement=True) | ||||
|  |  | |||
|  | @ -15,6 +15,13 @@ home_blueprint = Blueprint( | |||
| def home(): | ||||
|     return render_template("home.html") | ||||
| 
 | ||||
| @home_blueprint.route("/home/<sid>", methods=["GET", "POST"]) | ||||
| def home_query(sid): | ||||
|     if "query" in request.args: | ||||
|         query = request.args.get("query") | ||||
|         return render_template("home.html", query=query, sid=sid) | ||||
|     return render_template("404.html") | ||||
| 
 | ||||
| @home_blueprint.route("/query/<sid>") | ||||
| def query(sid): | ||||
|     session = HomeModel.get_session(sid) | ||||
|  | @ -24,7 +31,7 @@ def query(sid): | |||
|         query_loc = session.query_enter | ||||
|     else: | ||||
|         for s in SessionModel.sessions: | ||||
|             if s.id == sid: | ||||
|             if s.uuid == sid: | ||||
|                 flag = True | ||||
|                 query_loc = s.query | ||||
|                 session=s | ||||
|  | @ -64,6 +71,7 @@ def run_modules(): | |||
|         if "input" in request.json: | ||||
|             if "modules" in request.json: | ||||
|                 session = SessionModel.Session_class(request.json) | ||||
|                 HomeModel.set_flask_session(session, request.json["parent_id"]) | ||||
|                 session.start() | ||||
|                 SessionModel.sessions.append(session) | ||||
|                 return jsonify(session.status()), 201 | ||||
|  | @ -79,7 +87,7 @@ def status(sid): | |||
|         return jsonify(HomeModel.get_status_db(sess)) | ||||
|     else: | ||||
|         for s in SessionModel.sessions: | ||||
|             if s.id == sid: | ||||
|             if s.uuid == sid: | ||||
|                 return jsonify(s.status()) | ||||
|     return jsonify({'message': 'Scan session not found'}), 404 | ||||
| 
 | ||||
|  | @ -91,7 +99,7 @@ def result(sid): | |||
|         return jsonify(HomeModel.get_result_db(sess)) | ||||
|     else: | ||||
|         for s in SessionModel.sessions: | ||||
|             if s.id == sid: | ||||
|             if s.uuid == sid: | ||||
|                 return jsonify(s.get_result()) | ||||
|     return jsonify({'message': 'Scan session not found'}), 404 | ||||
| 
 | ||||
|  | @ -145,4 +153,35 @@ def history(): | |||
| def get_history(): | ||||
|     """Get all history""" | ||||
|     histories = HomeModel.get_history() | ||||
|     return histories | ||||
|     return histories | ||||
| 
 | ||||
| @home_blueprint.route("/history_session", methods=["GET"]) | ||||
| def history_session(): | ||||
|     """View all history""" | ||||
|     return render_template("history_session.html", tree_view=False) | ||||
| 
 | ||||
| @home_blueprint.route("/get_history_session", methods=["GET"]) | ||||
| def get_history_session(): | ||||
|     """Get all history""" | ||||
|     histories = HomeModel.get_history_session() | ||||
|     if histories: | ||||
|         return histories | ||||
|     return {} | ||||
| 
 | ||||
| @home_blueprint.route("/save_history/<sid>", methods=["GET"]) | ||||
| def save_history(sid): | ||||
|     return HomeModel.save_history_core(sid) | ||||
| 
 | ||||
| 
 | ||||
| @home_blueprint.route("/history_tree", methods=["GET"]) | ||||
| def history_tree(): | ||||
|     """View all history""" | ||||
|     return render_template("history_session.html", tree_view=True) | ||||
| 
 | ||||
| @home_blueprint.route("/get_history_tree", methods=["GET"]) | ||||
| def get_history_tree(): | ||||
|     """Get all history""" | ||||
|     histories = HomeModel.get_history_tree() | ||||
|     if histories: | ||||
|         return histories | ||||
|     return {} | ||||
|  | @ -1,7 +1,10 @@ | |||
| import json | ||||
| from .utils.utils import query_get_module | ||||
| from .utils.utils import query_get_module, isUUID | ||||
| from . import db | ||||
| from .db_class.db import History, Module, Config, Module_Config, Session_db | ||||
| from .db_class.db import History, Module, Config, Module_Config, Session_db, History_Tree | ||||
| from . import sess | ||||
| from flask import session as sess | ||||
| from sqlalchemy import desc | ||||
| 
 | ||||
| 
 | ||||
| def get_module(mid): | ||||
|  | @ -29,7 +32,7 @@ def get_module_config_both(mid, cid): | |||
|     return Module_Config.query.filter_by(module_id=mid, config_id=cid).first() | ||||
| 
 | ||||
| def get_session(sid): | ||||
|     """Return a session by id""" | ||||
|     """Return a session by uuid""" | ||||
|     return Session_db.query.filter_by(uuid=sid).first() | ||||
| 
 | ||||
| def get_modules(): | ||||
|  | @ -138,14 +141,142 @@ def get_result_db(session): | |||
| def get_history(): | ||||
|     """Return history""" | ||||
|     histories_list = list() | ||||
|     histories = History.query.all() | ||||
|     histories = History.query.order_by(desc(History.id)) | ||||
|     for history in histories: | ||||
|         session = Session_db.query.get(history.session_id) | ||||
|         histories_list.append({ | ||||
|             "uuid": session.uuid,  | ||||
|             "query": session.query_enter,  | ||||
|             "modules": json.loads(session.modules_list),  | ||||
|             "input": session.input_query,  | ||||
|             "query_date": session.query_date.strftime('%Y-%m-%d') | ||||
|             }) | ||||
|         histories_list.append(session.history_json()) | ||||
|     return histories_list | ||||
| 
 | ||||
| 
 | ||||
| def util_set_flask_session(parent_id, loc_session, current_session): | ||||
|     if parent_id == loc_session["uuid"]: | ||||
|         loc_json = { | ||||
|             "uuid": current_session.uuid, | ||||
|             "modules": current_session.modules_list, | ||||
|             "query": current_session.query, | ||||
|             "input": current_session.input_query, | ||||
|             "query_date": current_session.query_date.strftime('%Y-%m-%d') | ||||
|         } | ||||
|         loc_session["children"].append(loc_json) | ||||
|         return True | ||||
|     elif "children" in loc_session: | ||||
|         return deep_explore(loc_session["children"], parent_id, current_session) | ||||
| 
 | ||||
| def deep_explore(session_dict, parent_id, current_session): | ||||
|     for loc_session in session_dict: | ||||
|         if not "children" in loc_session: | ||||
|             loc_session["children"] = list() | ||||
|         if util_set_flask_session(parent_id, loc_session, current_session): | ||||
|             return True | ||||
|     return False | ||||
| 
 | ||||
| def set_flask_session(current_session, parent_id): | ||||
|     current_query = sess.get("current_query") | ||||
|     if not current_query or current_query not in sess: | ||||
|         loc_json = { | ||||
|             "uuid": current_session.uuid, | ||||
|             "modules": current_session.modules_list, | ||||
|             "query": current_session.query, | ||||
|             "input": current_session.input_query, | ||||
|             "query_date": current_session.query_date.strftime('%Y-%m-%d') | ||||
|         } | ||||
| 
 | ||||
|         sess["current_query"] = current_session.uuid | ||||
|         sess[sess.get("current_query")] = loc_json | ||||
|         sess[sess.get("current_query")]["children"] = list() | ||||
|     else: | ||||
|         # sess["uuid"] | ||||
|         loc_session = sess.get(sess.get("current_query")) | ||||
|         if not "children" in loc_session: | ||||
|             loc_session["children"] = list() | ||||
|         if not util_set_flask_session(parent_id, loc_session, current_session): | ||||
|             sess["current_query"] = current_session.uuid | ||||
| 
 | ||||
| def get_history_session(): | ||||
|     current_query = sess.get("current_query") | ||||
|     loc_list = list() | ||||
|     if current_query: | ||||
|         # If current query have no children then don't display it | ||||
|         # It's already save in history | ||||
|         # Only parent-child tree structure is in flask session | ||||
|         current_query_value = sess.get(sess.get("current_query")) | ||||
|         if current_query_value and current_query_value["children"]: | ||||
|             loc_list.append(current_query_value) | ||||
|     for q in sess: | ||||
|         if isUUID(q): | ||||
|             # If query have no children then don't display it | ||||
|             q_value = sess.get(q) | ||||
|             if q_value["children"]: | ||||
|                 if not q == current_query: | ||||
|                     loc_list.append(q_value) | ||||
| 
 | ||||
|     return loc_list | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| def util_save_history(session): | ||||
|     loc_dict = dict() | ||||
|     loc_dict[session["uuid"]] = [] | ||||
| 
 | ||||
|     if "children" in session and session["children"]: | ||||
|         for child in session["children"]: | ||||
|             loc_dict[session["uuid"]].append(util_save_history(child)) | ||||
|     return loc_dict | ||||
| 
 | ||||
| 
 | ||||
| def save_history_core(sid): | ||||
|     """Save history from session to db""" | ||||
|     if sid in sess: | ||||
|         session = sess.get(sid) | ||||
|         # Doesn't already exist | ||||
|         history_tree_db = History_Tree.query.filter_by(session_uuid=session["uuid"]).first() | ||||
|         if not history_tree_db: | ||||
|             if "children" in session and session["children"]: | ||||
|                 # Get all children before add to db | ||||
|                 loc_dict = util_save_history(session) | ||||
|                 h = History_Tree( | ||||
|                     session_uuid = session["uuid"], | ||||
|                     tree=json.dumps(loc_dict) | ||||
|                 ) | ||||
|                 db.session.add(h) | ||||
|                 db.session.commit() | ||||
|                 return {"message": "History Save", 'toast_class': "success-subtle"} | ||||
|             return {"message": "No children", 'toast_class': "warning-subtle"} | ||||
|         # Save same session but with new value | ||||
|         elif not json.loads(history_tree_db.tree) == session: | ||||
|             if "children" in session and session["children"]: | ||||
|                 # Get all children before add to db | ||||
|                 loc_dict = util_save_history(session) | ||||
|                 history_tree_db.tree = json.dumps(loc_dict) | ||||
|                 db.session.commit() | ||||
|                 return {"message": "History updated", 'toast_class': "success-subtle"} | ||||
|         return {"message": "History already saved", 'toast_class': "warning-subtle"} | ||||
|     return {"message": "Session not found", 'toast_class': "danger-subtle"} | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| def util_get_history_tree(child): | ||||
|     loc_child = list(child.keys())[0] | ||||
|     loc_session = get_session(loc_child) | ||||
|     loc_json = loc_session.history_json() | ||||
|     loc_json["children"] = list() | ||||
|     if child[loc_child]: | ||||
|         for s_child in child[loc_child]: | ||||
|             loc_json["children"].append(util_get_history_tree(s_child)) | ||||
|     return loc_json | ||||
| 
 | ||||
| def get_history_tree(): | ||||
|     """Return all histories saved as tree""" | ||||
|     histories_tree = History_Tree.query.order_by(desc(History_Tree.id)) | ||||
|     loc_dict = list() | ||||
|     for history_tree in histories_tree: | ||||
|         tree = json.loads(history_tree.tree) | ||||
|          | ||||
|         loc_session = get_session(history_tree.session_uuid) | ||||
|         loc_json = loc_session.history_json() | ||||
|         loc_json["children"] = list() | ||||
|         for child in tree[history_tree.session_uuid]: | ||||
|             loc_json["children"].append(util_get_history_tree(child)) | ||||
|         loc_dict.append(loc_json) | ||||
|     return loc_dict | ||||
|  |  | |||
|  | @ -14,7 +14,7 @@ sessions = list() | |||
| 
 | ||||
| class Session_class: | ||||
|     def __init__(self, request_json) -> None: | ||||
|         self.id = str(uuid4()) | ||||
|         self.uuid = str(uuid4()) | ||||
|         self.thread_count = 4 | ||||
|         self.jobs = Queue(maxsize=0) | ||||
|         self.threads = [] | ||||
|  | @ -63,7 +63,7 @@ class Session_class: | |||
|         registered = len(self.result) | ||||
| 
 | ||||
|         return { | ||||
|             'id': self.id, | ||||
|             'id': self.uuid, | ||||
|             'total': total, | ||||
|             'complete': complete, | ||||
|             'remaining': remaining, | ||||
|  | @ -110,7 +110,7 @@ class Session_class: | |||
|             else: | ||||
|                 send_to = {"module": work[1], self.input_query: self.query, "config": loc_config} | ||||
|             res = query_post_query(send_to) | ||||
|             print(res) | ||||
|             # print(res) | ||||
|             if "error" in res: | ||||
|                 self.nb_errors += 1 | ||||
|             self.result[work[1]] = res | ||||
|  | @ -124,7 +124,7 @@ class Session_class: | |||
|     def save_info(self): | ||||
|         """Save info in the db""" | ||||
|         s = Session_db( | ||||
|             uuid=str(self.id), | ||||
|             uuid=str(self.uuid), | ||||
|             modules_list=json.dumps(self.modules_list), | ||||
|             query_enter=self.query, | ||||
|             input_query=self.input_query, | ||||
|  |  | |||
|  | @ -1,5 +1,4 @@ | |||
| 
 | ||||
| const { ref, nextTick } = Vue | ||||
| export default { | ||||
| 	name: "History_view", | ||||
| 	delimiters: ['[[', ']]'], | ||||
|  | @ -7,36 +6,63 @@ export default { | |||
| 		history: Object, | ||||
| 		key_loop: Number | ||||
| 	}, | ||||
| 	setup(props) { | ||||
| 		 | ||||
| 		 | ||||
| 
 | ||||
| 		return { | ||||
| 
 | ||||
| 		} | ||||
| 	}, | ||||
| 	template: ` | ||||
| 	<div class="list-group" style="margin-bottom: 20px;"> | ||||
| 		<a :href="'/query/'+history.uuid" class="list-group-item list-group-item-action"> | ||||
| 			<div class="d-flex w-100 justify-content-between"> | ||||
| 				<h5 class="mb-1">[[key_loop+1]]- [[history.query]]</h5> | ||||
| 				<small><i>[[history.uuid]]</i></small> | ||||
| 			</div> | ||||
| 			<p class="mb-1" style="color: green;"><u>Input Attribute</u>:</p> | ||||
| 			<div>[[history.input]]</div> | ||||
| 			<br> | ||||
| 			<p class="mb-1" style="color: #2000ff;"><u>Modules</u>:</p> | ||||
| 			<div> | ||||
| 				<template v-for="module in history.modules">[[module]],</template> | ||||
| 			</div> | ||||
| 
 | ||||
| 			 | ||||
| 			<div class="d-flex w-100 justify-content-between"> | ||||
| 				<div></div> | ||||
| 				<small><i>[[history.query_date]]</i></small> | ||||
| 			</div> | ||||
| 	<div style="display: flex;"> | ||||
| 		<div style="list-style-type: none; padding: 10px; font-size: large; margin-left: 13px" > | ||||
| 			<a v-if="'children' in history && history['children'].length" data-bs-toggle="collapse" style="color: black;" :href="'#collapseChild-'+history.uuid" role="button" aria-expanded="true" :aria-controls="'collapseChild-'+history.uuid"> | ||||
| 				<i class="fa-solid fa-caret-down"></i> | ||||
| 			</a> | ||||
| 		</div> | ||||
| 		<a style="text-decoration: none; color: black;" data-bs-toggle="collapse" :href="'#collapse'+history.uuid" role="button" aria-expanded="false" :aria-controls="'collapse'+history.uuid"> | ||||
| 			<ul class="list-group list-group-horizontal" style="padding-top: 5px;"> | ||||
| 				<li class="list-group-item"> | ||||
| 					<h5>[[history.query]]</h5> | ||||
| 				</li> | ||||
| 				<li class="list-group-item"> | ||||
| 					<h5 style="color: brown"><u>Input Attributes</u></h5> | ||||
| 					[[history.input]] | ||||
| 				</li> | ||||
| 				<li class="list-group-item"> | ||||
| 					<h5 style="color: brown"><u>Modules</u></h5> | ||||
| 					<template v-for="module in history.modules">[[module]],</template> | ||||
| 				</li> | ||||
| 			</ul | ||||
| 		</a> | ||||
| 	</div>	 | ||||
| 	</div> | ||||
| 	<div> | ||||
| 		<div class="collapse" :id="'collapse'+history.uuid" style="width: 70%; margin-left: 30px"> | ||||
| 			<div class="card card-body"> | ||||
| 				<div class="d-flex w-100 justify-content-between"> | ||||
| 					<h5 class="mb-1">[[history.query]]</h5> | ||||
| 					<small><i>[[history.uuid]]</i></small> | ||||
| 				</div> | ||||
| 				<p class="mb-1" style="color: green;"><u>Input Attribute</u>:</p> | ||||
| 				<div>[[history.input]]</div> | ||||
| 				<br> | ||||
| 				<p class="mb-1" style="color: #2000ff;"><u>Modules</u>:</p> | ||||
| 				<div> | ||||
| 					<template v-for="module in history.modules">[[module]],</template> | ||||
| 				</div> | ||||
| 				<div></div> | ||||
| 				<div class="d-flex w-100 justify-content-between"> | ||||
| 					<div><a :href="'/query/'+history.uuid">See results</a></div> | ||||
| 					<small><i>[[history.query_date]]</i></small> | ||||
| 				</div> | ||||
| 			</div> | ||||
| 		</div> | ||||
| 
 | ||||
| 		<div class="collapse show" :id="'collapseChild-'+history.uuid"> | ||||
| 			<ul style="list-style-type: none;"> | ||||
| 				<li> | ||||
| 					<div class="card-body"> | ||||
| 						<template v-for="h, key in history['children']"> | ||||
| 							<history_view :history="h" :key_loop="key" /> | ||||
| 						</template> | ||||
| 					</div> | ||||
| 				</li> | ||||
| 			</ul> | ||||
| 		</div> | ||||
| 	</div> | ||||
| 	` | ||||
| } | ||||
|  | @ -9,12 +9,32 @@ | |||
| 
 | ||||
|     <hr> | ||||
|     <br> | ||||
| 
 | ||||
|     <div v-if="history"> | ||||
|         <template v-for="h, key in history"> | ||||
|             <history_view :history="h" :key_loop="key" /> | ||||
|             <div class="list-group" style="margin-bottom: 20px;"> | ||||
|                 <a :href="'/query/'+h.uuid" class="list-group-item list-group-item-action"> | ||||
|                     <div class="d-flex w-100 justify-content-between"> | ||||
|                         <h5 class="mb-1">[[key+1]]- [[h.query]]</h5> | ||||
|                         <small><i>[[h.uuid]]</i></small> | ||||
|                     </div> | ||||
|                     <p class="mb-1" style="color: green;"><u>Input Attribute</u>:</p> | ||||
|                     <div>[[h.input]]</div> | ||||
|                     <br> | ||||
|                     <p class="mb-1" style="color: #2000ff;"><u>Modules</u>:</p> | ||||
|                     <div> | ||||
|                         <template v-for="module in h.modules">[[module]],</template> | ||||
|                     </div> | ||||
|          | ||||
|                      | ||||
|                     <div class="d-flex w-100 justify-content-between"> | ||||
|                         <div></div> | ||||
|                         <small><i>[[h.query_date]]</i></small> | ||||
|                     </div> | ||||
|                 </a> | ||||
|             </div> | ||||
|         </template> | ||||
|     </div> | ||||
|     	 | ||||
|      | ||||
|     <span id="goTop">[<a href="#top">Go Back Top</a>]</span> | ||||
| {% endblock %} | ||||
|  | @ -22,7 +42,7 @@ | |||
| {% block script %} | ||||
| <script type="module"> | ||||
|     const { createApp, ref, onMounted, nextTick, defineComponent} = Vue | ||||
|     import {display_toast, message_list} from '/static/js/toaster.js' | ||||
|     import {message_list} from '/static/js/toaster.js' | ||||
|     import history_view from '/static/js/history_view.js' | ||||
|     createApp({ | ||||
|         delimiters: ['[[', ']]'], | ||||
|  |  | |||
|  | @ -0,0 +1,137 @@ | |||
| <!--  | ||||
|     Author: David Cruciani | ||||
| --> | ||||
| 
 | ||||
| {% extends 'base.html' %} | ||||
| 
 | ||||
| {% block content %} | ||||
|     <input hidden value="{{tree_view}}" id="tree_view"> | ||||
|     <h1 id="top">History</h1> | ||||
|     <small v-if="!tree_view"><i>All histories present here will be delete at the end of the session</i></small> | ||||
|     <hr> | ||||
|      | ||||
|     <template v-if="Object.keys(history).length"> | ||||
|         <div v-for="his, key in history" style="background-color: white; border: 1px solid #808080a1; border-radius: 8px; padding: 10px; margin-top: 17px;"> | ||||
|             <div class="d-flex w-100 justify-content-between"> | ||||
|                 <h4># [[key + 1]]</h4> | ||||
|                 <button v-if="!tree_view" class="btn btn-primary btn-sm" @click="save_history(his)">Save</button> | ||||
|             </div> | ||||
|             <hr> | ||||
|             <div style="display: flex;"> | ||||
|                 <a style="padding: 10px; font-size: large; color: black;" v-if="'children' in his && his['children'].length" data-bs-toggle="collapse" :href="'#collapseChild-'+his.uuid" aria-expanded="true" :aria-controls="'collapseChild-'+his.uuid"> | ||||
|                     <i class="fa-solid fa-caret-down"></i> | ||||
|                 </a> | ||||
|                 <a style="text-decoration: none; color: black;" data-bs-toggle="collapse" :href="'#collapse'+his.uuid" role="button" aria-expanded="false" :aria-controls="'collapse'+his.uuid"> | ||||
|                     <ul class="list-group list-group-horizontal"> | ||||
|                         <li class="list-group-item"> | ||||
|                             <h4>[[his.query]]</h4> | ||||
|                         </li> | ||||
|                         <li class="list-group-item"> | ||||
|                             <h5 style="color: brown"><u>Input Attributes</u></h5> | ||||
|                             [[his.input]] | ||||
|                         </li> | ||||
|                         <li class="list-group-item"> | ||||
|                             <h5 style="color: brown"><u>Modules</u></h5> | ||||
|                             <template v-for="module in his.modules">[[module]],</template> | ||||
|                         </li> | ||||
|                     </ul> | ||||
|                 </a> | ||||
|             </div> | ||||
|             <div> | ||||
|                 <div class="collapse" :id="'collapse'+his.uuid" style="width: 70%; margin-left:30px"> | ||||
|                     <div class="card card-body"> | ||||
|                         <div class="d-flex w-100 justify-content-between"> | ||||
|                             <h5 class="mb-1">[[his.query]]</h5> | ||||
|                             <small><i>[[his.uuid]]</i></small> | ||||
|                         </div> | ||||
|                         <p class="mb-1" style="color: green;"><u>Input Attribute</u>:</p> | ||||
|                         <div>[[his.input]]</div> | ||||
|                         <br> | ||||
|                         <p class="mb-1" style="color: #2000ff;"><u>Modules</u>:</p> | ||||
|                         <div> | ||||
|                             <template v-for="module in his.modules">[[module]],</template> | ||||
|                         </div> | ||||
|                         <div></div> | ||||
|                         <div class="d-flex w-100 justify-content-between"> | ||||
|                             <div><a :href="'/query/'+his.uuid">See results</a></div> | ||||
|                             <small><i>[[his.query_date]]</i></small> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 </div> | ||||
| 
 | ||||
|                 <div class="collapse show" :id="'collapseChild-'+his.uuid"> | ||||
|                     <ul style="list-style-type: none;"> | ||||
|                         <li> | ||||
|                             <div class="card-body"> | ||||
|                                 <template v-for="h, key in his['children']"> | ||||
|                                     <history_view :history="h" :key_loop="key" /> | ||||
|                                 </template> | ||||
|                             </div> | ||||
|                         </li> | ||||
|                     </ul> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
|     </template> | ||||
| 
 | ||||
|     <div v-else> | ||||
|         <i>No History</i> | ||||
|     </div> | ||||
|      | ||||
|     <span id="goTop">[<a href="#top">Go Back Top</a>]</span> | ||||
| {% endblock %} | ||||
| 
 | ||||
| {% block script %} | ||||
| <script type="module"> | ||||
|     const { createApp, ref, onMounted, nextTick, defineComponent} = Vue | ||||
|     import {display_toast, message_list} from '/static/js/toaster.js' | ||||
|     import history_view from '/static/js/history_view.js' | ||||
|     createApp({ | ||||
|         delimiters: ['[[', ']]'], | ||||
|         components: { | ||||
|             history_view | ||||
|         }, | ||||
|         setup() { | ||||
|             const history = ref({}) | ||||
|             const tree_view = ref(false) | ||||
| 
 | ||||
|             async function get_history_session(){ | ||||
|                 let res = await fetch("/get_history_session") | ||||
|                 let loc = await res.json() | ||||
|                 history.value = loc | ||||
|             } | ||||
|             async function get_history_tree(){ | ||||
|                 let res = await fetch("/get_history_tree") | ||||
|                 let loc = await res.json() | ||||
|                 history.value = loc | ||||
|             } | ||||
| 
 | ||||
|             async function save_history(history){ | ||||
|                 const res = await fetch("/save_history/" + history.uuid) | ||||
|                 display_toast(res) | ||||
|             } | ||||
| 
 | ||||
|             onMounted(() => { | ||||
|                 tree_view.value = $("#tree_view").val() | ||||
|                 if(tree_view.value == "True"){ | ||||
|                     get_history_tree() | ||||
|                     tree_view.value = true | ||||
|                 } | ||||
|                 else{ | ||||
|                     tree_view.value = false | ||||
|                     get_history_session() | ||||
|                 } | ||||
|             }) | ||||
| 
 | ||||
| 
 | ||||
|             return { | ||||
|                 message_list, | ||||
|                 history, | ||||
|                 tree_view, | ||||
|                 save_history, | ||||
|             } | ||||
|         } | ||||
|     }).mount('.container') | ||||
| 
 | ||||
| </script> | ||||
| {% endblock %} | ||||
|  | @ -15,7 +15,8 @@ | |||
|     <br> | ||||
|     <div style="width:50%; transform: translate(50%, 0);"> | ||||
|         <div> | ||||
|             <input type="text" id="process-query" placeholder="Enter here..." autofocus class="form-control" style="border-radius: 5px;" /> | ||||
|             <input type="hidden" id="parent_id" value="{{sid}}"> | ||||
|             <input type="text" value="{{query}}" id="process-query" placeholder="Enter here..." autofocus class="form-control" style="border-radius: 5px;" /> | ||||
|         </div> | ||||
|         <span v-if="status_site" id="status">[[status_site]]</span> | ||||
|     </div> | ||||
|  | @ -100,8 +101,9 @@ | |||
|                 let error_flag = false | ||||
| 
 | ||||
|                 let result_dict = {"modules": $("#modules_select").val(),  | ||||
|                                     "input": $("#input_select").val(),  | ||||
|                                     "query": current_query.value | ||||
|                                     "input": $("#input_select").val(), | ||||
|                                     "query": current_query.value, | ||||
|                                     "parent_id": $("#parent_id").val() | ||||
|                                 } | ||||
|                 result_dict["config"] = {} | ||||
|                 for(let el in config_query.value){ | ||||
|  |  | |||
|  | @ -127,6 +127,7 @@ | |||
|                                             <div> | ||||
|                                                 Value: [[attr.value]] | ||||
|                                             </div> | ||||
|                                             <a v-if="attr.type != 'counter' && attr.type != 'datetime'" :href="'/home/{{sid}}?query='+attr.value">query</a> | ||||
|                                         </div> | ||||
|                                     </div> | ||||
|                                     <hr> | ||||
|  |  | |||
|  | @ -18,6 +18,12 @@ | |||
| 				<a style="margin-top: 30px;" href="/history" class="list-group-item list-group-item-action py-2 ripple"> | ||||
| 					<i class="fa-solid fa-clock-rotate-left fa-fw me-3"></i><span>History</span> | ||||
| 				</a> | ||||
| 				<a style="margin-top: 30px;" href="/history_session" class="list-group-item list-group-item-action py-2 ripple"> | ||||
| 					<i class="fa-solid fa-clock fa-fw me-3"></i><span>History Session</span> | ||||
| 				</a> | ||||
| 				<a style="margin-top: 30px;" href="/history_tree" class="list-group-item list-group-item-action py-2 ripple"> | ||||
| 					<i class="fa-solid fa-timeline fa-fw me-3"></i><span>History Tree</span> | ||||
| 				</a> | ||||
| 				<a style="margin-top: 30px;" href="/modules_config" class="list-group-item list-group-item-action py-2 ripple"> | ||||
| 					<i class="fa-solid fa-gear fa-fw me-3"></i><span>Config</span> | ||||
| 				</a> | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| # import os | ||||
| # import uuid | ||||
| import uuid | ||||
| import json | ||||
| import requests | ||||
| # import jsonschema | ||||
|  | @ -31,12 +31,12 @@ def query_post_query(data, headers={'Content-type': 'application/json'}): | |||
|     return r.json() | ||||
| 
 | ||||
| 
 | ||||
| # def isUUID(uid): | ||||
| #     try: | ||||
| #         uuid.UUID(str(uid)) | ||||
| #         return True | ||||
| #     except ValueError: | ||||
| #         return False | ||||
| def isUUID(uid): | ||||
|     try: | ||||
|         uuid.UUID(str(uid)) | ||||
|         return True | ||||
|     except ValueError: | ||||
|         return False | ||||
| 
 | ||||
| 
 | ||||
| # def form_to_dict(form): | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 David Cruciani
						David Cruciani