시스템 설정 탭 스크롤/섹션화 및 빈 상태값 보정
This commit is contained in:
parent
cfa4c73b25
commit
5ac6281195
|
|
@ -282,6 +282,10 @@ class SchedulerManager:
|
|||
|
||||
for post_dict in posts_data:
|
||||
try:
|
||||
# 목록 데이터 보정: 일부 게시글은 status가 공백으로 내려올 수 있음
|
||||
if not str(post_dict.get('status', '')).strip():
|
||||
post_dict['status'] = "미분류"
|
||||
|
||||
# Pydantic 모델을 통한 데이터 검증
|
||||
post_obj = VOCPost(**post_dict)
|
||||
except ValidationError as e:
|
||||
|
|
|
|||
|
|
@ -202,49 +202,47 @@ class SettingsDialog(ctk.CTkToplevel):
|
|||
|
||||
def _init_system_tab(self):
|
||||
font_bold = theme_manager.get_font(13, "bold")
|
||||
|
||||
# === 로그 관리 섹션 ===
|
||||
ctk.CTkLabel(self.tab_system, text="시스템 로그 관리", font=font_bold).pack(pady=(10, 5), anchor="w", padx=20)
|
||||
|
||||
|
||||
system_body = ctk.CTkScrollableFrame(self.tab_system)
|
||||
system_body.pack(fill="both", expand=True, padx=10, pady=10)
|
||||
|
||||
# === A. 진단/로그 ===
|
||||
ctk.CTkLabel(system_body, text="진단 및 로그", font=font_bold).pack(pady=(6, 5), anchor="w", padx=12)
|
||||
|
||||
def open_logs():
|
||||
from view.dialogs.log_viewer_dialog import LogViewerDialog
|
||||
LogViewerDialog(self)
|
||||
|
||||
|
||||
ctk.CTkButton(
|
||||
self.tab_system,
|
||||
text="📋 로그 확인",
|
||||
system_body,
|
||||
text="📋 로그 확인",
|
||||
command=open_logs,
|
||||
width=200,
|
||||
height=35
|
||||
).pack(pady=5, padx=20, anchor="w")
|
||||
|
||||
# 구분선
|
||||
ctk.CTkLabel(self.tab_system, text="", height=1, fg_color="gray").pack(fill="x", padx=20, pady=15)
|
||||
|
||||
# === 보고서 저장 경로 섹션 ===
|
||||
ctk.CTkLabel(self.tab_system, text="보고서 저장 경로", font=font_bold).pack(pady=(10, 5), anchor="w", padx=20)
|
||||
|
||||
# 현재 경로 표시 프레임
|
||||
path_frame = ctk.CTkFrame(self.tab_system, fg_color="transparent")
|
||||
path_frame.pack(fill="x", padx=20, pady=5)
|
||||
|
||||
# 현재 경로 가져오기 (기본값: output 폴더)
|
||||
height=35,
|
||||
).pack(pady=5, padx=12, anchor="w")
|
||||
|
||||
ctk.CTkLabel(system_body, text="", height=1, fg_color="gray").pack(fill="x", padx=12, pady=12)
|
||||
|
||||
# === B. 보고서 ===
|
||||
ctk.CTkLabel(system_body, text="보고서 저장", font=font_bold).pack(pady=(6, 5), anchor="w", padx=12)
|
||||
|
||||
path_frame = ctk.CTkFrame(system_body, fg_color="transparent")
|
||||
path_frame.pack(fill="x", padx=12, pady=5)
|
||||
|
||||
current_path = self.controller.settings.get('report', {}).get('output_path', '')
|
||||
if not current_path:
|
||||
# 기본 경로 설정
|
||||
from utils.path_utils import get_base_dir
|
||||
current_path = str(get_base_dir().parent / "output")
|
||||
|
||||
|
||||
self.report_path_label = ctk.CTkLabel(
|
||||
path_frame,
|
||||
text=current_path,
|
||||
font=theme_manager.get_font(11),
|
||||
text_color=("gray40", "gray60"),
|
||||
anchor="w"
|
||||
anchor="w",
|
||||
)
|
||||
self.report_path_label.pack(side="left", fill="x", expand=True, padx=(0, 10))
|
||||
|
||||
# 경로 변경 버튼
|
||||
|
||||
ctk.CTkButton(
|
||||
path_frame,
|
||||
text="📁 폴더 선택",
|
||||
|
|
@ -252,90 +250,89 @@ class SettingsDialog(ctk.CTkToplevel):
|
|||
width=120,
|
||||
height=35,
|
||||
fg_color=("#1f538d", "#2980b9"),
|
||||
hover_color=("#174a7a", "#1f6fa8")
|
||||
hover_color=("#174a7a", "#1f6fa8"),
|
||||
).pack(side="left")
|
||||
|
||||
# 안내 문구
|
||||
|
||||
ctk.CTkLabel(
|
||||
self.tab_system,
|
||||
text="※ HWP 및 PDF 보고서가 저장될 폴더를 지정합니다.",
|
||||
system_body,
|
||||
text="※ HWP/PDF 보고서 저장 위치를 지정합니다.",
|
||||
font=theme_manager.get_font(10),
|
||||
text_color="gray"
|
||||
).pack(anchor="w", padx=45, pady=(5, 0))
|
||||
text_color="gray",
|
||||
).pack(anchor="w", padx=36, pady=(4, 0))
|
||||
|
||||
ctk.CTkLabel(self.tab_system, text="", height=1, fg_color="gray").pack(fill="x", padx=20, pady=15)
|
||||
|
||||
ctk.CTkLabel(self.tab_system, text="업데이트 정책", font=font_bold).pack(pady=(10, 5), anchor="w", padx=20)
|
||||
ctk.CTkLabel(system_body, text="", height=1, fg_color="gray").pack(fill="x", padx=12, pady=12)
|
||||
|
||||
# === C. 업데이트 ===
|
||||
ctk.CTkLabel(system_body, text="업데이트 정책", font=font_bold).pack(pady=(6, 5), anchor="w", padx=12)
|
||||
update_settings = self.controller.settings.get('update', {})
|
||||
|
||||
ctk.CTkLabel(self.tab_system, text="허용 업데이트 등급 (쉼표 구분)", font=theme_manager.get_font(11)).pack(anchor="w", padx=20)
|
||||
self.entry_allowed_levels = ctk.CTkEntry(self.tab_system)
|
||||
self.entry_allowed_levels.pack(fill="x", padx=20, pady=(4, 8))
|
||||
ctk.CTkLabel(system_body, text="허용 업데이트 등급 (쉼표 구분)", font=theme_manager.get_font(11)).pack(anchor="w", padx=12)
|
||||
self.entry_allowed_levels = ctk.CTkEntry(system_body)
|
||||
self.entry_allowed_levels.pack(fill="x", padx=12, pady=(4, 8))
|
||||
self.entry_allowed_levels.insert(0, ", ".join(update_settings.get('allowed_update_levels', ['patch', 'minor', 'major'])))
|
||||
|
||||
ctk.CTkLabel(self.tab_system, text="클린 설치 적용 등급 (쉼표 구분)", font=theme_manager.get_font(11)).pack(anchor="w", padx=20)
|
||||
self.entry_clean_levels = ctk.CTkEntry(self.tab_system)
|
||||
self.entry_clean_levels.pack(fill="x", padx=20, pady=(4, 8))
|
||||
ctk.CTkLabel(system_body, text="클린 설치 적용 등급 (쉼표 구분)", font=theme_manager.get_font(11)).pack(anchor="w", padx=12)
|
||||
self.entry_clean_levels = ctk.CTkEntry(system_body)
|
||||
self.entry_clean_levels.pack(fill="x", padx=12, pady=(4, 8))
|
||||
self.entry_clean_levels.insert(0, ", ".join(update_settings.get('clean_install_levels', ['minor', 'major'])))
|
||||
|
||||
ctk.CTkLabel(self.tab_system, text="보존 파일 패턴 (쉼표 구분)", font=theme_manager.get_font(11)).pack(anchor="w", padx=20)
|
||||
self.entry_preserve_globs = ctk.CTkEntry(self.tab_system)
|
||||
self.entry_preserve_globs.pack(fill="x", padx=20, pady=(4, 8))
|
||||
ctk.CTkLabel(system_body, text="보존 파일 패턴 (쉼표 구분)", font=theme_manager.get_font(11)).pack(anchor="w", padx=12)
|
||||
self.entry_preserve_globs = ctk.CTkEntry(system_body)
|
||||
self.entry_preserve_globs.pack(fill="x", padx=12, pady=(4, 8))
|
||||
self.entry_preserve_globs.insert(0, ", ".join(update_settings.get('preserve_globs', ['data/*.sqlite', 'data/*.json', 'data/*.db'])))
|
||||
|
||||
self.cleanup_backup_var = ctk.BooleanVar(value=bool(update_settings.get('cleanup_backup_on_success', True)))
|
||||
ctk.CTkSwitch(
|
||||
self.tab_system,
|
||||
system_body,
|
||||
text="업데이트 성공 시 백업 폴더 자동 정리",
|
||||
variable=self.cleanup_backup_var,
|
||||
).pack(anchor="w", padx=20, pady=(4, 6))
|
||||
).pack(anchor="w", padx=12, pady=(2, 6))
|
||||
|
||||
self.clean_install_var = ctk.BooleanVar(value=bool(update_settings.get('clean_install_before_copy', True)))
|
||||
ctk.CTkSwitch(
|
||||
self.tab_system,
|
||||
system_body,
|
||||
text="업데이트 전 기존 파일 정리(잔존 라이브러리 간섭 방지)",
|
||||
variable=self.clean_install_var,
|
||||
).pack(anchor="w", padx=20, pady=(0, 6))
|
||||
).pack(anchor="w", padx=12, pady=(0, 6))
|
||||
|
||||
ctk.CTkLabel(
|
||||
self.tab_system,
|
||||
system_body,
|
||||
text="※ major/minor 업데이트는 기본적으로 클린 설치 권장",
|
||||
font=theme_manager.get_font(10),
|
||||
text_color="gray"
|
||||
).pack(anchor="w", padx=45, pady=(0, 0))
|
||||
text_color="gray",
|
||||
).pack(anchor="w", padx=36, pady=(0, 0))
|
||||
|
||||
ctk.CTkLabel(self.tab_system, text="", height=1, fg_color="gray").pack(fill="x", padx=20, pady=15)
|
||||
|
||||
ctk.CTkLabel(self.tab_system, text="Supabase 동기화", font=font_bold).pack(pady=(10, 5), anchor="w", padx=20)
|
||||
ctk.CTkLabel(system_body, text="", height=1, fg_color="gray").pack(fill="x", padx=12, pady=12)
|
||||
|
||||
# === D. Supabase 동기화 ===
|
||||
ctk.CTkLabel(system_body, text="Supabase 동기화", font=font_bold).pack(pady=(6, 5), anchor="w", padx=12)
|
||||
sync_settings = self.controller.settings.get('sync', {})
|
||||
|
||||
self.sync_enabled_var = ctk.BooleanVar(value=bool(sync_settings.get('enabled', False)))
|
||||
ctk.CTkSwitch(
|
||||
self.tab_system,
|
||||
system_body,
|
||||
text="크롤링 대신 Supabase 동기화 사용",
|
||||
variable=self.sync_enabled_var,
|
||||
).pack(anchor="w", padx=20, pady=(4, 6))
|
||||
).pack(anchor="w", padx=12, pady=(2, 6))
|
||||
|
||||
ctk.CTkLabel(self.tab_system, text="동기화 주기(분)", font=theme_manager.get_font(11)).pack(anchor="w", padx=20)
|
||||
self.combo_sync_interval = ctk.CTkComboBox(self.tab_system, values=["1", "3", "5", "10", "30"])
|
||||
self.combo_sync_interval.pack(fill="x", padx=20, pady=(4, 8))
|
||||
ctk.CTkLabel(system_body, text="동기화 주기(분)", font=theme_manager.get_font(11)).pack(anchor="w", padx=12)
|
||||
self.combo_sync_interval = ctk.CTkComboBox(system_body, values=["1", "3", "5", "10", "30"])
|
||||
self.combo_sync_interval.pack(fill="x", padx=12, pady=(4, 8))
|
||||
self.combo_sync_interval.set(str(sync_settings.get('pull_interval_minutes', 3)))
|
||||
|
||||
ctk.CTkLabel(self.tab_system, text="동기화 대상 테이블", font=theme_manager.get_font(11)).pack(anchor="w", padx=20)
|
||||
self.entry_sync_table = ctk.CTkEntry(self.tab_system)
|
||||
self.entry_sync_table.pack(fill="x", padx=20, pady=(4, 8))
|
||||
ctk.CTkLabel(system_body, text="동기화 대상 테이블", font=theme_manager.get_font(11)).pack(anchor="w", padx=12)
|
||||
self.entry_sync_table = ctk.CTkEntry(system_body)
|
||||
self.entry_sync_table.pack(fill="x", padx=12, pady=(4, 8))
|
||||
self.entry_sync_table.insert(0, str(sync_settings.get('table', 'posts')))
|
||||
|
||||
ctk.CTkLabel(
|
||||
self.tab_system,
|
||||
system_body,
|
||||
text="※ URL/KEY는 update 연결정보를 재사용합니다(기본).",
|
||||
font=theme_manager.get_font(10),
|
||||
text_color="gray"
|
||||
).pack(anchor="w", padx=45, pady=(0, 0))
|
||||
text_color="gray",
|
||||
).pack(anchor="w", padx=36, pady=(0, 0))
|
||||
|
||||
ctk.CTkButton(self.tab_system, text="설정 저장", command=self.save_all).pack(pady=20)
|
||||
ctk.CTkButton(system_body, text="설정 저장", command=self.save_all).pack(pady=20)
|
||||
|
||||
def _select_report_folder(self):
|
||||
"""보고서 저장 폴더 선택 다이얼로그"""
|
||||
|
|
|
|||
Loading…
Reference in New Issue