Halo多博客备份,同时备份redis与mysql,将备份文件上传到百度云

代码:https://github.com/loks666/py_tools

写在前面

我的服务器运行了多个halo博客,都在同一个域名下,只是用前缀区分,所以代码中我也是使用前缀区分的,使用了list元祖中包含了多个halo站点信息,记得在代码中修改为自己的信息,如果只有一个,即只保留一个就好

我都使用的是docker容器运行,docker-compose管理,一定要谨记自己的挂载盘在哪里

代码中是/data/blog/博客名,数据库:/data/mysql,redis:/data/redis

备份的文件夹生成在:/backup文件夹下,记得创建或者自己修改

关于bypy
bypy是百度的python客户端,如果你需要在服务器运行,需要你在本地先安装bypy包

然后在powershell执行:

bypy list

这个时候它会给你一个链接,复制到浏览器打开,登录后会有一个码,把这个码复制进命令行

回车,然后在你的本地用户文件夹会生成一个.bypy文件夹,把这个文件夹上传到你服务器的用户文件夹下,这样就能在你本地使用bypy包了

每日备份

  1. 输入 crontab -e 命令来编辑cron文件。

  2. 在打开的编辑器中,添加以下行(这会在每天凌晨2点运行你的脚本):

  3. 0 2 * * * /usr/bin/python3 /path/to/your/script.py
    /usr/bin/python3是你的python解释器路径

    /path/to/your/script.py是你的脚本路径(即backup_by_BaiDuYun.py)
import base64
import json
import os
import shutil
import time
import logging
from datetime import datetimeimport requests
from bypy import ByPy# 设置日志
logging.basicConfig(filename='backup_by_BaiDuYun.log', level=logging.INFO)def backup_blog(prefix, port, user, password, backup_path):# 网站地址website = f"http://localhost:{port}"# halo2备份文件夹路径backup_halo_path = f"/data/blog/{prefix}/backups"backup_api = website + f"/apis/migration.halo.run/v1alpha1/backups"check_api = website + f"/apis/migration.halo.run/v1alpha1/backups?sort=metadata.creationTimestamp%2Cdesc"# 获取现在的时间 2023-09-24T13:14:18.650Znow_time = datetime.now().strftime('%Y-%m-%dT%H:%M:%S.%f')[:-3] + 'Z'logging.info(now_time)# 构建认证头部auth_header = "Basic " + base64.b64encode((user + ":" + password).encode()).decode()payload = json.dumps({"apiVersion": "migration.halo.run/v1alpha1","kind": "Backup","metadata": {"generateName": "backup-","name": ""},"spec": {"expiresAt": now_time,}})headers = {'User-Agent': '','Content-Type': 'application/json','Authorization': "Basic " + base64.b64encode((user + ":" + password).encode()).decode(),}response = requests.request("POST", backup_api, headers=headers, data=payload)logging.info(response.text)if response.status_code == 201:logging.info(f"{prefix}备份请求成功!")while True:check_response = requests.request("GET", check_api, headers=headers)if check_response.status_code == 200:backup_data = json.loads(check_response.text)items = backup_data.get("items", [])if items[0]["status"]["phase"] == "SUCCEEDED":logging.info(f"{prefix}备份完成!")new_backup_name = items[0]["status"]["filename"]breakif items[0]["status"]["phase"] == "RUNNING":logging.info(f"{prefix}正在备份!")time.sleep(10)else:logging.error(f"{prefix}查询备份请求失败!错误代码:{check_response.status_code}")shutil.copy(backup_halo_path + "/" + new_backup_name, backup_path + "/" + new_backup_name)logging.info(f"{prefix}备份文件复制完成!")else:logging.error(f"{prefix}备份请求失败!错误代码:{response.status_code}")def ignore_sock_files(dirname, filenames):return [name for name in filenames if name.endswith('.sock')]def backup_mysql(backup_path):# 复制MySQL数据dst_path = backup_path + "/mysql"if os.path.exists(dst_path):shutil.rmtree(dst_path)shutil.copytree("/data/mysql", dst_path, ignore=ignore_sock_files)def backup_redis(backup_path):# 复制Redis数据dst_path = backup_path + "/redis"if os.path.exists(dst_path):shutil.rmtree(dst_path)shutil.copytree("/data/redis", dst_path, ignore=ignore_sock_files)def zip_and_upload(directory):# 打包并上传到百度云shutil.make_archive(directory, 'zip', directory)bp = ByPy()bp.upload(localpath=directory + ".zip", remotepath="/backup/" + directory + ".zip", ondup='overwrite')# 删除原始文件夹shutil.rmtree(directory)logging.info(f"{directory} has been deleted after zipping and uploading.")if __name__ == '__main__':# 创建日期文件夹date_folder = "/backup/" + datetime.now().strftime('%Y-%m-%d')os.makedirs(date_folder, exist_ok=True)# 调用函数进行备份blogs = [('博客', '端口号', '管理员用户名', '管理员密码'), ('博客', '端口号', '管理员用户名', '管理员密码'),('博客', '端口号', '管理员用户名', '管理员密码'), ('博客', '端口号', '管理员用户名', '管理员密码')]for prefix, port, user, password in blogs:os.makedirs(f"{date_folder}/halo/{prefix}", exist_ok=True)backup_blog(prefix, port, user, password, f"{date_folder}/halo/{prefix}")# 备份MySQL和Redisbackup_mysql(date_folder)backup_redis(date_folder)# 打包并上传所有备份zip_and_upload(date_folder)

鸣谢:Halo用户@Jevon:利用aligo实现Halo自动备份数据到阿里云盘-Jiewen’blog

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/580453.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PSV新内存卡(或内存卡格式化后)如何安装VITASHELL文件管理器

本博文适合PSV破解固化后的系统,例如变革3.65破解固化后换新的内存卡,或者内存卡格式化后如何在内存卡上安装文件管理器(没有文件管理器无法安装游戏)。如果你的PSV还没破解,那本文不适合没破解的情况,按照…

数据库(多对多表关系及关联查询)

添加外键约束: alter table 表名 drop foreign_key fk(外键约束)_ 表名_列名_列名 添加约束规则: 1.主表中没有对应记录,不能将记录添加到从表 2.从表存在与主表对应的记录,不能从主表中删除该行 3.删除主标前,先…

问题:执行conda init 提示 No action taken,然后无法正确激活环境

执行完下面代码后, conda activate base 报错,提示先执行conda init,于是再执行下面代码 conda init发现还报错提示提示 No action taken。 解决方法: 打开一个新的终端窗口,您应该就可以正常使用conda命令。(把其…

VIRTUALBOX VAGRANT虚拟机网速慢解决方案

查看时长 time curl -s http://www.baidu.com > /dev/null 1config.vm.provider :virtualbox do |vb| 2 vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"] 3 vb.customize ["modifyvm", :id, "--natdn…

ElasticSearch 的 mapping 参数 - fields

概要 在 es 中,一个字段可能运用于不同的场景,但是某个字段类型的使用场景是有局限的 下面,我们先来看一段 es 查询语句: $must ["bool" > ["should" > [["range" > ["user_id.r…

设计模式之-观察者模式,快速掌握观察者模式,通俗易懂的讲解观察者模式以及它的使用场景

文章目录 一、快速理解观察者模式二、观察者模式适用场景三、观察者模式优缺点观察者模式的优点包括:观察者模式的缺点包括: 四、代码示例五、我们来听一个故事,加深理解 一、快速理解观察者模式 当谈到设计模式中的观察者模式(O…

视觉学习(7) —— 接收数据和发送数据以及全局变量和浮点数

1、前提 创建一个四个字节的地址 2、发送数据 (1)直接发送数据 再观察地址里的值 与我们想要值不一样 输入0,而实际值则为 结论:直接输入值到地址,值会发生变化 (2)走全局变量发送数据 添加全…

系列十(实战)、发送 接收批量消息(Java操作RocketMQ)

一、发送 & 接收批量消息 1.1、概述 批量消息是指RocketMQ可以把一组消息集合一次性发送,这一组消息会被当做一个消息供消费者消费。 1.2、Demo05MQTestApp /*** Author : 一叶浮萍归大海* Date: 2023/12/25 11:48* Description: 发送 & 接收批量消息*/ …

基于SSM实现的电动汽车充电网点管理系统

一、系统架构 前端:jsp | jquery | bootstrap | css 后端:spring | springmvc | jdbc 环境:jdk1.8 | mysql 二、代码及数据库 三、功能介绍 01. web端-首页 02. web端-登录 03. web端-注册 04. web端-我要充电 05. web端-个人中心-消…

搞定Apache Superset

踩雷了无数次终于解决了Superset的一系列问题 现在是北京时间2023年12月27日,亲测有效。 Superset概述 Apache Superset是一个现代的数据探索和可视化平台。它功能强大且十分易用,可对接各种数据源,包括很多现代的大数据分析引擎&#xff…

php5.6安装mongo扩展

需要依赖 可以参考 php5.6安装openssl扩展 https://pecl.php.net/package/mongo 安装mongo扩展 wget https://pecl.php.net/get/mongo-1.6.16.tgz/Users/hina/Applications/php/5.6.40/bin/phpize./configure --with-php-config/Users/hina/Applications/php/5.6.40/bin/ph…

JS深浅拷贝

区分 B复制了A的值,如果A被修改,B的值也被改变,那就是浅拷贝。 如果B的值没有跟着修改,那就是深拷贝 深浅拷贝的方式 1、遍历赋值 2、Object.create() 3、JSON.parse()和JSON.stringify() 浅拷贝-遍历 let a {name:"…

recognize-anything 识别万物

docker run --gpus all -itd --nametest -v /app:/app nvcr.io/nvidia/cuda:11.8.0-devel-ubuntu22.04 ###########安装过程######################## # 更新包索引 apt update # 安装 Python 3 apt install python3 -y # 安装 pip apt install python3-pip -y # 安装…

k8s面试之——简述网络模型

kubernetes网络模型是kubernetes集群中管理容器网络通信的一种机制,用于实现pod间、pod与外部网络间的通信和互联,并提供了多种网络插件和配置选项来满足不同应用场景下的需求。kubernetes网络模型可以分为一下几个部分: 1. pod网络模型 在…

详解结构体(包含结构体内存对齐,柔性数组,位段)【尊嘟很详细】

​ 结构体 结构体是一些值的集合,这些值称为成员变量,结构的成员可以是标量、数组、指针,甚至是其他结构体。 成员名可以与程序中其它变量同名,互不干扰。 结构体的定义 (struct结构名{}) struct books {int a;c…

饮用水除溴酸盐和硝酸盐中的应用与优势

随着人们对健康和生活质量的日益关注,饮用水安全问题成为了社会关注的焦点。在自然水体中,溴酸盐和硝酸盐的含量往往较高,而这些物质对人体健康存在一定的潜在风险。因此,饮用水处理中如何有效去除溴酸盐和硝酸盐,成为…

TypeScript下载安装,编译运行

TypeScript是拥有类型的JavaScript超集,它可以编译成普通、干净、完整的JavaScript代码。 简单理解:TypeScript就是加强版的JavaScript。 TypeScript最终会被编译成JavaScript代码,那么我们必然需要对应的编译环境 环境搭建前提&#xff1a…

【扩散模型】7、GLIDE | 文本指引的图像生成和编辑

论文:GLIDE: Towards Photorealistic Image Generation and Editing with Text-Guided Diffusion Models 代码:https://link.zhihu.com/?targethttps%3A//github.com/openai/glide-text2im 出处:OpenAI 一、背景 在扩散模型经过了一系列…

【51单片机系列】DS1302时钟模块

本文是关于DS1302时钟芯片的相关介绍。 文章目录 一、 DS1302时钟芯片介绍二、DS1302的使用2.1、DS1302的控制寄存器2.2、DS1302的日历/时钟寄存器2.3、片内RAM2.4、DS1302的读写时序 三、SPI总线介绍四、DS1302使用示例 一、 DS1302时钟芯片介绍 DS1302是DALLAS公司推出的涓流…

GitLab 删除或移动项目

首先明说,删除后无法恢复 第一步:找到要删除的项目 第二步:进入目录后,左侧菜单,设置 >>> 通用,拉到最下面找到“高级”,点击右侧“展开” 第三步:点击“展开”后往下拉&a…