python入门系列(一): github自动更新readme脚本

前情提示:
1,本人已有过相关编程基础,所以基本围绕着如何使用pythone构建一个脚本。例如本篇教程的起因是想要在github上执行自动化脚本更新readme。
2,所用编辑器为pycharm。

正文

1, 安装第三方模块

py的依赖安装是安装python解释器的环境,而pythone的环境又分为全局环境、虚拟环境。 这一点非常重要,因为通常来说,我们执行的脚本都不会去特地的创建一个虚拟环境,他们只要求使用pip安装全局环境,然后在脚本中直接使用import导入即可。

官方文档直译:
pip是首选的安装程序。从Python 3.4开始,它默认包含在Python二进制安装程序中。

虚拟环境是一个半隔离的Python环境,它允许为特定应用程序安装包使用,而不是安装到整个系统中。

venv是创建虚拟环境的标准工具,自Python 3.3以来一直是Python的一部分。从Python 3.4开始,它会默认在所有创建的虚拟环境中安装pip。

virtualenv是venv的一个第三方替代品(也是其前身)。它允许在3.4之前的Python版本中使用虚拟环境,这些版本或者根本不提供venv,或者无法自动将pip安装到创建的环境中。

Python软件包索引是公开发布的一组开源授权的软件包的公共仓库,供其他Python用户使用。

Python打包权威机构是负责维护和发展标准打包工具、相关元数据和文件格式标准的开发者和文档作者组成的团队。他们在GitHub上维护多种工具、文档和问题跟踪器。

distutils是最初的构建和分发系统,于1998年首次添加到Python标准库中。虽然直接使用distutils正在逐渐淘汰,但它仍然为当前打包和分发基础设施奠定了基础,它不仅仍然是标准库的一部分,而且其名称还以其他方式流传至今(例如用于协调Python打包标准开发的邮件列表的名称)。


基本用法
标准打包工具都设计为通过命令行使用。

以下命令将从Python软件包索引安装模块的最新版本及其依赖项:

python -m pip install SomePackage

注意 对于POSIX用户(包括macOS和Linux用户),本指南中的示例假设使用虚拟环境。
对于Windows用户,本指南中的示例假设在安装Python时选择了调整系统PATH环境变量的选项。

也可以直接在命令行中指定确切的或最低版本。当使用会被shell解释的比较运算符(如>、<)或其他特殊字符时,软件包名称和版本应用双引号括起来:

python -m pip install SomePackage==1.0.4    # 特定版本
python -m pip install "SomePackage>=1.0.4"  # 最低版本
通常,如果已安装了合适的模块,再次尝试安装将不会产生任何效果。升级现有模块必须显式请求:

python -m pip install --upgrade SomePackage

扩展:
使用配置文件安装

python -m pip install --upgrade pip # 升级pip版本
python -m pip install -r requirements.txt # 根据文件配置安装模块的环境当中

requirements.txt内容
requests>=2.25.0
feedparser>=6.0.0
PyGithub>=1.55

2,编写代码

经过第一步,我们已经可以完成常规开发中导包操作,接下来就是编写,而这一部分得以当下的ai和封装思想,外行人知道一点基本语法即可,至于api本身是需要积累的,个人认为不必要追求深入了解。

本次教程实现的脚本

from github import Github
from github import Auth
from datetime import datetime, timedelta
import pytz
import os


# getlist(g)  获取需要的仓库列表
def getlist(g):
    all_repos = g.get_user().get_repos()
    # 排除个人简介仓库
    filtered_repos = [repo for repo in all_repos if repo.full_name != "wenzhuo4657/wenzhuo4657"]
    return filtered_repos


# get_commits_count(repo)  获取仓库最近一天的提交数量
def get_commits_count(repo):
    # 获取当前时间
    now = datetime.now(pytz.UTC)
    # 计算昨天的时间
    yesterday = now - timedelta(days=1)
    
    try:
        # 获取最近一天的提交
        commits = repo.get_commits(since=yesterday, until=now)
        return commits.totalCount
    except Exception as e:
        print(f"获取仓库 {repo.full_name} 的提交数量时出错: {e}")
        return 0


# write_to_readme(repos_data)  将提交信息写入README.md
def write_to_readme(repos_data):
    readme_path = "README.md"
    
    # 读取现有README内容
    if os.path.exists(readme_path):
        with open(readme_path, 'r', encoding='utf-8') as f:
            content = f.read()
    else:
        content = ""
    
    # 找到"## 📊 最近活动"部分并替换
    start_marker = "## 📊 最近活动"
    end_marker = "*最后更新:"
    
    # 查找开始位置
    start_pos = content.find(start_marker)
    if start_pos == -1:
        # 如果没有找到标记,在文件末尾添加
        new_section = f"\n\n{start_marker}\n\n"
    else:
        # 找到结束位置
        end_pos = content.find(end_marker, start_pos)
        if end_pos == -1:
            end_pos = len(content)
        # 保留开始标记之前的内容
        content = content[:start_pos]
        new_section = f"{start_marker}\n\n"
    
    # 生成新的内容
    # 强制转换为UTC+8时区
    utc_plus_8 = pytz.timezone('Asia/Shanghai')
    current_time = datetime.now(utc_plus_8).strftime("%Y-%m-%d %H:%M:%S")
    
    # 统计信息
    total_repos = len(repos_data)
    active_repos = len([repo for repo in repos_data if repo['commits'] > 0])
    total_commits = sum(repo['commits'] for repo in repos_data)
    
    new_content = f"{content}{new_section}"
    new_content += f"📈 **今日统计**: {total_repos} 个仓库,{active_repos} 个活跃,共 {total_commits} 次提交\n\n"
    
    # 按提交数量排序
    sorted_repos = sorted(repos_data, key=lambda x: x['commits'], reverse=True)
    
    # 添加有提交的仓库
    if active_repos > 0:
        new_content += "### 🔥 今日活跃仓库\n\n"
        for repo in sorted_repos:
            if repo['commits'] > 0:
                commits_emoji = "🚀" if repo['commits'] >= 5 else "✨" if repo['commits'] >= 2 else "📝"
                new_content += f"- {commits_emoji} **[{repo['name']}](https://github.com/{repo['full_name']})**: {repo['commits']} 次提交\n"
        new_content += "\n"
    

    
    new_content += f"\n*最后更新: {current_time}*\n"
    
    # 写入文件
    with open(readme_path, 'w', encoding='utf-8') as f:
        f.write(new_content)
    
    print(f"✅ README.md 已更新,包含 {total_repos} 个仓库的提交信息")



if __name__ == "__main__":    # 程序入口,只有直接执行当前文件时才会执行
    print("Building README.md")
    TOKEN = os.environ.get("GT_TOKEN", "")

    if not TOKEN:
        print("错误: 未找到 GT_TOKEN 环境变量,请设置有效的 GitHub token")
        exit(1)

    auth = Auth.Token(TOKEN)
    g = Github(auth=auth)
    repos = getlist(g)
    
    print(f"📊 正在分析 {len(repos)} 个仓库的提交情况...")
    
    # 收集所有仓库的提交数据
    repos_data = []
    for repo in repos:
        commits_count = get_commits_count(repo)
        repos_data.append({
            'name': repo.name,
            'full_name': repo.full_name,
            'commits': commits_count
        })
        print(f"  ✓ {repo.full_name}: {commits_count} 个提交")
    
    # 写入README.md
    write_to_readme(repos_data)
    

完整案例: https://github.com/wenzhuo4657/wenzhuo4657
提醒: 如果想要在自己的仓库中运行,除去代码,还需要添加git的环境变量,具体需要查看工作流的定义

posted @ 2025-09-09 11:01  wenzhuo4657  阅读(1)  评论(0)    收藏  举报