ProjectTracker/tools/activity-scan.sh
StillHammer 5340baaa04 Add activity-scan.sh for on-demand repo scanning
Script for maicivy to fetch activity feed on-demand:
- Scans all git repos in REPOS_DIR
- Outputs JSON matching activity-feed.json spec
- Configurable showcase repos and GitHub URLs
- Default path: /home/debian

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 11:05:56 +07:00

160 lines
4.9 KiB
Bash

#!/bin/bash
#
# activity-scan.sh - Scan repos and output activity feed JSON
# Usage: ./activity-scan.sh [REPOS_DIR]
#
# Output format matches activity-feed.json spec for maicivy CV
#
set -e
REPOS_DIR="${1:-/home/debian}"
# Repos to showcase on CV
SHOWCASE_REPOS="maicivy vba-mcp-server vba-mcp-monorepo groveengine confluent seogeneratorserver civjdr videotoMP3Transcriptor freelance-dashboard freelance-notify timetrack-pro CTPL"
# GitHub URLs mapping (repo_name -> github_url)
declare -A GITHUB_URLS=(
["maicivy"]="https://github.com/AlexisTrouve/maicivy"
["confluent"]="https://github.com/AlexisTrouve/confluent"
["groveengine"]="https://github.com/AlexisTrouve/GroveEngine"
["vba-mcp-server"]="https://github.com/AlexisTrouve/vba-mcp-server"
["vba-mcp-monorepo"]="https://github.com/AlexisTrouve/vba-mcp-server"
["timetrack-pro"]="https://github.com/AlexisTrouve/timetrack-pro"
["freelance-dashboard"]="https://github.com/AlexisTrouve/freelance-dashboard"
["freelance-notify"]="https://github.com/AlexisTrouve/freelance-notify"
["RedditSaveSaver"]="https://github.com/AlexisTrouve/RedditSaveSaver"
["CTPL"]="https://github.com/AlexisTrouve/CTPL"
)
# Category mapping
declare -A CATEGORIES=(
["maicivy"]="WIP"
["vba-mcp-server"]="WIP"
["vba-mcp-monorepo"]="WIP"
["groveengine"]="WIP"
["confluent"]="WIP"
["seogeneratorserver"]="WIP"
["civjdr"]="CONSTANT"
["videotoMP3Transcriptor"]="DONE"
["freelance-dashboard"]="WIP"
["freelance-notify"]="WIP"
["timetrack-pro"]="WIP"
["CTPL"]="DONE"
)
# Escape JSON string
json_escape() {
printf '%s' "$1" | python3 -c 'import json,sys; print(json.dumps(sys.stdin.read())[1:-1])'
}
# Get languages from file extensions
get_languages() {
local repo_dir="$1"
cd "$repo_dir" 2>/dev/null || return
git ls-files 2>/dev/null | sed 's/.*\.//' | sort | uniq -c | sort -rn | head -5 | while read count ext; do
case "$ext" in
go) echo "Go" ;;
ts|tsx) echo "TypeScript" ;;
js|jsx) echo "JavaScript" ;;
py) echo "Python" ;;
rs) echo "Rust" ;;
cpp|cc|cxx|hpp) echo "C++" ;;
c|h) echo "C" ;;
rb) echo "Ruby" ;;
java) echo "Java" ;;
sh|bash) echo "Shell" ;;
sql) echo "SQL" ;;
*) ;;
esac
done | sort -u | head -4 | tr '\n' ',' | sed 's/,$//'
}
# Start JSON output
echo '{'
echo ' "last_updated": "'$(date -Iseconds)'",'
echo ' "projects": ['
first=true
total_commits_30d=0
active_count=0
for repo_path in "$REPOS_DIR"/*/; do
[ -d "$repo_path/.git" ] || continue
name=$(basename "$repo_path")
cd "$repo_path" 2>/dev/null || continue
# Get commit counts
commits_7d=$(git log --since="7 days ago" --oneline 2>/dev/null | wc -l | tr -d ' ')
commits_30d=$(git log --since="30 days ago" --oneline 2>/dev/null | wc -l | tr -d ' ')
total_commits_30d=$((total_commits_30d + commits_30d))
[ "$commits_30d" -gt 0 ] && active_count=$((active_count + 1))
# Check if showcase
showcase="false"
[[ " $SHOWCASE_REPOS " =~ " $name " ]] && showcase="true"
# Get category
category="${CATEGORIES[$name]:-WIP}"
# Get URLs
github_url="${GITHUB_URLS[$name]:-null}"
[ "$github_url" != "null" ] && github_url="\"$github_url\""
gitea_remote=$(git remote get-url origin 2>/dev/null || echo "")
if [[ "$gitea_remote" == *"git.etheryale.com"* ]]; then
repo_url="\"https://git.etheryale.com/StillHammer/$name\""
else
repo_url="null"
fi
# Get description from README or empty
description=""
if [ -f "README.md" ]; then
description=$(head -20 README.md | grep -E "^[A-Za-z]" | head -1 | cut -c1-150)
fi
description=$(json_escape "$description")
# Get languages
languages=$(get_languages "$repo_path")
# Get recent commits (last 3)
recent_commits=""
while IFS='|' read -r sha msg date author; do
[ -z "$sha" ] && continue
msg=$(json_escape "$msg")
[ -n "$recent_commits" ] && recent_commits="$recent_commits,"
recent_commits="$recent_commits{\"sha\":\"$sha\",\"message\":\"$msg\",\"date\":\"$date\",\"author\":\"$author\"}"
done < <(git log -3 --format="%h|%s|%aI|%an" 2>/dev/null)
# Output JSON
$first || echo ','
first=false
cat <<EOJSON
{
"name": "$name",
"description": "$description",
"repo_url": $repo_url,
"github_url": $github_url,
"category": "$category",
"showcase": $showcase,
"languages": [$(echo "$languages" | sed 's/\([^,]*\)/"\1"/g')],
"commits_7d": $commits_7d,
"commits_30d": $commits_30d,
"recent_commits": [$recent_commits]
}
EOJSON
done
echo ' ],'
echo ' "stats": {'
echo ' "total_commits_30d": '$total_commits_30d','
echo ' "active_projects": '$active_count','
echo ' "showcase_count": '$(echo "$SHOWCASE_REPOS" | wc -w)
echo ' }'
echo '}'