Skip to content

Instantly share code, notes, and snippets.

@VIRUXE
Created June 18, 2024 14:13
Show Gist options
  • Save VIRUXE/86a72ae8c7dd246bfa257224fe0d0d65 to your computer and use it in GitHub Desktop.
Save VIRUXE/86a72ae8c7dd246bfa257224fe0d0d65 to your computer and use it in GitHub Desktop.
Enumerate source repos and gists for one or multiple user accounts on GitHub
<?php
if (!isset($_GET['username']) && !isset($_GET['usernames'])) {
echo "Usage: gh_source_repos.php?username(s)=username1,username2,...";
exit();
}
$usernames = [];
if (isset($_GET['username']) || isset($_GET['usernames'])) $usernames = array_merge($usernames, explode(",", ($_GET['usernames'] ?? $_GET['username'])));
$all_repos = [];
$headers = stream_context_create([
'http' => [
'method' => 'GET',
'header' => 'User-Agent: curl/7.64.1',
]
]);
foreach ($usernames as $username) {
$API_ENDPOINT = "https://api.github.com/users/{$username}/repos";
$page = 1;
$all_repos[$username] = [];
while (true) {
$url = "{$API_ENDPOINT}?page={$page}";
echo $url . '<br>';
$response = @file_get_contents("{$API_ENDPOINT}?page={$page}", false, $headers);
if ($response === false) {
$status_line = $http_response_header[0];
preg_match('{HTTP\/\S*\s(\d{3})}', $status_line, $match);
$status = $match[1];
echo "Failed to fetch data from GitHub for user {$username}. HTTP Status: {$status}";
exit();
}
$repositories = json_decode($response, true);
if (empty($repositories)) break;
$filtered_repos_names = array_map(
fn($repo) => $repo["name"],
array_filter(
$repositories,
fn($repo) => !$repo["private"] && !$repo["fork"]
)
);
$all_repos[$username]['repos'] = array_merge($all_repos[$username]['repos'] ?? [], $filtered_repos_names);
$page++;
}
// Fetch gists
$response = @file_get_contents("https://api.github.com/users/{$username}/gists", false, $headers);
if ($response === false) {
echo "Failed to fetch gists from GitHub for user {$username}.";
exit();
}
$gists = json_decode($response, true);
$all_repos[$username]['gists'] = count($gists);
}
?>
<!DOCTYPE html>
<html>
<head>
<meta property="og:title" content="GitHub Source Repositories for '<?= implode(", ", $usernames) ?>'">
<meta property="og:description" content="<?= implode(", ", array_map(fn($username) => "$username ({$all_repos[$username]['repos']} repos/{$all_repos[$username]['gists']} gists)", $usernames)) ?>">
<style>
body {
font-family : 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
text-align : center;
display : flex;
justify-content: center;
align-items : center;
flex-direction : column;
height : 100vh;
margin : 0 10%;
}
footer {
position : fixed;
bottom : 0;
left : 0;
right : 0;
padding : 10px;
background: #f8f8f8;
border-top: 1px solid #e0e0e0;
}
</style>
</head>
<body>
<?php
foreach ($all_repos as $username => $data) {
$repoCount = count($data['repos']);
$gistCount = $data['gists'];
$repoList = implode(", ", $data['repos']);
echo <<<HTML
<p id="$username" title="Double-click to copy to clipboard!">
<a href="https://github.com/$username"><strong>$username</strong></a> ($repoCount repos/$gistCount gists): $repoList
</p>
HTML;
}
?>
<footer><a href="https://gist.github.com/VIRUXE/86a72ae8c7dd246bfa257224fe0d0d65">Source Code</a></footer>
<script>
with (document) {
querySelectorAll('p').forEach(p => {
p.addEventListener('dblclick', event => {
event.preventDefault();
var textarea = createElement('textarea');
textarea.value = p.innerText;
body.appendChild(textarea);
textarea.select();
execCommand('copy');
body.removeChild(textarea);
alert(`Copied '${p.id}' to clipboard!`);
});
});
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment