List of OpenVPN SurfShark servers Using jp group_by and count to sort JSON output from curl into sorted and counted list

Can anyone help me to understand and assist with a jq script please (only using jq)? Can anyone help me to write a script to take the output of:

`curl --silent "https://api.surfshark.com/v3/server/clusters" | jq` 

and list the number of servers in each countryCode and the min and max loadings on those servers, sorted by countryCode?

.countryCode 'count of number of servers' 'lowest .load' 'highest .load'
AU 5 13% 30%
UK 10 35% 88%
US 25 12% 50%

etc....

I believe the use of group_by, or a combination of that and map, set path, get path and count may work, but I'm hoping someone with higher skills can help me.

Each json entry looks like this:

[
  {
    "country": "Albania",
    "**countryCode**": "AL",
    "region": "Europe",
    "regionCode": "EU",
    "**load**": 12,
    "id": "4c333aa2-d08b-4d11-9073-61c351ce1c1e",
    "coordinates": {
      "longitude": 19.8188889,
      "latitude": 41.3275
    },
    "info": [
      {
        "id": "55994450-0c87-4df3-b585-3836c67a863d",
        "entry": {
          "value": "U2FsdGVkX1/VX5IKc3H3ruClgbw7JgnqW7Eacumx8aM="
        }
      }
    ],
    "type": "generic",
    "location": "Tirana",
    "**connectionName**": "al-tia.prod.surfshark.com",

Extract from another post referencing some of the possible commands

'map(.Properties.ItmId)
| reduce .[] as $i (
    {}; setpath([$i]; getpath([$i]) + 1)
  )
| to_entries | .[] | { "ItemId": .key, "Count": .value }'

how is this openwrt related ?

Because the script is running under OpenVPN to identify the VPN server. Doesn't it say that in the title? Are you here to complain or to contribute?

then it's openvpn related, at best, still not openwrt ?

Try this...

#!/bin/sh

surfshark=$(curl --silent https://api.surfshark.com/v3/server/clusters)
countrycodes=$(echo "$surfshark" | jq -r -c '.[].countryCode' | sort | uniq)
output=/tmp/surfshark

clear
echo "started..
"
for i in $countrycodes; do
  servers=$(echo "$surfshark" | jq -r -c ".[] | select( .countryCode == \"$i\" ) | .connectionName")
  echo "country code: $i"
  k=0
  for j in $servers; do
    k=$((k+1))
  done
  lowest_load=$(echo "$surfshark" | jq -r -c "[ .[] | select( .countryCode == \"$i\" ).load ] | min")
  highest_load=$(echo "$surfshark" | jq -r -c "[ .[] | select( .countryCode == \"$i\" ).load ] | max")
  echo "$i $k $lowest_load% $highest_load%" >> $output
done
echo
cat < $output
echo "
..completed
"
rm -f $output

displays an output like this...

.
country code: TW
country code: UA
country code: US
country code: VN
country code: ZA

AE 1 23% 23%
AL 1 10% 10%
AR 1 4% 4%
AT 1 13% 13%
AU 5 20% 27%
.

Rob - Top man! I'll give it a whirl!

smash that report button

If you ever plan to run this under OpenWrt, take this script ... less complex, it uses the standard JSON parser in OpenWrt, doesn't need temp files etc.

#!/bin/sh

json_in="$(curl --silent "https://api.surfshark.com/v3/server/clusters" 2>/dev/null)"

countries="$(printf "%s" "${json_in}" | jsonfilter -e '@.*.countryCode' | sort -u | awk '{ORS=" ";print}')"
for cc in ${countries}
do
        cnt="$(printf "%s" "${json_in}" | jsonfilter -e "@[@.countryCode=\"${cc}\"].countryCode" | wc -l)"
        min_max="$(printf "%s" "${json_in}" | jsonfilter -e "@[@.countryCode=\"${cc}\"].load" | sort | awk '{ORS=" ";print}')"
        min_max="${min_max#"${min_max%%[![:space:]]*}"}"
        min_max="${min_max%"${min_max##*[![:space:]]}"}"
        min="${min_max%% *}"
        max="${min_max##* }"
        printf "%-5s%-5s%-5s%s\n" "${cc}" "${cnt}" "${min}%" "${max}%"
done

Output as follows:

AE   1    23%  23%
AL   1    14%  14%
AR   1    5%   5%
AT   1    23%  23%
AU   5    17%  24%
AZ   1    19%  19%
BA   1    16%  16%
BE   1    20%  20%
BG   1    24%  24%
BR   1    41%  41%
CA   3    22%  31%
CH   1    20%  20%
[...]
2 Likes

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.