一直有一个想法:把 GitHub 上加星的仓库做成一个列表或者其他便于浏览查找的形式。今天,我就发现了这种工具。趁着午休,把它用上了,展示仓库:tianheg/stars。
该仓库中包含的这个列表是基于一个名为 starred
的 pip 包生成的,再通过
GitHub Action
持续集成,达到每天自动生成列表的目的。该仓库地址:maguowei/starred。
接下来记录整个过程:
一、
新建一个名字任意的仓库,新建文件名为 ci.yml
路径为
=~/.github/workflows/ci.yml=,并存放以下内容:
name: update stars # GitHub Action 的名字 on: workflow_dispatch: # 为了手动部署,查看运行过程 schedule: - cron: '00 0 * * *' # 定时:此时的时间是 08:00 CST – China Standard Time jobs: awesome-stars: name: update awesome-stars runs-on: ubuntu-latest # 运行在最新的 Ubuntu 环境中,即 Ubuntu 20.04 steps: - uses: actions/checkout@v1 - name: Set up Python uses: actions/setup-python@v1 with: python-version: 3.7 # 安装 3.7 版本的 python - name: Install dependencies # 更新 pip,安装 starred 包 run: | python -m pip install --upgrade pip pip install starred - name: update repo env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: starred --username tianheg --repository stars --sort --token ${GITHUB_TOKEN} --message 'stars update by github actions cron' # 执行生成 stars 列表的操作
手动运行该 GitHub Action,即生成一个属于你自己的 stars 列表,这是我的:
二、
我们来读读 starred
的代码,地址:maguowei/starred/blob/master/starred/starred.py:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
from io import BytesIO
from collections import OrderedDict
import click
from github3 import GitHub
from github3.exceptions import NotFoundError
from starred import VERSION
desc = '''# Awesome Stars [![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d730\
5f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/sindresorhus/awesome)
> A curated list of my GitHub stars! Generated by [starred](https://github.com/maguowei/starred)
## Contents
'''
license_ = '''
## License
[![CC0](http://mirrors.creativecommons.org/presskit/buttons/88x31/svg/cc-zero.svg)]\
(https://creativecommons.org/publicdomain/zero/1.0/)
To the extent possible under law, [{username}](https://github.com/{username})\
has waived all copyright and related or neighboring rights to this work.
'''
html_escape_table = {
">": ">",
"<": "<",
}
def html_escape(text):
"""Produce entities within text."""
return "".join(html_escape_table.get(c, c) for c in text)
@click.command()
@click.option('--username', envvar='USER', help='GitHub username')
@click.option('--token', envvar='GITHUB_TOKEN', help='GitHub token')
@click.option('--sort', is_flag=True, help='sort by language')
@click.option('--repository', default='', help='repository name')
@click.option('--message', default='update stars', help='commit message')
@click.version_option(version=VERSION, prog_name='starred')
def starred(username, token, sort, repository, message):
"""GitHub starred
creating your own Awesome List used GitHub stars!
example:
starred --username maguowei --sort > README.md
"""
if repository:
if not token:
click.secho('Error: create repository need set --token', fg='red')
return
file = BytesIO()
sys.stdout = file
else:
file = None
gh = GitHub(token=token)
stars = gh.starred_by(username)
click.echo(desc)
repo_dict = {}
for s in stars:
language = s.language or 'Others'
description = html_escape(s.description).replace('\n', '') if s.description else ''
if language not in repo_dict:
repo_dict[language] = []
repo_dict[language].append([s.name, s.html_url, description.strip()])
if sort:
repo_dict = OrderedDict(sorted(repo_dict.items(), key=lambda l: l[0]))
for language in repo_dict.keys():
data = u' - [{}](#{})'.format(language, '-'.join(language.lower().split()))
click.echo(data)
click.echo('')
for language in repo_dict:
click.echo('## {} \n'.format(language.replace('#', '# #')))
for repo in repo_dict[language]:
data = u'- [{}]({}) - {}'.format(*repo)
click.echo(data)
click.echo('')
click.echo(license_.format(username=username))
if file:
try:
rep = gh.repository(username, repository)
readme = rep.readme()
readme.update(message, file.getvalue())
except NotFoundError:
rep = gh.create_repository(repository, 'A curated list of my GitHub stars!')
rep.create_file('README.md', 'starred initial commit', file.getvalue())
click.launch(rep.html_url)
if __name__ == '__main__':
starred()
- 4 - 10 行是引用的类库
- 13 - 30 是生成的 README.md 中的文字叙述
- 42 - 48 是命令指示