github.com
Preztoはzshの設定ファイルの詰め合わせで,よく書かれた便利な設定をプラグイン機構によって手軽に導入することが出来ます。
私は数ヶ月前にzshの設定ファイルを作り直したときにPreztoを導入しました。とても便利です。
kujira16.hateblo.jp
残念なことに,ここ10ヶ月ほどmasterブランチの更新が無く,先行きが不透明なのでforkを探してみました。
ただ,Preztoはforkが非常に多く,Web上ではforkの一覧を見ることは出来ません(forkして自分の設定ファイルをアップロードしている人が多いためだと思われます)。
そこで,GitHubのAPIを利用して⭐の多いリポジトリを探してみました。
forkの一覧を取得するAPIの説明は以下のページに載っています。
https://developer.github.com/v3/repos/forks/
curl https://api.github.com/repos/sorin-ionescu/prezto/forks
のようにすればデータを取得できそうです。
ただ curl -I
としてレスポンスヘッダを見てみると Link
が付いていることからも分かるように,GitHubのAPIにはページネーションが設定されています。すべてのデータを取得するためにはリクエストパラメータを変えて何度かデータを取得する必要があります。
さらに X-RateLimit-Limit
というヘッダが付いていることからも分かるように,GitHubのAPIは認証なしで利用できる回数に制限があります。先ほどの Link
ヘッダによると105回ほどAPIを利用する必要があるのですが,X-RateLimit-Limit
ヘッダによれば認証なしでは60回しかAPIを利用できないようです。この制限については以下のページで説明があります。
https://developer.github.com/v3/#rate-limiting
認証の方法については上記のページの Authentication
の節で説明があります。アクセストークンを取得してリクエストヘッダかリクエストパラメータに付与すれば良いことがわかります。必要なアクセストークンは以下のページで取得できます。
https://github.com/settings/tokens
クローラを作る
forkしたリポジトリを全件取得するために以下のようなクローラを作りました(実際にはJupyter Notebook上で実行しました)。
HTTPリクエストの処理にはrequestsを使いました。認証のためのOAuthトークンを付けるために requests.get
の headers
オプション,Link
ヘッダをたどるために resp.links
,レスポンスの内容をJSONとして取り出すために resp.json()
を使っています。
ダウンロードしたデータの保存にはLevelDBを使いました。LevelDBはサーバーを用意することなく使えるKVSで,高度なことをしなければ Get
, Put
, Delete
, RangeIter
だけ覚えておけばそれなりに使えます。ただ byte以外のオブジェクトはkeyにもvalueにも受け付けてくれないので,strならencodeしたり,それ以外のオブジェクトならpickleでダンプしておく必要があります。
import leveldb
import requests
import pickle
def download(db, url, headers):
try:
resp_byte = db.Get(url.encode('UTF-8'))
return pickle.loads(resp_byte)
except KeyError:
resp = requests.get(url, headers=headers)
db.Put(url.encode('UTF-8'), pickle.dumps(resp))
return resp
db = leveldb.LevelDB('forks.leveldb')
token = 'XXXXXXXXXX'
headers = {'Authorization': 'token ' + token}
url = 'https://api.github.com/repos/sorin-ionescu/prezto/forks'
resp = download(db, url, headers)
while 'next' in resp.links:
url = resp.links['next']['url']
resp = download(db, url, headers)
for key, value in db.RangeIter():
resp = pickle.loads(value)
for repos in resp.json():
star = repos['stargazers_count']
if star >= 5:
print(star, repos['full_name'])
リクエストとリクエストの間には特に時間間隔を空けていないのですが,前述の通りリクエスト回数に制限が設けてあるので,それさえ守っておけばいいのかなと思っています。
結果
forkの中で5件以上スターがついているリポジトリは今日の時点で以下のものだけです。
最近のコミットがあるのは zsh-users のものだけでした。
結論
それなりに活発なforkは以下のリポジトリです。
github.com
本家の状況によってはこちらに乗り換えることも検討します。