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>
160 lines
4.9 KiB
Bash
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 '}'
|