# -*- coding: utf-8 -*- """ 상수 정의 모듈 애플리케이션 전역에서 사용되는 상수들을 정의합니다. 이 모듈은 다음을 포함합니다: - 애플리케이션 정보 - 팀 및 권한 관련 상수 - UI 관련 상수 - 데이터베이스 관련 상수 - 파일 경로 상수 """ import os from pathlib import Path from typing import Dict, List, Tuple # ============================================================================ # 애플리케이션 정보 # ============================================================================ APP_NAME = "전동차 업무 인수인계 시스템 (Created by ChoiKH)" APP_NAME_EN = "Train Handover System" APP_VERSION = "1.0.0" APP_AUTHOR = "검수팀" APP_DESCRIPTION = "전동차 운용실 업무 인수인계 및 고장관리 프로그램" # ============================================================================ # 경로 상수 # ============================================================================ # 프로젝트 루트 디렉토리 ROOT_DIR = Path(__file__).parent.parent.absolute() # 데이터 디렉토리 DATA_DIR = ROOT_DIR / "data" LOGS_DIR = ROOT_DIR / "logs" ASSETS_DIR = ROOT_DIR / "assets" FONTS_DIR = ASSETS_DIR / "fonts" ICONS_DIR = ASSETS_DIR / "icons" IMAGES_DIR = ASSETS_DIR / "images" STYLES_DIR = ASSETS_DIR / "styles" # 데이터베이스 파일 DB_FILE = DATA_DIR / "handover.db" # 설정 파일 CONFIG_FILE = ROOT_DIR / "config.ini" # ============================================================================ # 팀 관련 상수 # ============================================================================ # 팀 목록 TEAMS: List[str] = ["1팀", "2팀", "3팀", "4팀"] # 근무 유형 SHIFT_TYPES: Dict[str, str] = { "day": "주간", "night": "야간", } # 팀 직책 TEAM_POSITIONS: Dict[str, Dict] = { "vice_leader": { "name": "부팀장", "count": 2, # 각 팀당 2명 }, "operator": { "name": "운용", "count": 3, # 각 팀당 2~3명 }, } # ============================================================================ # 부서 및 권한 관련 상수 # ============================================================================ # 부서 목록 DEPARTMENTS: List[str] = [ "검수팀", "운전팀", "차량팀", "관제팀", "기타", ] # 역할 목록 ROLES: Dict[str, str] = { "admin": "관리자", "editor": "편집자", "viewer": "조회자", } # 부서별 기본 권한 DEPARTMENT_PERMISSIONS: Dict[str, str] = { "검수팀": "admin", # 모든 권한 "운전팀": "viewer", # 조회만 "차량팀": "viewer", # 조회만 "관제팀": "viewer", # 조회만 "기타": "viewer", # 조회만 } # ============================================================================ # 청소 유형 상수 # ============================================================================ CLEANING_TYPES: Dict[str, Dict] = { "none": { "name": "없음", "color": None, "shape": None, }, "medium": { "name": "중청소", "color": "#3498db", # 파란색 "shape": "rectangle", }, "large": { "name": "대청소", "color": "#e74c3c", # 빨간색 "shape": "circle", }, } # ============================================================================ # 고장 코드 관련 상수 # ============================================================================ # JSON 데이터 파일 경로 FAULT_DATA_FILE = DATA_DIR / "fault_data.json" # JSON에서 데이터 로드 def _load_fault_data(): """고장 관련 데이터를 JSON 파일에서 로드""" import json try: if FAULT_DATA_FILE.exists(): with open(FAULT_DATA_FILE, 'r', encoding='utf-8') as f: data = json.load(f) return data else: # 기본값 반환 return { "train_numbers": [], "stations": [], "column_numbers": [], "device_categories": [ "추진장치", "제동장치", "출입문", "냉난방", "조명", "방송", "ATC/ATO", "집전장치", "차체", "대차", "기타" ], "fault_codes": [] } except (json.JSONDecodeError, IOError, OSError): # 로드 실패 시 기본값 반환 return { "train_numbers": [], "stations": [], "column_numbers": [], "device_categories": [ "추진장치", "제동장치", "출입문", "냉난방", "조명", "방송", "ATC/ATO", "집전장치", "차체", "대차", "기타" ], "fault_codes": [] } # 고장 데이터 로드 _fault_data = _load_fault_data() # 편성번호 목록 TRAIN_NUMBERS: List[str] = _fault_data.get("train_numbers", []) # 역 목록 STATIONS: List[str] = _fault_data.get("stations", []) # 열번 목록 COLUMN_NUMBERS: List[str] = _fault_data.get("column_numbers", []) # 장치 분류 DEVICE_CATEGORIES: List[str] = _fault_data.get("device_categories", [ "추진장치", "제동장치", "출입문", "냉난방", "조명", "방송", "ATC/ATO", "집전장치", "차체", "대차", "기타" ]) # 고장코드 목록 FAULT_CODES: List[str] = _fault_data.get("fault_codes", []) # 고장출처 목록 FAULT_SOURCES: List[str] = [ "일상검수", "출고검수", "도착검수", "입고기관사", "상태권", "직원모니터링", "기타" ] # ============================================================================ # UI 관련 상수 # ============================================================================ # 레이아웃 비율 (퍼센트) LAYOUT_RATIOS: Dict[str, float] = { "info_bar": 10.0, # 상단 인포바 "content_area": 80.0, # 중앙 컨텐츠 "status_bar": 10.0, # 하단 상태바 "section_panel": 60.0, # 섹션 패널 (컨텐츠 내 좌측) "todo_panel": 40.0, # Todo 패널 (컨텐츠 내 우측) "daily_inspection": 30.0, # 일상검수 영역 "todo_list": 35.0, # 할일 목록 영역 "memo": 35.0, # 메모 영역 } # 폰트 설정 FONT_FAMILY = "GmarketSans" FONT_SIZES: Dict[str, int] = { "title": 18, "heading": 16, "subheading": 14, "body": 13, "small": 11, "tiny": 9, } # UI 영역별 폰트 설정 UI_FONT_SETTINGS: Dict[str, Dict] = { # 인포바 "info_bar": { "title": {"family": FONT_FAMILY, "size": 16, "weight": "bold"}, "content": {"family": FONT_FAMILY, "size": 14, "weight": "normal"}, "small": {"family": FONT_FAMILY, "size": 12, "weight": "normal"}, }, # 섹션 (지시, 고장, 작업, 기타) "section": { "title": {"family": FONT_FAMILY, "size": 16, "weight": "bold"}, "header": {"family": FONT_FAMILY, "size": 13, "weight": "bold"}, "content": {"family": FONT_FAMILY, "size": 13, "weight": "normal"}, "small": {"family": FONT_FAMILY, "size": 11, "weight": "normal"}, }, # 할일 목록 "todo": { "title": {"family": FONT_FAMILY, "size": 14, "weight": "bold"}, "content": {"family": FONT_FAMILY, "size": 13, "weight": "normal"}, "small": {"family": FONT_FAMILY, "size": 11, "weight": "normal"}, }, # 메모 "memo": { "title": {"family": FONT_FAMILY, "size": 14, "weight": "bold"}, "content": {"family": FONT_FAMILY, "size": 13, "weight": "normal"}, }, # 일상검수 "daily_inspection": { "title": {"family": FONT_FAMILY, "size": 14, "weight": "bold"}, "content": {"family": FONT_FAMILY, "size": 12, "weight": "normal"}, "train_number": {"family": FONT_FAMILY, "size": 13, "weight": "bold"}, }, # 상태바 "status_bar": { "content": {"family": FONT_FAMILY, "size": 12, "weight": "normal"}, }, # 다이얼로그 "dialog": { "title": {"family": FONT_FAMILY, "size": 12, "weight": "bold"}, "label": {"family": FONT_FAMILY, "size": 10, "weight": "normal"}, "input": {"family": FONT_FAMILY, "size": 10, "weight": "normal"}, "button": {"family": FONT_FAMILY, "size": 10, "weight": "medium"}, }, } # 테마 색상 (다크 테마) DARK_THEME_COLORS: Dict[str, str] = { "primary": "#3498db", "secondary": "#2ecc71", "accent": "#e74c3c", "warning": "#f39c12", "background": "#1a1a2e", "surface": "#16213e", "card": "#0f3460", "text_primary": "#ffffff", "text_secondary": "#a0a0a0", "border": "#2d3748", "hover": "#4a5568", "success": "#48bb78", "error": "#fc8181", } # 테마 색상 (라이트 테마) LIGHT_THEME_COLORS: Dict[str, str] = { "primary": "#2980b9", "secondary": "#27ae60", "accent": "#c0392b", "warning": "#d68910", "background": "#f5f7fa", "surface": "#ffffff", "card": "#ffffff", "text_primary": "#2c3e50", "text_secondary": "#7f8c8d", "border": "#e0e0e0", "hover": "#ecf0f1", "success": "#2ecc71", "error": "#e74c3c", } # ============================================================================ # 일상검수 관련 상수 # ============================================================================ # 일상검수 슬롯 수 DAILY_INSPECTION_SLOTS = 5 # ============================================================================ # 시간 관련 상수 # ============================================================================ # 업데이트 체크 주기 (초) UPDATE_CHECK_INTERVAL = 3600 # 1시간 # 날씨 정보 갱신 주기 (초) WEATHER_UPDATE_INTERVAL = 1800 # 30분 # 자동 저장 주기 (초) AUTO_SAVE_INTERVAL = 30 # 30초 # 로그 파일 보관 기간 (일) LOG_RETENTION_DAYS = 30 # ============================================================================ # 날씨 API 관련 상수 # ============================================================================ # 기상청 API (예시) WEATHER_API_URL = "https://api.openweathermap.org/data/2.5/weather" WEATHER_API_KEY = "" # 설정 파일에서 로드 # 기본 위치 (서울) DEFAULT_LOCATION: Dict[str, float] = { "lat": 37.5665, "lon": 126.9780, "name": "서울", } # ============================================================================ # 데이터베이스 관련 상수 # ============================================================================ # 테이블 이름 TABLE_NAMES: Dict[str, str] = { "users": "users", "teams": "teams", "instructions": "instructions", "faults": "faults", "works": "works", "miscs": "miscs", "daily_inspections": "daily_inspections", "todos": "todos", "memos": "memos", "settings": "settings", } # 팀 확인 상태 기본값 DEFAULT_TEAM_CONFIRMATIONS = { "1팀": False, "2팀": False, "3팀": False, "4팀": False, }