Current section
Files
Jump to
Current section
Files
lib/decoder.ex
defmodule Speedtest.Decoder do
import SweetXml
@moduledoc false
## in bytes
@download_sizes [350, 500, 750, 1000, 1500, 2000, 2500, 3000, 3500, 4000]
@upload_sizes [32768, 65536, 131_072, 262_144, 524_288, 1_048_576, 7_340_032]
def url(data) do
url = String.split(data, ":")
List.first(url)
end
def client(data) do
result =
data.body
|> xpath(
~x"//client",
ip: ~x"./@ip",
lat: ~x"./@lat",
lon: ~x"./@lon",
isp: ~x"./@isp",
country: ~x"./@country",
isprating: ~x"./@isprating",
rating: ~x"./@rating",
ispdlavg: ~x"./@ispdlavg",
ispulavg: ~x"./@ispulavg"
)
%{
ip: to_string(result.ip),
lat: to_float(result.lat),
lon: to_float(result.lon),
isp: to_string(result.isp),
country: to_string(result.country),
isprating: to_string(result.isprating),
rating: to_string(result.rating),
ispdlavg: to_string(result.ispdlavg),
ispulavg: to_string(result.ispulavg)
}
end
def server(data) do
results =
data.body
|> xpath(
~x"//servers/server"l,
url: ~x"./@url",
lat: ~x"./@lat",
lon: ~x"./@lon",
name: ~x"./@name",
country: ~x"./@country",
cc: ~x"./@cc",
sponsor: ~x"./@sponsor",
id: ~x"./@id",
host: ~x"./@host"
)
Enum.map(results, fn result ->
%{
url: to_string(result.url),
lat: to_float(result.lat),
lon: to_float(result.lon),
name: to_string(result.name),
country: to_string(result.country),
cc: to_string(result.cc),
sponsor: to_string(result.sponsor),
id: to_string(result.id),
host: to_string(result.host)
}
end)
end
def server_config(data) do
result =
data.body
|> xpath(
~x"//server-config",
threadcount: ~x"./@threadcount",
notonmap: ~x"./@notonmap",
forcepingid: ~x"./@forcepingid",
preferredserverid: ~x"./@preferredserverid",
ignoreids: ~x"./@ignoreids"
)
%{
threadcount: to_integer(result.threadcount),
notonmap: result.notonmap,
forcepingid: result.forcepingid,
preferredserverid: result.preferredserverid,
ignoreids: result.ignoreids
}
end
def config(data) do
server_config = server_config(data)
download = download(data)
upload = upload(data)
client = client(data)
head = upload.ratio - 1
tail = Enum.count(@upload_sizes) - 1
upload_sizes = Enum.slice(@upload_sizes, head..tail)
sizes = %{upload: upload_sizes, download: @download_sizes}
size_count = Enum.count(sizes.upload)
upload_count = upload.maxchunkcount / size_count
upload_count = Float.round(upload_count)
counts = %{upload: upload_count, download: download.threads}
threads = %{upload: upload.threads, download: server_config.threadcount * 2}
length = %{upload: upload.testlength, download: download.testlength}
reply = %{
client: client,
ignore_servers: server_config.ignoreids,
sizes: sizes,
counts: counts,
threads: threads,
length: length,
upload_max: upload_count * size_count
}
reply
end
def to_integer(data) do
data = to_string(data)
String.to_integer(data)
end
def to_float(data) do
data = to_string(data)
String.to_float(data)
end
def license(data) do
result =
data.body
|> xpath(~x"//licensekey/text()")
to_string(result)
end
def odometer(data) do
result =
data.body
|> xpath(
~x"//odometer",
start: ~x"./@start",
rate: ~x"./@rate"
)
%{start: to_integer(result.start), rate: to_integer(result.rate)}
end
def download(data) do
result =
data.body
|> xpath(
~x"//download",
testlength: ~x"./@testlength",
initialtest: ~x"./@initialtest",
mintestsize: ~x"./@mintestsize",
threadsperurl: ~x"./@threadsperurl"
)
%{
testlength: to_integer(result.testlength),
initialtest: to_string(result.initialtest),
mintestsize: to_string(result.mintestsize),
threads: to_integer(result.threadsperurl)
}
end
def upload(data) do
result =
data.body
|> xpath(
~x"//upload",
testlength: ~x"./@testlength",
ratio: ~x"./@ratio",
initialtest: ~x"./@initialtest",
mintestsize: ~x"./@mintestsize",
threads: ~x"./@threads",
maxchunksize: ~x"./@maxchunksize",
maxchunkcount: ~x"./@maxchunkcount",
threadsperurl: ~x"./@threadsperurl"
)
%{
ratio: to_integer(result.ratio),
maxchunksize: to_string(result.maxchunksize),
threads: to_integer(result.threads),
testlength: to_integer(result.testlength),
initialtest: to_integer(result.initialtest),
mintestsize: to_string(result.mintestsize),
maxchunkcount: to_integer(result.maxchunkcount)
}
end
def latency(data) do
result =
data.body
|> xpath(
~x"//latency",
testlength: ~x"./@testlength",
waittime: ~x"./@waittime",
timeout: ~x"./@timeout"
)
%{
testlength: to_integer(result.testlength),
waittime: to_integer(result.waittime),
timeout: to_integer(result.timeout)
}
end
def socket_download(data) do
result =
data.body
|> xpath(
~x"//socket-download",
testlength: ~x"./@testlength",
initialthreads: ~x"./@initialthreads",
minthreads: ~x"./@minthreads",
maxthreads: ~x"./@maxthreads",
threadratio: ~x"./@threadratio",
maxsamplesize: ~x"./@maxsamplesize",
minsamplesize: ~x"./@minsamplesize",
startsamplesize: ~x"./@startsamplesize",
startbuffersize: ~x"./@startbuffersize",
bufferlength: ~x"./@bufferlength",
packetlength: ~x"./@packetlength",
readbuffer: ~x"./@readbuffer"
)
%{
testlength: to_integer(data.testlength),
initialthreads: to_integer(result.initialthreads),
minthreads: to_integer(result.minthreads),
maxthreads: to_integer(result.maxthreads),
threadratio: to_string(data.threadratio),
maxsamplesize: to_integer(data.maxsamplesize),
minsamplesize: to_integer(data.minsamplesize),
startsamplesize: to_integer(data.startsamplesize),
startbuffersize: to_integer(data.startbuffersize),
bufferlength: to_integer(data.bufferlength),
packetlength: to_integer(data.packetlength),
readbuffer: to_integer(data.readbuffer)
}
end
def socket_upload(data) do
result =
data.body
|> xpath(
~x"//socket-upload",
testlength: ~x"./@testlength",
initialthreads: ~x"./@initialthreads",
minthreads: ~x"./@minthreads",
maxthreads: ~x"./@maxthreads",
threadratio: ~x"./@threadratio",
maxsamplesize: ~x"./@maxsamplesize",
minsamplesize: ~x"./@minsamplesize",
startsamplesize: ~x"./@startsamplesize",
startbuffersize: ~x"./@startbuffersize",
bufferlength: ~x"./@bufferlength",
packetlength: ~x"./@packetlength",
disabled: ~x"./@disabled"
)
disabled? =
case result.disabled == "true" do
true -> true
false -> false
end
%{
testlength: to_integer(data.testlength),
initialthreads: to_string(result.initialthreads),
minthreads: to_string(result.minthreads),
maxthreads: to_integer(result.maxthreads),
threadratio: to_string(data.threadratio),
maxsamplesize: to_integer(data.maxsamplesize),
minsamplesize: to_integer(data.minsamplesize),
startsamplesize: to_integer(data.startsamplesize),
startbuffersize: to_integer(data.startbuffersize),
bufferlength: to_integer(data.bufferlength),
packetlength: to_integer(data.packetlength),
disabled: disabled?
}
end
def socket_latency(data) do
result =
data.body
|> xpath(
~x"//socket-latency",
testlength: ~x"./@testlength",
waittime: ~x"./@waittime",
timeout: ~x"./@timeout"
)
%{
testlength: to_integer(result.testlength),
waittime: to_integer(result.waittime),
timeout: to_integer(result.timeout)
}
end
end