之前因为 jsDelivr 的 ICP 备案突然被扬了,用第三方的服务总还是感觉不放心,于是自己整了个放静态资源的 CDN,速度和稳定性是有保障了,但是每次主题之类的有什么更新都要在 GitHub 上手动下载然后传到存储桶上,这对于我这样的懒狗绝对是不能接受的,于是开始考虑写脚本自动化这个流程。
检测仓库更新并下载到本地
使用 GitHub 官方提供的 API 获取仓库最新的 tag
def GetTagName(repo):
response = requests.get(f"https://api.github.com/repos/{repo}/releases/latest")
return response.json()["tag_name"]
与本地存储的 tag 进行对比,不同则使用 git clone 指定的 tag 版本到本地
def CheckRepo(repo,repo_name,local_tag):
tag_name = GetTagName(repo)
if tag_name != local_tag :
SaveRepo(repo,repo_name,tag_name)
def SaveRepo(repo,repo_name,tag):
os.system(f"git clone -b {tag} --depth=1 https://github.com/{repo}")
将克隆下来的文件根据 tag 归档,更新数据库中的本地 tag
os.rename(f"{root_path}/{repo_name}",f"{root_path}/lib/{repo_name}/{tag}")
conn.execute(f"UPDATE repo SET local_tag = '{tag}' WHERE repo = '{repo}'")
将归档文件同步到存储桶上
CDN 后端存储用的是腾讯云的对象存储 COS,本来是打算直接用 Python 上传的,但是在翻 COS 的 Python SDK 文档的时候,发现 COS 官方的命令行工具 COSCLI 自带了同步文件夹的功能,于是偷个懒直接用 COSCLI 上传,拿宝塔创建了个定时任务自动同步。
./coscli sync lib/ cos://bucket-appid/lib/ --exclude ".git" -r
rm -rf lib
Bark 推送及 Log 记录
最后简单整了个日志记录和 Bark 推送通知到手机。
def LogInit():
logger_raw = logging.getLogger()
logger_raw.setLevel(logging.INFO)
formatter = logging.Formatter("[%(asctime)s] [%(levelname)s]: %(message)s")
formatter.converter = lambda x: time.localtime(x + 28800 + time.timezone)
console_handler = logging.StreamHandler(stream=sys.stdout)
console_handler.setFormatter(formatter)
logger_raw.addHandler(console_handler)
try:
file_handler = logging.FileHandler(log_file, encoding='utf-8')
file_handler.setFormatter(formatter)
logger_raw.addHandler(file_handler)
except:
...
data = {"title":"RepoSync","body":f"已同步 {repo_name} 的 {tag} 版本"}
response = requests.post(url=bark_url,data=data)
str = json.loads(response.text)
if str['message'] == "success":
logging.info("通知推送成功")
else:
logging.warning("通知推送失败")
结语
第一次写 Python 程序,边查文档边百度花了半天才做出来,本地和服务器都测试通过没什么问题,不过没考虑网络波动等等问题,这玩意儿的稳定性还要用一段时间才知道。
顺便扔个 GitHub 地址,纯新手,没什么参考价值就是了。
OriLight152/RepoSync