mirror of https://github.com/MISP/misp-dashboard
				
				
				
			Added linked pie plot with server
							parent
							
								
									71837d3308
								
							
						
					
					
						commit
						8942a43c18
					
				
							
								
								
									
										33
									
								
								server.py
								
								
								
								
							
							
						
						
									
										33
									
								
								server.py
								
								
								
								
							|  | @ -12,6 +12,7 @@ import os | |||
| import util | ||||
| import contributor_helper | ||||
| import users_helper | ||||
| import trendings_helper | ||||
| 
 | ||||
| configfile = os.path.join(os.environ['DASH_CONFIG'], 'config.cfg') | ||||
| cfg = configparser.ConfigParser() | ||||
|  | @ -34,6 +35,7 @@ serv_redis_db = redis.StrictRedis( | |||
| 
 | ||||
| contributor_helper = contributor_helper.Contributor_helper(serv_redis_db, cfg) | ||||
| users_helper = users_helper.Users_helper(serv_redis_db, cfg) | ||||
| trendings_helper = trendings_helper.Trendings_helper(serv_redis_db, cfg) | ||||
| 
 | ||||
| subscriber_log = redis_server_log.pubsub(ignore_subscribe_messages=True) | ||||
| subscriber_log.psubscribe(cfg.get('RedisLog', 'channel')) | ||||
|  | @ -485,6 +487,37 @@ def getLoginVSCOntribution(): | |||
|     data = users_helper.getLoginVSCOntribution(date) | ||||
|     return jsonify(data) | ||||
| 
 | ||||
| ''' TRENDINGS ''' | ||||
| @app.route("/_getTrendingEvents") | ||||
| def getTrendingEvents(): | ||||
|     try: | ||||
|         date = datetime.datetime.fromtimestamp(float(request.args.get('date'))) | ||||
|     except: | ||||
|         date = datetime.datetime.now() | ||||
| 
 | ||||
|     data = trendings_helper.getTrendingEvents(date) | ||||
|     return jsonify(data) | ||||
| 
 | ||||
| @app.route("/_getTrendingCategs") | ||||
| def getTrendingCategs(): | ||||
|     try: | ||||
|         date = datetime.datetime.fromtimestamp(float(request.args.get('date'))) | ||||
|     except: | ||||
|         date = datetime.datetime.now() | ||||
| 
 | ||||
|     data = trendings_helper.getTrendingCategs(date) | ||||
|     return jsonify(data) | ||||
| 
 | ||||
| @app.route("/_getTrendingTags") | ||||
| def getTrendingTags(): | ||||
|     try: | ||||
|         date = datetime.datetime.fromtimestamp(float(request.args.get('date'))) | ||||
|     except: | ||||
|         date = datetime.datetime.now() | ||||
| 
 | ||||
|     data = trendings_helper.getTrendingTags(date) | ||||
|     return jsonify(data) | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     app.run(host='localhost', port=8001, threaded=True) | ||||
|  |  | |||
|  | @ -1,22 +1,115 @@ | |||
| /* VARS */ | ||||
| var date; | ||||
| var eventPie = ["#eventPie"]; | ||||
| var eventLine = ["#eventLine"]; | ||||
| var categPie = ["#categPie"]; | ||||
| var categLine = ["#categLine"]; | ||||
| var tagPie = ["#tagPie"]; | ||||
| var tagLine = ["#tagLine"]; | ||||
| var sightingEventPieWidget; | ||||
| var sightingCategLineWidget; | ||||
| 
 | ||||
| /* OPTIONS */ | ||||
| var datePickerOptions = { | ||||
|     showOn: "button", | ||||
|     maxDate: 0, | ||||
|     buttonImage: urlIconCalendar, | ||||
|     buttonImageOnly: true, | ||||
|     buttonText: "Select date", | ||||
|     showAnim: "slideDown", | ||||
|     onSelect: dateChanged | ||||
| }; | ||||
| var lineChartOption = { | ||||
|     lines: { | ||||
|         show: true, | ||||
|         steps: true, | ||||
|         fill: true | ||||
|     }, | ||||
|     xaxis: { | ||||
|         mode: "time", | ||||
|         minTickSize: [1, "day"], | ||||
|     } | ||||
| }; | ||||
| var pieChartOption = { | ||||
|     series: { | ||||
|         pie: { | ||||
|             innerRadius: 0.5, | ||||
|             show: true | ||||
|         } | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| /* FUNCTIONS */ | ||||
| 
 | ||||
| function updatePie(pie, data) { | ||||
|     pieID = pie[0]; | ||||
|     pieWidget = pie[1]; | ||||
|     if (data === undefined || data.length == 0 || (data[0] == 0 && data[1] == 0)) { | ||||
|         toPlot = [{ label: 'No data', data: 100 }]; | ||||
|     } else { | ||||
|         toPlot = []; | ||||
|         for (item of data) { | ||||
|             toPlot.push({label: item[0], data: item[1]}); | ||||
|         } | ||||
|     } | ||||
|     console.log(toPlot); | ||||
|     if (!(pieWidget === undefined)) { | ||||
|         pieWidget.setData(toPlot); | ||||
|         pieWidget.setupGrid(); | ||||
|         pieWidget.draw(); | ||||
|     } else { | ||||
|         pieWidget = $.plot(pieID, toPlot, pieChartOption); | ||||
|         pie.push(pieWidget); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function updateLine(line, data) { | ||||
|     lineID = line[0]; | ||||
|     lineWidget = line[1]; | ||||
|     temp = []; | ||||
|     var i=0; | ||||
|     for (item of data) { | ||||
|         temp.push([new Date(item[0]*1000), item[1]]); | ||||
|     } | ||||
|     data = {label: 'Overtime', data: temp} | ||||
|     if (!(lineWidget === undefined)) { | ||||
|         lineWidget.setData(toPlot); | ||||
|         lineWidget.draw(); | ||||
|     } else { | ||||
|         lineWidget = $.plot(lineID, [data], lineChartOption); | ||||
|         line.push(lineWidget); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function updatePieLine(pie, line, url) { | ||||
|     // format date
 | ||||
|     // var now = new Date();
 | ||||
|     // if (date.toDateString() == now.toDateString()) {
 | ||||
|     //     date = now;
 | ||||
|     // } else {
 | ||||
|     //     date.setTime(date.getTime() + (24*60*60*1000-1)); // include data of selected date
 | ||||
|     // }
 | ||||
|     $.getJSON( url+"?date="+parseInt(date.getTime()/1000), function( data ) { | ||||
|         updatePie(pie, data[0][1]); | ||||
|         updateLine(line, data); | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| function dateChanged() { | ||||
|     var date = datePickerWidget.datepicker( "getDate" ); | ||||
|     console.log(date); | ||||
|     date = datePickerWidget.datepicker( "getDate" ); | ||||
|     updatePieLine(eventPie, eventLine, url_getTrendingEvent) | ||||
|     updatePieLine(categPie, categLine, url_getTrendingCateg) | ||||
|     updatePieLine(tagPie, tagLine, url_getTrendingTag) | ||||
| } | ||||
| 
 | ||||
| $(document).ready(function () { | ||||
| 
 | ||||
|     var datePickerOptions = { | ||||
|         showOn: "button", | ||||
|         maxDate: 0, | ||||
|         buttonImage: urlIconCalendar, | ||||
|         buttonImageOnly: true, | ||||
|         buttonText: "Select date", | ||||
|         showAnim: "slideDown", | ||||
|         onSelect: dateChanged | ||||
|     }; | ||||
|     var datePickerOptions = jQuery.extend({}, datePickerOptions); | ||||
|     datePickerWidget = $( "#datepicker" ); | ||||
|     datePickerWidget.datepicker(datePickerOptions); | ||||
|     datePickerWidget = $( "#datepicker" ).datepicker(datePickerOptions); | ||||
|     datePickerWidget.datepicker("setDate", new Date()); | ||||
|     date = datePickerWidget.datepicker( "getDate" ); | ||||
| 
 | ||||
|     updatePieLine(eventPie, eventLine, url_getTrendingEvent) | ||||
|     updatePieLine(categPie, categLine, url_getTrendingCateg) | ||||
|     updatePieLine(tagPie, tagLine, url_getTrendingTag) | ||||
| 
 | ||||
| }); | ||||
|  |  | |||
|  | @ -122,8 +122,9 @@ small { | |||
|                                     <b>Most active events</b> | ||||
|                                 </div> | ||||
|                                 <div id="panelbody" class="panel-body" style=""> | ||||
|                                     <div id="eventPie" style="width:100%; height: 100%;"></div> | ||||
|                                     <div id="eventLine" style="width:100%; height: 100%;"></div> | ||||
|                                     <div id="eventPie" style="width:100%; height: 15vh;"></div> | ||||
|                                     <div style="height: 10px;"></div> | ||||
|                                     <div id="eventLine" style="width:100%; height: 20vh;"></div> | ||||
|                                 </div> | ||||
|                             </div><!-- /.panel-body --> | ||||
|                         </div> | ||||
|  | @ -134,8 +135,9 @@ small { | |||
|                                     <b>Most active categories</b> | ||||
|                                 </div> | ||||
|                                 <div id="panelbody" class="panel-body" style=""> | ||||
|                                     <div id="categPie" style="width:100%; height: 100%;"></div> | ||||
|                                     <div id="categLine" style="width:100%; height: 100%;"></div> | ||||
|                                     <div id="categPie" style="width:100%; height: 15vh;"></div> | ||||
|                                     <div style="height: 10px;"></div> | ||||
|                                     <div id="categLine" style="width:100%; height: 20vh;"></div> | ||||
|                                 </div> | ||||
|                             </div><!-- /.panel-body --> | ||||
|                         </div> | ||||
|  | @ -143,11 +145,12 @@ small { | |||
|                         <div class="col-lg-4"> | ||||
|                             <div class="panel panel-default" style=""> | ||||
|                                 <div class="panel-heading bg-info" style="font-weight: bold;"> | ||||
|                                     <b>Popular tags</b> | ||||
|                                     <b>Most popular tags</b> | ||||
|                                 </div> | ||||
|                                 <div id="panelbody" class="panel-body" style=""> | ||||
|                                     <div id="tagsPie" style="width:100%; height: 100%;"></div> | ||||
|                                     <div id="tagsLine" style="width:100%; height: 100%;"></div> | ||||
|                                     <div id="tagPie" style="width:100%; height: 15vh;"></div> | ||||
|                                     <div style="height: 10px;"></div> | ||||
|                                     <div id="tagLine" style="width:100%; height: 20vh;"></div> | ||||
|                                 </div> | ||||
|                             </div><!-- /.panel-body --> | ||||
|                         </div> | ||||
|  | @ -160,8 +163,8 @@ small { | |||
|                                     <b>Sightings</b> | ||||
|                                 </div> | ||||
|                                 <div id="panelbody" class="panel-body" style=""> | ||||
|                                     <div id="sightingEventPie" style="width:100%; height: 100%;"></div> | ||||
|                                     <div id="sightingCategLine" style="width:100%; height: 100%;"></div> | ||||
|                                     <div id="sightingEventPie" style="width:100%; height: 10vh;"></div> | ||||
|                                     <div id="sightingCategLine" style="width:100%; height: 10vh;"></div> | ||||
|                                 </div> | ||||
|                             </div><!-- /.panel-body --> | ||||
|                         </div> | ||||
|  | @ -171,7 +174,7 @@ small { | |||
|                                     <b>Empty</b> | ||||
|                                 </div> | ||||
|                                 <div id="panelbody" class="panel-body" style=""> | ||||
|                                     <div id="" style="width:100%; height: 100%;"></div> | ||||
|                                     <div id="" style="width:100%; height: 10vh;"></div> | ||||
|                                 </div> | ||||
|                             </div><!-- /.panel-body --> | ||||
|                         </div> | ||||
|  | @ -191,6 +194,9 @@ small { | |||
|     <script> | ||||
|         /* URL */ | ||||
|         var urlIconCalendar = "{{ url_for('static', filename='pics/calendar.gif') }}"; | ||||
|         var url_getTrendingEvent = "{{ url_for('getTrendingEvents') }}"; | ||||
|         var url_getTrendingCateg = "{{ url_for('getTrendingCategs') }}"; | ||||
|         var url_getTrendingTag = "{{ url_for('getTrendingTags') }}"; | ||||
| 
 | ||||
|         /* DATA FROM CONF */ | ||||
| 
 | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ import geoip2.database | |||
| import util | ||||
| import contributor_helper | ||||
| import users_helper | ||||
| import trendings_helper | ||||
| 
 | ||||
| configfile = os.path.join(os.environ['DASH_CONFIG'], 'config.cfg') | ||||
| cfg = configparser.ConfigParser() | ||||
|  | @ -55,6 +56,7 @@ serv_redis_db = redis.StrictRedis( | |||
| 
 | ||||
| contributor_helper = contributor_helper.Contributor_helper(serv_redis_db, cfg) | ||||
| users_helper = users_helper.Users_helper(serv_redis_db, cfg) | ||||
| trendings_helper = trendings_helper.Trendings_helper(serv_redis_db, cfg) | ||||
| 
 | ||||
| reader = geoip2.database.Reader(PATH_TO_DB) | ||||
| 
 | ||||
|  | @ -190,15 +192,15 @@ def handler_keepalive(zmq_name, jsonevent): | |||
|     publish_log(zmq_name, 'Keepalive', to_push) | ||||
| 
 | ||||
| def handler_user(zmq_name, jsondata): | ||||
|     action = jsondata['action'] | ||||
|     json_user = jsondata['User'] | ||||
|     userID = json_user['id'] | ||||
|     org = userID | ||||
|     try: #only consider user login | ||||
|         timestamp = json_user['current_login'] | ||||
|     except KeyError: | ||||
|         return | ||||
|     if timestamp != 0: # "invited_by": "xxxx" ??? | ||||
|     json_org = jsondata['Organisation'] | ||||
|     org = json_org['name'] | ||||
|     if action == 'login': #only consider user login | ||||
|         timestamp = int(time.time()) | ||||
|         users_helper.add_user_login(timestamp, org) | ||||
|     else: | ||||
|         pass | ||||
| 
 | ||||
| def handler_conversation(zmq_name, jsonevent): | ||||
|     try: #only consider POST, not THREAD | ||||
|  | @ -234,6 +236,20 @@ def handler_sighting(zmq_name, jsondata): | |||
| def handler_event(zmq_name, jsonobj): | ||||
|     #fields: threat_level_id, id, info | ||||
|     jsonevent = jsonobj['Event'] | ||||
| 
 | ||||
|     #Add trending | ||||
|     eventName = jsonevent['info'] | ||||
|     timestamp = jsonevent['timestamp'] | ||||
|     trendings_helper.addTrendingEvent(eventName, timestamp) | ||||
|     try: | ||||
|         temp = jsonobj['EventTag'] | ||||
|         tags = [] | ||||
|         for tag in temp: | ||||
|             tags.append(tag['Tag']) | ||||
|     except KeyError: | ||||
|         tags = [] | ||||
|     trendings_helper.addTrendingTags(tags, timestamp) | ||||
| 
 | ||||
|     #redirect to handler_attribute | ||||
|     if 'Attribute' in jsonevent: | ||||
|         attributes = jsonevent['Attribute'] | ||||
|  | @ -270,6 +286,19 @@ def handler_attribute(zmq_name, jsonobj, hasAlreadyBeenContributed=False): | |||
|     if 'Attribute' in jsonobj: | ||||
|         jsonattr = jsonobj['Attribute'] | ||||
| 
 | ||||
|     #Add trending | ||||
|     categName = jsonattr['category'] | ||||
|     timestamp = jsonattr['timestamp'] | ||||
|     trendings_helper.addTrendingCateg(categName, timestamp) | ||||
|     try: | ||||
|         temp = jsonattr['Tag'] | ||||
|         tags = [] | ||||
|         for tag in temp: | ||||
|             tags.append(tag['Tag']) | ||||
|     except KeyError: | ||||
|         tags = [] | ||||
|     trendings_helper.addTrendingTags(tags, timestamp) | ||||
| 
 | ||||
|     to_push = [] | ||||
|     for field in json.loads(cfg.get('Log', 'fieldname_order')): | ||||
|         if type(field) is list: | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Sami Mokaddem
						Sami Mokaddem