#!/usr/bin/env python3
import re
import socket
import subprocess
import requests
_re_ping = re.compile(r".+= .+?/(.+?)/.+?/.+? ms", re.MULTILINE)
print("Hello There!\n")
print("Fetching hubs from the wiki....")
query = "[[Server:+]] [[Category:Nodes]] [[Node Type::Hub]]|?Server Name|?IPv4|?IPv6"
all_hubs = requests.get("https://wiki.letspiss.net/api.php", params={'action': 'ask', 'query': query, 'format': 'json'})
all_hubs = all_hubs.json()['query']['results']
all_pings = []
print(f"\nI got {len(all_hubs)} hubs. Pinging 'em all:")
for hub in all_hubs.values():
ipv4 = None
ipv6 = None
server_name = hub['printouts']['Server Name'][0]
print(f" - {server_name}...", end="", flush=True)
if hub['printouts']['IPv4']:
ipv4 = hub['printouts']['IPv4'][0]
if hub['printouts']['IPv6']:
ipv6 = hub['printouts']['IPv6'][0]
if not ipv4 and not ipv6: # resolve
try:
ipv4 = socket.getaddrinfo(server_name, None, family=socket.AF_INET, type=socket.SOCK_RAW)[0][4][0]
except socket.gaierror:
pass
try:
ipv6 = socket.getaddrinfo(server_name, None, family=socket.AF_INET6, type=socket.SOCK_RAW)[0][4][0]
except socket.gaierror:
pass
ipv4_ping = 0
ipv6_ping = 0
# Do the pinging
if ipv4:
command = ['ping', '-c', '5', ipv4]
try:
data = subprocess.check_output(command)
match = _re_ping.findall(data.decode())
ipv4_ping = float(match[0])
print(f" v4: {ipv4_ping}ms.", end="", flush=True)
except subprocess.CalledProcessError:
print(" v4: error.", end="", flush=True)
if ipv6:
command = ['ping', '-c', '5', ipv6]
try:
data = subprocess.check_output(command, stderr=subprocess.DEVNULL)
match = _re_ping.findall(data.decode())
ipv6_ping = float(match[0])
print(f" v6: {ipv6_ping}ms.")
except subprocess.CalledProcessError:
print(" v6: error.")
else:
print()
# Average because why not
server_ping = ipv4_ping + ipv6_ping
if ipv4_ping and ipv6_ping:
server_ping /= 2
if server_ping:
all_pings.append((server_name, server_ping))
# Do the sortin'
all_pings.sort(key=lambda x: x[1])
winners = all_pings[0:3]
print(f"\nI'm choosing {', '.join([x[0] for x in winners])}")
print("Grabbing the link blocks from the wiki...\n\n")
all_blocks = ""
for i in winners:
query = "{{Link_Block|[[Server:" + i[0] + "]]}}"
block = requests.get("https://wiki.letspiss.net/api.php",
params={'action': 'expandtemplates', 'text': query, 'format': 'json', 'prop': 'wikitext'})
block = block.json()['expandtemplates']['wikitext']
# Strip wiki stuff
block = block.replace("\n ", "\n").replace("[[SMW::off]]\n", "").replace("[[SMW::on]]", "")
block = block.replace("<br/>", "\n").replace(" ", " ")
block = block.replace("{ tls;", "{ tls; autoconnect;")
all_blocks += block
print("PUT THIS IN YOUR CONFIG FILE")
print("//", "-" * 70)
print(all_blocks)
print("//", "-" * 70)