Python 监控Github项目更新并自动下载
发布日期:2021-05-08 00:05:42 浏览次数:21 分类:精选文章

本文共 4075 字,大约阅读时间需要 13 分钟。

Python监控GitHub项目是否有更新

项目背景

维护开源项目的更新检测工作一直是一个令人头疼的事。如果项目代码越来越大,人工检查更新的工作就更加麻烦。因此,我们设计了一个自动化监控工具,能够通过Python脚本实时检测GitHub项目是否有更新,并自动下载更新包。


文件名格式规范

为了方便调用GitHub的API,我们对文件名进行了规范处理。GitHub API endpoint通常包含用户名或组织名(例如:https://api.github.com/repos/facebookresearch/fasttext),但由于文件名不能包含斜杠 /,我们采用下划线分割的方式,例如:facebookresearch_fasttext.zip。这种格式既便于API调用,也确保了文件管理的便捷性。


本地文件时间戳管理

为了比较线上项目与本地项目的更新时间,我们需要获取本地文件的修改时间。以下是实现这一功能的代码示例:

import os
from datetime import datetime
local_files = {}
for file in os.listdir('path/to/your/libs'):
file_path = os.path.join('path/to/your/libs', file)
file_info = os.path.getmtime(file_path)
local_files[file] = datetime.fromtimestamp(file_info)

通过上述代码,我们可以创建一个文件名与其最后修改时间的映射关系。


时间戳对比与更新判断

接下来,我们需要将GitHub API返回的更新时间转换为10位时间戳格式,与本地文件的时间戳进行对比。具体实现如下:

import requests
def get_update_time(repo):
url = f'https://api.github.com/repos/{repo}'
response = requests.get(url)
if response.status_code == 200:
last_update = response.json()['last_commit']['commit']['author']['datetime']
return int(last_update.strftime('%Y%m%dT%H%M%S')) # 转换为10位时间戳
return None
local_time = local_files['facebookresearch_fasttext']
remote_time = get_update_time('facebookresearch/fasttext')
if remote_time > local_time:
# 需要更新
download_and_extract()

自动下载更新包

在检测到线上项目有更新时,我们采用下面的方式进行自动下载和解压。由于大型文件下载可能导致速度问题,建议使用多线程下载工具或优化下载路径。

import requests
import os
import socket
def download_file(url, filename):
chunk_size = 1024
with open(filename, 'wb') as f:
for chunk in requests.download(url, stream=True):
f.write(chunk.content)
f.flush()
def main():
url = 'https://github.com/facebookresearch/fasttext/archive/master.zip'
filename = 'facebookresearch_fasttext.zip'
download_file(url, filename)
# 自动解压并移至libs目录
os.system(f' unzip {filename} -d libs')
if __name__ == '__main__':
main()

整体流程图

我们的工具将下载好的项目文件放在 libs 文件夹中,自动下载的文件则保存在 new 文件夹中。文件结构如下:

F:\pythondict\pythondict-downloads\
├── superviser.py
├── libs
│ ├── facebookresearch_fasttext.zip
│ └── facebookresearch_MUSE.zip
└── new

完整代码

为了便于复制使用,我们提供了完整的代码示例(图片格式已去除,仅保留代码内容):

import os
import requests
from datetime import datetime
# 定义文件路径
LIBRARY_PATH = 'libs/'
NEW_PATH = 'new/'
def get_local_files():
"""获取本地文件夹中的所有文件及其最后修改时间"""
file_info = {}
for file in os.listdir(LIBRARY_PATH):
file_path = os.path.join(LIBRARY_PATH, file)
mod_time = os.path.getmtime(file_path)
mod_date = datetime.fromtimestamp(mod_time)
file_info[file] = mod_date
return file_info
def get_remote_update_time(repo):
"""通过GitHub API获取项目的最后更新时间"""
url = f'https://api.github.com/repos/{repo}'
response = requests.get(url)
if response.status_code != 200:
return None
last_commit = response.json()['last_commit']
commit_time = last_commit['commit']['author']['datetime']
return int(commit_time.strftime('%Y%m%dT%H%M%S'))
def compare_and_download():
"""比较并下载需要更新的项目"""
local_files = get_local_files()
for repo in os.listdir(LIBRARY_PATH):
try:
remote_time = get_remote_update_time(f'{repo_owner}/{repo}')
except:
continue
if remote_time > local_files[repo]:
print(f'项目 {repo} 有更新,正在下载...')
download_url = f'https://github.com/{repo_owner}/{repo}/archive/master.zip'
file_name = f'{repo_owner}_{repo}.zip'
# 使用requests下载文件
with open(file_name, 'wb') as f:
for chunk in requests.download(download_url, stream=True):
f.write(chunk.content)
f.flush()
print('下载完成,正在解压...')
os.system(f' unzip {file_name} -d {LIBRARY_PATH}')
print('更新完成,文件已添加到libs目录。')
print('所有项目都已检查完毕,已下载最新更新。')
if __name__ == '__main__':
compare_and_download()

使用说明

  • pythondict-downloads 文件夹设为项目根目录
  • 修改 LIBRARY_PATHNEW_PATH 以适应你的文件结构
  • compare_and_download 函数中,修改 repo_owner 为你的GitHub用户名或组织名
  • 每天设置一个自动运行任务(例如使用 cronScheduledTask),确保及时获取最新更新

  • 欢迎在评论区留言,与我们一起探讨更多Python实用技巧!

    上一篇:准确率94%!Python 机器学习识别微博或推特机器人
    下一篇:7行代码 Python热力图可视化分析缺失数据处理

    发表评论

    最新留言

    不错!
    [***.144.177.141]2025年04月05日 12时52分52秒