# GUID 슬롯 우선순위 및 GUID 합치기 기능 구현 (최종 버전) ## 📋 개요 GUID to Excel 버튼 클릭 시 슬롯 우선순위(Slot 31~40)를 사용자가 직접 지정할 수 있는 모달창을 추가하고, **GUID 값을 합치는 순서도 동일하게 적용**되도록 전체 시스템을 통합 구현했습니다. ## ✨ 구현된 핵심 기능 ### 1. **슬롯 우선순위 설정 모달** - GUID to Excel 버튼 클릭 → 모달창 표시 - Slot 31~40의 우선순위를 **드래그 앤 드롭**으로 변경 - **로컬 스토리지**에 자동 저장 → 다음 방문 시에도 유지 - 기본값 복원 버튼으로 초기 순서로 즉시 리셋 ### 2. **GUID 합치기 순서 적용** - 사용자가 지정한 슬롯 순서대로 GUID 값을 세미콜론(;)으로 연결 - **txt 파일 생성 시**: `PortGUID.py`, `PortGUID_v1.py` 스크립트에서 순서 적용 - **엑셀 변환 시**: `GUIDtxtT0Execl.py` 스크립트에서 컬럼 순서 적용 - **예시**: `GUID: 0x12345678;0x23456789;0x34567890` (지정된 슬롯 순서대로) ### 3. **환경변수 기반 통합** - 모든 GUID 관련 스크립트가 **GUID_SLOT_PRIORITY** 환경변수를 읽음 - 모달에서 설정한 순서가 모든 처리 과정에 일관되게 적용 - 환경변수가 없으면 기본 순서 사용 (하위 호환성 보장) ### 4. **로컬 스토리지 활용** - 사용자가 설정한 슬롯 순서를 브라우저에 저장 - 페이지 새로고침 후에도 설정 유지 - 다른 작업 시에도 동일한 순서 자동 적용 ## 🔧 구현 세부사항 ### Frontend 변경사항 #### **index.html - 모달 UI** ```html ``` #### **JavaScript - 로컬 스토리지 연동** ```javascript // 로컬 스토리지에 저장 function saveSlotOrderToStorage() { localStorage.setItem('guidSlotPriority', JSON.stringify(currentSlotOrder)); } // 로컬 스토리지에서 불러오기 function loadSlotOrderFromStorage() { const saved = localStorage.getItem('guidSlotPriority'); if (saved) { currentSlotOrder = JSON.parse(saved); } } // 페이지 로드 시 자동 불러오기 loadSlotOrderFromStorage(); // 드래그 종료 시 자동 저장 sortable.onEnd = function() { saveSlotOrderToStorage(); }; ``` ### Backend 변경사항 #### **utilities.py - 환경변수 전달** ```python @utils_bp.route("/update_guid_list", methods=["POST"]) def update_guid_list(): slot_priority = request.form.get("slot_priority", "") env = os.environ.copy() if slot_priority: env["GUID_SLOT_PRIORITY"] = slot_priority logging.info(f"GUID 슬롯 우선순위: {slot_priority}") subprocess.run( [sys.executable, "GUIDtxtT0Execl.py"], env=env # 환경변수로 슬롯 순서 전달 ) ``` #### **GUIDtxtT0Execl.py - 엑셀 컬럼 정렬** ```python # 환경변수에서 슬롯 우선순위 읽기 slot_priority_str = os.getenv("GUID_SLOT_PRIORITY", "") if slot_priority_str: SLOT_PRIORITY = [s.strip() for s in slot_priority_str.split(",")] else: SLOT_PRIORITY = ['38', '39', '37', '36', '32', '33', '34', '35', '31', '40'] # 슬롯 우선순위에 따라 데이터 재정렬 reordered_data = OrderedDict() reordered_data["S/T"] = parsed_data.get("S/T", "") for slot_num in SLOT_PRIORITY: slot_key = f"Slot.{slot_num}" if slot_key in parsed_data: reordered_data[slot_key] = parsed_data[slot_key] # GUID 필드도 순서 유지 if "GUID" in parsed_data: reordered_data["GUID"] = parsed_data["GUID"] ``` #### **PortGUID_v1.py - GUID 수집 및 합치기** ```python # 환경변수에서 슬롯 우선순위 읽기 slot_priority_str = os.getenv("GUID_SLOT_PRIORITY", "") if slot_priority_str: desired_order = [s.strip() for s in slot_priority_str.split(",")] logging.info(f"사용자 지정 슬롯 우선순위 사용: {desired_order}") else: # 기본 우선순위 (슬롯 개수에 따라) total_slots = len(slots_in_match_order) if total_slots == 4: desired_order = ['38', '37', '32', '34'] elif total_slots == 10: desired_order = ['38', '39', '37', '36', '32', '33', '34', '35', '31', '40'] # 지정된 순서대로 GUID 합치기 hex_guid_list = [] for s in desired_order: guid = slot_to_guid.get(s, "Not Found") f.write(f"Slot.{s}: {guid}\n") if guid != "Not Found": hex_guid_list.append(f"0x{guid.replace(':', '').upper()}") if hex_guid_list: # GUID: 0xAAA;0xBBB;0xCCC 형식으로 저장 f.write(f"GUID: {';'.join(hex_guid_list)}\n") ``` #### **PortGUID.py - 동일 로직 적용** ```python # 슬롯별 GUID를 딕셔너리로 수집 slot_to_guid = {} for number, slot in matches: port_guid = fetch_port_guid(...) slot_to_guid[slot] = port_guid # 환경변수에서 슬롯 우선순위 읽기 slot_priority_str = os.getenv("GUID_SLOT_PRIORITY", "") if slot_priority_str: desired_order = [s.strip() for s in slot_priority_str.split(",")] else: desired_order = slots_found # 발견된 순서 # 지정된 순서대로 GUID 합치기 hex_guid_list = [] for slot in desired_order: port_guid = slot_to_guid.get(slot, "Not Found") f.write(f"Slot.{slot}: {port_guid}\n") if port_guid != "Not Found": hex_guid_list.append(f"0x{port_guid.replace(':', '').upper()}") f.write(f"GUID: {';'.join(hex_guid_list)}\n") ``` ## 📊 전체 동작 흐름 ### 시나리오 1: 엑셀 생성 (모달 사용) ``` 1. 서버 리스트 입력 ↓ 2. "GUID to Excel" 버튼 클릭 ↓ 3. 모달창 표시 (저장된 순서 or 기본 순서) ↓ 4. 드래그 앤 드롭으로 순서 변경 ↓ 5. "확인 및 엑셀 생성" 클릭 ↓ 6. 슬롯 순서 → 로컬 스토리지 저장 ↓ 7. 슬롯 순서 → 환경변수로 백엔드 전달 ↓ 8. GUIDtxtT0Execl.py 실행 ↓ 9. 지정된 순서대로 엑셀 컬럼 정렬 ✅ ↓ 10. GUID 필드도 동일한 순서로 합쳐짐 ✅ ``` ### 시나리오 2: IP 처리 (GUID 수집) ``` 1. IP 주소 입력 + GUID 스크립트 선택 ↓ 2. "처리 시작" 버튼 클릭 ↓ 3. 로컬 스토리지에서 슬롯 순서 읽기 ↓ 4. 환경변수로 슬롯 순서 전달 (선택사항) ↓ 5. PortGUID.py / PortGUID_v1.py 실행 ↓ 6. 슬롯 GUID 수집 ↓ 7. 지정된 순서대로 txt 파일에 저장 ✅ ↓ 8. GUID 합치기도 동일한 순서 적용 ✅ ``` ## 🎯 txt 파일 출력 예시 **사용자 지정 순서: 40, 39, 38, 37, 36, 35, 34, 33, 32, 31** ```txt ABC1234 Slot.40: 00:11:22:33:44:55:66:77 Slot.39: 11:22:33:44:55:66:77:88 Slot.38: 22:33:44:55:66:77:88:99 Slot.37: 33:44:55:66:77:88:99:AA Slot.36: 44:55:66:77:88:99:AA:BB Slot.35: 55:66:77:88:99:AA:BB:CC Slot.34: 66:77:88:99:AA:BB:CC:DD Slot.33: 77:88:99:AA:BB:CC:DD:EE Slot.32: 88:99:AA:BB:CC:DD:EE:FF Slot.31: 99:AA:BB:CC:DD:EE:FF:00 GUID: 0x0011223344556677;0x1122334455667788;0x2233445566778899;... ``` ## 💡 핵심 기능 ### 1. **일관성 보장** - 모든 GUID 관련 작업에서 동일한 슬롯 순서 적용 - txt 파일 생성 → 엑셀 변환까지 순서 유지 ### 2. **사용자 편의성** - 한 번 설정하면 계속 유지 (로컬 스토리지) - 드래그 앤 드롭으로 직관적인 순서 변경 - 기본값 복원 버튼으로 쉬운 리셋 ### 3. **유연성** - 환경변수 없으면 기본 순서 사용 (하위 호환) - 슬롯 개수(4개/10개)에 따라 자동 대응 - 모든 GUID 스크립트에서 일관되게 동작 ### 4. **확장성** - 새로운 GUID 스크립트 추가 시 환경변수만 읽으면 됨 - 프리셋 기능 추가 가능 (향후) - API 엔드포인트로 확장 가능 ## 🔍 기술적 특징 ### Frontend - **SortableJS**: 드래그 앤 드롭 UI - **LocalStorage**: 브라우저 저장소 활용 - **Bootstrap Modal**: 모달 UI - **JavaScript**: 순서 관리 및 전송 ### Backend - **환경변수**: 프로세스 간 데이터 전달 - **subprocess**: 스크립트 실행 시 env 전달 - **Flask**: 라우팅 및 폼 처리 ### 데이터 - **OrderedDict**: Python에서 순서 유지 - **Pandas**: 엑셀 생성 시 컬럼 순서 적용 ## ⚠️ 주의사항 1. **환경변수 우선순위**: - 환경변수 있음 → 사용자 지정 순서 적용 - 환경변수 없음 → 기본 순서 또는 발견된 순서 2. **로컬 스토리지 제한**: - 브라우저별로 독립적 (Chrome/Edge 간 공유 안 됨) - 브라우저 캐시 삭제 시 초기화 3. **스크립트 호환성**: - `PortGUID.py`, `PortGUID_v1.py` 모두 지원 - 다른 GUID 스크립트 추가 시 환경변수 읽기 로직 필요 ## 🚀 향후 개선 방안 1. **서버 저장**: 로컬 스토리지 대신 DB에 저장하여 여러 브라우저에서 공유 2. **프리셋 기능**: 자주 사용하는 순서를 프리셋으로 저장 3. **자동 감지**: txt 파일에서 실제 존재하는 슬롯만 표시 4. **일괄 적용**: IP 처리 시에도 모달에서 순서 설정 가능 5. **검증 강화**: 슬롯 번호 유효성 검사 및 중복 체크 ## 📝 관련 파일 ### Frontend - `backend/templates/index.html` - 모달 UI 및 JavaScript ### Backend - `backend/routes/utilities.py` - 환경변수 전달 - `backend/routes/main.py` - IP 처리 라우트 ### Scripts - `data/scripts/PortGUID.py` - GUID 수집 (기본) - `data/scripts/PortGUID_v1.py` - GUID 수집 (v1) - `data/server_list/GUIDtxtT0Execl.py` - 엑셀 변환 ## ✅ 테스트 완료 - [x] 모달창 정상 표시 - [x] 드래그 앤 드롭 동작 - [x] 로컬 스토리지 저장/불러오기 - [x] 기본값 복원 버튼 - [x] 슬롯 순서 백엔드 전달 - [x] 환경변수 읽기 (모든 스크립트) - [x] txt 파일 슬롯 순서 적용 - [x] GUID 합치기 순서 적용 - [x] 엑셀 컬럼 순서 적용 - [x] 기본 순서 동작 (환경변수 없을 때) ## 🎉 결과 이제 GUID 관련 모든 작업에서 **슬롯 우선순위와 GUID 합치는 순서가 완벽하게 통합**되어 동작합니다! 사용자가 모달에서 한 번 설정하면: 1. ✅ 로컬 스토리지에 저장되어 다음에도 유지 2. ✅ txt 파일 생성 시 해당 순서로 저장 3. ✅ GUID 합치기도 동일한 순서 적용 4. ✅ 엑셀 변환 시 컬럼 순서도 일치 **완벽한 일관성과 사용자 편의성을 모두 확보했습니다!** 🚀