From f0656d54de952f41a53f7d20d495431d27d4b67c Mon Sep 17 00:00:00 2001 From: CD Date: Fri, 6 Mar 2026 21:27:23 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EC=9C=A0=EB=A0=B9=20=EC=9B=8C=ED=81=AC?= =?UTF-8?q?=EC=8A=A4=ED=8E=98=EC=9D=B4=EC=8A=A4=20=ED=8F=B4=EB=8D=94?= =?UTF-8?q?=EB=8F=84=20=ED=95=A8=EA=BB=98=20=EC=9D=B4=EB=A6=84=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - cleanup_orphans: JSON 이름 + 실제 폴더 모두 _orphan_YYYYMMDD 접미사 - 같은 이름 재생성 시 새 폴더가 만들어짐 (충돌 없음) - 폴더 이름 중복 시 숫자 카운터 추가 --- core/workspace.py | 52 ++++++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/core/workspace.py b/core/workspace.py index d16fada..d75fe5d 100644 --- a/core/workspace.py +++ b/core/workspace.py @@ -160,45 +160,59 @@ class WorkspaceManager: ] def cleanup_orphans(self, valid_channel_ids: set[int]) -> list[Workspace]: - """존재하지 않는 채널의 워크스페이스를 이름 변경하여 보존. + """존재하지 않는 채널의 워크스페이스를 이름+폴더 변경하여 보존. - 삭제하지 않고 이름에 _orphan_날짜 접미사를 붙여 보존합니다. + 이름과 실제 폴더 모두 _orphan_날짜 접미사를 붙여 보존합니다. 기존 설정(Git, Vikunja)은 그대로 유지됩니다. Returns: 이름 변경된 워크스페이스 목록 (알림용) """ from datetime import datetime + import shutil renamed = [] suffix = f"_orphan_{datetime.now().strftime('%Y%m%d')}" for ch_id, ws in list(self.workspaces.items()): if ch_id not in valid_channel_ids: - old_name = ws.name # 이미 orphan 접미사가 있으면 스킵 if "_orphan_" in ws.name: continue - ws.name = f"{ws.name}{suffix}" - ws.channel_id = 0 # 채널 바인딩 해제 + + old_name = ws.name + old_path = Path(ws.path) + new_name = f"{ws.name}{suffix}" + + # 실제 폴더 이름 변경 + if old_path.exists(): + new_path = old_path.parent / f"{old_path.name}{suffix}" + # 이미 같은 이름 폴더가 있으면 숫자 추가 + counter = 1 + while new_path.exists(): + new_path = old_path.parent / f"{old_path.name}{suffix}_{counter}" + counter += 1 + try: + old_path.rename(new_path) + ws.path = str(new_path) + logger.info(f"폴더 이름 변경: {old_path} -> {new_path}") + except OSError as e: + logger.warning(f"폴더 이름 변경 실패: {e} (JSON만 업데이트)") + + ws.name = new_name + ws.channel_id = 0 renamed.append(ws) + + # 키를 orphan 키로 변경 + del self.workspaces[ch_id] + orphan_key = -abs(hash(new_name)) % (10**10) + self.workspaces[orphan_key] = ws + logger.info( - f"유령 워크스페이스 보존: {old_name} -> {ws.name} " - f"(채널 {ch_id} 없음, 설정 유지)" + f"유령 워크스페이스 보존: {old_name} -> {new_name} " + f"(채널 {ch_id} 없음, 설정+폴더 유지)" ) if renamed: - # 유령 항목은 channel_id=0 으로 이동 - to_remove = [ - ch_id for ch_id in self.workspaces - if ch_id not in valid_channel_ids and "_orphan_" not in self.workspaces[ch_id].name - ] - # 이미 이름 변경됐으므로 키만 정리 - for ch_id in list(self.workspaces.keys()): - if self.workspaces[ch_id].channel_id == 0 and ch_id != 0: - ws = self.workspaces.pop(ch_id) - # orphan은 이름을 키로 저장 (음수 해시) - orphan_key = -abs(hash(ws.name)) % (10**10) - self.workspaces[orphan_key] = ws self._save() return renamed