Skip to content

Instantly share code, notes, and snippets.

@meleu
Created August 3, 2024 23:29
Show Gist options
  • Save meleu/874e0f2713175dc4aa3602c6afd21e26 to your computer and use it in GitHub Desktop.
Save meleu/874e0f2713175dc4aa3602c6afd21e26 to your computer and use it in GitHub Desktop.
See the Olympics 2024 medal table in your terminal.
#!/usr/bin/env bash
# medals.sh
###########
# Show the Olympics 2024 medal table.
#
# Data from <https://olympics.com/en/paris-2024/medals>
#
# Dependencies:
# - curl
# - jq
# - htmlq (install with `brew install htmlq`)
#
# Inspiration:
# <https://www.reddit.com/r/learnpython/comments/1eeommk/olympic_medal_table_extract_script/>
#
# meleu - <https://meleu.dev/>
set -Eeuo pipefail
trap 'echo "[ERROR]: ${BASH_SOURCE}:${FUNCNAME}:${LINENO}"' ERR
readonly URL='https://olympics.com/en/paris-2024/medals'
main() {
# shellcheck disable=2155
local inputFile="$(mktemp)"
local jsonFile="${inputFile}.json"
local amount="${1:-10}"
getMedalPage "$inputFile"
getJsonData "$inputFile" "$amount" > "$jsonFile"
renderMedalTable "$jsonFile"
rm -rf "$inputFile" "$jsonFile"
}
getMedalPage() {
local file="$1"
# looks like olympics.com does not accept curl as an user-agent,
# then we need to send a custom one.
curl "$URL" \
--silent \
--location \
--user-agent "Mozilla/5.0" \
--output "$file"
}
getJsonData() {
local file="$1"
local max="${2:-10}"
htmlq \
--text \
'script#__NEXT_DATA__' \
--filename "$file" \
| jq \
".props.pageProps.initialMedals.medalStandings.medalsTable[:${max}]
| [ .[]
| {
description,
medalsNumber: [.medalsNumber[] | select(.type == \"Total\")]
}
]
| [.[] | {description, medalsNumber: .medalsNumber[0]}]"
}
renderMedalTable() {
local jsonFile="$1"
local medalTableData
local line
local gold silver bronze total country
medalTableData="$(
jq --raw-output \
'.[] | "\(.medalsNumber.gold):\(.medalsNumber.silver):\(.medalsNumber.bronze):\(.medalsNumber.total):\(.description)"' \
"$jsonFile"
)"
echo " 🥇 | 🥈 | 🥉 | total | Country"
echo "-----|-----|-----|-------|---------"
while IFS= read -r line || [[ -n "${line}" ]]; do
gold="$(cut -d: -f1 <<< "$line")"
silver="$(cut -d: -f2 <<< "$line")"
bronze="$(cut -d: -f3 <<< "$line")"
total="$(cut -d: -f4 <<< "$line")"
country="$(cut -d: -f5 <<< "$line")"
printf " %3s | %3s | %3s | %5s | %s\n" \
"$gold" "$silver" "$bronze" "$total" "$country"
done <<< "$medalTableData"
echo -e "\nSource: $URL"
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment