new: Add historical graph in ASN view
parent
fbc5a6a1bb
commit
2d9667e25b
|
@ -3,6 +3,7 @@
|
|||
|
||||
from typing import TypeVar
|
||||
import datetime
|
||||
from datetime import timedelta
|
||||
from dateutil.parser import parse
|
||||
|
||||
import logging
|
||||
|
@ -55,7 +56,7 @@ class Querying():
|
|||
key = f'{d}|{asn}|{ipversion}'
|
||||
return self.ranking.zrevrange(key, start=0, end=-1, withscores=True)
|
||||
|
||||
def asn_rank(self, asn: int, date: Dates= datetime.date.today(), source: str='', ipversion: str='v4'):
|
||||
def asn_rank(self, asn: int, date: Dates=datetime.date.today(), source: str='', ipversion: str='v4'):
|
||||
'''Get the rank of a single ASN, weighted by source.'''
|
||||
d = self.__normalize_date(date)
|
||||
if source:
|
||||
|
@ -64,7 +65,7 @@ class Querying():
|
|||
key = f'{d}|asns|{ipversion}'
|
||||
return self.ranking.zscore(key, asn)
|
||||
|
||||
def get_sources(self, date: Dates= datetime.date.today()):
|
||||
def get_sources(self, date: Dates=datetime.date.today()):
|
||||
'''Get the sources availables for a specific day (default: today).'''
|
||||
d = self.__normalize_date(date)
|
||||
key = f'{d}|sources'
|
||||
|
@ -75,3 +76,11 @@ class Querying():
|
|||
if all_descriptions or not descriptions:
|
||||
return descriptions
|
||||
return descriptions[sorted(descriptions.keys(), reverse=True)[0]]
|
||||
|
||||
def get_asn_history(self, asn: int, period: int=200, source: str='', ipversion: str='v4'):
|
||||
to_return = []
|
||||
today = datetime.date.today()
|
||||
for i in range(period):
|
||||
date = today - timedelta(days=i)
|
||||
to_return.insert(0, (date.isoformat(), self.asn_rank(asn, date, source, ipversion)))
|
||||
return to_return
|
||||
|
|
|
@ -5,5 +5,4 @@ set -x
|
|||
|
||||
mkdir -p web/static/
|
||||
|
||||
wget https://code.jquery.com/ui/1.12.1/jquery-ui.js -O web/static/jquery-ui.js
|
||||
wget https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css -O web/static/jquery-ui.css
|
||||
wget https://d3js.org/d3.v5.js -O web/static/d3.v5.js
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import json
|
||||
|
||||
from flask import Flask, render_template, request, session
|
||||
from flask_bootstrap import Bootstrap
|
||||
|
||||
from bgpranking.querying import Querying
|
||||
from pathlib import Path
|
||||
from datetime import date, timedelta
|
||||
|
||||
|
||||
|
@ -16,9 +17,6 @@ app.secret_key = '\xeb\xfd\x1b\xee\xed<\xa5~\xd5H\x85\x00\xa5r\xae\x80t5@\xa2&>\
|
|||
Bootstrap(app)
|
||||
app.config['BOOTSTRAP_SERVE_LOCAL'] = True
|
||||
|
||||
jquery_js = Path('static', 'jquery-ui.js')
|
||||
jquery_css = Path('static', 'jquery-ui.css')
|
||||
|
||||
|
||||
def load_session():
|
||||
if request.method == 'POST':
|
||||
|
@ -48,7 +46,7 @@ def index():
|
|||
q = Querying()
|
||||
sources = q.get_sources(date=session['date'])
|
||||
session.pop('asn', None)
|
||||
ranks = q.asns_global_ranking(limit=-1, **session)
|
||||
ranks = q.asns_global_ranking(limit=100, **session)
|
||||
descriptions = [q.get_asn_descriptions(int(asn)) for asn, rank in ranks]
|
||||
r = zip(ranks, descriptions)
|
||||
return render_template('index.html', ranks=r, sources=sources, **session)
|
||||
|
@ -60,3 +58,12 @@ def asn_details():
|
|||
q = Querying()
|
||||
ranks = q.asn_details(**session)
|
||||
return render_template('asn.html', ranks=ranks, **session)
|
||||
|
||||
|
||||
@app.route('/asn_history', methods=['GET', 'POST'])
|
||||
def asn_history():
|
||||
load_session()
|
||||
print(session.keys())
|
||||
session.pop('date')
|
||||
q = Querying()
|
||||
return json.dumps(q.get_asn_history(**session))
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
body { font: 12px Arial;}
|
||||
|
||||
path {
|
||||
stroke: steelblue;
|
||||
stroke-width: 2;
|
||||
fill: none;
|
||||
}
|
||||
|
||||
.axis path,
|
||||
.axis line {
|
||||
fill: none;
|
||||
stroke: grey;
|
||||
stroke-width: 1;
|
||||
shape-rendering: crispEdges;
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
// set the dimensions and margins of the graph
|
||||
var margin = {top: 20, right: 20, bottom: 30, left: 50},
|
||||
width = 960 - margin.left - margin.right,
|
||||
height = 500 - margin.top - margin.bottom;
|
||||
|
||||
// parse the date / time
|
||||
var parseTime = d3.timeParse("%Y-%m-%d");
|
||||
|
||||
// set the ranges
|
||||
var x = d3.scaleTime().range([0, width]);
|
||||
var y = d3.scaleLinear().range([height, 0]);
|
||||
|
||||
// define the line
|
||||
var valueline = d3.line()
|
||||
.x(function(d) { return x(d[0]); })
|
||||
.y(function(d) { return y(d[1]); });
|
||||
|
||||
// append the svg obgect to the body of the page
|
||||
// appends a 'group' element to 'svg'
|
||||
// moves the 'group' element to the top left margin
|
||||
var svg = d3.select("body").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 + ")");
|
||||
|
||||
function draw(data) {
|
||||
|
||||
var data = data;
|
||||
|
||||
// Scale the range of the data
|
||||
x.domain(d3.extent(data, function(d) { return d[0]; }));
|
||||
y.domain([0, d3.max(data, function(d) { return d[1]; })]);
|
||||
|
||||
// Add the valueline path.
|
||||
svg.append("path")
|
||||
.data([data])
|
||||
.attr("class", "line")
|
||||
.attr("d", valueline);
|
||||
// Add the X Axis
|
||||
svg.append("g")
|
||||
.attr("transform", "translate(0," + height + ")")
|
||||
.call(d3.axisBottom(x));
|
||||
|
||||
// Add the Y Axis
|
||||
svg.append("g")
|
||||
.call(d3.axisLeft(y));
|
||||
}
|
||||
|
||||
// Get the data
|
||||
d3.json("/asn_history", {credentials: 'same-origin'}).then(function(data) {
|
||||
// trigger render
|
||||
draw(data);
|
||||
});
|
|
@ -1,7 +1,18 @@
|
|||
{% extends "main.html" %}
|
||||
|
||||
{% block head %}
|
||||
{{ super() }}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='linegraph.css') }}">
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block title %}Ranking - {{ asn }}{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
{{ super() }}
|
||||
<script src='{{ url_for('static', filename='linegraph.js') }}'></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<center>
|
||||
<h1>Ranking - {{asn}}</h1></br></br>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
{% block scripts %}
|
||||
{{ super() }}
|
||||
<script src='{{ url_for('static', filename='d3.v5.js') }}'></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block head %}
|
||||
|
|
Loading…
Reference in New Issue