Last active
July 22, 2024 15:37
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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