#!/bin/bash # workJson.sh # This script scans directories for PHP applications, creates or updates a workingOn.json file. # It identifies new applications and updates existing ones based on modification times. # --- Configuration --- JSON_FILE="workingOn.json" BASE_URL="http://localhost/" # Base URL for your web server, adjust as needed. # --- Helper Functions --- # Function to check if jq is installed check_jq() { if ! command -v jq &> /dev/null; then echo "Error: 'jq' is not installed." echo "Please install 'jq' to run this script. For example, on Debian/Ubuntu: sudo apt-get install jq" echo "On macOS: brew install jq" exit 1 fi } # Function to get the current date in YYYY-MM-DD format get_current_date() { date +"%Y-%m-%d" } # Function to convert a path to a URL path_to_url() { local path="$1" local start_dir_abs="$2" local relative_path="" # Get the real path of the directory local real_path=$(realpath "$path") local real_start_dir=$(realpath "$start_dir_abs") # Check if the real path starts with the real start directory if [[ "$real_path" == "$real_start_dir"* ]]; then # Calculate relative path from start_dir_abs # Remove the start_dir_abs prefix, and leading/trailing slashes relative_path="${real_path#$real_start_dir}" relative_path="${relative_path#/}" # Remove leading slash relative_path="${relative_path%/}" # Remove trailing slash # Construct the URL echo "${BASE_URL}${relative_path}" else echo "" # Return empty if not within the base directory fi } # --- Main Script Logic --- # 1. Check for jq check_jq # 2. Parse Arguments if [ "$#" -ne 3 ]; then echo "Usage: $0 " echo " : The root directory to start scanning from." echo " : Include directories whose last modification time is older than this many days." echo " : Include directories containing PHP files updated within this many days." exit 1 fi START_DIR="$1" DAYS_OLD_DIR="$2" DAYS_LAST_UPDATED_PHP="$3" CURRENT_DATE=$(get_current_date) # Ensure start directory exists if [ ! -d "$START_DIR" ]; then echo "Error: Start directory '$START_DIR' not found." exit 1 fi # 3. Load existing JSON data or initialize empty array if [ -f "$JSON_FILE" ]; then EXISTING_DATA=$(cat "$JSON_FILE") if ! echo "$EXISTING_DATA" | jq -e '.[0]' &> /dev/null; then # If file exists but is empty or invalid JSON, reinitialize EXISTING_DATA="[]" echo "Warning: '$JSON_FILE' was empty or invalid. Initializing as empty array." fi else EXISTING_DATA="[]" echo "Info: '$JSON_FILE' not found. Creating a new one." fi # Use a temporary file for new data to avoid race conditions/corruption NEW_DATA_TEMP=$(mktemp) echo "[]" > "$NEW_DATA_TEMP" # Initialize temp file with empty array # 4. Find relevant directories and process them # Find directories that are older than DAYS_OLD_DIR (modification time of the directory itself) # and also contain PHP files updated within DAYS_LAST_UPDATED_PHP. # We'll iterate through all directories and apply filters in the loop. # Use find to get all directories under START_DIR find "$START_DIR" -type d -print0 | while IFS= read -r -d $'\0' DIR; do # Skip the start directory itself if it's the only one found if [ "$DIR" = "$START_DIR" ]; then continue fi # Calculate directory modification age DIR_MOD_DATE=$(stat -c %y "$DIR" | cut -d ' ' -f 1) DIR_MOD_TIMESTAMP=$(date -d "$DIR_MOD_DATE" +%s) CURRENT_TIMESTAMP=$(date +%s) DIR_AGE_SECONDS=$((CURRENT_TIMESTAMP - DIR_MOD_TIMESTAMP)) DIR_AGE_DAYS=$((DIR_AGE_SECONDS / 86400)) # 86400 seconds in a day # Check if directory is older than DAYS_OLD_DIR if [ "$DIR_AGE_DAYS" -lt "$DAYS_OLD_DIR" ]; then continue # Skip if directory is not old enough fi # Find PHP files updated within DAYS_LAST_UPDATED_PHP within this directory RECENT_PHP_FILE=$(find "$DIR" -maxdepth 1 -type f -name "*.php" -mtime -"$DAYS_LAST_UPDATED_PHP" -print -quit) if [ -z "$RECENT_PHP_FILE" ]; then continue # Skip if no recently updated PHP files found fi APP_NAME=$(basename "$DIR") FULL_DIR_PATH=$(realpath "$DIR") STARTUP_LINK="" # Prioritize index.php if [ -f "$FULL_DIR_PATH/index.php" ]; then STARTUP_LINK=$(path_to_url "$FULL_DIR_PATH/index.php" "$START_DIR") else # Otherwise, pick the first PHP file found in the directory FIRST_PHP_FILE=$(find "$FULL_DIR_PATH" -maxdepth 1 -type f -name "*.php" | head -n 1) if [ -n "$FIRST_PHP_FILE" ]; then STARTUP_LINK=$(path_to_url "$FIRST_PHP_FILE" "$START_DIR") fi fi # Check if this directory already exists in the JSON EXISTING_ENTRY=$(echo "$EXISTING_DATA" | jq --arg dir "$FULL_DIR_PATH" '.[] | select(.directory == $dir)') if [ -n "$EXISTING_ENTRY" ]; then # Entry exists, update status and lastUpdated, preserve links and comment STATUS="updated" COMMENT=$(echo "$EXISTING_ENTRY" | jq -r '.comment // ""') SECONDARY_LINK=$(echo "$EXISTING_ENTRY" | jq -r '.secondaryLink // ""') # Preserve existing startup link if it was already set, otherwise use the newly found one PRESERVED_STARTUP_LINK=$(echo "$EXISTING_ENTRY" | jq -r '.startUp // ""') if [ -n "$PRESERVED_STARTUP_LINK" ]; then STARTUP_LINK="$PRESERVED_STARTUP_LINK" fi else # New entry STATUS="new" COMMENT="" SECONDARY_LINK="" fi # Construct the new entry NEW_ENTRY=$(jq -n \ --arg app "$APP_NAME" \ --arg dir "$FULL_DIR_PATH" \ --arg startup "$STARTUP_LINK" \ --arg secondary "$SECONDARY_LINK" \ --arg comment "$COMMENT" \ --arg status "$STATUS" \ --arg last_updated "$CURRENT_DATE" \ '{appName: $app, directory: $dir, startUp: $startup, secondaryLink: $secondary, comment: $comment, status: $status, lastUpdated: $last_updated}') # Add the new entry to the temporary JSON array jq ". += [$NEW_ENTRY]" "$NEW_DATA_TEMP" > tmp.$$.json && mv tmp.$$.json "$NEW_DATA_TEMP" done # 5. Merge existing entries that were not found in the current scan (keep them, but don't mark as updated) # This step ensures entries for projects you're still working on but haven't touched recently # are still in the list, but their status won't be 'new' or 'updated' unless re-scanned. # Get directories from the newly scanned data SCANNED_DIRS=$(jq -r '.[].directory' "$NEW_DATA_TEMP") # Iterate through existing data and add entries not found in the new scan echo "$EXISTING_DATA" | jq -c '.[]' | while IFS= read -r EXISTING_ITEM; do EXISTING_DIR=$(echo "$EXISTING_ITEM" | jq -r '.directory') # Check if this existing directory was NOT part of the recent scan if ! echo "$SCANNED_DIRS" | grep -q "^$EXISTING_DIR$"; then # Add the existing item as is, but ensure its status is not 'new' or 'updated' # unless it was already marked as such. We'll set it to 'other' if it was 'new'/'updated' from a previous run # but is no longer being actively scanned. CURRENT_STATUS=$(echo "$EXISTING_ITEM" | jq -r '.status') if [[ "$CURRENT_STATUS" == "new" || "$CURRENT_STATUS" == "updated" ]]; then # If it was recently new/updated but not found in current scan, revert status to 'other' EXISTING_ITEM=$(echo "$EXISTING_ITEM" | jq '.status = "other"') fi jq ". += [$EXISTING_ITEM]" "$NEW_DATA_TEMP" > tmp.$$.json && mv tmp.$$.json "$NEW_DATA_TEMP" fi done # 6. Finalize and save the JSON file jq '.' "$NEW_DATA_TEMP" > "$JSON_FILE" rm "$NEW_DATA_TEMP" echo "Successfully updated '$JSON_FILE'." echo "To view your working projects, open 'workingOn.php' in your web browser." echo "You can manually edit '$JSON_FILE' to add comments or secondary links."