diff options
author | 2020-05-04 00:45:07 +0200 | |
---|---|---|
committer | 2020-05-04 00:45:07 +0200 | |
commit | 1676f2fc64880251befdb18ad22f59dae0ae1f4e (patch) | |
tree | d5db46ed33b2a0a9cc23be5ecddd0c887ad91106 | |
parent | mirmon-wrapper.sh: missed case in args (diff) | |
download | gentoo-mirrorstats-1676f2fc64880251befdb18ad22f59dae0ae1f4e.tar.gz gentoo-mirrorstats-1676f2fc64880251befdb18ad22f59dae0ae1f4e.tar.bz2 gentoo-mirrorstats-1676f2fc64880251befdb18ad22f59dae0ae1f4e.zip |
Generate html pages based on the mirmon data
A python script is used to generate html pages based
on the data produced by mirmon. The html pages visualize
the mirror stats using the gentoo tyrian theme.
Signed-off-by: Max Magorsch <arzano@gentoo.org>
-rwxr-xr-x | html/generate.py | 178 | ||||
-rw-r--r-- | html/help.jinja2 | 163 | ||||
-rw-r--r-- | html/stats.jinja2 | 339 |
3 files changed, 680 insertions, 0 deletions
diff --git a/html/generate.py b/html/generate.py new file mode 100755 index 0000000..d6f21c0 --- /dev/null +++ b/html/generate.py @@ -0,0 +1,178 @@ +#!/usr/bin/python + +# +# Generate html pages based on the Mirmon data +# +# This script will parse the json files that contain the mirmon +# data and have been generated before. The json data is used to +# generate html pages that visualize the mirmon data in a human +# readable way. +# +# +# Leaflet is used to visualize the mirrors on a world map. Further- +# more Datatables are used to display the mirrors. +# + +import datetime +import socket +import urllib.request, json +import xml.etree.ElementTree as ET +import jinja2 + +html_folder = "/var/www/mirrorstats.gentoo.org/htdocs/" +cache_path = "/var/www/mirrorstats.gentoo.org/var/html_data_cache.json" + + +mirrorstats = [ 'https://mirrorstats.gentoo.org/rsync/state.json', + 'https://mirrorstats.gentoo.org/distfiles/state.json', + 'https://mirrorstats.gentoo.org/snapshots/state.json', + 'https://mirrorstats.gentoo.org/releases/state.json', + 'https://mirrorstats.gentoo.org/experimental/state.json' + ] + +cache_data = {} + + +# +# Retrieve and parse the JSON at the given URL +# +def getJson(url): + req = urllib.request.Request(url) + r = urllib.request.urlopen(req).read() + return json.loads(r.decode('utf-8')) + + +# +# Retrieve and parse the XML at the given URL +# +def getXML(url): + req = urllib.request.Request(url) + r = urllib.request.urlopen(req).read() + return ET.loads(r.decode('utf-8')).getroot() + + +# +# Get the ip of the given host +# +def getIp(hostname): + try: + ip = socket.gethostbyname(hostname) + except: + ip = "" + return ip + + +# +# Render the stats template for a given page, i.e. all, rsync, distfiles... +# +def renderStatsTemplate(templateEnv, page): + if page == "all": + mirrorstatsList = mirrorstats + else: + mirrorstatsList = ['https://mirrorstats.gentoo.org/' + page + '/state.json'] + + lastUpdate, hostList = getHostList(mirrorstatsList) + template = templateEnv.get_template("stats.jinja2") + template.stream(lastUpdate=lastUpdate, type=page, mirrors=hostList, locations=json.dumps(hostList)).dump(html_folder + page + ".html") + return lastUpdate + + +# read the cache +with open(cache_path) as json_file: + cache_data = json.load(json_file) + +# +# The all mirrors that are present in the given list +# +def getHostList(mirrorstatsList): + hosts = {} + lastUpdate = "" + + # process all mirrors + for mirror_url in mirrorstatsList: + + mirrorData = getJson(mirror_url) + lastUpdate = datetime.datetime.fromtimestamp(int(mirrorData['LastUpdate'])).strftime('%Y-%m-%d %H:%M:%S') + + for mirror in mirrorData['Mirrors']: + if len(mirrorData['Mirrors'][mirror]) >= 0: + for mirrorHost in mirrorData['Mirrors'][mirror]: + hostname = mirrorHost['Host'] + if hostname not in hosts: + hosts[hostname] = {} + + hosts[hostname]['Hostname'] = hostname + + if hostname in cache_data['hosts']: + ip = cache_data['hosts'][hostname] + else: + ip = getIp(hostname) + # populate cache with new value + cache_data['hosts'][hostname] = ip + + if ip != "": + hosts[hostname]['Ip'] = ip + + if 'Stats' not in hosts[hostname]: + hosts[hostname]['Stats'] = [] + + mirrorHost['Type'] = mirror_url.replace("https://mirrorstats.gentoo.org/", "").replace("/state.json", "") + hosts[hostname]['Stats'].append(mirrorHost) + + # compute available protocols + for host in hosts: + protocols = [] + for stat in hosts[host]['Stats']: + protocols.append(stat['Protocol']) + + hosts[host]['Protocols'] = list(set(protocols)) + + # compute mirror locations + for host in hosts: + if 'Ip' not in hosts[host]: + continue + + ip = hosts[host]['Ip'] + if ip in cache_data['ips']: + hosts[host]['Location'] = cache_data['ips'][ip] + else: + mirrorGeoData = getJson("https://ipinfo.io/" + ip + "/json") + hosts[host]['Location'] = mirrorGeoData['loc'] + # populate cache with new value + cache_data['ips'][ip] = mirrorGeoData['loc'] + + return lastUpdate, hosts + + +# +# render jinja2 +# +templateLoader = jinja2.FileSystemLoader(searchpath="./") +templateEnv = jinja2.Environment(loader=templateLoader) + +## stats +lastUpdate = renderStatsTemplate(templateEnv, "all") +renderStatsTemplate(templateEnv, "rsync") +renderStatsTemplate(templateEnv, "distfiles") +renderStatsTemplate(templateEnv, "snapshots") +renderStatsTemplate(templateEnv, "releases") +renderStatsTemplate(templateEnv, "experimental") + +## about +template = templateEnv.get_template("help.jinja2") +template.stream(lastUpdate=lastUpdate).dump(html_folder + "help.html") + + +# +# write the cache +# +with open(cache_path, 'w') as fp: + json.dump(cache_data, fp) + + +# +# finish +# +print("Finished.") + + diff --git a/html/help.jinja2 b/html/help.jinja2 new file mode 100644 index 0000000..6e08363 --- /dev/null +++ b/html/help.jinja2 @@ -0,0 +1,163 @@ +<!DOCTYPE html> +<html> + <head> + <title>Gentoo Mirrorstats</title> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <link href="https://assets.gentoo.org/tyrian/v2/tyrian.min.css" rel="stylesheet" media="screen"> + <link rel="icon" href="https://www.gentoo.org/favicon.ico" type="image/x-icon"> + </head> + + <body> + + <header> + <div class="site-title"> + <div class="container"> + <div class="row justify-content-between"> + <div class="logo"> + <a href="/" title="Back to the homepage" class="site-logo"> + <img src="https://assets.gentoo.org/tyrian/site-logo.png" alt="Gentoo" srcset="https://assets.gentoo.org/tyrian/v2/site-logo.svg"> + </a> + <span class="site-label">Mirrorstats</span> + </div> + <div class="site-title-buttons"> + <div class="btn-group btn-group-sm"> + <a href="https://get.gentoo.org/" role="button" class="btn get-gentoo"><span class="fa fa-fw fa-download"></span> <strong>Get Gentoo!</strong></a> + <div class="btn-group btn-group-sm"> + <a class="btn gentoo-org-sites dropdown-toggle" data-toggle="dropdown" data-target="#" href="#"> + <span class="fa fa-fw fa-map-o"></span> <span class="d-none d-sm-inline">gentoo.org sites</span> <span class="caret"></span> + </a> + <div class="dropdown-menu dropdown-menu-right"> + <a class="dropdown-item" href="https://www.gentoo.org/" title="Main Gentoo website"><span class="fa fa-home fa-fw"></span> gentoo.org</a> + <a class="dropdown-item" href="https://wiki.gentoo.org/" title="Find and contribute documentation"><span class="fa fa-file-text-o fa-fw"></span> Wiki</a> + <a class="dropdown-item" href="https://bugs.gentoo.org/" title="Report issues and find common issues"><span class="fa fa-bug fa-fw"></span> Bugs</a> + <a class="dropdown-item" href="https://forums.gentoo.org/" title="Discuss with the community"><span class="fa fa-comments-o fa-fw"></span> Forums</a> + <a class="dropdown-item" href="https://packages.gentoo.org/" title="Find software for your Gentoo"><span class="fa fa-hdd-o fa-fw"></span> Packages</a> + <div class="dropdown-divider"></div> + <a class="dropdown-item" href="https://planet.gentoo.org/" title="Find out what's going on in the developer community"><span class="fa fa-rss fa-fw"></span> Planet</a> + <a class="dropdown-item" href="https://archives.gentoo.org/" title="Read up on past discussions"><span class="fa fa-archive fa-fw"></span> Archives</a> + <a class="dropdown-item" href="https://sources.gentoo.org/" title="Browse our source code"><span class="fa fa-code fa-fw"></span> Sources</a> + <div class="dropdown-divider"></div> + <a class="dropdown-item" href="https://infra-status.gentoo.org/" title="Get updates on the services provided by Gentoo"><span class="fa fa-server fa-fw"></span> Infra Status</a> + </div> + </div> + </div> + </div> + </div> + </div> + </div> + <nav class="tyrian-navbar navbar navbar-dark navbar-expand-lg bg-primary" role="navigation"> + <div class="container"> + <div class="navbar-header"> + <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbar-main-collapse" aria-controls="navbar-main-collapse" aria-expanded="false" aria-label="Toggle navigation"> + <span class="navbar-toggler-icon"></span> + </button> + </div> + <div class="collapse navbar-collapse navbar-main-collapse" id="navbar-main-collapse"> + <ul class="navbar-nav mr-auto"> + <li class="nav-item"><a class="nav-link" href="all.html">Home</a></li> + <li class="nav-item"><a class="nav-link" href="rsync.html">Rsync</a></li> + <li class="nav-item"><a class="nav-link" href="distfiles.html">Distfiles</a></li> + <li class="nav-item"><a class="nav-link" href="snapshots.html">Snapshots</a></li> + <li class="nav-item"><a class="nav-link" href="releases.html">Releases</a></li> + <li class="nav-item"><a class="nav-link" href="experimental.html">Experimental</a></li> + <li class="nav-item active"><a class="nav-link" href="help.html">Help</a></li> + </ul> + </div> + </div> + </nav> + </header> + + + <div class="container"> + <div class="row"> + <div class="col-md-12"> + <h1 class="first-header">About Gentoo Mirrors</h1> + <div class="alert alert-info"> + If you experience problems with this site (<tt>mirrorstats.gentoo.org</tt>), please file clearly marked bugs in + <a href="https://bugs.gentoo.org/enter_bug.cgi?assigned_to=infra-bugs%40gentoo.org&bug_file_loc=http%3A%2F%2F&bug_severity=normal&bug_status=CONFIRMED&cf_runtime_testing_required=---&comment=This%20page%20is%20NOT%20for%20problems%20with%20a%20specific%20mirror.%0D%0A%0D%0APlease%20include%20a%20summary%20of%20your%20problem%20with%20mirrorstats.gentoo.org%20here.%0D%0A%0D%0A&component=Other%20web%20server%20issues&contenttypemethod=autodetect&contenttypeselection=text%2Fplain&defined_groups=1&flag_type-4=X&form_name=enter_bug&maketemplate=Remember%20values%20as%20bookmarkable%20template&op_sys=Linux&priority=Normal&product=Gentoo%20Infrastructure&rep_platform=All&short_desc=mirrorstats.gentoo.org%3A%20PROBLEM%20SUMMARY&version=unspecified">Gentoo Bugzilla (product <i>Infrastructure</i>)</a>. + Please remember to include <tt>mirrorstats</tt> in the summary line. + </div> + <h2 id="moreInformation">Gentoo rsync mirrors</h2> + <p>Gentoo rsync mirrors tracked include both official mirrors run by the Gentoo Infrastructure team, as well as community-run mirrors.</p> + <ul> + <li><a href="https://www.gentoo.org/support/rsync-mirrors/">Listing of Gentoo rsync mirrors</a></li> + <li><a href="https://wiki.gentoo.org/wiki/Project:Infrastructure/Mirrors/Rsync">How to contribute a new rsync mirror</a></li> + <li><a href="/rsync/">Status of Gentoo rsync mirrors</a></li> + </ul> + <h2>Gentoo source mirrors</h2> + <ul> + <li><a href="https://www.gentoo.org/downloads/mirrors/">Listing of Gentoo source mirrors</a></li> + <li><a href="https://wiki.gentoo.org/wiki/Project:Infrastructure/Mirrors/Source">How to contribute a new source mirror</a></li> + <li><a href="/distfiles/">Status of Gentoo source mirrors: <tt>/distfiles/</tt></a> + <li><a href="/experimental/">Status of Gentoo source mirrors: <tt>/experimental/</tt></a> + <li><a href="/releases/">Status of Gentoo source mirrors: <tt>/releases/</tt></a> + <li><a href="/snapshots/">Status of Gentoo source mirrors: <tt>/snapshots/</tt></a> + </ul> + <div class="alert alert-warning"> + If you experience problems with a specific mirror, please file clearly marked bugs in <a href="https://bugs.gentoo.org/enter_bug.cgi?product=Mirrors">Gentoo Bugzilla (product <i>Mirrors</i>)</a>.</br> + Please include lots of details about the problem, as the Gentoo + mirror team will have to contact the administrator of individual + mirrors to work on problems. + <ul> + <li><b>Hostname</b> of the mirror (in the summary & description)</li> + <li><b>IP</b> of the mirror: many mirrors have multiple nodes behind a single DNS entry</li> + <li><b>Timestamp</b> of the problem</li> + <li><b>Logs</b> of the problem</li> + </ul> + </div> + </div> + </div> + </div> + + + <footer> + <div class="container"> + <div class="row"> + <div class="col-12 offset-md-2 col-md-7"> + <h3 class="footerhead">Gentoo Mirrorstats</h3> + <div class="row"> + <div class="col-xs-12 col-md-4"> + <span class="kk-group-header">Mirror Data as current of</span><br>{{ lastUpdate }} + </div> + <div class="col-xs-12 col-md-4"> + </div> + <div class="col-xs-12 col-md-4"> + </div> + </div> + </div> + <div class="col-12 col-md-3"> + <h3 class="footerhead">Questions or comments?</h3> + Please feel free to <a href="https://www.gentoo.org/inside-gentoo/contact/">contact us</a>. + <p class="mt-2"><a href="https://gitweb.gentoo.org/proj/gentoo-mirrorstats.git/">Gentoo Mirrorstats</a></p> + </div> + </div> + <div class="row"> + <div class="col-2 col-sm-3 col-md-2"> + <ul class="footerlinks three-icons"> + <li><a href="https://twitter.com/gentoo" title="@Gentoo on Twitter"><span class="fa fa-twitter fa-fw"></span></a></li> + <li><a href="https://www.facebook.com/gentoo.org" title="Gentoo on Facebook"><span class="fa fa-facebook fa-fw"></span></a></li> + <li><a href="https://www.reddit.com/r/Gentoo/" title="Gentoo on Reddit"><span class="fa fa-reddit-alien fa-fw"></span></a></li> + </ul> + </div> + <div class="col-10 col-sm-9 col-md-10"> + <strong>© 2001–2020 Gentoo Foundation, Inc.</strong><br> + <small> + Gentoo is a trademark of the Gentoo Foundation, Inc. + The contents of this document, unless otherwise expressly stated, are licensed under the + <a href="https://creativecommons.org/licenses/by-sa/4.0/" rel="license">CC-BY-SA-4.0</a> license. + The <a href="https://www.gentoo.org/inside-gentoo/foundation/name-logo-guidelines.html">Gentoo Name and Logo Usage Guidelines</a> apply. + </small> + </div> + </div> + </div> + </footer> + + + <script src="https://assets.gentoo.org/tyrian/v2/jquery-3.3.slim.js"></script> + <script src="https://assets.gentoo.org/tyrian/v2/popper.min.js"></script> + <script src="https://assets.gentoo.org/tyrian/v2/bootstrap.min.js"></script> + + + </body> +</html> diff --git a/html/stats.jinja2 b/html/stats.jinja2 new file mode 100644 index 0000000..e13cd45 --- /dev/null +++ b/html/stats.jinja2 @@ -0,0 +1,339 @@ +<!DOCTYPE html> +<html> + <head> + <title>Gentoo Mirrorstats</title> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <link href="https://assets.gentoo.org/tyrian/v2/tyrian.min.css" rel="stylesheet" media="screen"> + <link href="https://www.gentoo.org/assets/css/leaflet.css" rel="stylesheet" media="screen"> + <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/bs4/dt-1.10.20/datatables.min.css"/> + <link rel="icon" href="https://www.gentoo.org/favicon.ico" type="image/x-icon"> + </head> + + <body> + + <header> + <div class="site-title"> + <div class="container"> + <div class="row justify-content-between"> + <div class="logo"> + <a href="/" title="Back to the homepage" class="site-logo"> + <img src="https://assets.gentoo.org/tyrian/site-logo.png" alt="Gentoo" srcset="https://assets.gentoo.org/tyrian/v2/site-logo.svg"> + </a> + <span class="site-label">Mirrorstats</span> + </div> + <div class="site-title-buttons"> + <div class="btn-group btn-group-sm"> + <a href="https://get.gentoo.org/" role="button" class="btn get-gentoo"><span class="fa fa-fw fa-download"></span> <strong>Get Gentoo!</strong></a> + <div class="btn-group btn-group-sm"> + <a class="btn gentoo-org-sites dropdown-toggle" data-toggle="dropdown" data-target="#" href="#"> + <span class="fa fa-fw fa-map-o"></span> <span class="d-none d-sm-inline">gentoo.org sites</span> <span class="caret"></span> + </a> + <div class="dropdown-menu dropdown-menu-right"> + <a class="dropdown-item" href="https://www.gentoo.org/" title="Main Gentoo website"><span class="fa fa-home fa-fw"></span> gentoo.org</a> + <a class="dropdown-item" href="https://wiki.gentoo.org/" title="Find and contribute documentation"><span class="fa fa-file-text-o fa-fw"></span> Wiki</a> + <a class="dropdown-item" href="https://bugs.gentoo.org/" title="Report issues and find common issues"><span class="fa fa-bug fa-fw"></span> Bugs</a> + <a class="dropdown-item" href="https://forums.gentoo.org/" title="Discuss with the community"><span class="fa fa-comments-o fa-fw"></span> Forums</a> + <a class="dropdown-item" href="https://packages.gentoo.org/" title="Find software for your Gentoo"><span class="fa fa-hdd-o fa-fw"></span> Packages</a> + <div class="dropdown-divider"></div> + <a class="dropdown-item" href="https://planet.gentoo.org/" title="Find out what's going on in the developer community"><span class="fa fa-rss fa-fw"></span> Planet</a> + <a class="dropdown-item" href="https://archives.gentoo.org/" title="Read up on past discussions"><span class="fa fa-archive fa-fw"></span> Archives</a> + <a class="dropdown-item" href="https://sources.gentoo.org/" title="Browse our source code"><span class="fa fa-code fa-fw"></span> Sources</a> + <div class="dropdown-divider"></div> + <a class="dropdown-item" href="https://infra-status.gentoo.org/" title="Get updates on the services provided by Gentoo"><span class="fa fa-server fa-fw"></span> Infra Status</a> + </div> + </div> + </div> + </div> + </div> + </div> + </div> + <nav class="tyrian-navbar navbar navbar-dark navbar-expand-lg bg-primary" role="navigation"> + <div class="container"> + <div class="navbar-header"> + <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbar-main-collapse" aria-controls="navbar-main-collapse" aria-expanded="false" aria-label="Toggle navigation"> + <span class="navbar-toggler-icon"></span> + </button> + </div> + <div class="collapse navbar-collapse navbar-main-collapse" id="navbar-main-collapse"> + <ul class="navbar-nav mr-auto"> + <li class="nav-item {%if type == 'all'%}active{%endif%}"><a class="nav-link" href="all.html">Home</a></li> + <li class="nav-item {%if type == 'rsync'%}active{%endif%}"><a class="nav-link" href="rsync.html">Rsync</a></li> + <li class="nav-item {%if type == 'distfiles'%}active{%endif%}"><a class="nav-link" href="distfiles.html">Distfiles</a></li> + <li class="nav-item {%if type == 'snapshots'%}active{%endif%}"><a class="nav-link" href="snapshots.html">Snapshots</a></li> + <li class="nav-item {%if type == 'releases'%}active{%endif%}"><a class="nav-link" href="releases.html">Releases</a></li> + <li class="nav-item {%if type == 'experimental'%}active{%endif%}"><a class="nav-link" href="experimental.html">Experimental</a></li> + <li class="nav-item "><a class="nav-link" href="help.html">Help</a></li> + </ul> + </div> + </div> + </nav> + </header> + + + <div class="container"> + <div class="row"> + <div class="col-md-12"> + <h1 class="first-header">Gentoo {% if type != "all" %}{{ type[0]|upper}}{{type[1:]}}{%endif%} Mirrors + {% if type != "all" %} + <small class="ml-2 mt-2 float-right" style="font-size: 60%;"> + <a title="Json Data" class="mr-2 text-muted" href="/{{type}}/state.json"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path d="M5 3h2v2H5v5a2 2 0 0 1-2 2a2 2 0 0 1 2 2v5h2v2H5c-1.07-.27-2-.9-2-2v-4a2 2 0 0 0-2-2H0v-2h1a2 2 0 0 0 2-2V5a2 2 0 0 1 2-2m14 0a2 2 0 0 1 2 2v4a2 2 0 0 0 2 2h1v2h-1a2 2 0 0 0-2 2v4a2 2 0 0 1-2 2h-2v-2h2v-5a2 2 0 0 1 2-2a2 2 0 0 1-2-2V5h-2V3h2m-7 12a1 1 0 0 1 1 1a1 1 0 0 1-1 1a1 1 0 0 1-1-1a1 1 0 0 1 1-1m-4 0a1 1 0 0 1 1 1a1 1 0 0 1-1 1a1 1 0 0 1-1-1a1 1 0 0 1 1-1m8 0a1 1 0 0 1 1 1a1 1 0 0 1-1 1a1 1 0 0 1-1-1a1 1 0 0 1 1-1z" fill="#777777"/></svg></a> + <a title="Original Mirmon Page" class="text-muted" href="/{{type}}/"><i class="fa fa-bar-chart" aria-hidden="true"></i></a> + </small> + {% endif %} + </h1> + + + <p> + Welcome to the Gentoo Linux <tt>mirrorstats</tt> system. Below you can see an overview of all Gentoo {% if type != "all" %}{{ type[0]|upper}}{{type[1:]}}{%endif%} mirrors.<br/> + For more information about Gentoo mirrors, how to contribute a mirror or any problems please have a look at the <a href="help.html">help page</a>. + </p> + <div id="mirrorLocations" style="height: 500px; margin-bottom: 1em;"></div> + </div> + + <div class="col-md-12 my-4"> + <table id="table_id" class="display table"> + <thead> + <tr> + <th>Host</th> + {% if type == "all" %}<th>Type</th>{% endif %} + <th>Protocol</th> + <th class="statusHistory">Daily Stats</th> + <th class="statusHistory">Probe Stats</th> + <th style="text-align: right;">Last State</th> + </tr> + </thead> + <tbody> + + {% for mirror in mirrors %} + {% for stat in mirrors[mirror]['Stats'] %} + <tr> + <td>{{ mirror }}</td> + {% if type == "all" %}<td>{{ stat['Type'] }}</td>{% endif %} + <td>{{ stat['Protocol'] }}</td> + <td>{{ stat['StateHistory'] }}</td> + <td>{{ stat['ProbeHistory'] }}</td> + <td style="text-align: right;"> + {% if stat['StatusLastProbe'] == "ok" %} + <span class="badge badge-success">OK</span> + {% elif stat['StatusLastProbe'] == "hangs" %} + <span class="badge badge-danger">Hangs</span> + {% elif stat['StatusLastProbe'] == "no_time" %} + <span class="badge badge-danger">No Time</span> + {% elif stat['StatusLastProbe'] == "site_not_found" %} + <span class="badge badge-danger">Site Not Found</span> + {% elif stat['StatusLastProbe'] == "'-1'" %} + <span class="badge badge-danger">-1</span> + {% else %} + <span class="badge badge-warning">{{ stat['StatusLastProbe'] }}</span> + {% endif %} + </td> + </tr> + {% endfor %} + {% endfor %} + + </tbody> + </table> + + </div> + </div> + </div> + + + <footer> + <div class="container"> + <div class="row"> + <div class="col-12 offset-md-2 col-md-7"> + <h3 class="footerhead">Gentoo Mirrorstats</h3> + <div class="row"> + <div class="col-xs-12 col-md-4"> + <span class="kk-group-header">Mirror Data as current of</span><br>{{ lastUpdate }} + </div> + <div class="col-xs-12 col-md-4"> + <span>Data powered by:</span><br><a href="http://www.staff.science.uu.nl/~penni101/mirmon/">Mirmon v2.11</a> + </div> + <div class="col-xs-12 col-md-4"> + </div> + </div> + </div> + <div class="col-12 col-md-3"> + <h3 class="footerhead">Questions or comments?</h3> + Please feel free to <a href="https://www.gentoo.org/inside-gentoo/contact/">contact us</a>. + <p class="mt-2"><a href="https://gitweb.gentoo.org/proj/gentoo-mirrorstats.git/">Gentoo Mirrorstats</a></p> + </div> + </div> + <div class="row"> + <div class="col-2 col-sm-3 col-md-2"> + <ul class="footerlinks three-icons"> + <li><a href="https://twitter.com/gentoo" title="@Gentoo on Twitter"><span class="fa fa-twitter fa-fw"></span></a></li> + <li><a href="https://www.facebook.com/gentoo.org" title="Gentoo on Facebook"><span class="fa fa-facebook fa-fw"></span></a></li> + <li><a href="https://www.reddit.com/r/Gentoo/" title="Gentoo on Reddit"><span class="fa fa-reddit-alien fa-fw"></span></a></li> + </ul> + </div> + <div class="col-10 col-sm-9 col-md-10"> + <strong>© 2001–2020 Gentoo Foundation, Inc.</strong><br> + <small> + Gentoo is a trademark of the Gentoo Foundation, Inc. + The contents of this document, unless otherwise expressly stated, are licensed under the + <a href="https://creativecommons.org/licenses/by-sa/4.0/" rel="license">CC-BY-SA-4.0</a> license. + The <a href="https://www.gentoo.org/inside-gentoo/foundation/name-logo-guidelines.html">Gentoo Name and Logo Usage Guidelines</a> apply. + </small> + </div> + </div> + </div> + </footer> + + <script> + var mirrorLocations = {{locations}}; + </script> + + + <script src="https://assets.gentoo.org/tyrian/v2/jquery-3.3.slim.js"></script> + <script src="https://assets.gentoo.org/tyrian/v2/popper.min.js"></script> + <script src="https://assets.gentoo.org/tyrian/v2/bootstrap.min.js"></script> + + <script src="https://www.gentoo.org/assets/js/leaflet.js"></script> + + <script type="text/javascript" src="https://cdn.datatables.net/v/bs4/dt-1.10.20/rg-1.1.1/datatables.min.js"></script> + + <script> + + $(function() { + L.Icon.Default.imagePath = 'https://www.gentoo.org/assets/img/maps/'; + var map = L.map('mirrorLocations', { zoomAnimationThreshold: 9 } ).setView([30, 0], 2); + var markers = {}; + + map.addLayer(new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { minZoom: 2, maxZoom: 8, attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors' })); + + + var greenIcon = new L.Icon({ + iconUrl: 'https://cdn.rawgit.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-green.png', + shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png', + iconSize: [25, 41], + iconAnchor: [12, 41], + popupAnchor: [1, -34], + shadowSize: [41, 41] + }); + + var orangeIcon = new L.Icon({ + iconUrl: 'https://cdn.rawgit.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-gold.png', + shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png', + iconSize: [25, 41], + iconAnchor: [12, 41], + popupAnchor: [1, -34], + shadowSize: [41, 41] + }); + + var redIcon = new L.Icon({ + iconUrl: 'https://cdn.rawgit.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-red.png', + shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png', + iconSize: [25, 41], + iconAnchor: [12, 41], + popupAnchor: [1, -34], + shadowSize: [41, 41] + }); + + + + $.each(mirrorLocations, function(index, mirror) { + if(mirror.Location){ + lat = mirror.Location.split(",")[0]; + long = mirror.Location.split(",")[1]; + + ok = 0; + for (let i = 0; i < mirror.Stats.length; i++){ + if(mirror.Stats[i].StatusLastProbe == "ok"){ + ok++; + } + } + + if(ok == mirror.Stats.length){ + marker = L.marker([lat, long], {icon: greenIcon}).addTo(map); + }else if(ok == 0){ + marker = L.marker([lat, long], {icon: redIcon}).addTo(map); + }else{ + marker = L.marker([lat, long], {icon: orangeIcon}).addTo(map); + } + + popupText = "<h4 class='mt-2'> " + mirror.Hostname + "</h4>"; + + popupText += "<table class='table'><tr>{% if type == 'all' %}<th>Type</th>{% endif %}<th>Protocol</th><th>Probe History</th><th>Last Probe</th></tr>"; + for (let i = 0; i < mirror.Stats.length; i++){ + probeHistory = ""; + for (let j = 0; j < mirror.Stats[i].ProbeHistory.length; j++) { + if(mirror.Stats[i].ProbeHistory[j] == "s"){ + probeHistory += '<i class="fa fa-fw fa-check" style="color:#28a745;" aria-hidden="true"></i>'; + }else{ + probeHistory += '<i class="fa fa-fw fa-times" style="color:#dc3545;" aria-hidden="true"></i>'; + } + } + + lastProbeStatus = mirror.Stats[i].StatusLastProbe; + + if(lastProbeStatus == "ok"){ + lastProbeStatus = '<span class="badge badge-success">OK</span>'; + } else if(lastProbeStatus == "hangs"){ + lastProbeStatus = '<span class="badge badge-danger">Hangs</span>'; + } else if(lastProbeStatus == "no_time"){ + lastProbeStatus = '<span class="badge badge-danger">No Time</span>'; + } else if(lastProbeStatus == "site_not_found"){ + lastProbeStatus = '<span class="badge badge-danger">Site Not Found</span>'; + } else if(lastProbeStatus == "'-1'"){ + lastProbeStatus = '<span class="badge badge-danger">-1</span>'; + } else { + lastProbeStatus = '<span class="badge badge-warning">' + lastProbeStatus + '</span>'; + } + + popupText += "<tr>{% if type == 'all' %}<td>" + mirror.Stats[i].Type + "</td>{% endif %}<td>" + mirror.Stats[i].Protocol + "</td><td>" + probeHistory + "</td><td>" + lastProbeStatus + "</td></tr>"; + } + popupText += "</table>"; + + + marker.bindPopup(popupText, { + minWidth : 500, + maxWidth : 600, + maxHeight : 260, + }); + + markers[index] = marker; + } + }); + }); + </script> + + <script> + + $(document).ready( function () { + $('#table_id').DataTable({ + "autoWidth": true, + "iDisplayLength": 25, + // TODO Group by Region in future + // rowGroup: { + // dataSrc: 1 + // } + "columnDefs": [ + { + "render": function ( data, type, row ) { + state_str = data.split("-")[data.split("-").length-1]; + result = ""; + + for (let i = 0; i < state_str.length; i++){ + if(state_str[i] == 's'){ + result += '<i class="fa fa-check" style="color:#28a745;width:1rem;text-align:center;" aria-hidden="true"></i>\n'; + }else{ + result += '<i class="fa fa-times" style="color:#dc3545;width:1rem;text-align:center;" aria-hidden="true"></i>\n'; + } + } + + return result; + }, + "targets": "statusHistory" + }, + ] + }); + } ); + + </script> + + </body> +</html> |