Skip to content

Instantly share code, notes, and snippets.

@skyme5
Last active March 9, 2021 14:50
Show Gist options
  • Save skyme5/903e1c8255d7d4a9a13b994d6a0cc578 to your computer and use it in GitHub Desktop.
Save skyme5/903e1c8255d7d4a9a13b994d6a0cc578 to your computer and use it in GitHub Desktop.
Find the closest CTAN mirror
require 'awesome_print'
require 'http'
require 'net/ping'
require 'uri'
require 'tty-table'
$MIRROR_DOC = 'https://ctan.org/tex-archive/README.mirrors'
$NEAREST = {}
def get_servers(type = 'rsync')
doc = HTTP.follow.get($MIRROR_DOC).to_s
URI.extract(doc, [type].flatten)
end
def measure_latency(addr, count=5)
# shell_out = `ping -n 5 #{addr}`
# captured = /Pinging\s+(?<host>[^\s]+)\s+\[(?<ip>[^\]]+)\]\s+[^:]+:[\r\n]+((Reply from [\d\.]+: bytes=\d+ time=[\dms]+ TTL=\d+[\r\n]+)+|(Request timed out\.[\r\n]+)+)Ping statistics for [\d\.]+:[\r\n]+\s+Packets: Sent = \d+, Received = \d+, Lost = \d+ \([\d%]+ loss\),[\r\n]+(Approximate round trip times in milli-seconds:[\r\n]+\s+Minimum = (?<minimum>[\dms]+), Maximum = (?<maximum>[\dms]+), Average = (?<average>[\dms]+))?/.match(shell_out)
# return captured[:average]
site = Net::Ping::External.new(addr, timeout=2)
average = 1000.001
count.times do
if site.ping
average = 0.0 if average == 1000.001
average += site.duration
end
end
return (average/count).round(4)
end
servers = get_servers
servers.each_with_index do |site, index|
host = URI(site).host
print "[#{index}/#{servers.length}] Pinging #{host}"
latency = measure_latency(host)
print " (took #{latency})\n"
$NEAREST[site] = latency
end
table = TTY::Table.new do |t|
t << ['Latency', 'Server']
$NEAREST.sort_by {|key, value| value}.each do |k,v|
t << [v, k]
end
end
puts table.render(:ascii)
out = File.open('mirror.bat', 'w')
out.puts "@echo off"
out.puts "rsync -avL --delete #{$NEAREST.sort_by {|key, value| value}.first[0]}systems/texlive/tlnet/ /a/TexLive/mirror/"
out.puts "pause"
out.close
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment