|
|
|
<!DOCTYPE html>
|
|
|
|
<html lang="en">
|
|
|
|
<head>
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
|
|
|
|
|
|
<meta name="HandheldFriendly" content="True">
|
|
|
|
<meta name="MobileOptimized" content="320">
|
|
|
|
<link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon" />
|
|
|
|
|
|
|
|
<meta property="fb:app_id" content="0" />
|
|
|
|
<meta property="og:image" content="https://www.getmonero.org/press-kit/symbols/monero-symbol-on-white-480.png" />
|
|
|
|
<meta property="og:description" content="xmrnodes" />
|
|
|
|
<meta property="og:url" content="http://localhost" />
|
|
|
|
<meta property="og:title" content="XMR Nodes" />
|
|
|
|
<meta property="og:type" content="website" />
|
|
|
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
|
|
|
<meta name="theme-color" content="#ffffff">
|
|
|
|
<meta name="apple-mobile-web-app-title" content="XMR Nodes">
|
|
|
|
<meta name="application-name" content="XMR Nodes">
|
|
|
|
<meta name="msapplication-TileColor" content="#da532c">
|
|
|
|
<meta name="keywords" content="wownero, monero, xmr, bitmonero, cryptocurrency">
|
|
|
|
<link rel="stylesheet" href="//cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.5.0/css/ol.css" type="text/css">
|
|
|
|
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" type="text/css">
|
|
|
|
<style>
|
|
|
|
.map {
|
|
|
|
height: 750px;
|
|
|
|
margin: 0;
|
|
|
|
padding: 0;
|
|
|
|
}
|
|
|
|
.popover-body {
|
|
|
|
min-width: 276px;
|
|
|
|
}
|
|
|
|
</style>
|
|
|
|
<script src="https://cdn.polyfill.io/v3/polyfill.min.js?features=fetch,requestAnimationFrame,Element.prototype.classList,URL,TextDecoder"></script>
|
|
|
|
<script src="//cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.5.0/build/ol.js"></script>
|
|
|
|
<script src="//code.jquery.com/jquery-3.5.1.min.js"></script>
|
|
|
|
<script src="//maxcdn.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.bundle.min.js"></script>
|
|
|
|
<title>XMR Nodes</title>
|
|
|
|
</head>
|
|
|
|
|
|
|
|
<body>
|
|
|
|
|
|
|
|
{% with messages = get_flashed_messages() %}
|
|
|
|
{% if messages %}
|
|
|
|
<ul class="flashes pure-u-1 center">
|
|
|
|
{% for message in messages %}
|
|
|
|
<li>{{ message }}</li>
|
|
|
|
{% endfor %}
|
|
|
|
</ul>
|
|
|
|
{% endif %}
|
|
|
|
{% endwith %}
|
|
|
|
|
|
|
|
<div class="center">
|
|
|
|
<a href="#footer">See more</a>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<!-- Map -->
|
|
|
|
<h2>View Map</h2>
|
|
|
|
<div id="map" class="map"></div>
|
|
|
|
<div id="popup" class="popup" title="Welcome to OpenLayers"></div>
|
|
|
|
<p>Found Peers (via source node, levin p2p): {{ peers | length }}</p>
|
|
|
|
<p>Source Node: {{ source_node }}</p>
|
|
|
|
<p>
|
|
|
|
This is not a full representation of the entire Monero network,
|
|
|
|
just a look into the peers being crawled from the source node ({{ source_node }})
|
|
|
|
and the nodes already added to the monero.fail database.
|
|
|
|
New peers are searched for on a recurring interval throughout the day.
|
|
|
|
</p>
|
|
|
|
|
|
|
|
<div id="" class="center">
|
|
|
|
<br>
|
|
|
|
<a href="https://twitter.com/lza_menace" target="_blank">Contact me</a>
|
|
|
|
-
|
|
|
|
<a href="https://github.com/lalanza808/monero.fail" target="_blank">Source Code</a>
|
|
|
|
-
|
|
|
|
<a href="{{ url_for('resources') }}">Resources</a>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<!-- Footer -->
|
|
|
|
<div id="footer" class="center">
|
|
|
|
<a href="/">Go home</a>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<script>
|
|
|
|
// Marker layer
|
|
|
|
markerLayer = new ol.layer.Vector({
|
|
|
|
source: new ol.source.Vector({
|
|
|
|
features: [],
|
|
|
|
projection: 'EPSG:3857'
|
|
|
|
})
|
|
|
|
});
|
|
|
|
|
|
|
|
// Create the map
|
|
|
|
var map = new ol.Map({
|
|
|
|
target: 'map',
|
|
|
|
layers: [
|
|
|
|
new ol.layer.Tile({
|
|
|
|
source: new ol.source.OSM()
|
|
|
|
}),
|
|
|
|
markerLayer
|
|
|
|
],
|
|
|
|
view: new ol.View({
|
|
|
|
center: ol.proj.fromLonLat([0, 25]),
|
|
|
|
zoom: 1
|
|
|
|
})
|
|
|
|
});
|
|
|
|
|
|
|
|
// Define a circle marker
|
|
|
|
var circle = new ol.style.Style({
|
|
|
|
image: new ol.style.Circle({
|
|
|
|
radius: 5,
|
|
|
|
fill: new ol.style.Fill({
|
|
|
|
color: 'rgba(76,76,76,.75)',
|
|
|
|
}),
|
|
|
|
stroke: new ol.style.Stroke({
|
|
|
|
color: 'rgba(53,53,53,.75)',
|
|
|
|
width: 1
|
|
|
|
})
|
|
|
|
})
|
|
|
|
});
|
|
|
|
|
|
|
|
{% for peer in peers %}
|
|
|
|
var feature = new ol.Feature(
|
|
|
|
new ol.geom.Point(ol.proj.transform(['{{ peer.lon }}', '{{ peer.lat }}'], 'EPSG:4326', 'EPSG:3857'))
|
|
|
|
);
|
|
|
|
feature.description = [
|
|
|
|
'Peer {{ peer.url }}',
|
|
|
|
'Last seen {{ peer.datetime }}'
|
|
|
|
];
|
|
|
|
feature.setStyle(circle);
|
|
|
|
markerLayer.getSource().addFeature(feature);
|
|
|
|
{% endfor %}
|
|
|
|
|
|
|
|
// Setup popup
|
|
|
|
var popup = new ol.Overlay({
|
|
|
|
element: $('#popup')[0],
|
|
|
|
});
|
|
|
|
map.addOverlay(popup);
|
|
|
|
|
|
|
|
// Show details on each pixel
|
|
|
|
map.on("click", function(e) {
|
|
|
|
var element = popup.getElement();
|
|
|
|
$(element).popover('dispose')
|
|
|
|
map.forEachFeatureAtPixel(e.pixel, function (feature, layer) {
|
|
|
|
var coordinate = e.coordinate;
|
|
|
|
$(element).popover('dispose');
|
|
|
|
popup.setPosition(coordinate);
|
|
|
|
element.title = feature.description[0]
|
|
|
|
$(element).popover({
|
|
|
|
container: element,
|
|
|
|
placement: 'top',
|
|
|
|
animation: false,
|
|
|
|
html: true,
|
|
|
|
content: '<p>' + feature.description[1] + '</p>',
|
|
|
|
});
|
|
|
|
$(element).popover('show');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
</script>
|
|
|
|
|
|
|
|
</body>
|
|
|
|
</html>
|