PyWxDump/pywxdump/file/AttachmentContext.py
2024-07-13 22:01:21 +08:00

189 lines
4.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import os
from datetime import datetime
from typing import AnyStr, Callable, Union, IO
from flask import send_file, Response
from pywxdump.common.config.oss_config.s3_config import S3Config
from pywxdump.common.config.oss_config_manager import OSSConfigManager
from pywxdump.file.Attachment import Attachment
from pywxdump.file.LocalAttachment import LocalAttachment
from pywxdump.file.S3Attachment import S3Attachment
def determine_strategy(file_path: str) -> Attachment:
"""
根据文件路径确定使用的附件策略本地或S3
参数:
file_path (str): 文件路径。
返回:
Attachment: 返回对应的附件策略类实例。
"""
if file_path.startswith(f"s3://"):
return OSSConfigManager().get_attachment("s3", S3Attachment)
else:
return LocalAttachment()
def exists(path: str) -> bool:
"""
检查文件或目录是否存在。
参数:
path (str): 文件或目录路径。
返回:
bool: 如果存在返回True否则返回False。
"""
return determine_strategy(path).exists(path)
def open_file(path: str, mode: str) -> IO:
"""
打开一个文件并返回文件对象。
参数:
path (str): 文件路径。
mode (str): 打开文件的模式。
返回:
IO: 文件对象。
"""
return determine_strategy(path).open(path, mode)
def makedirs(path: str) -> bool:
"""
创建目录,包括所有中间目录。
参数:
path (str): 目录路径。
返回:
bool: 总是返回True。
"""
return determine_strategy(path).makedirs(path)
def join(path: str, *paths: str) -> str:
"""
连接一个或多个路径组件。
参数:
path (str): 第一个路径组件。
*paths (str): 其他路径组件。
返回:
str: 连接后的路径。
"""
return determine_strategy(path).join(path, *paths)
def dirname(path: str) -> str:
"""
获取路径的目录名。
参数:
path (str): 文件路径。
返回:
str: 目录名。
"""
return determine_strategy(path).dirname(path)
def basename(path: str) -> str:
"""
获取路径的基本名(文件名)。
参数:
path (str): 文件路径。
返回:
str: 基本名(文件名)。
"""
return determine_strategy(path).basename(path)
def send_attachment(
path_or_file: Union[os.PathLike[AnyStr], str],
mimetype: Union[str, None] = None,
as_attachment: bool = False,
download_name: Union[str, None] = None,
conditional: bool = True,
etag: Union[bool, str] = True,
last_modified: Union[datetime, int, float, None] = None,
max_age: Union[None, int, Callable[[Union[str, None]], Union[int, None]]] = None,
) -> Response:
"""
发送附件文件。
参数:
path_or_file (Union[os.PathLike[AnyStr], str]): 文件路径或文件对象。
mimetype (Union[str, None]): 文件的MIME类型。
as_attachment (bool): 是否作为附件下载。
download_name (Union[str, None]): 下载时的文件名。
conditional (bool): 是否使用条件请求。
etag (Union[bool, str]): ETag值。
last_modified (Union[datetime, int, float, None]): 最后修改时间。
max_age (Union[None, int, Callable[[Union[str, None]], Union[int, None]]]): 缓存最大时间。
返回:
Response: Flask的响应对象。
"""
file_io = open_file(path_or_file, "rb")
# 如果没有提供 download_name 或 mimetype则从 path_or_file 中获取文件名和 MIME 类型
if download_name is None:
download_name = basename(path_or_file)
if mimetype is None:
mimetype = 'application/octet-stream'
return send_file(file_io, mimetype, as_attachment, download_name, conditional, etag, last_modified, max_age)
def download_file(db_path, local_path):
"""
从db_path下载文件到local_path。
参数:
db_path (str): 数据库文件路径。
local_path (str): 本地文件路径。
返回:
str: 本地文件路径。
"""
with open(local_path, 'wb') as f:
with open_file(db_path, 'rb') as r:
f.write(r.read())
return local_path
def isLocalPath(path: str) -> bool:
"""
判断路径是否为本地路径。
参数:
path (str): 文件或目录路径。
返回:
bool: 如果是本地路径返回True否则返回False。
"""
strategy = determine_strategy(path)
return isinstance(strategy, type(LocalAttachment()))
def getsize(path: str):
"""
获取文件大小
参数:
path (str): 文件路径
返回:
int: 文件大小
"""
return determine_strategy(path).getsize(path)