Files
2026-08-13 18:24:50 +08:00

62 lines
2.1 KiB
Python

# coding: utf-8
import os
import shutil
from ..core.exceptions import ProjectImportError
# 按长度降序排列,先匹配 .tar.gz 等复合扩展名
ARCHIVE_EXTENSIONS = (".tar.gz", ".tar.bz2", ".tar.xz", ".tgz", ".tbz2", ".txz", ".zip", ".rar", ".7z", ".tar", ".gz", ".bz2", ".xz")
def archive_base_name(path):
"""从压缩包路径推断项目名:去掉扩展名,保留压缩包基础名。"""
base = os.path.basename(path)
lower = base.lower()
for extension in ARCHIVE_EXTENSIONS:
if lower.endswith(extension):
return base[: -len(extension)]
return os.path.splitext(base)[0]
class BaseSource:
def __init__(self, session, config, work_dir, reporter):
self.session = session
self.config = config or {}
self.work_dir = work_dir
self.reporter = reporter
def check_cancelled(self):
self.reporter.check_cancelled()
def fetch(self):
raise NotImplementedError
def copy_directory(source, destination, progress=None, cancelled=None):
if os.path.exists(destination):
shutil.rmtree(destination, ignore_errors=True)
os.makedirs(destination, mode=0o755, exist_ok=True)
files = []
for current, dirs, names in os.walk(source, followlinks=False):
dirs[:] = [name for name in dirs if not os.path.islink(os.path.join(current, name))]
for name in names:
path = os.path.join(current, name)
if not os.path.islink(path):
files.append(path)
total = max(1, len(files))
for index, path in enumerate(files, 1):
if cancelled:
cancelled()
relative = os.path.relpath(path, source)
target = os.path.join(destination, relative)
os.makedirs(os.path.dirname(target), mode=0o755, exist_ok=True)
shutil.copy2(path, target)
if progress:
progress(index / total, "Copying {}".format(relative.replace("\\", "/")))
if not files and not os.path.isdir(source):
raise ProjectImportError("Source directory does not exist", "SOURCE_NOT_FOUND")
return destination