1 |
commit: 1676f2fc64880251befdb18ad22f59dae0ae1f4e |
2 |
Author: Max Magorsch <arzano <AT> gentoo <DOT> org> |
3 |
AuthorDate: Sun May 3 22:45:07 2020 +0000 |
4 |
Commit: Max Magorsch <arzano <AT> gentoo <DOT> org> |
5 |
CommitDate: Sun May 3 22:45:07 2020 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/gentoo-mirrorstats.git/commit/?id=1676f2fc |
7 |
|
8 |
Generate html pages based on the mirmon data |
9 |
|
10 |
A python script is used to generate html pages based |
11 |
on the data produced by mirmon. The html pages visualize |
12 |
the mirror stats using the gentoo tyrian theme. |
13 |
|
14 |
Signed-off-by: Max Magorsch <arzano <AT> gentoo.org> |
15 |
|
16 |
html/generate.py | 178 ++++++++++++++++++++++++++++ |
17 |
html/help.jinja2 | 163 ++++++++++++++++++++++++++ |
18 |
html/stats.jinja2 | 339 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
19 |
3 files changed, 680 insertions(+) |
20 |
|
21 |
diff --git a/html/generate.py b/html/generate.py |
22 |
new file mode 100755 |
23 |
index 0000000..d6f21c0 |
24 |
--- /dev/null |
25 |
+++ b/html/generate.py |
26 |
@@ -0,0 +1,178 @@ |
27 |
+#!/usr/bin/python |
28 |
+ |
29 |
+# |
30 |
+# Generate html pages based on the Mirmon data |
31 |
+# |
32 |
+# This script will parse the json files that contain the mirmon |
33 |
+# data and have been generated before. The json data is used to |
34 |
+# generate html pages that visualize the mirmon data in a human |
35 |
+# readable way. |
36 |
+# |
37 |
+# |
38 |
+# Leaflet is used to visualize the mirrors on a world map. Further- |
39 |
+# more Datatables are used to display the mirrors. |
40 |
+# |
41 |
+ |
42 |
+import datetime |
43 |
+import socket |
44 |
+import urllib.request, json |
45 |
+import xml.etree.ElementTree as ET |
46 |
+import jinja2 |
47 |
+ |
48 |
+html_folder = "/var/www/mirrorstats.gentoo.org/htdocs/" |
49 |
+cache_path = "/var/www/mirrorstats.gentoo.org/var/html_data_cache.json" |
50 |
+ |
51 |
+ |
52 |
+mirrorstats = [ 'https://mirrorstats.gentoo.org/rsync/state.json', |
53 |
+ 'https://mirrorstats.gentoo.org/distfiles/state.json', |
54 |
+ 'https://mirrorstats.gentoo.org/snapshots/state.json', |
55 |
+ 'https://mirrorstats.gentoo.org/releases/state.json', |
56 |
+ 'https://mirrorstats.gentoo.org/experimental/state.json' |
57 |
+ ] |
58 |
+ |
59 |
+cache_data = {} |
60 |
+ |
61 |
+ |
62 |
+# |
63 |
+# Retrieve and parse the JSON at the given URL |
64 |
+# |
65 |
+def getJson(url): |
66 |
+ req = urllib.request.Request(url) |
67 |
+ r = urllib.request.urlopen(req).read() |
68 |
+ return json.loads(r.decode('utf-8')) |
69 |
+ |
70 |
+ |
71 |
+# |
72 |
+# Retrieve and parse the XML at the given URL |
73 |
+# |
74 |
+def getXML(url): |
75 |
+ req = urllib.request.Request(url) |
76 |
+ r = urllib.request.urlopen(req).read() |
77 |
+ return ET.loads(r.decode('utf-8')).getroot() |
78 |
+ |
79 |
+ |
80 |
+# |
81 |
+# Get the ip of the given host |
82 |
+# |
83 |
+def getIp(hostname): |
84 |
+ try: |
85 |
+ ip = socket.gethostbyname(hostname) |
86 |
+ except: |
87 |
+ ip = "" |
88 |
+ return ip |
89 |
+ |
90 |
+ |
91 |
+# |
92 |
+# Render the stats template for a given page, i.e. all, rsync, distfiles... |
93 |
+# |
94 |
+def renderStatsTemplate(templateEnv, page): |
95 |
+ if page == "all": |
96 |
+ mirrorstatsList = mirrorstats |
97 |
+ else: |
98 |
+ mirrorstatsList = ['https://mirrorstats.gentoo.org/' + page + '/state.json'] |
99 |
+ |
100 |
+ lastUpdate, hostList = getHostList(mirrorstatsList) |
101 |
+ template = templateEnv.get_template("stats.jinja2") |
102 |
+ template.stream(lastUpdate=lastUpdate, type=page, mirrors=hostList, locations=json.dumps(hostList)).dump(html_folder + page + ".html") |
103 |
+ return lastUpdate |
104 |
+ |
105 |
+ |
106 |
+# read the cache |
107 |
+with open(cache_path) as json_file: |
108 |
+ cache_data = json.load(json_file) |
109 |
+ |
110 |
+# |
111 |
+# The all mirrors that are present in the given list |
112 |
+# |
113 |
+def getHostList(mirrorstatsList): |
114 |
+ hosts = {} |
115 |
+ lastUpdate = "" |
116 |
+ |
117 |
+ # process all mirrors |
118 |
+ for mirror_url in mirrorstatsList: |
119 |
+ |
120 |
+ mirrorData = getJson(mirror_url) |
121 |
+ lastUpdate = datetime.datetime.fromtimestamp(int(mirrorData['LastUpdate'])).strftime('%Y-%m-%d %H:%M:%S') |
122 |
+ |
123 |
+ for mirror in mirrorData['Mirrors']: |
124 |
+ if len(mirrorData['Mirrors'][mirror]) >= 0: |
125 |
+ for mirrorHost in mirrorData['Mirrors'][mirror]: |
126 |
+ hostname = mirrorHost['Host'] |
127 |
+ if hostname not in hosts: |
128 |
+ hosts[hostname] = {} |
129 |
+ |
130 |
+ hosts[hostname]['Hostname'] = hostname |
131 |
+ |
132 |
+ if hostname in cache_data['hosts']: |
133 |
+ ip = cache_data['hosts'][hostname] |
134 |
+ else: |
135 |
+ ip = getIp(hostname) |
136 |
+ # populate cache with new value |
137 |
+ cache_data['hosts'][hostname] = ip |
138 |
+ |
139 |
+ if ip != "": |
140 |
+ hosts[hostname]['Ip'] = ip |
141 |
+ |
142 |
+ if 'Stats' not in hosts[hostname]: |
143 |
+ hosts[hostname]['Stats'] = [] |
144 |
+ |
145 |
+ mirrorHost['Type'] = mirror_url.replace("https://mirrorstats.gentoo.org/", "").replace("/state.json", "") |
146 |
+ hosts[hostname]['Stats'].append(mirrorHost) |
147 |
+ |
148 |
+ # compute available protocols |
149 |
+ for host in hosts: |
150 |
+ protocols = [] |
151 |
+ for stat in hosts[host]['Stats']: |
152 |
+ protocols.append(stat['Protocol']) |
153 |
+ |
154 |
+ hosts[host]['Protocols'] = list(set(protocols)) |
155 |
+ |
156 |
+ # compute mirror locations |
157 |
+ for host in hosts: |
158 |
+ if 'Ip' not in hosts[host]: |
159 |
+ continue |
160 |
+ |
161 |
+ ip = hosts[host]['Ip'] |
162 |
+ if ip in cache_data['ips']: |
163 |
+ hosts[host]['Location'] = cache_data['ips'][ip] |
164 |
+ else: |
165 |
+ mirrorGeoData = getJson("https://ipinfo.io/" + ip + "/json") |
166 |
+ hosts[host]['Location'] = mirrorGeoData['loc'] |
167 |
+ # populate cache with new value |
168 |
+ cache_data['ips'][ip] = mirrorGeoData['loc'] |
169 |
+ |
170 |
+ return lastUpdate, hosts |
171 |
+ |
172 |
+ |
173 |
+# |
174 |
+# render jinja2 |
175 |
+# |
176 |
+templateLoader = jinja2.FileSystemLoader(searchpath="./") |
177 |
+templateEnv = jinja2.Environment(loader=templateLoader) |
178 |
+ |
179 |
+## stats |
180 |
+lastUpdate = renderStatsTemplate(templateEnv, "all") |
181 |
+renderStatsTemplate(templateEnv, "rsync") |
182 |
+renderStatsTemplate(templateEnv, "distfiles") |
183 |
+renderStatsTemplate(templateEnv, "snapshots") |
184 |
+renderStatsTemplate(templateEnv, "releases") |
185 |
+renderStatsTemplate(templateEnv, "experimental") |
186 |
+ |
187 |
+## about |
188 |
+template = templateEnv.get_template("help.jinja2") |
189 |
+template.stream(lastUpdate=lastUpdate).dump(html_folder + "help.html") |
190 |
+ |
191 |
+ |
192 |
+# |
193 |
+# write the cache |
194 |
+# |
195 |
+with open(cache_path, 'w') as fp: |
196 |
+ json.dump(cache_data, fp) |
197 |
+ |
198 |
+ |
199 |
+# |
200 |
+# finish |
201 |
+# |
202 |
+print("Finished.") |
203 |
+ |
204 |
+ |
205 |
|
206 |
diff --git a/html/help.jinja2 b/html/help.jinja2 |
207 |
new file mode 100644 |
208 |
index 0000000..6e08363 |
209 |
--- /dev/null |
210 |
+++ b/html/help.jinja2 |
211 |
@@ -0,0 +1,163 @@ |
212 |
+<!DOCTYPE html> |
213 |
+<html> |
214 |
+ <head> |
215 |
+ <title>Gentoo Mirrorstats</title> |
216 |
+ <meta charset="utf-8"> |
217 |
+ <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
218 |
+ <link href="https://assets.gentoo.org/tyrian/v2/tyrian.min.css" rel="stylesheet" media="screen"> |
219 |
+ <link rel="icon" href="https://www.gentoo.org/favicon.ico" type="image/x-icon"> |
220 |
+ </head> |
221 |
+ |
222 |
+ <body> |
223 |
+ |
224 |
+ <header> |
225 |
+ <div class="site-title"> |
226 |
+ <div class="container"> |
227 |
+ <div class="row justify-content-between"> |
228 |
+ <div class="logo"> |
229 |
+ <a href="/" title="Back to the homepage" class="site-logo"> |
230 |
+ <img src="https://assets.gentoo.org/tyrian/site-logo.png" alt="Gentoo" srcset="https://assets.gentoo.org/tyrian/v2/site-logo.svg"> |
231 |
+ </a> |
232 |
+ <span class="site-label">Mirrorstats</span> |
233 |
+ </div> |
234 |
+ <div class="site-title-buttons"> |
235 |
+ <div class="btn-group btn-group-sm"> |
236 |
+ <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> |
237 |
+ <div class="btn-group btn-group-sm"> |
238 |
+ <a class="btn gentoo-org-sites dropdown-toggle" data-toggle="dropdown" data-target="#" href="#"> |
239 |
+ <span class="fa fa-fw fa-map-o"></span> <span class="d-none d-sm-inline">gentoo.org sites</span> <span class="caret"></span> |
240 |
+ </a> |
241 |
+ <div class="dropdown-menu dropdown-menu-right"> |
242 |
+ <a class="dropdown-item" href="https://www.gentoo.org/" title="Main Gentoo website"><span class="fa fa-home fa-fw"></span> gentoo.org</a> |
243 |
+ <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> |
244 |
+ <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> |
245 |
+ <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> |
246 |
+ <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> |
247 |
+ <div class="dropdown-divider"></div> |
248 |
+ <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> |
249 |
+ <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> |
250 |
+ <a class="dropdown-item" href="https://sources.gentoo.org/" title="Browse our source code"><span class="fa fa-code fa-fw"></span> Sources</a> |
251 |
+ <div class="dropdown-divider"></div> |
252 |
+ <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> |
253 |
+ </div> |
254 |
+ </div> |
255 |
+ </div> |
256 |
+ </div> |
257 |
+ </div> |
258 |
+ </div> |
259 |
+ </div> |
260 |
+ <nav class="tyrian-navbar navbar navbar-dark navbar-expand-lg bg-primary" role="navigation"> |
261 |
+ <div class="container"> |
262 |
+ <div class="navbar-header"> |
263 |
+ <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"> |
264 |
+ <span class="navbar-toggler-icon"></span> |
265 |
+ </button> |
266 |
+ </div> |
267 |
+ <div class="collapse navbar-collapse navbar-main-collapse" id="navbar-main-collapse"> |
268 |
+ <ul class="navbar-nav mr-auto"> |
269 |
+ <li class="nav-item"><a class="nav-link" href="all.html">Home</a></li> |
270 |
+ <li class="nav-item"><a class="nav-link" href="rsync.html">Rsync</a></li> |
271 |
+ <li class="nav-item"><a class="nav-link" href="distfiles.html">Distfiles</a></li> |
272 |
+ <li class="nav-item"><a class="nav-link" href="snapshots.html">Snapshots</a></li> |
273 |
+ <li class="nav-item"><a class="nav-link" href="releases.html">Releases</a></li> |
274 |
+ <li class="nav-item"><a class="nav-link" href="experimental.html">Experimental</a></li> |
275 |
+ <li class="nav-item active"><a class="nav-link" href="help.html">Help</a></li> |
276 |
+ </ul> |
277 |
+ </div> |
278 |
+ </div> |
279 |
+ </nav> |
280 |
+ </header> |
281 |
+ |
282 |
+ |
283 |
+ <div class="container"> |
284 |
+ <div class="row"> |
285 |
+ <div class="col-md-12"> |
286 |
+ <h1 class="first-header">About Gentoo Mirrors</h1> |
287 |
+ <div class="alert alert-info"> |
288 |
+ If you experience problems with this site (<tt>mirrorstats.gentoo.org</tt>), please file clearly marked bugs in |
289 |
+ <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>. |
290 |
+ Please remember to include <tt>mirrorstats</tt> in the summary line. |
291 |
+ </div> |
292 |
+ <h2 id="moreInformation">Gentoo rsync mirrors</h2> |
293 |
+ <p>Gentoo rsync mirrors tracked include both official mirrors run by the Gentoo Infrastructure team, as well as community-run mirrors.</p> |
294 |
+ <ul> |
295 |
+ <li><a href="https://www.gentoo.org/support/rsync-mirrors/">Listing of Gentoo rsync mirrors</a></li> |
296 |
+ <li><a href="https://wiki.gentoo.org/wiki/Project:Infrastructure/Mirrors/Rsync">How to contribute a new rsync mirror</a></li> |
297 |
+ <li><a href="/rsync/">Status of Gentoo rsync mirrors</a></li> |
298 |
+ </ul> |
299 |
+ <h2>Gentoo source mirrors</h2> |
300 |
+ <ul> |
301 |
+ <li><a href="https://www.gentoo.org/downloads/mirrors/">Listing of Gentoo source mirrors</a></li> |
302 |
+ <li><a href="https://wiki.gentoo.org/wiki/Project:Infrastructure/Mirrors/Source">How to contribute a new source mirror</a></li> |
303 |
+ <li><a href="/distfiles/">Status of Gentoo source mirrors: <tt>/distfiles/</tt></a> |
304 |
+ <li><a href="/experimental/">Status of Gentoo source mirrors: <tt>/experimental/</tt></a> |
305 |
+ <li><a href="/releases/">Status of Gentoo source mirrors: <tt>/releases/</tt></a> |
306 |
+ <li><a href="/snapshots/">Status of Gentoo source mirrors: <tt>/snapshots/</tt></a> |
307 |
+ </ul> |
308 |
+ <div class="alert alert-warning"> |
309 |
+ 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> |
310 |
+ Please include lots of details about the problem, as the Gentoo |
311 |
+ mirror team will have to contact the administrator of individual |
312 |
+ mirrors to work on problems. |
313 |
+ <ul> |
314 |
+ <li><b>Hostname</b> of the mirror (in the summary & description)</li> |
315 |
+ <li><b>IP</b> of the mirror: many mirrors have multiple nodes behind a single DNS entry</li> |
316 |
+ <li><b>Timestamp</b> of the problem</li> |
317 |
+ <li><b>Logs</b> of the problem</li> |
318 |
+ </ul> |
319 |
+ </div> |
320 |
+ </div> |
321 |
+ </div> |
322 |
+ </div> |
323 |
+ |
324 |
+ |
325 |
+ <footer> |
326 |
+ <div class="container"> |
327 |
+ <div class="row"> |
328 |
+ <div class="col-12 offset-md-2 col-md-7"> |
329 |
+ <h3 class="footerhead">Gentoo Mirrorstats</h3> |
330 |
+ <div class="row"> |
331 |
+ <div class="col-xs-12 col-md-4"> |
332 |
+ <span class="kk-group-header">Mirror Data as current of</span><br>{{ lastUpdate }} |
333 |
+ </div> |
334 |
+ <div class="col-xs-12 col-md-4"> |
335 |
+ </div> |
336 |
+ <div class="col-xs-12 col-md-4"> |
337 |
+ </div> |
338 |
+ </div> |
339 |
+ </div> |
340 |
+ <div class="col-12 col-md-3"> |
341 |
+ <h3 class="footerhead">Questions or comments?</h3> |
342 |
+ Please feel free to <a href="https://www.gentoo.org/inside-gentoo/contact/">contact us</a>. |
343 |
+ <p class="mt-2"><a href="https://gitweb.gentoo.org/proj/gentoo-mirrorstats.git/">Gentoo Mirrorstats</a></p> |
344 |
+ </div> |
345 |
+ </div> |
346 |
+ <div class="row"> |
347 |
+ <div class="col-2 col-sm-3 col-md-2"> |
348 |
+ <ul class="footerlinks three-icons"> |
349 |
+ <li><a href="https://twitter.com/gentoo" title="@Gentoo on Twitter"><span class="fa fa-twitter fa-fw"></span></a></li> |
350 |
+ <li><a href="https://www.facebook.com/gentoo.org" title="Gentoo on Facebook"><span class="fa fa-facebook fa-fw"></span></a></li> |
351 |
+ <li><a href="https://www.reddit.com/r/Gentoo/" title="Gentoo on Reddit"><span class="fa fa-reddit-alien fa-fw"></span></a></li> |
352 |
+ </ul> |
353 |
+ </div> |
354 |
+ <div class="col-10 col-sm-9 col-md-10"> |
355 |
+ <strong>© 2001–2020 Gentoo Foundation, Inc.</strong><br> |
356 |
+ <small> |
357 |
+ Gentoo is a trademark of the Gentoo Foundation, Inc. |
358 |
+ The contents of this document, unless otherwise expressly stated, are licensed under the |
359 |
+ <a href="https://creativecommons.org/licenses/by-sa/4.0/" rel="license">CC-BY-SA-4.0</a> license. |
360 |
+ The <a href="https://www.gentoo.org/inside-gentoo/foundation/name-logo-guidelines.html">Gentoo Name and Logo Usage Guidelines</a> apply. |
361 |
+ </small> |
362 |
+ </div> |
363 |
+ </div> |
364 |
+ </div> |
365 |
+ </footer> |
366 |
+ |
367 |
+ |
368 |
+ <script src="https://assets.gentoo.org/tyrian/v2/jquery-3.3.slim.js"></script> |
369 |
+ <script src="https://assets.gentoo.org/tyrian/v2/popper.min.js"></script> |
370 |
+ <script src="https://assets.gentoo.org/tyrian/v2/bootstrap.min.js"></script> |
371 |
+ |
372 |
+ |
373 |
+ </body> |
374 |
+</html> |
375 |
|
376 |
diff --git a/html/stats.jinja2 b/html/stats.jinja2 |
377 |
new file mode 100644 |
378 |
index 0000000..e13cd45 |
379 |
--- /dev/null |
380 |
+++ b/html/stats.jinja2 |
381 |
@@ -0,0 +1,339 @@ |
382 |
+<!DOCTYPE html> |
383 |
+<html> |
384 |
+ <head> |
385 |
+ <title>Gentoo Mirrorstats</title> |
386 |
+ <meta charset="utf-8"> |
387 |
+ <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
388 |
+ <link href="https://assets.gentoo.org/tyrian/v2/tyrian.min.css" rel="stylesheet" media="screen"> |
389 |
+ <link href="https://www.gentoo.org/assets/css/leaflet.css" rel="stylesheet" media="screen"> |
390 |
+ <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/bs4/dt-1.10.20/datatables.min.css"/> |
391 |
+ <link rel="icon" href="https://www.gentoo.org/favicon.ico" type="image/x-icon"> |
392 |
+ </head> |
393 |
+ |
394 |
+ <body> |
395 |
+ |
396 |
+ <header> |
397 |
+ <div class="site-title"> |
398 |
+ <div class="container"> |
399 |
+ <div class="row justify-content-between"> |
400 |
+ <div class="logo"> |
401 |
+ <a href="/" title="Back to the homepage" class="site-logo"> |
402 |
+ <img src="https://assets.gentoo.org/tyrian/site-logo.png" alt="Gentoo" srcset="https://assets.gentoo.org/tyrian/v2/site-logo.svg"> |
403 |
+ </a> |
404 |
+ <span class="site-label">Mirrorstats</span> |
405 |
+ </div> |
406 |
+ <div class="site-title-buttons"> |
407 |
+ <div class="btn-group btn-group-sm"> |
408 |
+ <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> |
409 |
+ <div class="btn-group btn-group-sm"> |
410 |
+ <a class="btn gentoo-org-sites dropdown-toggle" data-toggle="dropdown" data-target="#" href="#"> |
411 |
+ <span class="fa fa-fw fa-map-o"></span> <span class="d-none d-sm-inline">gentoo.org sites</span> <span class="caret"></span> |
412 |
+ </a> |
413 |
+ <div class="dropdown-menu dropdown-menu-right"> |
414 |
+ <a class="dropdown-item" href="https://www.gentoo.org/" title="Main Gentoo website"><span class="fa fa-home fa-fw"></span> gentoo.org</a> |
415 |
+ <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> |
416 |
+ <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> |
417 |
+ <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> |
418 |
+ <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> |
419 |
+ <div class="dropdown-divider"></div> |
420 |
+ <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> |
421 |
+ <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> |
422 |
+ <a class="dropdown-item" href="https://sources.gentoo.org/" title="Browse our source code"><span class="fa fa-code fa-fw"></span> Sources</a> |
423 |
+ <div class="dropdown-divider"></div> |
424 |
+ <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> |
425 |
+ </div> |
426 |
+ </div> |
427 |
+ </div> |
428 |
+ </div> |
429 |
+ </div> |
430 |
+ </div> |
431 |
+ </div> |
432 |
+ <nav class="tyrian-navbar navbar navbar-dark navbar-expand-lg bg-primary" role="navigation"> |
433 |
+ <div class="container"> |
434 |
+ <div class="navbar-header"> |
435 |
+ <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"> |
436 |
+ <span class="navbar-toggler-icon"></span> |
437 |
+ </button> |
438 |
+ </div> |
439 |
+ <div class="collapse navbar-collapse navbar-main-collapse" id="navbar-main-collapse"> |
440 |
+ <ul class="navbar-nav mr-auto"> |
441 |
+ <li class="nav-item {%if type == 'all'%}active{%endif%}"><a class="nav-link" href="all.html">Home</a></li> |
442 |
+ <li class="nav-item {%if type == 'rsync'%}active{%endif%}"><a class="nav-link" href="rsync.html">Rsync</a></li> |
443 |
+ <li class="nav-item {%if type == 'distfiles'%}active{%endif%}"><a class="nav-link" href="distfiles.html">Distfiles</a></li> |
444 |
+ <li class="nav-item {%if type == 'snapshots'%}active{%endif%}"><a class="nav-link" href="snapshots.html">Snapshots</a></li> |
445 |
+ <li class="nav-item {%if type == 'releases'%}active{%endif%}"><a class="nav-link" href="releases.html">Releases</a></li> |
446 |
+ <li class="nav-item {%if type == 'experimental'%}active{%endif%}"><a class="nav-link" href="experimental.html">Experimental</a></li> |
447 |
+ <li class="nav-item "><a class="nav-link" href="help.html">Help</a></li> |
448 |
+ </ul> |
449 |
+ </div> |
450 |
+ </div> |
451 |
+ </nav> |
452 |
+ </header> |
453 |
+ |
454 |
+ |
455 |
+ <div class="container"> |
456 |
+ <div class="row"> |
457 |
+ <div class="col-md-12"> |
458 |
+ <h1 class="first-header">Gentoo {% if type != "all" %}{{ type[0]|upper}}{{type[1:]}}{%endif%} Mirrors |
459 |
+ {% if type != "all" %} |
460 |
+ <small class="ml-2 mt-2 float-right" style="font-size: 60%;"> |
461 |
+ <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> |
462 |
+ <a title="Original Mirmon Page" class="text-muted" href="/{{type}}/"><i class="fa fa-bar-chart" aria-hidden="true"></i></a> |
463 |
+ </small> |
464 |
+ {% endif %} |
465 |
+ </h1> |
466 |
+ |
467 |
+ |
468 |
+ <p> |
469 |
+ 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/> |
470 |
+ 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>. |
471 |
+ </p> |
472 |
+ <div id="mirrorLocations" style="height: 500px; margin-bottom: 1em;"></div> |
473 |
+ </div> |
474 |
+ |
475 |
+ <div class="col-md-12 my-4"> |
476 |
+ <table id="table_id" class="display table"> |
477 |
+ <thead> |
478 |
+ <tr> |
479 |
+ <th>Host</th> |
480 |
+ {% if type == "all" %}<th>Type</th>{% endif %} |
481 |
+ <th>Protocol</th> |
482 |
+ <th class="statusHistory">Daily Stats</th> |
483 |
+ <th class="statusHistory">Probe Stats</th> |
484 |
+ <th style="text-align: right;">Last State</th> |
485 |
+ </tr> |
486 |
+ </thead> |
487 |
+ <tbody> |
488 |
+ |
489 |
+ {% for mirror in mirrors %} |
490 |
+ {% for stat in mirrors[mirror]['Stats'] %} |
491 |
+ <tr> |
492 |
+ <td>{{ mirror }}</td> |
493 |
+ {% if type == "all" %}<td>{{ stat['Type'] }}</td>{% endif %} |
494 |
+ <td>{{ stat['Protocol'] }}</td> |
495 |
+ <td>{{ stat['StateHistory'] }}</td> |
496 |
+ <td>{{ stat['ProbeHistory'] }}</td> |
497 |
+ <td style="text-align: right;"> |
498 |
+ {% if stat['StatusLastProbe'] == "ok" %} |
499 |
+ <span class="badge badge-success">OK</span> |
500 |
+ {% elif stat['StatusLastProbe'] == "hangs" %} |
501 |
+ <span class="badge badge-danger">Hangs</span> |
502 |
+ {% elif stat['StatusLastProbe'] == "no_time" %} |
503 |
+ <span class="badge badge-danger">No Time</span> |
504 |
+ {% elif stat['StatusLastProbe'] == "site_not_found" %} |
505 |
+ <span class="badge badge-danger">Site Not Found</span> |
506 |
+ {% elif stat['StatusLastProbe'] == "'-1'" %} |
507 |
+ <span class="badge badge-danger">-1</span> |
508 |
+ {% else %} |
509 |
+ <span class="badge badge-warning">{{ stat['StatusLastProbe'] }}</span> |
510 |
+ {% endif %} |
511 |
+ </td> |
512 |
+ </tr> |
513 |
+ {% endfor %} |
514 |
+ {% endfor %} |
515 |
+ |
516 |
+ </tbody> |
517 |
+ </table> |
518 |
+ |
519 |
+ </div> |
520 |
+ </div> |
521 |
+ </div> |
522 |
+ |
523 |
+ |
524 |
+ <footer> |
525 |
+ <div class="container"> |
526 |
+ <div class="row"> |
527 |
+ <div class="col-12 offset-md-2 col-md-7"> |
528 |
+ <h3 class="footerhead">Gentoo Mirrorstats</h3> |
529 |
+ <div class="row"> |
530 |
+ <div class="col-xs-12 col-md-4"> |
531 |
+ <span class="kk-group-header">Mirror Data as current of</span><br>{{ lastUpdate }} |
532 |
+ </div> |
533 |
+ <div class="col-xs-12 col-md-4"> |
534 |
+ <span>Data powered by:</span><br><a href="http://www.staff.science.uu.nl/~penni101/mirmon/">Mirmon v2.11</a> |
535 |
+ </div> |
536 |
+ <div class="col-xs-12 col-md-4"> |
537 |
+ </div> |
538 |
+ </div> |
539 |
+ </div> |
540 |
+ <div class="col-12 col-md-3"> |
541 |
+ <h3 class="footerhead">Questions or comments?</h3> |
542 |
+ Please feel free to <a href="https://www.gentoo.org/inside-gentoo/contact/">contact us</a>. |
543 |
+ <p class="mt-2"><a href="https://gitweb.gentoo.org/proj/gentoo-mirrorstats.git/">Gentoo Mirrorstats</a></p> |
544 |
+ </div> |
545 |
+ </div> |
546 |
+ <div class="row"> |
547 |
+ <div class="col-2 col-sm-3 col-md-2"> |
548 |
+ <ul class="footerlinks three-icons"> |
549 |
+ <li><a href="https://twitter.com/gentoo" title="@Gentoo on Twitter"><span class="fa fa-twitter fa-fw"></span></a></li> |
550 |
+ <li><a href="https://www.facebook.com/gentoo.org" title="Gentoo on Facebook"><span class="fa fa-facebook fa-fw"></span></a></li> |
551 |
+ <li><a href="https://www.reddit.com/r/Gentoo/" title="Gentoo on Reddit"><span class="fa fa-reddit-alien fa-fw"></span></a></li> |
552 |
+ </ul> |
553 |
+ </div> |
554 |
+ <div class="col-10 col-sm-9 col-md-10"> |
555 |
+ <strong>© 2001–2020 Gentoo Foundation, Inc.</strong><br> |
556 |
+ <small> |
557 |
+ Gentoo is a trademark of the Gentoo Foundation, Inc. |
558 |
+ The contents of this document, unless otherwise expressly stated, are licensed under the |
559 |
+ <a href="https://creativecommons.org/licenses/by-sa/4.0/" rel="license">CC-BY-SA-4.0</a> license. |
560 |
+ The <a href="https://www.gentoo.org/inside-gentoo/foundation/name-logo-guidelines.html">Gentoo Name and Logo Usage Guidelines</a> apply. |
561 |
+ </small> |
562 |
+ </div> |
563 |
+ </div> |
564 |
+ </div> |
565 |
+ </footer> |
566 |
+ |
567 |
+ <script> |
568 |
+ var mirrorLocations = {{locations}}; |
569 |
+ </script> |
570 |
+ |
571 |
+ |
572 |
+ <script src="https://assets.gentoo.org/tyrian/v2/jquery-3.3.slim.js"></script> |
573 |
+ <script src="https://assets.gentoo.org/tyrian/v2/popper.min.js"></script> |
574 |
+ <script src="https://assets.gentoo.org/tyrian/v2/bootstrap.min.js"></script> |
575 |
+ |
576 |
+ <script src="https://www.gentoo.org/assets/js/leaflet.js"></script> |
577 |
+ |
578 |
+ <script type="text/javascript" src="https://cdn.datatables.net/v/bs4/dt-1.10.20/rg-1.1.1/datatables.min.js"></script> |
579 |
+ |
580 |
+ <script> |
581 |
+ |
582 |
+ $(function() { |
583 |
+ L.Icon.Default.imagePath = 'https://www.gentoo.org/assets/img/maps/'; |
584 |
+ var map = L.map('mirrorLocations', { zoomAnimationThreshold: 9 } ).setView([30, 0], 2); |
585 |
+ var markers = {}; |
586 |
+ |
587 |
+ 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' })); |
588 |
+ |
589 |
+ |
590 |
+ var greenIcon = new L.Icon({ |
591 |
+ iconUrl: 'https://cdn.rawgit.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-green.png', |
592 |
+ shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png', |
593 |
+ iconSize: [25, 41], |
594 |
+ iconAnchor: [12, 41], |
595 |
+ popupAnchor: [1, -34], |
596 |
+ shadowSize: [41, 41] |
597 |
+ }); |
598 |
+ |
599 |
+ var orangeIcon = new L.Icon({ |
600 |
+ iconUrl: 'https://cdn.rawgit.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-gold.png', |
601 |
+ shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png', |
602 |
+ iconSize: [25, 41], |
603 |
+ iconAnchor: [12, 41], |
604 |
+ popupAnchor: [1, -34], |
605 |
+ shadowSize: [41, 41] |
606 |
+ }); |
607 |
+ |
608 |
+ var redIcon = new L.Icon({ |
609 |
+ iconUrl: 'https://cdn.rawgit.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-red.png', |
610 |
+ shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png', |
611 |
+ iconSize: [25, 41], |
612 |
+ iconAnchor: [12, 41], |
613 |
+ popupAnchor: [1, -34], |
614 |
+ shadowSize: [41, 41] |
615 |
+ }); |
616 |
+ |
617 |
+ |
618 |
+ |
619 |
+ $.each(mirrorLocations, function(index, mirror) { |
620 |
+ if(mirror.Location){ |
621 |
+ lat = mirror.Location.split(",")[0]; |
622 |
+ long = mirror.Location.split(",")[1]; |
623 |
+ |
624 |
+ ok = 0; |
625 |
+ for (let i = 0; i < mirror.Stats.length; i++){ |
626 |
+ if(mirror.Stats[i].StatusLastProbe == "ok"){ |
627 |
+ ok++; |
628 |
+ } |
629 |
+ } |
630 |
+ |
631 |
+ if(ok == mirror.Stats.length){ |
632 |
+ marker = L.marker([lat, long], {icon: greenIcon}).addTo(map); |
633 |
+ }else if(ok == 0){ |
634 |
+ marker = L.marker([lat, long], {icon: redIcon}).addTo(map); |
635 |
+ }else{ |
636 |
+ marker = L.marker([lat, long], {icon: orangeIcon}).addTo(map); |
637 |
+ } |
638 |
+ |
639 |
+ popupText = "<h4 class='mt-2'> " + mirror.Hostname + "</h4>"; |
640 |
+ |
641 |
+ popupText += "<table class='table'><tr>{% if type == 'all' %}<th>Type</th>{% endif %}<th>Protocol</th><th>Probe History</th><th>Last Probe</th></tr>"; |
642 |
+ for (let i = 0; i < mirror.Stats.length; i++){ |
643 |
+ probeHistory = ""; |
644 |
+ for (let j = 0; j < mirror.Stats[i].ProbeHistory.length; j++) { |
645 |
+ if(mirror.Stats[i].ProbeHistory[j] == "s"){ |
646 |
+ probeHistory += '<i class="fa fa-fw fa-check" style="color:#28a745;" aria-hidden="true"></i>'; |
647 |
+ }else{ |
648 |
+ probeHistory += '<i class="fa fa-fw fa-times" style="color:#dc3545;" aria-hidden="true"></i>'; |
649 |
+ } |
650 |
+ } |
651 |
+ |
652 |
+ lastProbeStatus = mirror.Stats[i].StatusLastProbe; |
653 |
+ |
654 |
+ if(lastProbeStatus == "ok"){ |
655 |
+ lastProbeStatus = '<span class="badge badge-success">OK</span>'; |
656 |
+ } else if(lastProbeStatus == "hangs"){ |
657 |
+ lastProbeStatus = '<span class="badge badge-danger">Hangs</span>'; |
658 |
+ } else if(lastProbeStatus == "no_time"){ |
659 |
+ lastProbeStatus = '<span class="badge badge-danger">No Time</span>'; |
660 |
+ } else if(lastProbeStatus == "site_not_found"){ |
661 |
+ lastProbeStatus = '<span class="badge badge-danger">Site Not Found</span>'; |
662 |
+ } else if(lastProbeStatus == "'-1'"){ |
663 |
+ lastProbeStatus = '<span class="badge badge-danger">-1</span>'; |
664 |
+ } else { |
665 |
+ lastProbeStatus = '<span class="badge badge-warning">' + lastProbeStatus + '</span>'; |
666 |
+ } |
667 |
+ |
668 |
+ 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>"; |
669 |
+ } |
670 |
+ popupText += "</table>"; |
671 |
+ |
672 |
+ |
673 |
+ marker.bindPopup(popupText, { |
674 |
+ minWidth : 500, |
675 |
+ maxWidth : 600, |
676 |
+ maxHeight : 260, |
677 |
+ }); |
678 |
+ |
679 |
+ markers[index] = marker; |
680 |
+ } |
681 |
+ }); |
682 |
+ }); |
683 |
+ </script> |
684 |
+ |
685 |
+ <script> |
686 |
+ |
687 |
+ $(document).ready( function () { |
688 |
+ $('#table_id').DataTable({ |
689 |
+ "autoWidth": true, |
690 |
+ "iDisplayLength": 25, |
691 |
+ // TODO Group by Region in future |
692 |
+ // rowGroup: { |
693 |
+ // dataSrc: 1 |
694 |
+ // } |
695 |
+ "columnDefs": [ |
696 |
+ { |
697 |
+ "render": function ( data, type, row ) { |
698 |
+ state_str = data.split("-")[data.split("-").length-1]; |
699 |
+ result = ""; |
700 |
+ |
701 |
+ for (let i = 0; i < state_str.length; i++){ |
702 |
+ if(state_str[i] == 's'){ |
703 |
+ result += '<i class="fa fa-check" style="color:#28a745;width:1rem;text-align:center;" aria-hidden="true"></i>\n'; |
704 |
+ }else{ |
705 |
+ result += '<i class="fa fa-times" style="color:#dc3545;width:1rem;text-align:center;" aria-hidden="true"></i>\n'; |
706 |
+ } |
707 |
+ } |
708 |
+ |
709 |
+ return result; |
710 |
+ }, |
711 |
+ "targets": "statusHistory" |
712 |
+ }, |
713 |
+ ] |
714 |
+ }); |
715 |
+ } ); |
716 |
+ |
717 |
+ </script> |
718 |
+ |
719 |
+ </body> |
720 |
+</html> |