Skip to content

Instantly share code, notes, and snippets.

@mecograph
Last active July 22, 2024 15:37
Show Gist options
  • Save mecograph/d655dd72b961762017906da3d4addf4d to your computer and use it in GitHub Desktop.
Save mecograph/d655dd72b961762017906da3d4addf4d to your computer and use it in GitHub Desktop.
This script provides a user-friendly interface for interacting with an API, offering options to check for unused elements or search for specific element usage, complete with progress indicators and graceful interruption handling.
#!/bin/bash
# ANSI color codes
green="\033[32m"
bright_black="\033[90m"
red="\033[31m"
blue="\033[34m"
reset="\033[0m"
# Set OAuth token and space ID
OAUTH_TOKEN="MY_OAUTH_TOKEN" # https://app.storyblok.com/#/me/account?tab=token
SPACE_ID="MY_SPACE_ID" # can be found in space settings
CHECK_MARK="\033[0;32m\xE2\x9C\x94\033[0m"
PER_PAGE=1000
# Utility function for menu control
ESC=$(printf "\033")
cursor_blink_on() { printf "$ESC[?25h"; }
cursor_blink_off() { printf "$ESC[?25l"; }
cursor_to() { printf "$ESC[$1;${2:-1}H"; }
print_option() { printf " $1 "; }
print_selected() {
printf "${blue}${red}$1${reset} "
}
get_cursor_row() { IFS=';' read -sdR -p $'\E[6n' ROW COL; echo ${ROW#*[}; }
key_input() {
read -s -n3 key 2>/dev/null >&2
if [[ $key = $ESC[A ]]; then echo up; fi
if [[ $key = $ESC[B ]]; then echo down; fi
if [[ $key = "" ]]; then echo enter; fi
}
# Display menu and get user selection
show_menu() {
echo "Select the function to execute:"
options=("1) Check for unused storyblok components" "2) Find usage of a specific storyblok component" "3) Exit")
for opt in "${options[@]}"; do printf "\n"; done
local lastrow=$(get_cursor_row)
local startrow=$(($lastrow - ${#options[@]}))
trap "cursor_blink_on; stty echo; printf '\n'; exit" 2
cursor_blink_off
local selected=0
while true; do
local idx=0
for opt in "${options[@]}"; do
cursor_to $(($startrow + $idx))
if [ $idx -eq $selected ]; then
print_selected "$opt"
else
print_option "$opt"
fi
((idx++))
done
case $(key_input) in
enter) break ;;
up)
((selected--))
if [ $selected -lt 0 ]; then selected=$((${#options[@]} - 1)); fi
;;
down)
((selected++))
if [ $selected -ge ${#options[@]} ]; then selected=0; fi
;;
esac
done
cursor_to $lastrow
printf "\n"
cursor_blink_on
return $selected
}
# Show progress indicator
show_progress() {
local duration=$1
local interval=0.1
local total_intervals=$(echo "$duration / $interval" | bc)
local current_interval=0
handle_interrupt() {
printf "\nInterrupted\n"
exit 1
}
trap 'handle_interrupt' SIGINT
while [ $current_interval -lt $total_intervals ]; do
printf "."
sleep $interval
((current_interval++))
done
trap - SIGINT
}
# --------------------------------------
# Check for unused components
# --------------------------------------
checkForUnusedComponents() {
# Print loading message and progress indicator
echo -ne "${blue}Loading components from Storyblok API${reset}"
show_progress 5 & progress_pid=$!
# Trap SIGINT to cancel the operation gracefully
trap 'kill $progress_pid; printf "\n❗️Cancelled\n"; exit 1' SIGINT
# Fetch components
components=$(curl -s -X GET "https://api.storyblok.com/v1/spaces/$SPACE_ID/components/" \
-H "Authorization: $OAUTH_TOKEN" \
-G --data-urlencode "per_page=$PER_PAGE")
wait $progress_pid
trap - SIGINT
component_names=$(echo $components | jq -r '.components[].name')
used_components=()
unused_components=()
total_components=$(echo "$component_names" | wc -w)
current_component=0
printf "\r\033[2K${CHECK_MARK} %d components loaded from Storyblok!\n" "$total_components"
# Check for usage of each component
for component in $component_names; do
((current_component++))
printf "\r${blue}Processing component %d of %d${reset}" "$current_component" "$total_components"
stories=$(curl -s -X GET "https://api.storyblok.com/v1/spaces/$SPACE_ID/stories/" \
-H "Authorization: $OAUTH_TOKEN" \
-G --data-urlencode "contain_component=$component" \
--data-urlencode "per_page=1")
story_count=$(echo $stories | jq '.stories | length')
if [ $story_count -gt 0 ]; then
used_components+=("$component")
else
unused_components+=("$component")
fi
done
# Print results
if [ ${#unused_components[@]} -gt 0 ]; then
printf "\r\033[2K${CHECK_MARK} Found %d unused components:\n" "${#unused_components[@]}"
for unused_component in "${unused_components[@]}"; do
printf " - %s\n" "$unused_component"
done
else
printf "\r\033[2K${CHECK_MARK} No unused components were found\n"
fi
}
# --------------------------------------
# Find usage of a specific component
# --------------------------------------
findComponentUsage() {
while true; do
# Prompt for component name
read -p "Enter the component name: " component_name
echo -ne "\033[1A\033[2K\r\033[2K${blue}Searching for usage of ${component_name}${reset}"
show_progress 5 & progress_pid=$!
# Trap SIGINT to cancel the operation gracefully
trap 'kill $progress_pid; printf "\n❗️Cancelled\n"; exit 1' SIGINT
stories=$(curl -s -X GET "https://api.storyblok.com/v1/spaces/$SPACE_ID/stories/" \
-H "Authorization: $OAUTH_TOKEN" \
-G --data-urlencode "contain_component=$component_name" \
--data-urlencode "per_page=$PER_PAGE")
wait $progress_pid
trap - SIGINT
# Print results
story_count=$(echo $stories | jq '.stories | length')
if [ $story_count -gt 0 ]; then
echo -en "\r\033[2K${CHECK_MARK} $component_name is used in the following stories ($story_count total):\n"
echo $stories | jq -r --arg space_id "$SPACE_ID" '
.stories[] |
"\n\(.name) (created \(.created_at | sub("\\.[0-9]+Z$"; "Z") | fromdateiso8601 | strftime("%d.%m.%Y")) by \(.last_author.userid) | published: \(.published // false | if . then "🟢" else "🔴" end))\nURL:\t\thttps://www.kartenliebe.de/\(.path)\nSTORYBLOK:\thttps://app.storyblok.com/#/me/spaces/\($space_id)/stories/0/0/\(.id)\n"
'
break
else
# Prompt to try again
echo -en "\r\033[2K❌ $component_name is not used in any story. Want to try again? (yes/no): "
read answer
if [[ "$answer" != "yes" ]]; then
echo "👋 Ok, bye"
exit 1
fi
fi
done
}
# Main script logic
if [ -z "$1" ]; then
clear
show_menu
selected_option=$?
case $selected_option in
0) checkForUnusedComponents ;;
1) findComponentUsage ;;
2) echo "👋 Ok, bye"; exit 0 ;;
esac
else
method=$1
case $method in
checkForUnusedComponents) checkForUnusedComponents ;;
findComponentUsage) findComponentUsage ;;
*)
echo "Usage: ./storyblokClient.sh <method>"
echo "Methods:"
echo " checkForUnusedComponents"
echo " findComponentUsage"
exit 1
;;
esac
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment