Public
Edited
Jul 16, 2024
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
peer_table = { // merging per RRC metadata with per peer metadata
var d = {}; // temp data structure to reduce to a table in the end
rrc_data['data']['rrcs'].forEach( (rrc_info) => {
const rrc_cc = _rrc2cc( rrc_info );
console.log( rrc_cc )
rrc_info['peers'].forEach( (peer_info) => {
var ip = peer_info['ip'].toLowerCase() // for lack of ipaddr (or other canonicisation)
d[ ip ] = peer_info
d[ ip ]['rrc'] = rrc_info['name']
d[ ip ]['rrc_cc'] = rrc_cc
d[ ip ]['is_multihop'] = rrc_info['multihop']
d[ ip ]['is_up'] = true
})
})
peer_data['data'].forEach( ( ppd ) => { // ppd = per peer data
var ip = ppd['ip'].toLowerCase()
console.log( ip )
ip in d ? undefined : d[ ip ] = {'is_up': false }
ppd['country'] ? d[ ip ]['peer_cc'] = ppd['country'] : undefined
ppd['city'] ? d[ ip ]['peer_city'] = ppd['city'] : undefined
ppd['feed_type'] ? d[ ip ]['feed_type'] = ppd['feed_type'] : undefined

console.log( "WAAH", d[ ip ] )
})
return Object.values( d );
}
Insert cell
// multihop countries
mh_countries = peer_data['data'].map(
(i) => { return i.country }
).reduce( (i,j) => {
return(
i[j] ? ++i[j] :(i[j] = 1),
i) }
,{} )
Insert cell
up_peers_per_country = { // this is so ugly!
var countries = []
console.log( "TL", peer_table.length );
peer_table.forEach( (p) => {
if ( p['is_up'] ) {
console.log( p )
if ( p['peer_cc'] !== undefined ) {
countries.push( p['peer_cc'] )
console.log( "MHO", p['peer_cc'] )
} else if ( p['rrc_cc'] !== undefined ) {
countries.push( p['rrc_cc'] )
//console.log( "RRC", p['rrc_cc'] )
} else {
countries.push( undefined )
}
}
})
countries = countries.reduce( (i,j) => {
return(
i[j] ? ++i[j] :(i[j] = 1),
i) }
,{} ) // this counts the countries
// now make a nice data table
var cc_counts = []
for (const [cc, count] of Object.entries(countries)) {
cc_counts.push( {'cc': cc, 'count': count} )
//console.log( cc, count )
}

return cc_counts
}
Insert cell
peer_data = fetch("https://www.ris.ripe.net/prototypes/peer-metadata/metadata_latest.json").then((response) => response.json())
Insert cell
rrc_data = fetch("https://stat.ripe.net/data/rrc-info/data.json").then((response) => response.json())
Insert cell
_rrc2cc = function( rrcmeta ) {
var loc = undefined;
var gl_arr = rrcmeta.geographical_location.split(',')
gl_arr = gl_arr[ gl_arr.length - 1 ]
const ugly_map = {
' US': 'US',
' Netherlands': 'NL',
' Brazil': 'BR',
' Germany': 'DE',
' South Africa': 'ZA',
' Spain': 'ES',
' Singapore': 'SG',
' Switzerland': 'CH',
' Japan': 'JP',
' Austria': 'AT',
' Russian Federation': 'RU',
' UAE': 'AE',
' Romania': 'RO',
' Italy': 'IT',
' Sweden': 'SE',
' France': 'FR',
' United Kingdom': 'GB'
}
if ( rrcmeta.multihop == false ) {
// console.log( gl_arr , ugly_map[ gl_arr ] )
return ugly_map[ gl_arr ]
}
return loc
}
Insert cell
cc2rir = fetch("https://sg-pub.ripe.net/emile/tmp/cc2rir.json").then((response) => response.json())
Insert cell
// this didn't help
// ipaddr = require('ipaddr@0.1.0/ip.js').catch(() => window["http"])

Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more