|
|
|
@ -127,7 +127,7 @@ class CollectorApp: |
|
|
|
def __init__(self, root): |
|
|
|
self.root = root |
|
|
|
self.root.title("文件采集客户端") |
|
|
|
self.root.geometry("1180x720") |
|
|
|
self.root.geometry("1280x720") |
|
|
|
self.root.resizable(True, True) |
|
|
|
|
|
|
|
self.config_path = get_runtime_dir() / "collector_config.json" |
|
|
|
@ -148,6 +148,7 @@ class CollectorApp: |
|
|
|
"bu_no": StringVar(), |
|
|
|
"equipment_no": StringVar(), |
|
|
|
"source_path": StringVar(), |
|
|
|
"backup_path": StringVar(), |
|
|
|
}) |
|
|
|
|
|
|
|
self._build_ui() |
|
|
|
@ -175,22 +176,25 @@ class CollectorApp: |
|
|
|
Button(self.root, text="开始同步", command=self.start_collect).place(x=180, y=54) |
|
|
|
Button(self.root, text="停止同步", command=self.stop_collect).place(x=265, y=54) |
|
|
|
|
|
|
|
Label(self.root, text="配置说明:最多3行,每行需填写 site + buNo + equipmentNo + 本地目录").place(x=360, y=58) |
|
|
|
Label(self.root, text="配置说明:最多3行,每行需填写 site + buNo + equipmentNo + 本地目录;备份目录可选(为空则自动使用本地目录_bak)").place(x=360, y=58) |
|
|
|
|
|
|
|
Label(self.root, text="行").place(x=20, y=100) |
|
|
|
Label(self.root, text="Site").place(x=80, y=100) |
|
|
|
Label(self.root, text="BuNo").place(x=230, y=100) |
|
|
|
Label(self.root, text="EquipmentNo").place(x=380, y=100) |
|
|
|
Label(self.root, text="本地目录").place(x=560, y=100) |
|
|
|
Label(self.root, text="BuNo").place(x=220, y=100) |
|
|
|
Label(self.root, text="EquipmentNo").place(x=360, y=100) |
|
|
|
Label(self.root, text="本地目录").place(x=530, y=100) |
|
|
|
Label(self.root, text="备份目录").place(x=890, y=100) |
|
|
|
|
|
|
|
for idx, row in enumerate(self.row_vars): |
|
|
|
y = 130 + idx * 40 |
|
|
|
Label(self.root, text=str(idx + 1)).place(x=26, y=y) |
|
|
|
Entry(self.root, textvariable=row["site"], width=16).place(x=80, y=y) |
|
|
|
Entry(self.root, textvariable=row["bu_no"], width=16).place(x=230, y=y) |
|
|
|
Entry(self.root, textvariable=row["equipment_no"], width=18).place(x=380, y=y) |
|
|
|
Entry(self.root, textvariable=row["source_path"], width=56).place(x=560, y=y) |
|
|
|
Button(self.root, text="选择目录", command=lambda x=idx: self.choose_source_dir(x)).place(x=1010, y=y - 4) |
|
|
|
Entry(self.root, textvariable=row["bu_no"], width=16).place(x=220, y=y) |
|
|
|
Entry(self.root, textvariable=row["equipment_no"], width=18).place(x=360, y=y) |
|
|
|
Entry(self.root, textvariable=row["source_path"], width=40).place(x=530, y=y) |
|
|
|
Button(self.root, text="选择目录", command=lambda x=idx: self.choose_source_dir(x)).place(x=815, y=y - 4) |
|
|
|
Entry(self.root, textvariable=row["backup_path"], width=30).place(x=890, y=y) |
|
|
|
Button(self.root, text="选择目录", command=lambda x=idx: self.choose_backup_dir(x)).place(x=1110, y=y - 4) |
|
|
|
|
|
|
|
self.log_text = ScrolledText(self.root, width=165, height=23) |
|
|
|
self.log_text.place(x=20, y=280) |
|
|
|
@ -209,7 +213,22 @@ class CollectorApp: |
|
|
|
def choose_source_dir(self, row_index): |
|
|
|
path = filedialog.askdirectory(title="选择第%d行本地目录" % (row_index + 1)) |
|
|
|
if path: |
|
|
|
self.row_vars[row_index]["source_path"].set(path) |
|
|
|
row = self.row_vars[row_index] |
|
|
|
row["source_path"].set(path) |
|
|
|
if not row["backup_path"].get().strip(): |
|
|
|
row["backup_path"].set(self._default_backup_path(path)) |
|
|
|
|
|
|
|
def choose_backup_dir(self, row_index): |
|
|
|
path = filedialog.askdirectory(title="选择第%d行备份目录" % (row_index + 1)) |
|
|
|
if path: |
|
|
|
self.row_vars[row_index]["backup_path"].set(path) |
|
|
|
|
|
|
|
def _default_backup_path(self, source_path): |
|
|
|
source_text = str(source_path).strip() |
|
|
|
if not source_text: |
|
|
|
return "" |
|
|
|
source = Path(source_text) |
|
|
|
return str(source.parent / (source.name + "_bak")) |
|
|
|
|
|
|
|
def _load_config(self): |
|
|
|
if not self.config_path.exists(): |
|
|
|
@ -228,14 +247,21 @@ class CollectorApp: |
|
|
|
"bu_no": config.get("bu_no", ""), |
|
|
|
"equipment_no": config.get("equipment_no", ""), |
|
|
|
"source_path": config.get("source_path", ""), |
|
|
|
"backup_path": config.get("backup_path", ""), |
|
|
|
}] |
|
|
|
|
|
|
|
for idx in range(min(3, len(rows))): |
|
|
|
item = rows[idx] if isinstance(rows[idx], dict) else {} |
|
|
|
source_path = str(item.get("source_path", "")).strip() |
|
|
|
backup_path = str(item.get("backup_path", "")).strip() |
|
|
|
if source_path and not backup_path: |
|
|
|
backup_path = self._default_backup_path(source_path) |
|
|
|
|
|
|
|
self.row_vars[idx]["site"].set(str(item.get("site", "")).strip()) |
|
|
|
self.row_vars[idx]["bu_no"].set(str(item.get("bu_no", "")).strip()) |
|
|
|
self.row_vars[idx]["equipment_no"].set(str(item.get("equipment_no", "")).strip()) |
|
|
|
self.row_vars[idx]["source_path"].set(str(item.get("source_path", "")).strip()) |
|
|
|
self.row_vars[idx]["source_path"].set(source_path) |
|
|
|
self.row_vars[idx]["backup_path"].set(backup_path) |
|
|
|
|
|
|
|
self.log("配置加载完成。") |
|
|
|
if self._can_auto_start(): |
|
|
|
@ -295,25 +321,37 @@ class CollectorApp: |
|
|
|
bu_no = row["bu_no"].get().strip() |
|
|
|
equipment_no = row["equipment_no"].get().strip() |
|
|
|
source_path = row["source_path"].get().strip() |
|
|
|
backup_path = row["backup_path"].get().strip() |
|
|
|
|
|
|
|
filled_count = 0 |
|
|
|
for value in (site, bu_no, equipment_no, source_path): |
|
|
|
for value in (site, bu_no, equipment_no, source_path, backup_path): |
|
|
|
if value: |
|
|
|
filled_count += 1 |
|
|
|
|
|
|
|
if filled_count == 0: |
|
|
|
continue |
|
|
|
|
|
|
|
if require_complete and filled_count < 4: |
|
|
|
required_count = 0 |
|
|
|
for value in (site, bu_no, equipment_no, source_path): |
|
|
|
if value: |
|
|
|
required_count += 1 |
|
|
|
|
|
|
|
if require_complete and required_count < 4: |
|
|
|
raise ValueError("第%d行配置未填写完整,请补全site、buNo、equipmentNo、本地目录。" % (idx + 1)) |
|
|
|
|
|
|
|
if filled_count == 4: |
|
|
|
if required_count == 4: |
|
|
|
if not backup_path: |
|
|
|
backup_path = self._default_backup_path(source_path) |
|
|
|
if os.path.normcase(os.path.normpath(source_path)) == os.path.normcase(os.path.normpath(backup_path)): |
|
|
|
raise ValueError("第%d行配置错误:本地目录和备份目录不能相同。" % (idx + 1)) |
|
|
|
|
|
|
|
rows.append({ |
|
|
|
"row_index": idx + 1, |
|
|
|
"site": site, |
|
|
|
"bu_no": bu_no, |
|
|
|
"equipment_no": equipment_no, |
|
|
|
"source_path": source_path, |
|
|
|
"backup_path": backup_path, |
|
|
|
}) |
|
|
|
|
|
|
|
if raise_on_empty and len(rows) == 0: |
|
|
|
@ -434,14 +472,20 @@ class CollectorApp: |
|
|
|
self.log("读取文件状态失败: %s, 原因: %s" % (file_path, e)) |
|
|
|
return None |
|
|
|
|
|
|
|
def _get_backup_dir(self, source_path): |
|
|
|
source = Path(source_path) |
|
|
|
return source.parent / (source.name + "_bak") |
|
|
|
def _get_backup_dir(self, row): |
|
|
|
backup_path = str(row.get("backup_path", "")).strip() |
|
|
|
if backup_path: |
|
|
|
return Path(backup_path) |
|
|
|
return Path(self._default_backup_path(row["source_path"])) |
|
|
|
|
|
|
|
def _backup_and_remove_file(self, row, file_path): |
|
|
|
source_path = row["source_path"] |
|
|
|
row_index = row["row_index"] |
|
|
|
backup_dir = self._get_backup_dir(source_path) |
|
|
|
backup_dir = self._get_backup_dir(row) |
|
|
|
|
|
|
|
if os.path.normcase(os.path.normpath(str(source_path))) == os.path.normcase(os.path.normpath(str(backup_dir))): |
|
|
|
self.log("第%d行备份目录不能与本地目录相同: %s" % (row_index, backup_dir)) |
|
|
|
return False |
|
|
|
|
|
|
|
try: |
|
|
|
backup_dir.mkdir(parents=True, exist_ok=True) |
|
|
|
|