Compare commits

...

5 Commits

2 changed files with 73 additions and 23 deletions

View File

@@ -6,8 +6,15 @@ import requests
import tempfile import tempfile
import json import json
# 存储上次上传的信息 # 缓存目录和文件配置
LAST_UPLOAD_FILE = '.last_upload.json' CACHE_DIR = '.working_cache'
UPLOAD_CACHE_FILE = os.path.join(CACHE_DIR, 'upload.json')
DOWNLOAD_CACHE_FILE = os.path.join(CACHE_DIR, 'download.json')
# 确保缓存目录存在
def ensure_cache_dir():
"""确保缓存目录存在"""
os.makedirs(CACHE_DIR, exist_ok=True)
def get_file_hash(file_path): def get_file_hash(file_path):
@@ -19,14 +26,19 @@ def get_file_hash(file_path):
return hash_md5.hexdigest() return hash_md5.hexdigest()
def get_working_files(): def get_working_dir():
"""从环境变量WORKING_FILES获取要打包的文件列表""" """获取工作目录,处理默认值和路径转换"""
working_files_env = os.environ.get('WORKING_FILES', '')
working_dir = os.environ.get('WORKING_DIR', '.') working_dir = os.environ.get('WORKING_DIR', '.')
# 确保WORKING_DIR是绝对路径 # 确保WORKING_DIR是绝对路径
if not os.path.isabs(working_dir): if not os.path.isabs(working_dir):
working_dir = os.path.abspath(working_dir) working_dir = os.path.abspath(working_dir)
return working_dir
def get_working_files():
"""从环境变量WORKING_FILES获取要打包的文件列表"""
working_files_env = os.environ.get('WORKING_FILES', '')
working_dir = get_working_dir()
if not working_files_env: if not working_files_env:
return [] return []
@@ -64,8 +76,8 @@ def check_files_modified(working_files):
current_hashes[file_path] = get_file_hash(file_path) current_hashes[file_path] = get_file_hash(file_path)
# 读取上次的哈希值 # 读取上次的哈希值
if os.path.exists(LAST_UPLOAD_FILE): if os.path.exists(UPLOAD_CACHE_FILE):
with open(LAST_UPLOAD_FILE, 'r') as f: with open(UPLOAD_CACHE_FILE, 'r') as f:
last_data = json.load(f) last_data = json.load(f)
# 比较哈希值 # 比较哈希值
@@ -123,6 +135,16 @@ def download_and_extract(download_url, extract_dir='.', password=None):
# 确保解压目录存在 # 确保解压目录存在
os.makedirs(extract_dir, exist_ok=True) os.makedirs(extract_dir, exist_ok=True)
# 检查是否与最后一次下载的URL相同
ensure_cache_dir()
if os.path.exists(DOWNLOAD_CACHE_FILE):
with open(DOWNLOAD_CACHE_FILE, 'r') as f:
last_data = json.load(f)
if last_data.get('download_url') == download_url:
print(f"URL {download_url} is the same as last download. Skipping download.")
return True
# 下载ZIP文件到临时目录 # 下载ZIP文件到临时目录
with tempfile.NamedTemporaryFile(suffix='.zip', delete=False) as tmp: with tempfile.NamedTemporaryFile(suffix='.zip', delete=False) as tmp:
zip_path = tmp.name zip_path = tmp.name
@@ -167,6 +189,26 @@ def download_and_extract(download_url, extract_dir='.', password=None):
raise e raise e
print(f"Download and extraction completed successfully.") print(f"Download and extraction completed successfully.")
# 将下载信息保存到解压目录
download_info = {
'download_url': download_url,
'extract_dir': extract_dir,
'timestamp': os.path.getmtime(zip_path),
'encrypted': bool(password),
'extracted_files': len(os.listdir(extract_dir)) if os.path.exists(extract_dir) else 0
}
download_info_file = os.path.join(extract_dir, '.download_info.json')
with open(download_info_file, 'w') as f:
json.dump(download_info, f, indent=2)
# 保存下载信息到全局缓存
ensure_cache_dir()
with open(DOWNLOAD_CACHE_FILE, 'w') as f:
json.dump(download_info, f, indent=2)
print(f"Download information saved to {download_info_file}")
return True return True
except (requests.exceptions.RequestException, zipfile.BadZipFile, IOError, Exception) as e: except (requests.exceptions.RequestException, zipfile.BadZipFile, IOError, Exception) as e:
raise Exception(f"Failed to download and extract: {str(e)}") raise Exception(f"Failed to download and extract: {str(e)}")
@@ -199,9 +241,7 @@ def upload_working_files(password=None):
try: try:
# 获取WORKING_DIR # 获取WORKING_DIR
working_dir = os.environ.get('WORKING_DIR', '.') working_dir = get_working_dir()
if not os.path.isabs(working_dir):
working_dir = os.path.abspath(working_dir)
# 打包文件 # 打包文件
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf: with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
@@ -212,22 +252,31 @@ def upload_working_files(password=None):
# 如果提供了密码创建加密ZIP文件 # 如果提供了密码创建加密ZIP文件
if password: if password:
# 直接创建加密ZIP文件替换原有的非加密文件 # 删除原有的非加密文件
os.unlink(zip_path) os.unlink(zip_path)
# 获取WORKING_DIR # 获取WORKING_DIR
working_dir = os.environ.get('WORKING_DIR', '.') working_dir = get_working_dir()
if not os.path.isabs(working_dir):
working_dir = os.path.abspath(working_dir)
# 使用内置的zipfile模块创建加密ZIP # 尝试使用7zip创建加密ZIP文件
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED, compresslevel=9) as zipf: try:
import subprocess
# 构建7zip命令 - 注意7zip参数之间没有空格
cmd = ['7z', 'a', '-tzip', '-p' + password, '-mx9', zip_path]
# 添加所有文件到命令中
for file_path in working_files: for file_path in working_files:
# 计算相对路径,保持目录结构 # 计算相对路径,保持目录结构
arcname = os.path.relpath(file_path, working_dir) arcname = os.path.relpath(file_path, working_dir)
zipf.write(file_path, arcname) # 7zip需要相对路径从working_dir开始
# 设置密码用于解密 cmd.append(os.path.relpath(file_path, working_dir))
zipf.setpassword(password.encode())
# 切换到working_dir执行命令确保相对路径正确
subprocess.run(cmd, check=True, capture_output=True, cwd=working_dir)
except (subprocess.CalledProcessError, FileNotFoundError):
# 如果7zip不可用抛出错误
raise Exception("Failed to create encrypted ZIP file: 7zip is not available or failed to execute")
# 上传到tmpfile # 上传到tmpfile
download_url = upload_to_tmpfile(zip_path) download_url = upload_to_tmpfile(zip_path)
@@ -239,7 +288,8 @@ def upload_working_files(password=None):
current_hashes[file_path] = get_file_hash(file_path) current_hashes[file_path] = get_file_hash(file_path)
# 保存本次上传信息 # 保存本次上传信息
with open(LAST_UPLOAD_FILE, 'w') as f: ensure_cache_dir()
with open(UPLOAD_CACHE_FILE, 'w') as f:
json.dump({ json.dump({
'hashes': current_hashes, 'hashes': current_hashes,
'download_url': download_url, 'download_url': download_url,

View File

@@ -3,8 +3,8 @@ name = "myscripts"
version = "0.1.0" version = "0.1.0"
description = "Add your description here" description = "Add your description here"
readme = "README.md" readme = "README.md"
requires-python = ">=3.13" requires-python = ">=3.10"
dependencies = ["requests"] dependencies = ["requests"]
[project.scripts] [project.scripts]
working_tool = "myscripts.working_tool:main" working_tool = "myscripts.working_tool:main"