mirror of https://github.com/D4-project/d4-core
chg: [web] add basic flask server
parent
598ef2e8d8
commit
cac6a1ce3c
|
@ -2,3 +2,5 @@
|
|||
*.csr
|
||||
*.pem
|
||||
*.key
|
||||
data/
|
||||
logs/
|
||||
|
|
|
@ -229,11 +229,14 @@ class Echo(Protocol, TimeoutMixin):
|
|||
if redis_server_stream.xlen('stream:{}:{}'.format(data_header['type'], self.session_uuid)) < self.stream_max_size:
|
||||
|
||||
redis_server_stream.xadd('stream:{}:{}'.format(data_header['type'], self.session_uuid), {'message': data[header_size:], 'uuid': data_header['uuid_header'], 'timestamp': data_header['timestamp'], 'version': data_header['version']})
|
||||
|
||||
# daily stats
|
||||
redis_server_metadata.zincrby('stat_uuid_ip:{}:{}'.format(date, data_header['uuid_header']), 1, ip)
|
||||
redis_server_metadata.zincrby('stat_ip_uuid:{}:{}'.format(date, ip), 1, data_header['uuid_header'])
|
||||
|
||||
redis_server_metadata.zincrby('daily_uuid:{}'.format(date), 1, data_header['uuid_header'])
|
||||
redis_server_metadata.zincrby('daily_ip:{}'.format(date), 1, ip)
|
||||
redis_server_metadata.zincrby('daily_type:{}'.format(date), 1, data_header['type'])
|
||||
redis_server_metadata.zincrby('stat_type_uuid:{}:{}'.format(date, data_header['type']), 1, data_header['uuid_header'])
|
||||
|
||||
#
|
||||
if not redis_server_metadata.hexists('metadata_uuid:{}'.format(data_header['uuid_header']), 'first_seen'):
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*-coding:UTF-8 -*
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import redis
|
||||
import flask
|
||||
import datetime
|
||||
|
||||
from flask import Flask, render_template, jsonify, request, Blueprint, redirect, url_for
|
||||
|
||||
baseUrl = ''
|
||||
if baseUrl != '':
|
||||
baseUrl = '/'+baseUrl
|
||||
|
||||
host_redis_metadata = "localhost"
|
||||
port_redis_metadata= 6380
|
||||
|
||||
redis_server_metadata = redis.StrictRedis(
|
||||
host=host_redis_metadata,
|
||||
port=port_redis_metadata,
|
||||
db=0,
|
||||
decode_responses=True)
|
||||
|
||||
app = Flask(__name__, static_url_path=baseUrl+'/static/')
|
||||
app.config['MAX_CONTENT_LENGTH'] = 900 * 1024 * 1024
|
||||
|
||||
# ========== ROUTES ============
|
||||
@app.route('/')
|
||||
def index():
|
||||
return render_template("index.html")
|
||||
|
||||
@app.route('/_json_daily_uuid_stats')
|
||||
def _json_daily_uuid_stats():
|
||||
date = datetime.datetime.now().strftime("%Y%m%d")
|
||||
daily_uuid = redis_server_metadata.zrange('daily_uuid:{}'.format(date), 0, -1, withscores=True)
|
||||
|
||||
data_daily_uuid = []
|
||||
for result in daily_uuid:
|
||||
data_daily_uuid.append({"key": result[0], "value": int(result[1])})
|
||||
|
||||
return jsonify(data_daily_uuid)
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(host='0.0.0.0', port=7000, threaded=True)
|
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
|
@ -0,0 +1,237 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<!-- Core CSS -->
|
||||
<link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" rel="stylesheet">
|
||||
|
||||
<!-- JS -->
|
||||
<script src="{{ url_for('static', filename='js/d3.min.js')}}"></script>
|
||||
|
||||
<style>
|
||||
#div_chart{
|
||||
width:600px;
|
||||
margin:20px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font: inherit;
|
||||
font-size: 100%;
|
||||
vertical-align: baseline;
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
|
||||
font-weight: inherit;
|
||||
}
|
||||
#chart{
|
||||
width:600px;
|
||||
height:1000px;
|
||||
}
|
||||
.bar{
|
||||
fill:#eaeaea;
|
||||
}
|
||||
text.label{
|
||||
fill: #777777;
|
||||
color: #777777;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
}
|
||||
text.category{
|
||||
fill: #666666;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div id="everything">
|
||||
<div id="chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div id="everything">
|
||||
<div id="charter"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
<script>
|
||||
////
|
||||
//http://bl.ocks.org/charlesdguthrie/11356441, updated and modified
|
||||
//updating BarChart
|
||||
var setup = function(targetID){
|
||||
//Set size of svg element and chart
|
||||
var margin = {top: 0, right: 0, bottom: 0, left: 0},
|
||||
width = 600 - margin.left - margin.right,
|
||||
height = 1000 - margin.top - margin.bottom,
|
||||
categoryIndent = 4*15 + 5,
|
||||
defaultBarWidth = 2000;
|
||||
|
||||
//Set up scales
|
||||
var x = d3.scaleLinear()
|
||||
.domain([0,defaultBarWidth])
|
||||
.range([0,width]);
|
||||
var y = d3.scaleBand()
|
||||
.rangeRound([0, height])
|
||||
.padding(0.1);
|
||||
|
||||
d3.select(targetID).selectAll("svg").remove()
|
||||
var svg = d3.select(targetID).append("svg")
|
||||
.attr("width", width + margin.left + margin.right)
|
||||
.attr("height", height + margin.top + margin.bottom)
|
||||
.append("g")
|
||||
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
|
||||
|
||||
var settings = {
|
||||
margin:margin, width:width, height:height, categoryIndent:categoryIndent,
|
||||
svg:svg, x:x, y:y
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
|
||||
var redrawChart = function(targetID, newdata) {
|
||||
|
||||
//Import settings
|
||||
var margin=settings.margin, width=settings.width, height=settings.height, categoryIndent=settings.categoryIndent,
|
||||
svg=settings.svg, x=settings.x, y=settings.y;
|
||||
|
||||
//Reset domains
|
||||
y.domain(newdata.sort(function(a,b){
|
||||
return b.value - a.value;
|
||||
})
|
||||
.map(function(d) { return d.key; }));
|
||||
var barmax = d3.max(newdata, function(e) {
|
||||
return e.value;
|
||||
});
|
||||
x.domain([0,barmax]);
|
||||
|
||||
/////////
|
||||
//ENTER//
|
||||
/////////
|
||||
|
||||
//Create chart row and move to below the bottom of the chart
|
||||
var chartRow = svg.selectAll("g.chartRow")
|
||||
.data(newdata, function(d){ return d.key});
|
||||
var newRow = chartRow
|
||||
.enter()
|
||||
.append("g")
|
||||
.attr("class", "chartRow")
|
||||
.attr("transform", "translate(0," + height + margin.top + margin.bottom + ")");
|
||||
|
||||
//bars
|
||||
newRow.insert("rect")
|
||||
.attr("class","bar")
|
||||
.attr("x", 0)
|
||||
.attr("opacity",0)
|
||||
.attr("height", y.bandwidth())
|
||||
.attr("width", function(d) { return x(d.value);})
|
||||
|
||||
//labels
|
||||
newRow.append("text")
|
||||
.attr("class","label")
|
||||
.attr("y", y.bandwidth()/2)
|
||||
.attr("x",0)
|
||||
.attr("opacity",0)
|
||||
.attr("dy",".35em")
|
||||
.attr("dx","0.5em")
|
||||
.text(function(d){return d.value;});
|
||||
|
||||
//text
|
||||
newRow.append("text")
|
||||
.attr("class","category")
|
||||
.attr("text-overflow","ellipsis")
|
||||
.attr("y", y.bandwidth()/2)
|
||||
.attr("x",categoryIndent)
|
||||
.attr("opacity",0)
|
||||
.attr("dy",".35em")
|
||||
.attr("dx","5em")
|
||||
.text(function(d){return d.key});
|
||||
|
||||
|
||||
//////////
|
||||
//UPDATE//
|
||||
//////////
|
||||
|
||||
//Update bar widths
|
||||
chartRow.select(".bar").transition()
|
||||
.duration(300)
|
||||
.attr("width", function(d) { return x(d.value);})
|
||||
.attr("opacity",1);
|
||||
|
||||
//Update data labels
|
||||
chartRow.select(".label").transition()
|
||||
.duration(300)
|
||||
.attr("opacity",1)
|
||||
.tween("text", function(d) {
|
||||
var node = this, i = d3.interpolate(+this.textContent.replace(/\,/g,''), +d.value);
|
||||
return function(t) {
|
||||
node.textContent = Math.round(i(t));
|
||||
};
|
||||
});
|
||||
|
||||
//Fade in categories
|
||||
chartRow.select(".category").transition()
|
||||
.duration(300)
|
||||
.attr("opacity",1);
|
||||
|
||||
|
||||
////////
|
||||
//EXIT//
|
||||
////////
|
||||
|
||||
//Fade out and remove exit elements
|
||||
chartRow.exit().transition()
|
||||
.style("opacity","0")
|
||||
.attr("transform", "translate(0," + (height + margin.top + margin.bottom) + ")")
|
||||
.remove();
|
||||
|
||||
|
||||
////////////////
|
||||
//REORDER ROWS//
|
||||
////////////////
|
||||
|
||||
var delay = function(d, i) { return 200 + i * 30; };
|
||||
|
||||
chartRow.transition()
|
||||
.delay(delay)
|
||||
.duration(900)
|
||||
.attr("transform", function(d){ return "translate(0," + y(d.key) + ")"; });
|
||||
};
|
||||
|
||||
var pullData = function(settings,callback){
|
||||
d3.json("{{ url_for('_json_daily_uuid_stats') }}", function (err, data){
|
||||
if (err) return console.warn(err);
|
||||
callback(settings,data);
|
||||
})
|
||||
}
|
||||
|
||||
//Sort data in descending order
|
||||
var formatData = function(data){
|
||||
return data.sort(function (a, b) {
|
||||
return b.value - a.value;
|
||||
})
|
||||
.slice(0, 15); // linit to 15 items
|
||||
}
|
||||
|
||||
var redraw = function(settings){
|
||||
pullData(settings,redrawChart)
|
||||
}
|
||||
|
||||
//setup
|
||||
var settings = setup('#chart');
|
||||
redraw(settings)
|
||||
|
||||
//Interval
|
||||
setInterval(function(){
|
||||
redraw(settings)
|
||||
}, 4000);
|
||||
////
|
||||
|
||||
</script>
|
|
@ -0,0 +1,61 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
BOOTSTRAP_VERSION='4.2.1'
|
||||
FONT_AWESOME_VERSION='4.7.0'
|
||||
D3_JS_VERSION='4.13.0'
|
||||
|
||||
if [ ! -d static/css ]; then
|
||||
mkdir static/css
|
||||
fi
|
||||
if [ ! -d static/js ]; then
|
||||
mkdir static/js
|
||||
fi
|
||||
|
||||
rm -rf temp
|
||||
mkdir temp
|
||||
|
||||
wget https://github.com/twbs/bootstrap/releases/download/v${BOOTSTRAP_VERSION}/bootstrap-${BOOTSTRAP_VERSION}-dist.zip -O temp/bootstrap${BOOTSTRAP_VERSION}.zip
|
||||
|
||||
#wget https://github.com/FortAwesome/Font-Awesome/archive/v${FONT_AWESOME_VERSION}.zip -O temp/FONT_AWESOME_${FONT_AWESOME_VERSION}.zip
|
||||
wget https://github.com/d3/d3/releases/download/v${D3_JS_VERSION}/d3.zip -O temp/d3_${D3_JS_VERSION}.zip
|
||||
|
||||
# dateRangePicker
|
||||
#wget https://github.com/moment/moment/archive/2.22.2.zip -O temp/moment_2.22.2.zip
|
||||
#wget https://github.com/longbill/jquery-date-range-picker/archive/v0.18.0.zip -O temp/daterangepicker_v0.18.0.zip
|
||||
|
||||
|
||||
unzip temp/bootstrap${BOOTSTRAP_VERSION}.zip -d temp/
|
||||
#unzip temp/FONT_AWESOME_${FONT_AWESOME_VERSION}.zip -d temp/
|
||||
unzip temp/d3_${D3_JS_VERSION}.zip -d temp/
|
||||
|
||||
#unzip temp/moment_2.22.2.zip -d temp/
|
||||
#unzip temp/daterangepicker_v0.18.0.zip -d temp/
|
||||
|
||||
mv temp/bootstrap-${BOOTSTRAP_VERSION}-dist/js/bootstrap.min.js ./static/js/
|
||||
mv temp/bootstrap-${BOOTSTRAP_VERSION}-dist/css/bootstrap.min.css ./static/css/
|
||||
mv temp/bootstrap-${BOOTSTRAP_VERSION}-dist/css/bootstrap.min.css.map ./static/css/
|
||||
|
||||
|
||||
#mv temp/Font-Awesome-${FONT_AWESOME_VERSION} temp/font-awesome
|
||||
|
||||
#rm -rf ./static/fonts/ ./static/font-awesome/
|
||||
#mv temp/font-awesome/ ./static/
|
||||
|
||||
#mv temp/jquery-date-range-picker-0.18.0/dist/daterangepicker.min.css ./static/css/
|
||||
|
||||
mv temp/d3.min.js ./static/js/
|
||||
#mv temp/moment-2.22.2/min/moment.min.js ./static/js/
|
||||
#mv temp/jquery-date-range-picker-0.18.0/dist/jquery.daterangepicker.min.js ./static/js/
|
||||
|
||||
rm -rf temp
|
||||
|
||||
JQVERSION="3.3.1"
|
||||
wget http://code.jquery.com/jquery-${JQVERSION}.min.js -O ./static/js/jquery.js
|
||||
|
||||
#Ressources for dataTable
|
||||
wget https://cdn.datatables.net/v/bs4/dt-1.10.18/datatables.min.css -O ./static/css/dataTables.bootstrap.css
|
||||
wget https://cdn.datatables.net/v/bs4/dt-1.10.18/datatables.min.js -O ./static/js/dataTables.bootstrap.js
|
||||
|
||||
rm -rf temp
|
Loading…
Reference in New Issue