Last active
March 18, 2024 23:35
-
-
Save jackbdu/1e664c154f934c5d6f6f7ec51e5df037 to your computer and use it in GitHub Desktop.
Generating simple redirect index.html in docs/subfolder in GitHub repo
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 | |
| # | |
| # Redirect Generator | |
| # | |
| # Author: Jack B. Du ([email protected]) | |
| # | |
| # Usage: | |
| # ./redirect-generator.sh # Interactive mode: prompts for folder name and URL. | |
| # ./redirect-generator.sh --update-from-csv # Update redirects from CSV file interactively. | |
| # ./redirect-generator.sh --update-from-csv --confirm-all # Update redirects from CSV file without confirmation prompts. | |
| # ./redirect-generator.sh --help # Displays usage information and exits. | |
| # | |
| # Flags: | |
| # --update-from-csv: Update redirects from a CSV file, reading folder names and URLs to create or update redirects. | |
| # --confirm-all: When updating from the CSV file, this flag skips manual confirmation prompts for each redirect. | |
| # --help: Displays this usage information and exits. | |
| # | |
| # Description: | |
| # This script generates a redirect HTML file in the specified folder, redirecting to the provided URL. | |
| # It validates URLs, including checks for reachability and HTTP status codes, and prompts the user for | |
| # confirmation before proceeding with potentially unreachable or problematic URLs. The script can operate | |
| # in an interactive mode for individual redirects or batch process updates from a CSV file. It maintains | |
| # a CSV log of successful redirects for record-keeping and future updates. | |
| # | |
| # Enhancements include logging of actions for audit trails, and configuration through external files for flexibility. | |
| # The script also supports relative URLs (starting with a dot) without prepending "https://", | |
| # accommodating a wider range of redirect targets. | |
| # | |
| # Credits: Created with help from ChatGPT. | |
| # Default configurations can be overridden by a separate configuration file. | |
| # This allows for easier customization without modifying the script itself. | |
| CONFIG_FILE="redirect-generator.config" | |
| if [ -f "$CONFIG_FILE" ]; then | |
| source "$CONFIG_FILE" | |
| fi | |
| # Default file locations, which can be overridden by the configuration file. | |
| CSV_FILE="${CSV_FILE:-redirects.csv}" | |
| LOG_FILE="${LOG_FILE:-redirect-generator.log}" | |
| # Function for logging messages with timestamps to a log file. | |
| # This is useful for tracking the script's operations and debugging issues. | |
| log() { | |
| echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE" | |
| } | |
| # Ensures URLs start with http://, https://, or a dot (.). If not, https:// is prepended. | |
| # URLs starting with a dot are typically used for relative paths, so they should be left as is. | |
| prepend_https() { | |
| local url=$1 | |
| # Check if URL starts with http://, https://, or a dot (.) | |
| if ! [[ $url =~ ^https?:// ]] && ! [[ $url =~ ^\. ]]; then | |
| url="https://${url}" | |
| fi | |
| echo "$url" | |
| } | |
| # Validates the URL's reachability and HTTP status using curl. | |
| # Provides warnings for unreachable URLs or those that return error codes. | |
| validate_url() { | |
| local url=$(prepend_https "$1") | |
| if ! curl --head --silent --fail "$url" > /dev/null; then | |
| log "Warning: The URL '$url' is not reachable or does not exist." | |
| read -p "Warning: The URL '$url' is not reachable or does not exist. Do you still want to proceed? (y/n): " proceed_confirmation < /dev/tty | |
| if [[ $proceed_confirmation != [yY] ]]; then | |
| log "Aborted by user due to unreachable URL." | |
| echo "Aborted. Exiting script." | |
| exit 1 | |
| fi | |
| fi | |
| # Check if the URL returns a 2xx status code (indicating success) | |
| if ! curl --head --silent --fail --output /dev/null --write-out "%{http_code}" "$url" | grep -qE '^2'; then | |
| log "Warning: The URL '$url' returned a non-successful HTTP status code." | |
| read -p "Warning: The URL '$url' returned a non-successful HTTP status code. Do you still want to proceed? (y/n): " proceed_confirmation < /dev/tty | |
| if [[ $proceed_confirmation != [yY] ]]; then | |
| log "Aborted by user due to a non-successful HTTP status code." | |
| echo "Aborted. Exiting script." | |
| exit 1 | |
| fi | |
| fi | |
| echo "$url" | |
| } | |
| # Validates the folder name against a pattern and checks for its existence. | |
| # Prompts for confirmation before overwriting an existing folder. | |
| validate_folder() { | |
| local folder_name=$(echo "$1" | tr '[:upper:]' '[:lower:]') | |
| if [[ ! "$folder_name" =~ ^[a-z0-9_\-~.]+$ ]]; then | |
| log "Error: Invalid folder name '$folder_name'." | |
| echo "Error: Invalid folder name. Please use only lowercase letters, numbers, hyphens, underscores, periods, and tildes." | |
| exit 1 | |
| fi | |
| if [ -d "docs/${folder_name}" ]; then | |
| read -p "The folder 'docs/${folder_name}' already exists. Do you want to overwrite it? (y/n): " overwrite_confirmation < /dev/tty | |
| if [[ $overwrite_confirmation != [yY] ]]; then | |
| log "Aborted by user due to existing folder 'docs/${folder_name}." | |
| echo "Aborted. Exiting script." | |
| exit 1 | |
| fi | |
| fi | |
| echo "$folder_name" | |
| } | |
| # Shows help information with usage instructions and options description. | |
| # This function improves the script's usability by guiding the user. | |
| show_help() { | |
| echo "Usage: $0 [OPTIONS]" | |
| echo "Options:" | |
| echo " --update-from-csv Update redirects from a CSV file." | |
| echo " --confirm-all Automatically confirm all updates when updating from CSV file." | |
| echo " --help Show this help message." | |
| echo "" | |
| echo "Description:" | |
| echo " This script generates a redirect HTML file in the specified folder, redirecting to the provided URL." | |
| } | |
| # Function to create or update the redirect HTML file | |
| # This function also logs the creation or update action. | |
| create_redirect_html() { | |
| local folder_name=$1 | |
| local redirect_url=$2 | |
| # Ensure the target directory exists | |
| mkdir -p "docs/${folder_name}" || { echo "Error: Failed to create folder 'docs/${folder_name}'."; log "Error: Failed to create folder 'docs/${folder_name}'."; exit 1; } | |
| # Define the HTML content for the redirect | |
| local html_content=$(cat <<EOF | |
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <meta http-equiv="refresh" content="0; URL='${redirect_url}'"> | |
| <style> | |
| @keyframes fadeIn { | |
| from { opacity: 0; } | |
| to { opacity: 1; } | |
| } | |
| body { | |
| opacity: 0; /* Initially hide the h1 */ | |
| animation: fadeIn 1s ease-out 2s forwards; /* Animation delayed by 2 second */ | |
| font-family: Ubuntu, Arial, sans-serif; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| height: 100vh; | |
| text-align: center; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div> | |
| <h1>Redirecting...</h1> | |
| <p>If you are not redirected automatically, <a href="${redirect_url}">click here</a>.</p> | |
| </div> | |
| </body> | |
| </html> | |
| EOF | |
| ) | |
| # Write the HTML content to the index.html file within the specified folder | |
| local file_path="docs/${folder_name}/index.html" | |
| echo "${html_content}" > "${file_path}" | |
| echo "index.html file created in 'docs/${folder_name}' folder, redirecting to '${redirect_url}'." | |
| log "Redirect for '${folder_name}' created or updated, pointing to '${redirect_url}'." | |
| # Update or create an entry in the CSV file for the redirect | |
| # This part keeps track of all redirects for future reference or updates | |
| if [ -f "$CSV_FILE" ]; then | |
| local temp_file=$(mktemp) | |
| awk -v folder_name="$folder_name" -v redirect_url="$redirect_url" -F',' 'BEGIN {OFS=","} {if ($1 == folder_name) {$2=redirect_url; print $0; found=1} else {print $0}} END {if (!found) {print folder_name, redirect_url}}' "$CSV_FILE" > "$temp_file" | |
| mv "$temp_file" "$CSV_FILE" | |
| else | |
| echo "${folder_name},${redirect_url}" > "$CSV_FILE" | |
| fi | |
| } | |
| # Function to handle updates from a CSV file | |
| # This processes each line of the CSV to update or create redirects | |
| update_from_csv() { | |
| local confirm_all=$1 | |
| # Check for the presence of the CSV file | |
| if [ ! -f "$CSV_FILE" ]; then | |
| log "Error: CSV file '$CSV_FILE' not found." | |
| echo "Error: CSV file '$CSV_FILE' not found." | |
| exit 1 | |
| fi | |
| # Read each line from the CSV file and process it | |
| while IFS=',' read -r folder_name redirect_url || [ -n "$folder_name" ]; do | |
| # Skip header line if present | |
| if [[ "$folder_name" == "Folder Name" ]]; then | |
| continue | |
| fi | |
| # For the --confirm-all flag, bypass user confirmation | |
| if [[ $confirm_all != "true" ]]; then | |
| read -p "Update redirect for folder '${folder_name}' to '${redirect_url}'? (y/n): " user_confirmation < /dev/tty | |
| if [[ $user_confirmation != [yY] ]]; then | |
| echo "Skipping folder '${folder_name}'." | |
| log "Update for '${folder_name}' skipped by user." | |
| continue | |
| fi | |
| # Validate folder name and confirm if it already exists | |
| folder_name=$(validate_folder "$folder_name") | |
| if [ $? -ne 0 ]; then | |
| # Error occurred, continue to next entry | |
| echo "$folder_name" | |
| continue | |
| fi | |
| # Validate the URL | |
| redirect_url=$(validate_url "$redirect_url") | |
| if [ $? -ne 0 ]; then | |
| # Error occurred, continue to next entry | |
| echo "$redirect_url" | |
| continue | |
| fi | |
| fi | |
| # Create or update the redirect | |
| create_redirect_html "$folder_name" "$redirect_url" | |
| done < "$CSV_FILE" | |
| } | |
| # Main execution logic | |
| main() { | |
| # Parsing command-line options to set script behavior. | |
| # Supports updating from a CSV file, automatic confirmation, and showing help. | |
| while [[ "$#" -gt 0 ]]; do | |
| case $1 in | |
| --update-from-csv) update_from_csv="true"; shift ;; | |
| --confirm-all) confirm_all="true"; shift ;; | |
| --help) show_help; exit 0 ;; | |
| *) echo "Unknown option: $1"; show_help; exit 1 ;; | |
| esac | |
| done | |
| if [[ $update_from_csv == "true" ]]; then | |
| update_from_csv "$confirm_all" | |
| else | |
| # Prompt user to enter the folder name where they want to create the index.html file | |
| read -p "Enter the folder name where you want to create the index.html file: " folder_name | |
| # Validate folder name and confirm if it already exists | |
| folder_name=$(validate_folder "$folder_name") | |
| if [ $? -ne 0 ]; then | |
| echo "$folder_name" | |
| # Error occurred, exit script | |
| exit 1 | |
| fi | |
| # Prompt user to enter the URL they want to redirect to | |
| read -p "Enter the URL you want to redirect to: " redirect_url | |
| # Validate the URL | |
| redirect_url=$(validate_url "$redirect_url") | |
| if [ $? -ne 0 ]; then | |
| echo "$redirect_url" | |
| # Error occurred, exit script | |
| exit 1 | |
| fi | |
| # Create the redirect HTML file | |
| create_redirect_html "$folder_name" "$redirect_url" | |
| fi | |
| } | |
| # Execute the main function with all provided arguments | |
| main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment