Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

如何用一个仓库记录自己的一年 #209

Open
yihong0618 opened this issue May 28, 2021 · 41 comments
Open

如何用一个仓库记录自己的一年 #209

yihong0618 opened this issue May 28, 2021 · 41 comments
Labels
Top Top label of gitblog 技术文章 技术文章

Comments

@yihong0618
Copy link
Owner

yihong0618 commented May 28, 2021

写在前面

从最开始的用 GitHub 的 Issues 写博客,到尝试用 GitHub 记录的年度数据已经二年有余了,从最开始有想法 2020, 到 2021 加了很多功能,把大部分的记录自动化,一点一点记录也算是有些心得了,这篇文章就介绍一下我是怎么做的,能帮助到同样感兴趣的大家就更好了。也算是践行这 2 年对我影响最大的文章之一

People Die, but Long Live GitHub

GitHub 的一个 repo 能做什么?

  1. 能记录 Issues
  2. Issues 可以评论
  3. 能给 Issue 打标签
  4. 能有一张展示的 README
  5. README 能引入 svg
  6. 有 Actions 可以辅助自动化
  7. Actions 可以放 secrets
  8. 可以用 cron 和各种事件触发 Actions
  9. API 公开,可以自己 DIY
  10. 有手机应用,不用开电脑能随时随地记录
  11. 有评论区
  12. 私有仓库这些以上的都有

好,我们把这些结合起来,记录自己的一年~

数字区

image
上图这些数字区是怎么实现方式分为两部分:

  • API 获取 -- 扇贝,开心词场,多邻国
  • Issues 配合 labels 获取,俯卧撑,花费。。。

每天早 8 点和晚 9 点,定时跑一次,计算数据进行整合,并配合 telegram 的 bot 提醒自己。
入口大家可以参考 Actions 的这个 workflow

Issues 的代码思路为获取 label -> 通过 label 找 issues -> issues 的评论特定格式 -> 通过函数解析 -> 整合 -> 通过正则替换 README 中的原有数据(文字) (README 可以写注释,而注释是不显示的,利用这个完成显示和替换)

def main(
    login_dict,
    github_token,
    repo_name,
):
    my_num_stat_str = MY_NUMBER_STAT_HEAD
    # API STAT STR
    for name, value_dict in MY_STATUS_DICT_FROM_API.items():
        try:
            url = value_dict.get("url")
            md_name = f"[{name}]({url})"
            # maybe a better way?
            total_data, streak, today_check = value_dict.get("daily_func")(
                *login_dict.get(name, tuple())
            )
            total_data_str = str(total_data) + value_dict.get("unit_str", "")
            my_num_stat_str += make_stat_str(
                md_name, total_data_str, streak, today_check
            )
        # just a tricky code for others for use
        except Exception as e:
            print(e)
            continue

    u = Github(github_token)
    # COMMENTS STAT STR
    for name, value_dict in MY_STATUS_DICT_FROM_COMMENTS.items():
        try:
            labels, map_func, reduce_func = LABEL_DAILY_DICT.get(name)
        except:
            # tricky for mine
            continue
        func = value_dict.get("daily_func")
        if not func:
            break

        issues = u.get_repo(repo_name).get_issues(labels=labels)
        total_data, streak, today_check, url, month_summary_dict = func(
            issues, map_func, reduce_func
        )
        # change the issue body for month summary
        unit = value_dict.get("unit_str", "")
        for i in issues:
            body = ""
            for b in i.body.splitlines():
                # from the summary table
                if b.startswith("|"):
                    break
                body += b + "\r\n"
            body = body + "\r\n" + make_month_summary_str(month_summary_dict, unit)
            # edit this issue body
            i.edit(body=body)
        name = f"[{name}]({url})"
        total_data_str = str(total_data) + unit
        my_num_stat_str += make_stat_str(name, total_data_str, streak, today_check)

    replace_readme_comments("README.md", my_num_stat_str, "my_number")

多说几句早起

关于早起这个数据和 issue 因为自己喜欢诗歌,我找了一个获取一句诗的 API, 然后自动评论,评论是带时间戳的,正好记录自己的起床时间。
那么是怎么触发的呢?
我用的是 iOS 系统,而 iOS 有个重要的功能是“捷径“。利用捷径可以触发 Actions workflow 的 api, 触发 api 就有时间戳了,再判断是不是早起,给自己发送就好了。
捷径的触发条件是闹钟关闭,为了保险起见,我可能比闹钟起的早,再加一条关闭背单词软件,解决了用 GitHub 记录早起的问题。

def make_get_up_message():
    sentence = get_one_sentence()
    now = pendulum.now(TIMEZONE)
    # 3 - 6 means early for me
    is_get_up_early = 3 <= now.hour <= 6
    get_up_time = now.to_datetime_string()
    body = GET_UP_MESSAGE_TEMPLATE.format(get_up_time=get_up_time, sentence=sentence)
    return body, is_get_up_early

关于如何利用捷径配合 Actions 我写过一篇文章 -- 巧妙利用 iOS 的快捷指令配合 GitHub Actions 实现自动化
image
而早起这句诗,我期待好久的 -- 苟利国家生死以,岂因福祸避趋之。还没随机到,随到这一天我决定跑 19.26 km.

GitHubPost 区

利用了我写的 GitHubPoster 项目,自动生成 svg 引入,而自动跑的脚本也在那个项目上。
image

GitHub Repos 区

利用我写的 github-readme-stats 自动替换生成。
image
image

娱乐区

全部利用 Issues 评论 -> 触发 Actions -> 自动替换 README 的注释区域生成
image

def replace_readme_comments(file_name, comment_str, comments_name):
    with open(file_name, "r+") as f:
        text = f.read()
        # regrex sub from github readme comments
        text = re.sub(
            GITHUB_README_COMMENTS.format(name=comments_name),
            r"\1{}\n\3".format(comment_str),
            text,
            flags=re.DOTALL,
        )
        f.seek(0)
        f.write(text)
        f.truncate()

做饭区

和上面类似,因为做的太多,我生成了个表格
image

def parse_cook_issue_table(me, issues):
    comments_str = MY_FOOD_STAT_HEAD
    food_dict = defaultdict(lambda: ["", "", 0])
    for issue in issues:
        comments = issue.get_comments()
        for c in comments:
            if not isMe(c, me):
                continue
            date_str = format_time(c.created_at)
            food_list_str = c.body.splitlines()[0]
            food_list = food_list_str.split(" ")
            for food in food_list:
                if food not in food_dict:
                    food_dict[food][0] = f"[{date_str}]({c.html_url})"
                    food_dict[food][1] = f"[{date_str}]({c.html_url})"
                else:
                    food_dict[food][1] = f"[{date_str}]({c.html_url})"
                food_dict[food][2] += 1
    for k, v in food_dict.items():
        comments_str += MY_FOOD_STAT_TEMPLATE.format(
            name=k, first_date=v[0], last_date=v[1], times=v[2]
        )
    return comments_str

月度数据

每次自动生成还会 edit issue 的内容生成月度数据整合
image

博客区

在 blog 的 repo 写 issue ->curl 2021 的 Actions workflow api -> 自动生成
image
image

收藏文章博客区

这个完全手动添加,我想保留一些仪式感
image

我也想做一个

如果大家想同样做一个这样的年度数据可以 follow 以下步骤:

  1. fork or clone 这个项目
  2. 增加 issues 打 label
  3. 修改 config
  4. 修改一些 api 的 config 数据换成自己的
  5. 如果有问题可以邮件或私信我
COOK_LABEL_LIST = [
    "Cook",
]
MOVIE_LABEL_LIST = [
    "Movie",
]
READ_LABEL_LIST = [
    "Read",
]
DRAMA_LABEL_LIST = [
    "Drama",
]
PUSHUP_LABEL_LIST = [
    "PushUps",
]
BANGUMI_LABEL_LIST = [
    "Bangumi",
]
GAME_LABEL_LIST = [
    "Game",
]
MONEY_LABEL_LIST = [
    "Money",
]
MEDITATION_LABEL_LIST = [
    "Meditation",
]
MORNING_LABEL_LIST = [
    "Morning",
]
GTD_LABEL_LIST = [
    "GTD",
]
MY_BLOG_REPO = "yihong0618/gitblog"
GITHUB_README_COMMENTS = (
    "(<!--START_SECTION:{name}-->\n)(.*)(<!--END_SECTION:{name}-->\n)"
)

# add new label here
LABEL_DICT = {
    "Cook": {"label_list": COOK_LABEL_LIST, "comment_name": "my_cook"},
    "Movie": {"label_list": MOVIE_LABEL_LIST, "comment_name": "my_movie"},
    "Read": {"label_list": READ_LABEL_LIST, "comment_name": "my_read"},
    "Drama": {"label_list": DRAMA_LABEL_LIST, "comment_name": "my_drama"},
    "Bangumi": {"label_list": BANGUMI_LABEL_LIST, "comment_name": "my_bangumi"},
    "Game": {"label_list": GAME_LABEL_LIST, "comment_name": "my_game"},
}


##### SHANBAY ######
MY_SHANBAY_USER_NAME = "ufewz"
SHANBAY_CALENDAR_API = "https://apiv3.shanbay.com/uc/checkin/calendar/dates/?user_id={user_name}&start_date={start_date}&end_date={end_date}"
MY_SHANBAY_URL = f"https://web.shanbay.com/web/users/{MY_SHANBAY_USER_NAME}/zone"

##### DUO ######
MY_DUOLINGO_URL = "https://www.duolingo.com/profile/yihong0618"

##### CICHANG ######
MY_CICHANG_URL = "https://twitter.com/yihong06181/status/1359040099107897344?s=20"


##### FOOD ######
MY_FOOD_STAT_HEAD = (
    "| Name | First_date | Last_date | Times | \n | ---- | ---- | ---- | ---- |\n"
)
MY_FOOD_STAT_TEMPLATE = "| {name} | {first_date} | {last_date} | {times} |\n"

##### Month Summary ######
MONTH_SUMMARY_HEAD = "| Month | Number | \n | ---- | ---- | \n"

MONTH_SUMMARY_STAT_TEMPLATE = "| {month} | {number} |\n"
@ruter
Copy link

ruter commented May 28, 2021

So cool!

@MFYDev
Copy link

MFYDev commented May 28, 2021

That is so cool and geek! Awesome!

@yihong0618
Copy link
Owner Author

如果不想公开自己的信息,所有以上的东西,私有仓库都可以做的。

@aaashuai
Copy link

帅啊!

@madawei2699
Copy link

学习了

@humyna
Copy link

humyna commented Jun 1, 2021

👍

@askming
Copy link

askming commented Jun 2, 2021

厉害,准备学习实践一下

@yihong0618
Copy link
Owner Author

厉害,准备学习实践一下

好的哈哈,有点个人向,代码不是很通用,有问题随时交流。

@donychen1134
Copy link

学习了,不仅是有效的工具,还有自律、坚持的品质

@taseikyo
Copy link

taseikyo commented Jun 8, 2021

很棒的想法!看得我也想尝试一下了😸

@Daydog
Copy link

Daydog commented Jun 13, 2021

我在https://www.tomatolist.com/ 上面记录自己的番茄用时,不知道能不能调用API,自动统计到数字区

@yihong0618
Copy link
Owner Author

我在https://www.tomatolist.com/ 上面记录自己的番茄用时,不知道能不能调用API,自动统计到数字区

有 api 的话想想办法可以。

@yihong0618
Copy link
Owner Author

全部改成了表格

@supercaizehua
Copy link

学习了

@Daydog
Copy link

Daydog commented Sep 14, 2021

image
请问在这一步出现这个error,get daily 这个模块无法更新,需要需改哪里

@yihong0618
Copy link
Owner Author

image

请问在这一步出现这个error,get daily 这个模块无法更新,需要需改哪里

随便写点啥,别空着,这块我没考虑边界(^^)

@Daydog
Copy link

Daydog commented Sep 14, 2021

image
请问在这一步出现这个error,get daily 这个模块无法更新,需要需改哪里

随便写点啥,别空着,这块我没考虑边界(^^)

写了文字后,俯卧撑记录出现月度统计,但是报如下错误,- _-!
image

@yihong0618
Copy link
Owner Author

第一行是数字

@Daydog
Copy link

Daydog commented Sep 20, 2021

image
请问出现这个报错怎么办

@yihong0618
Copy link
Owner Author

image
请问出现这个报错怎么办

你是把 requirements.txt 删了么?

@Daydog
Copy link

Daydog commented Sep 27, 2021

image
请问出现这个报错怎么办

你是把 requirements.txt 删了么?

我检查了一下,没有删requirements.txt,除了会报错之外,readme居然是正常自动更新的,也就是报错了,但是程序还正常跑了

有一个issue不知在哪里提合适,就是“月度数据” 汇总那里好像只支持整数,能支持小数点后多几位就好了

@yihong0618
Copy link
Owner Author

image
请问出现这个报错怎么办

你是把 requirements.txt 删了么?

我检查了一下,没有删requirements.txt,除了会报错之外,readme居然是正常自动更新的,也就是报错了,但是程序还正常跑了

有一个issue不知在哪里提合适,就是“月度数据” 汇总那里好像只支持整数,能支持小数点后多几位就好了

可以支持的。。你需要看懂里面的代码。。。转成 float 就行了。

@Daydog
Copy link

Daydog commented Sep 27, 2021

可以支持的。。你需要看懂里面的代码。。。转成 float 就行了。

https://github.com/yihong0618/2021/blob/main/get_daily.py#L96
我猜应该是这里int变成float

@awaityou
Copy link

请问出现这个报错怎么办
llll

@yihong0618
Copy link
Owner Author

请问出现这个报错怎么办 llll

需要配置 token 到 secrets 里,并在 yml 里更改
这里可能你得拉下最新代码。

@zerone0x
Copy link

感谢分享,太棒的想法!

@jaydillon
Copy link

感谢分享

@lesnolie
Copy link

你好,迁移到2023年以后,数字区无论怎么改ISSUE,README都没有反应,无法生成数字区。
主要是周记和GTD。
如图:
image
耗了一天,实在不知道如何解决。请教一下是哪里出了问题。
万分感谢

@yihong0618
Copy link
Owner Author

@lesnolie 你的 repo 是?

@lesnolie
Copy link

不好意思忘记添加了,在这里。

https://github.com/lesnolie/2023

@yihong0618
Copy link
Owner Author

@lesnolie
本地跑在这加 print 看看哪里有问题
image

@yihong0618
Copy link
Owner Author

@lesnolie 明天我找时间帮你看看

@lesnolie
Copy link

lesnolie commented Feb 1, 2023

谢谢大佬🙏

@yihong0618
Copy link
Owner Author

@lesnolie

把你项目这个文件
https://github.com/lesnolie/2023/blob/main/get_daily.py#L98

最下面加上

    main(
        {},
        options.github_token,
        options.repo_name,
    )

@lesnolie
Copy link

lesnolie commented Feb 1, 2023

最下面

正常了,非常感谢

@QiYongchuan
Copy link

您好,我遇到了一个问题是action显示正常,但是无法更新README,在查看push这一步时,显示403 权限问题,在我问了gpt后,建议我设置 Git 远程 URL 的步骤,但是仍然没有解决问题。
image

QiYongchuan/MyGitBlog#38

@yihong0618
Copy link
Owner Author

您好,我遇到了一个问题是action显示正常,但是无法更新README,在查看push这一步时,显示403 权限问题,在我问了gpt后,建议我设置 Git 远程 URL 的步骤,但是仍然没有解决问题。 image

QiYongchuan/MyGitBlog#38

在设置里增加写的权限

@QiYongchuan
Copy link

您好,我遇到了一个问题是action显示正常,但是无法更新README,在查看push这一步时,显示403 权限问题,在我问了gpt后,建议我设置 Git 远程 URL 的步骤,但是仍然没有解决问题。 image
QiYongchuan/MyGitBlog#38

在设置里增加写的权限

谢谢大佬! 我的终于成功啦! 期间踩了不少的坑,一度放弃了,但看到最后在README页更新那一刻,真爽

@dululu
Copy link

dululu commented Jan 1, 2024

😹

@haowang-bioinfo
Copy link

我用GitHub repo做记录差不多有三年了。
看到这个issue之后,真是让我大开眼界 👍 学习中 🤝

@yihong0618
Copy link
Owner Author

我用GitHub repo做记录差不多有三年了。 看到这个issue之后,真是让我大开眼界 👍 学习中 🤝

握手!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Top Top label of gitblog 技术文章 技术文章
Projects
None yet
Development

No branches or pull requests