This commit is contained in:
unknown
2026-03-21 07:26:38 +09:00
parent 166d94fca4
commit 40150cd66d
406 changed files with 34179 additions and 55658 deletions
+4 -4
View File
@@ -126,13 +126,13 @@ def main():
# ---- Preset 기본값 설정 ----
if args.preset == "guid":
default_input_dir = Path(os.getenv("GUID_TXT_DIR", DATA_ROOT / "guid_file"))
default_input_dir = Path(os.getenv("GUID_TXT_DIR", DATA_ROOT / "repository" / "guid_file"))
default_list_file = Path(os.getenv("GUID_LIST_FILE", DATA_ROOT / "server_list" / "guid_list.txt"))
default_output = Path(os.getenv("GUID_OUTPUT_XLSX", DATA_ROOT / "idrac_info" / "XE9680_GUID.xlsx"))
default_output = Path(os.getenv("GUID_OUTPUT_XLSX", DATA_ROOT / "temp" / "staging" / "XE9680_GUID.xlsx"))
else: # gpu
default_input_dir = Path(os.getenv("GPU_TXT_DIR", DATA_ROOT / "gpu_serial"))
default_input_dir = Path(os.getenv("GPU_TXT_DIR", DATA_ROOT / "repository" / "gpu_serial"))
default_list_file = Path(os.getenv("GPU_LIST_FILE", DATA_ROOT / "server_list" / "gpu_serial_list.txt"))
default_output = Path(os.getenv("GPU_OUTPUT_XLSX", DATA_ROOT / "idrac_info" / "GPU_SERIALS.xlsx"))
default_output = Path(os.getenv("GPU_OUTPUT_XLSX", DATA_ROOT / "temp" / "staging" / "GPU_SERIALS.xlsx"))
input_dir: Path = args.input_dir or default_input_dir
list_file: Path | None = args.list_file or (default_list_file if default_list_file.is_file() else None)
+2 -2
View File
@@ -34,10 +34,10 @@ DATA_ROOT = resolve_data_root()
SERVER_LIST_DIR = Path(os.getenv("GUID_SERVER_LIST_DIR", DATA_ROOT / "server_list"))
SERVER_LIST_FILE = Path(os.getenv("GUID_LIST_FILE", SERVER_LIST_DIR / "guid_list.txt"))
GUID_TXT_DIR = Path(os.getenv("GUID_TXT_DIR", DATA_ROOT / "guid_file"))
GUID_TXT_DIR = Path(os.getenv("GUID_TXT_DIR", DATA_ROOT / "repository" / "guid_file"))
OUTPUT_XLSX = Path(
os.getenv("GUID_OUTPUT_XLSX", DATA_ROOT / "idrac_info" / "XE9680_GUID.xlsx")
os.getenv("GUID_OUTPUT_XLSX", DATA_ROOT / "temp" / "staging" / "XE9680_GUID.xlsx")
)
# Make sure output directory exists
+2 -2
View File
@@ -30,8 +30,8 @@ DATA_ROOT = resolve_data_root()
SERVER_LIST_DIR = DATA_ROOT / "server_list"
SERVER_LIST_FILE = SERVER_LIST_DIR / "server_list.txt"
MAC_TXT_DIR = DATA_ROOT / "mac"
OUTPUT_XLSX = DATA_ROOT / "idrac_info" / "mac_info.xlsx"
MAC_TXT_DIR = DATA_ROOT / "repository" / "mac"
OUTPUT_XLSX = DATA_ROOT / "temp" / "staging" / "mac_info.xlsx"
# Ensure output directory exists
OUTPUT_XLSX.parent.mkdir(parents=True, exist_ok=True)
-49
View File
@@ -1,49 +0,0 @@
import os
import pandas as pd
# server_list.txt 파일이 있는 폴더 경로
server_list_folder = '/app/idrac_info/server_list/' # 실제 경로로 수정
server_list_file = os.path.join(server_list_folder, 'server_list.txt')
# 추출할 .txt 파일들이 있는 폴더 경로
data_files_folder = '/app/idrac_info/mac/' # 실제 경로로 수정
# server_list.txt 파일에서 파일명을 읽어들임
with open(server_list_file, 'r') as f:
file_names = f.read().splitlines()
# 각 파일의 내용을 저장할 리스트 생성
data_list = []
index_list = []
# 각 파일을 읽어들여 리스트에 저장
sequence_number = 1
for file_name in file_names:
file_path = os.path.join(data_files_folder, f'{file_name}.txt')
if os.path.exists(file_path):
with open(file_path, 'r') as file:
lines = file.readlines()
for line in lines:
cleaned_line = line.strip().upper() # 대문자로 변환
if cleaned_line: # 빈 라인은 무시
data_list.append(cleaned_line)
if len(cleaned_line) == 7:
index_list.append(sequence_number)
sequence_number += 1
else:
index_list.append('') # 7자가 아닌 경우 빈 문자열로 유지
else:
index_list.append('') # 빈 라인은 인덱스에도 빈 값으로 유지
else:
data_list.append('')
index_list.append('') # 파일이 없을 경우 빈 문자열로 유지
# 데이터를 DataFrame으로 변환하여 B열부터 시작하도록 함
df = pd.DataFrame({
'Index': index_list,
'Content': data_list
})
# 엑셀 파일로 저장
output_file = '/app/idrac_info/idrac_info/mac_info.xlsx'
df.to_excel(output_file, index=False, header=False)
+80 -3
View File
@@ -1,3 +1,80 @@
1V48HG4
1T48HG4
7Y3J2H4
G8KS3H4
F9KS3H4
2BKS3H4
JW3J2H4
49KS3H4
BX3J2H4
5X3J2H4
HX3J2H4
1NRS3H4
7PRS3H4
4X3J2H4
29KS3H4
CY3J2H4
3RPJ5H4
GQPJ5H4
C4DY4H4
G3DY4H4
79KS3H4
8X3J2H4
9QPJ5H4
B4DY4H4
45DY4H4
HPPJ5H4
88KS3H4
JX3J2H4
7Z3J2H4
DVRS3H4
18KS3H4
5Y3J2H4
H3DY4H4
94DY4H4
F3DY4H4
24DY4H4
69PG4H4
19PG4H4
J1DY4H4
4QPJ5H4
D4DY4H4
8TPJ5H4
43DY4H4
53DY4H4
2QPJ5H4
CPPJ5H4
44DY4H4
FQPJ5H4
G2DY4H4
H7KS3H4
D9KS3H4
49PG4H4
5RPJ5H4
9RPJ5H4
2JKS3H4
23DY4H4
BNRS3H4
79PG4H4
JKPG4H4
GNRS3H4
FY3J2H4
9NRS3H4
B8PG4H4
39PG4H4
99PG4H4
48PG4H4
D8PG4H4
3PRS3H4
D8KS3H4
1X3J2H4
9X3J2H4
2X3J2H4
J2DY4H4
BQPJ5H4
2Z3J2H4
GX3J2H4
C9KS3H4
3WRG4H4
1JKS3H4
29PG4H4
DQPJ5H4
68DY4H4
+80 -2
View File
@@ -1,2 +1,80 @@
1BZ7HG4
7Y3J2H4
G8KS3H4
F9KS3H4
2BKS3H4
JW3J2H4
49KS3H4
BX3J2H4
5X3J2H4
HX3J2H4
1NRS3H4
7PRS3H4
4X3J2H4
29KS3H4
CY3J2H4
3RPJ5H4
GQPJ5H4
C4DY4H4
G3DY4H4
79KS3H4
8X3J2H4
9QPJ5H4
B4DY4H4
45DY4H4
HPPJ5H4
88KS3H4
JX3J2H4
7Z3J2H4
DVRS3H4
18KS3H4
5Y3J2H4
H3DY4H4
94DY4H4
F3DY4H4
24DY4H4
69PG4H4
19PG4H4
J1DY4H4
4QPJ5H4
D4DY4H4
8TPJ5H4
43DY4H4
53DY4H4
2QPJ5H4
CPPJ5H4
44DY4H4
FQPJ5H4
G2DY4H4
H7KS3H4
D9KS3H4
49PG4H4
5RPJ5H4
9RPJ5H4
2JKS3H4
23DY4H4
BNRS3H4
79PG4H4
JKPG4H4
GNRS3H4
FY3J2H4
9NRS3H4
B8PG4H4
39PG4H4
99PG4H4
48PG4H4
D8PG4H4
3PRS3H4
D8KS3H4
1X3J2H4
9X3J2H4
2X3J2H4
J2DY4H4
BQPJ5H4
2Z3J2H4
GX3J2H4
C9KS3H4
3WRG4H4
1JKS3H4
29PG4H4
DQPJ5H4
68DY4H4
+2 -1
View File
@@ -31,7 +31,8 @@ def zip_selected_files(folder_path, file_list, output_zip):
# /app/idrac_info/backup/ 폴더 내 폴더를 나열하고 사용자 선택 받는 함수
def select_folder():
base_path = "/data/app/idrac_info/data/backup/"
# Assume script is in data/server_list, backup is in data/system/backup
base_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "system", "backup")
if not os.path.isdir(base_path):
raise ValueError(f"기본 경로 '{base_path}'이(가) 존재하지 않습니다.")
+20 -3
View File
@@ -1,3 +1,20 @@
1V48HG4
1T48HG4
BDNXRH4
J9MXRH4
6DNXRH4
59MXRH4
G9MXRH4
79MXRH4
B9MXRH4
99MXRH4
9GMXRH4
49MXRH4
89MXRH4
G8MXRH4
H8MXRH4
1BMXRH4
4BMXRH4
GV5MQH4
6W5MQH4
JT5MQH4
DT5MQH4
3V5MQH4
+307
View File
@@ -0,0 +1,307 @@
from __future__ import annotations
import os
import argparse
import sys
import logging
from pathlib import Path
from collections import OrderedDict
import pandas as pd
# -----------------------------------------------------------------------------
# Logging Configuration
# -----------------------------------------------------------------------------
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s [INFO] %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
logger = logging.getLogger(__name__)
# -----------------------------------------------------------------------------
# Path Resolution
# -----------------------------------------------------------------------------
def resolve_data_root() -> Path:
"""
Priority:
1) Env var IDRAC_DATA_DIR (absolute/relative OK)
2) nearest parent of this file that contains a 'data' folder
3) ./data under current working directory
"""
env = os.getenv("IDRAC_DATA_DIR")
if env:
return Path(env).expanduser().resolve()
here = Path(__file__).resolve()
for p in [here] + list(here.parents):
if (p / "data").is_dir():
return (p / "data").resolve()
# Fallback to current working directory assumption
cwd_data = Path.cwd() / "data"
if cwd_data.is_dir():
return cwd_data.resolve()
# Final fallback: Assume we are in data/server_list/ -> go up two levels
return here.parent.parent
DATA_ROOT = resolve_data_root()
# Default Paths (can be overridden by args)
DEFAULT_GUID_INPUT = DATA_ROOT / "repository" / "guid_file"
DEFAULT_GPU_INPUT = DATA_ROOT / "repository" / "gpu_serial"
DEFAULT_MAC_INPUT = DATA_ROOT / "repository" / "mac"
DEFAULT_GUID_LIST = DATA_ROOT / "server_list" / "guid_list.txt"
DEFAULT_GPU_LIST = DATA_ROOT / "server_list" / "gpu_serial_list.txt"
DEFAULT_MAC_LIST = DATA_ROOT / "server_list" / "server_list.txt"
DEFAULT_GUID_OUTPUT = DATA_ROOT / "temp" / "staging" / "XE9680_GUID.xlsx"
DEFAULT_GPU_OUTPUT = DATA_ROOT / "temp" / "staging" / "GPU_SERIALS.xlsx"
DEFAULT_MAC_OUTPUT = DATA_ROOT / "temp" / "staging" / "mac_info.xlsx"
# -----------------------------------------------------------------------------
# Utility Functions
# -----------------------------------------------------------------------------
def read_lines_any_encoding(path: Path) -> list[str]:
"""Read text file trying common encodings."""
if not path.is_file():
return []
encodings = ["utf-8-sig", "utf-8", "cp949", "euc-kr", "latin-1"]
for enc in encodings:
try:
with path.open("r", encoding=enc, errors="strict") as f:
return f.read().splitlines()
except Exception:
continue
# last resort
with path.open("r", encoding="utf-8", errors="replace") as f:
return f.read().splitlines()
def parse_txt_key_value(file_path: Path) -> dict:
"""
Parse standarized Key: Value files (GPU, GUID).
First line is assumed to be S/T (Service Tag).
"""
lines = read_lines_any_encoding(file_path)
if not lines:
return {}
data = OrderedDict()
data["S/T"] = lines[0].strip()
for raw in lines[1:]:
line = raw.strip()
if not line or ":" not in line:
continue
key, value = line.split(":", 1)
data[key.strip()] = value.strip()
return dict(data)
# -----------------------------------------------------------------------------
# Mode: MAC
# -----------------------------------------------------------------------------
def process_mac(input_dir: Path, list_file: Path, output_xlsx: Path):
"""
Logic from excel.py
"""
if not list_file.is_file():
raise FileNotFoundError(f"Server list file not found: {list_file}")
file_names = read_lines_any_encoding(list_file)
data_list: list[str] = []
index_list: list[int | str] = []
sequence_number = 1
for name in file_names:
base = (name or "").strip()
if not base:
continue
txt_path = input_dir / f"{base}.txt"
if not txt_path.is_file():
# Missing file handling
data_list.append("")
index_list.append("")
continue
lines = read_lines_any_encoding(txt_path)
for line in lines:
cleaned = (line or "").strip().upper()
if cleaned:
data_list.append(cleaned)
# Specific logic: if length is 7, treat as an index/sequence indicator
if len(cleaned) == 7:
index_list.append(sequence_number)
sequence_number += 1
else:
index_list.append("")
else:
data_list.append("")
index_list.append("")
# Create DataFrame
df = pd.DataFrame({
"Index": index_list,
"Content": data_list,
})
# Save without header, without index
output_xlsx.parent.mkdir(parents=True, exist_ok=True)
df.to_excel(output_xlsx, index=False, header=False)
logger.info(f"[MAC] Saved to {output_xlsx}")
# -----------------------------------------------------------------------------
# Mode: GPU
# -----------------------------------------------------------------------------
def process_gpu(input_dir: Path, list_file: Path, output_xlsx: Path):
"""
Logic from GPUTOExecl.py
"""
if not input_dir.is_dir():
raise FileNotFoundError(f"Input directory not found: {input_dir}")
# File collection
files: list[Path] = []
if list_file and list_file.is_file():
names = [x.strip() for x in read_lines_any_encoding(list_file) if x.strip()]
for name in names:
p = input_dir / f"{name}.txt"
if p.is_file():
files.append(p)
else:
logger.warning(f"[GPU] File not found: {p.name}")
else:
# Fallback to glob
files = sorted(input_dir.glob("*.txt"))
if not files:
logger.warning("[GPU] No files to process.")
return
# Parse
rows = []
for p in files:
rows.append(parse_txt_key_value(p))
df = pd.DataFrame(rows)
# Insert 'No' column
df.insert(0, "No", range(1, len(df) + 1))
output_xlsx.parent.mkdir(parents=True, exist_ok=True)
df.to_excel(output_xlsx, index=False)
logger.info(f"[GPU] Saved to {output_xlsx}")
# -----------------------------------------------------------------------------
# Mode: GUID
# -----------------------------------------------------------------------------
def process_guid(input_dir: Path, list_file: Path, output_xlsx: Path):
"""
Logic from GUIDtxtT0Execl.py
"""
if not input_dir.is_dir():
raise FileNotFoundError(f"Input directory not found: {input_dir}")
# Determine Slot Priority
slot_priority_str = os.getenv("GUID_SLOT_PRIORITY", "")
if slot_priority_str:
slot_priority = [s.strip() for s in slot_priority_str.split(",") if s.strip()]
logger.info(f"[GUID] Custom slot priority: {slot_priority}")
else:
slot_priority = ['38', '39', '37', '36', '32', '33', '34', '35', '31', '40']
logger.info(f"[GUID] Default slot priority: {slot_priority}")
# File collection
files: list[Path] = []
names = []
if list_file and list_file.is_file():
names = [x.strip() for x in read_lines_any_encoding(list_file) if x.strip()]
# Process
rows = []
for name in names:
txt_path = input_dir / f"{name}.txt"
if not txt_path.is_file():
logger.warning(f"[GUID] File not found: {txt_path.name}")
continue
raw_data = parse_txt_key_value(txt_path)
# Reorder and reconstruct GUID
ordered_data = OrderedDict()
ordered_data["S/T"] = raw_data.get("S/T", "")
new_guid_list = []
for slot_num in slot_priority:
slot_key = f"Slot.{slot_num}"
val = raw_data.get(slot_key)
if val:
ordered_data[slot_key] = val
if val != "Not Found" and ":" in val:
clean_hex = val.replace(":", "").upper()
new_guid_list.append(f"0x{clean_hex}")
# GUID Selection logic
if new_guid_list:
ordered_data["GUID"] = ";".join(new_guid_list)
elif "GUID" in raw_data:
ordered_data["GUID"] = raw_data["GUID"]
# Add remaining fields
for k, v in raw_data.items():
if k not in ordered_data:
ordered_data[k] = v
rows.append(dict(ordered_data))
if not rows:
logger.warning("[GUID] No data processed.")
# Create empty excel if needed or just return
return
df = pd.DataFrame(rows)
df.insert(0, "No", range(1, len(df) + 1))
output_xlsx.parent.mkdir(parents=True, exist_ok=True)
df.to_excel(output_xlsx, index=False)
logger.info(f"[GUID] Saved to {output_xlsx}")
# -----------------------------------------------------------------------------
# Main Entry Point
# -----------------------------------------------------------------------------
def main():
parser = argparse.ArgumentParser(description="Unified Excel Generator")
parser.add_argument("--mode", required=True, choices=["mac", "gpu", "guid"], help="Generation mode")
parser.add_argument("--input-dir", type=Path, help="Input directory (optional override)")
parser.add_argument("--list-file", type=Path, help="List file (optional override)")
parser.add_argument("--output-xlsx", type=Path, help="Output XLSX path (optional override)")
args = parser.parse_args()
mode = args.mode
# Determine effective paths based on mode and overrides
if mode == "mac":
input_dir = args.input_dir or DEFAULT_MAC_INPUT
list_file = args.list_file or DEFAULT_MAC_LIST
output_xlsx = args.output_xlsx or DEFAULT_MAC_OUTPUT
process_mac(input_dir, list_file, output_xlsx)
elif mode == "gpu":
input_dir = args.input_dir or DEFAULT_GPU_INPUT
list_file = args.list_file or DEFAULT_GPU_LIST
output_xlsx = args.output_xlsx or DEFAULT_GPU_OUTPUT
process_gpu(input_dir, list_file, output_xlsx)
elif mode == "guid":
input_dir = args.input_dir or DEFAULT_GUID_INPUT
list_file = args.list_file or DEFAULT_GUID_LIST
output_xlsx = args.output_xlsx or DEFAULT_GUID_OUTPUT
process_guid(input_dir, list_file, output_xlsx)
if __name__ == "__main__":
main()