Skip to content

Instantly share code, notes, and snippets.

@martinwoodward
Last active August 22, 2022 14:12
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save martinwoodward/288812fa142e0b1153f60b9555b3d978 to your computer and use it in GitHub Desktop.
Save martinwoodward/288812fa142e0b1153f60b9555b3d978 to your computer and use it in GitHub Desktop.
Very quick ruby script to create a bash script that will create a montage of your org.
# Set OCTOKIT_ACCESS_TOKEN to authenticate with a PAT
# Something like OCTOKIT_ACCESS_TOKEN=<<TOKEN>> bundle exec ruby create-org-montage-script.rb
require "octokit"
Octokit.auto_paginate = true
# Replace <<ORG_NAME>> with your GitHub org
members = Octokit.org_members "<<ORG_NAME>>"
open('org-montage.sh', 'w') { |f|
# Yeah, I'm creating a bash script in Ruby - bite me
f << "#!/bin/bash\n"
members.each do |m|
f << "curl " + m[:avatar_url] + " --output images/" + m[:id].to_s + ".jpg\n"
end
# Uses 'montage' command from ImageMagick (apt install imagemagick)
# http://www.imagemagick.org/Usage/montage/
# You probably want to play with the number across here to get a 16:9 image.
# I'm creating an image that is 58 images wide made up of 48x48 pixel tiles.
f << "montage images/*.jpg -resize 48x48 -mode Concatenate -tile 58x ghmontage.jpg\n"
}
@andyfeller
Copy link

andyfeller commented Aug 19, 2022

THANK YOU!

Looking to contribute to this amazing idea, here's a version that essentially wraps gh CLI to pull the info from GraphQL. I'd love to turn this into a GitHub CLI extension. Any and all feedback appreciated, @martinwoodward

#! /bin/bash

AVATARPIXELS=48
MONTAGEWIDTH=58
ORGANIZATION=
PRESERVE=false
TEAM=

__USAGE="
GitHub team member montage generator.

Usage: $(basename $0) [options] -o <organization> -t <team>

Options:
	-a, --avatar-pixels <pixels>        Size of GitHub avatar icons in pixels
	-d, --debug                         Enable debugging
	-m, --montage-width <icons>         Width of GitHub montage in number of avatar icons
	-o, --organization <organization>   Organization slug / login
	-p, --preserve                      Preserve temporary directory containing data
	-t, --team <team>                   Team slug / login
";

die() {
	printf "\nError: %s\n" "$1"
	echo "$__USAGE"
	exit 1
}

if ! command -v gh &> /dev/null; then
	die "'gh' could not be found"
fi

if ! command -v montage &> /dev/null; then
	die "'montage' could not be found"
fi


while getopts "a:dhm:o:pt:-:" OPT; do
	if [ "$OPT" = "-" ]; then    # long option: reformulate OPT and OPTARG
		OPT="${OPTARG%%=*}"      # extract long option name
		OPTARG="${OPTARG#$OPT}"	 # extract long option argument (may be empty)
		OPTARG="${OPTARG#=}"     # if long option argument, remove assigning `=`
	fi

	case "$OPT" in

		avatar-pixels | a)
			AVATARPIXELS="${OPTARG}"
			echo "Avatar pixels: $AVATARPIXELS"
			;;

		debug | d)
			set -x
			;;

		help | h)
			echo "$__USAGE"
			exit 0
			;;

		montage-width | m)
			MONTAGEWIDTH="${OPTARG}"
			echo "Montage width: $MONTAGEWIDTH"
			;;

		organization | o)
			ORGANIZATION="${OPTARG}"
			echo "Organization: $ORGANIZATION"
			;;

		preserve | p)
			echo "Preserving temporary directory"
			PRESERVE=true
			;;

		team | t)
			TEAM="${OPTARG}"
			echo "Team: $TEAM"
			;;
	esac
done

if [ -z "${ORGANIZATION}" ]; then
	die "Must provide organization"
fi

if [ -z "${TEAM}" ]; then
	die "Must provide team"
fi


TMPDIR="$(mktemp -d -t github-montage)"
TMPFILE="$TMPDIR/generate-montage.sh"
MONTAGEFILE="$ORGANIZATION-$TEAM.jpg"

echo "Created temporary directory for generating GitHub montage:  $TMPDIR"

if ! $PRESERVE; then
	trap 'rm -rf -- "$TMPDIR"' EXIT
fi

gh api graphql --paginate -F login="$ORGANIZATION" -F slug="$TEAM" -F size="$AVATARPIXELS" -f query='
	query GetOrgTeamAvatars($login: String!, $slug: String!, $size: Int!, $endCursor: String) {
	  organization(login: $login) {
		team(slug: $slug) {
		  members(first: 10, after: $endCursor) {
			pageInfo {
			  endCursor
			  hasNextPage
			}
			nodes {
			  avatarUrl(size: $size)
			  databaseId
			}
		  }
		}
	  }
	}' --template "{{ range .data.organization.team.members.nodes }}
curl -s \"{{ .avatarUrl }}\" --output $TMPDIR/{{ .databaseId }}.jpg{{ end }}" >> $TMPFILE

cat << EOF >> $TMPFILE

montage $TMPDIR/*.jpg -mode Concatenate -tile ${MONTAGEWIDTH}x $MONTAGEFILE
EOF

/bin/bash $TMPFILE
echo "Created montage image:  $MONTAGEFILE"

@andyfeller
Copy link

For posterity, this work has been incorporated into https://github.com/andyfeller/gh-montage as an easy to use GitHub CLI extension!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment