Created
July 6, 2019 05:58
-
-
Save nexpr/2b8baedaf9693fd17cec433703f9aeb9 to your computer and use it in GitHub Desktop.
github のユーザやグループのリポジトリリストをダイアログで一覧表示する/フォークは除去してスターの降順で並べる/このコードをユーザページで実行すれば使える/実行方法は直接でも拡張機能でもユーザスクリプトでも
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
async function getUserRepositories(username, force_all) { | |
const res = await fetch(`https://api.github.com/users/${username}/repos`) | |
if (!res.ok) { | |
throw { error: "invalid-username", username } | |
} | |
const repos = await res.json() | |
const link = res.headers.get("link") | |
if (link) { | |
const [, next_url, last_url] = link.match(/<(.*?)>; rel="next", <(.*?)>; rel="last"/) || [] | |
const last_page = ~~new URL(last_url).searchParams.get("page") | |
if (!force_all && last_page > 10) { | |
throw { error: "many-page", last: last_page } | |
} | |
for (let page = 2; page < last_page; page++) { | |
await new Promise(r => setTimeout(r, 200)) | |
const url = new URL(next_url) | |
url.searchParams.set("page", page) | |
const page_repos = await (await fetch(url)).json() | |
repos.push(...page_repos) | |
} | |
} | |
return repos | |
} | |
function show(repos) { | |
const div = document.createElement("div") | |
const sroot = div.attachShadow({ mode: "open" }) | |
sroot.innerHTML = ` | |
<style> | |
.bg { | |
position: fixed; | |
z-index: 999999; | |
left: 0; | |
top: 0; | |
width: 100vw; | |
height: 100vh; | |
background: #fffb; | |
display: flex; | |
} | |
.content { | |
display: flex; | |
flex-flow: column; | |
width: 60vw; | |
height: 60vh; | |
margin: auto; | |
border: 2px solid #ddd; | |
background: white; | |
border-radius: 20px; | |
padding: 20px; | |
} | |
.scroller { | |
flex: 1 1 auto; | |
overflow: auto; | |
} | |
h1 { | |
margin: 0 0 10px; | |
} | |
td { | |
padding: 2px 15px; | |
} | |
</style> | |
<div class="bg"> | |
<div class="content"> | |
<h1>Repository List (フォークなし/スター数降順)</h1> | |
<div class="scroller"> | |
<table> | |
<thead> | |
<tr> | |
<th>Rank</th> | |
<th>Stars</th> | |
<th>name</th> | |
<th>Language</th> | |
<th>Description</th> | |
</tr> | |
</thead> | |
<tbody> | |
${repos | |
.map((e, i) => { | |
return ` | |
<tr> | |
<td>${i + 1}</td> | |
<td>${e.stargazers_count}</td> | |
<td><a href="${e.html_url}">${e.full_name}</a></td> | |
<td>${e.language}</td> | |
<td>${esc(e.description)}</td> | |
</tr> | |
` | |
}) | |
.join("")} | |
</tbody> | |
</table> | |
</div> | |
</div> | |
</div> | |
` | |
sroot.addEventListener("click", eve => eve.target.matches(".bg") && div.remove()) | |
document.body.append(div) | |
} | |
function esc(s) { | |
const d = document.createElement("div") | |
d.textContent = s | |
return d.innerHTML | |
} | |
async function main(username, force_all) { | |
try { | |
const repos = await getUserRepositories(username, force_all) | |
const sorted_no_fork_repos = repos.filter(e => !e.fork).sort((a, b) => b.stargazers_count - a.stargazers_count) | |
show(sorted_no_fork_repos) | |
} catch (err) { | |
if (err.error === "invalid-username") { | |
alert(`${err.username} がみつかりません`) | |
} else if (err.error === "many-page") { | |
const will_continue = confirm(`リポジトリ数が多すぎます (${err.last}ページ)\n続行しますか?`) | |
if (will_continue) { | |
main(username, true) | |
} | |
} else { | |
throw err | |
} | |
} | |
} | |
const paths = location.pathname.split("/") | |
if (paths.length === 2 && paths[1] !== "") { | |
main(paths[1], false) | |
} else { | |
alert("このスクリプトはユーザページでのみ実行できます") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment