本文最后更新于 2024-10-04,文章内容可能已经过时。

自动生成子文件夹并上传至 Alist S3 脚本配置文档

此文档将指导你如何使用修改后的 Python 脚本,其中包括以下功能:

  1. 手动设置主文件夹名称。
  2. 在主文件夹下自动生成一个 backup+时间 的子文件夹。
  3. 上传本地文件至 Alist S3 存储,并保存在 主文件夹/backup+时间 目录中。

本教程使用Alist中的S3协议进行搭建对接的123云盘

1,先进入Alist的官网安装并运行,由于网络上此教程太多,我这边不过多教学,官网的一键安装也十分方便(Alist官网地址:alist.nn.ci

2,进入Alist后台->存储->添加 来添加存储,我们以123pan为例

image-20240829180949416

3,成功添加

image-20240829181029527

4,进入123盘,在根目录新建desktop以及mobile文件夹用于存储手机和电脑访问时候呈现出不同尺寸的图片,并且检查是否正常创建

image-20240829181235977

5,进入Alist后台创建S3协议的密钥以及id

在设置->对象存储中点击S3 generate来创建Key,在下方添加桶以及位置

image-20240829181626581

配置完成后去Alist的配置文件位置修改配置文件让他启用S3服务

image-20240829182645804

脚本的配置

完整代码

import os
import boto3
import schedule
import time
from datetime import datetime
from botocore.exceptions import NoCredentialsError, PartialCredentialsError

# ===================== 配置部分 =====================
DIRECTORY_TO_UPLOAD = '/path/to/your/local_directory'  # 本地需要上传的目录(一定要是绝对路径!!)
S3_BUCKET_NAME = 'your-s3-bucket-name'  # S3 桶名称
ALIST_S3_ENDPOINT = 'http://YOUR_IP:YOUR_PORT'  # Alist S3 的 IP + 端口
AWS_ACCESS_KEY_ID = 'YOUR_AWS_ACCESS_KEY_ID'  # Alist S3 的访问密钥
AWS_SECRET_ACCESS_KEY = 'YOUR_AWS_SECRET_ACCESS_KEY'  # Alist S3 的密钥
UPLOAD_INTERVAL_MINUTES = 60  # 每隔 60 分钟上传一次
UPLOAD_NOW = True  # 设置为 True 表示立即上传, False 表示不立即上传
SCHEDULED_UPLOAD = True  # 设置为 True 表示定期上传,False 表示仅执行一次上传
CUSTOM_FOLDER_NAME = 'your-custom-folder'  # 手动设置的主文件夹名称
# ===================== 配置部分结束 =====================

# 初始化 S3 客户端,使用 Alist 的 IP + 端口作为 endpoint_url
s3 = boto3.client(
    's3',
    aws_access_key_id=AWS_ACCESS_KEY_ID,  # 替换为 Alist 的访问密钥
    aws_secret_access_key=AWS_SECRET_ACCESS_KEY,  # 替换为 Alist 的密钥
    endpoint_url=ALIST_S3_ENDPOINT,  # Alist S3 的 IP + 端口
    region_name='us-east-1'  # 区域随意设置一个
)

# 生成 backup+时间 文件夹名称的函数
def generate_backup_folder_name():
    # 使用当前日期时间生成文件夹名称,例如 'backup-2024-10-04-14-30'
    return f"backup-{datetime.now().strftime('%Y-%m-%d-%H-%M')}"

# 上传目录到 S3 的函数,带有自动生成的 backup+时间子文件夹名称
def upload_directory_to_s3(directory_path, bucket_name, custom_folder_name):
    try:
        # 生成 backup+时间 的子文件夹名称
        backup_folder_name = generate_backup_folder_name()
        # 在自定义的主文件夹下生成 backup+时间 的子文件夹
        full_folder_path = os.path.join(custom_folder_name, backup_folder_name)

        # 遍历指定目录中的所有文件和子目录
        for root, dirs, files in os.walk(directory_path):
            for file_name in files:
                full_file_path = os.path.join(root, file_name)  # 文件的完整路径
                # 定义 S3 中的文件路径,包含主文件夹和 backup+时间 文件夹
                s3_file_path = os.path.join(full_folder_path, os.path.relpath(full_file_path, directory_path))
                try:
                    # 上传文件到 S3
                    s3.upload_file(full_file_path, bucket_name, s3_file_path)
                    print(f"Uploaded: {full_file_path} to {bucket_name}/{s3_file_path}")
                except FileNotFoundError:
                    print(f"文件未找到: {full_file_path}")
                except NoCredentialsError:
                    print("无法找到 S3 凭证。")
                except PartialCredentialsError:
                    print("提供的 S3 凭证不完整。")
    except Exception as e:
        print(f"错误: {e}")

# 调度上传任务的函数
def schedule_upload(directory_path, bucket_name, custom_folder_name, interval_minutes):
    # 定义调度任务的函数
    def job():
        print(f"正在上传 {directory_path} 到 S3 桶 {bucket_name}...")
        upload_directory_to_s3(directory_path, bucket_name, custom_folder_name)

    # 安排任务按照指定的时间间隔运行
    schedule.every(interval_minutes).minutes.do(job)

    print(f"已安排每 {interval_minutes} 分钟上传一次。")

    # 持续运行调度程序
    while True:
        schedule.run_pending()  # 运行待处理的任务
        time.sleep(1)  # 等待 1 秒后检查下一个任务

# 主函数入口
if __name__ == "__main__":
    # 如果上传标志为 True,则立即上传一次
    if UPLOAD_NOW:
        print(f"立即上传 {DIRECTORY_TO_UPLOAD} 到 S3 桶 {S3_BUCKET_NAME}...")
        upload_directory_to_s3(DIRECTORY_TO_UPLOAD, S3_BUCKET_NAME, CUSTOM_FOLDER_NAME)
  
    # 根据 SCHEDULED_UPLOAD 判断是否定期上传
    if SCHEDULED_UPLOAD:
        # 启动上传任务的调度
        schedule_upload(DIRECTORY_TO_UPLOAD, S3_BUCKET_NAME, CUSTOM_FOLDER_NAME, UPLOAD_INTERVAL_MINUTES)
    else:
        print("已设置为仅执行一次上传任务。")

本地需要上传的目录

  • 变量: DIRECTORY_TO_UPLOAD

  • 描述: 指定本地需要上传的目录路径(一定要是绝对路径!!)。此目录中的文件会被上传到 S3 中。

  • 示例:

    DIRECTORY_TO_UPLOAD = '/path/to/your/local_directory'
    

    '/path/to/your/local_directory' 替换为你实际想要上传的本地目录路径。例如:

    DIRECTORY_TO_UPLOAD = '/home/user/documents'
    

2. S3 桶名称

  • 变量: S3_BUCKET_NAME

  • 描述: 指定你在 Alist S3 服务中的存储桶(bucket)名称,所有文件将被上传至该桶中。

  • 示例:

    S3_BUCKET_NAME = 'your-s3-bucket-name'
    

    'your-s3-bucket-name' 替换为你实际的 S3 桶名称,例如:

    S3_BUCKET_NAME = 'my-backup-bucket'
    

3. Alist S3 服务的 IP 和端口

  • 变量: ALIST_S3_ENDPOINT

  • 描述: 访问 Alist S3 服务的 IP 地址和端口。格式为 http://IP:PORT

  • 示例:

    ALIST_S3_ENDPOINT = 'http://YOUR_IP:YOUR_PORT'
    

    'http://YOUR_IP:YOUR_PORT' 替换为你的 Alist S3 服务的 IP 地址和端口。例如,如果服务在 192.168.1.100 上运行,端口为 9000

    ALIST_S3_ENDPOINT = 'http://192.168.1.100:9000'
    

4. 访问密钥 (AWS Access Key ID)

  • 变量: AWS_ACCESS_KEY_ID

  • 描述: 用于 Alist S3 服务的访问密钥,用于身份验证。

  • 示例:

    AWS_ACCESS_KEY_ID = 'YOUR_AWS_ACCESS_KEY_ID'
    

    'YOUR_AWS_ACCESS_KEY_ID' 替换为你的实际 Alist S3 访问密钥,例如:

    AWS_ACCESS_KEY_ID = 'ABCD1234EXAMPLE'
    

5. 密钥 (AWS Secret Access Key)

  • 变量: AWS_SECRET_ACCESS_KEY

  • 描述: 用于 Alist S3 服务的密钥,与访问密钥一起用于身份验证。

  • 示例:

    AWS_SECRET_ACCESS_KEY = 'YOUR_AWS_SECRET_ACCESS_KEY'
    

    'YOUR_AWS_SECRET_ACCESS_KEY' 替换为你的实际密钥,例如:

    AWS_SECRET_ACCESS_KEY = 'abcd1234secretEXAMPLE'
    

6. 手动设置的主文件夹名称

  • 变量: CUSTOM_FOLDER_NAME

  • 描述: 这是你手动设置的主文件夹名称。所有文件将会上传到 S3 中此主文件夹下的 backup+时间 子文件夹中。

  • 示例:

    CUSTOM_FOLDER_NAME = 'your-custom-folder'
    

    例如,将此设置为 my-backups,脚本会将所有文件上传到 my-backups/backup-时间 的路径中。


7. 上传时间间隔(分钟)

  • 变量: UPLOAD_INTERVAL_MINUTES

  • 描述: 控制脚本自动上传的时间间隔,单位为分钟。脚本会按照该时间间隔定期上传文件。

  • 示例:

    UPLOAD_INTERVAL_MINUTES = 60
    

    在此示例中,脚本会每隔 60 分钟上传一次文件。可以根据你的需求修改为不同的间隔时间。


8. 立即上传开关

  • 变量: UPLOAD_NOW

  • 描述: 布尔值,控制脚本在启动时是否立即上传文件。如果设置为 True,脚本会在启动时立即上传;如果为 False,则只按照调度时间上传。

  • 示例:

    UPLOAD_NOW = True
    

    设置为 True 时,脚本会立即执行上传任务。如果不希望立即上传,可以将其设置为 False


9. 定期上传开关

  • 变量: SCHEDULED_UPLOAD

  • 描述: 控制是否启用定期上传。如果设置为 True,脚本会按设定的时间间隔定期执行上传。如果设置为 False,脚本只会运行一次。

  • 示例:

    SCHEDULED_UPLOAD = True
    

    如果设置为 True,脚本会按 UPLOAD_INTERVAL_MINUTES 定期上传文件。设置为 False 时,脚本只会执行一次上传任务,然后退出。


10. 自动生成 backup+时间 子文件夹

  • 变量: generate_backup_folder_name()

  • 描述: 这个函数会自动生成一个以 backup+时间 格式命名的子文件夹,用于存储每次上传的文件。

  • 生成格式: backup-YYYY-MM-DD-HH-MM,例如:

    backup-2024-10-04-14-30
    

    每次运行脚本,都会在手动设置的主文件夹下生成一个新的 backup+时间 子文件夹,并将本地文件上传到这个子文件夹中。


运行方式:

  1. 将脚本保存为 .py 文件(例如 upload_to_s3.py)。

  2. 使用 Python 运行脚本:

    python3 upload_to_s3.py
    
  3. 立即上传:如果 UPLOAD_NOW = True,脚本会立即执行上传任务。

  4. 如果UPLOAD_NOW = false的时候,推荐使用宝塔的计划任务来让他自动执行
    image-20241004134216628

  5. 运行一次脚本等待几秒

    image-20241004134257943

  6. 定期上传:如果 SCHEDULED_UPLOAD = True,脚本会按设定的时间间隔定期上传。

示例配置:

DIRECTORY_TO_UPLOAD = '/home/user/documents'  # 本地目录
S3_BUCKET_NAME = 'my-backup-bucket'  # S3 桶名称
ALIST_S3_ENDPOINT = 'http://192.168.1.100:9000'  # Alist S3 服务 IP 和端口
AWS_ACCESS_KEY_ID = 'ABCD1234EXAMPLE'  # 访问密钥
AWS_SECRET_ACCESS_KEY = 'abcd1234secretEXAMPLE'  # 密钥
UPLOAD_INTERVAL_MINUTES = 30  # 每 30 分钟上传一次
UPLOAD_NOW = True  # 立即上传
SCHEDULED_UPLOAD = True  # 定期上传
CUSTOM_FOLDER_NAME = 'my-backups'  # 主文件夹名称

文件上传结构示例:

image-20241004133119193

假设 CUSTOM_FOLDER_NAME = 'my-backups',上传后的文件路径将如下所示:

S3_BUCKET_NAME/my-backups/backup-2024-10-04-14-30/file1.txt
S3_BUCKET_NAME/my-backups/backup-2024-10-04-14-30/file2.txt

通过该脚本配置,你可以灵活设置手动文件夹名称,同时利用自动生成的 backup+时间 子文件夹来管理文件的上传,方便备份和归档管理。如果你有任何其他问题,欢迎继续咨询!