111 lines
3.1 KiB
Python
111 lines
3.1 KiB
Python
"""Calendar TUI configuration."""
|
|
|
|
import os
|
|
from pathlib import Path
|
|
from typing import Optional
|
|
|
|
try:
|
|
import toml
|
|
except ImportError:
|
|
toml = None # type: ignore
|
|
|
|
|
|
# Default configuration values
|
|
DEFAULT_CONFIG = {
|
|
"display": {
|
|
"work_day_start_hour": 7, # 7 AM
|
|
"work_day_end_hour": 19, # 7 PM
|
|
"include_weekends": True,
|
|
"minutes_per_row": 30,
|
|
"day_column_width": 20,
|
|
"week_start_day": 0, # 0=Sunday, 1=Monday, ..., 6=Saturday
|
|
},
|
|
"backend": {
|
|
"type": "khal", # khal, calcurse, etc.
|
|
"calendar_path": "~/Calendar/corteva",
|
|
},
|
|
"theme": {
|
|
"event_color": "blue",
|
|
"overlap_color": "dark_orange",
|
|
"cursor_style": "reverse",
|
|
"work_hours_time_color": "blue",
|
|
"off_hours_time_color": "bright_black",
|
|
},
|
|
}
|
|
|
|
|
|
def get_config_path() -> Path:
|
|
"""Get the calendar config file path."""
|
|
# Check XDG_CONFIG_HOME first, then fall back to ~/.config
|
|
config_home = os.environ.get("XDG_CONFIG_HOME", os.path.expanduser("~/.config"))
|
|
return Path(config_home) / "luk" / "calendar.toml"
|
|
|
|
|
|
def load_config() -> dict:
|
|
"""Load calendar configuration from TOML file.
|
|
|
|
Returns merged config with defaults for any missing values.
|
|
"""
|
|
config = DEFAULT_CONFIG.copy()
|
|
|
|
config_path = get_config_path()
|
|
if config_path.exists() and toml is not None:
|
|
try:
|
|
user_config = toml.load(config_path)
|
|
# Deep merge user config into defaults
|
|
for section, values in user_config.items():
|
|
if section in config and isinstance(config[section], dict):
|
|
config[section].update(values)
|
|
else:
|
|
config[section] = values
|
|
except Exception:
|
|
pass # Use defaults on error
|
|
|
|
return config
|
|
|
|
|
|
def get_display_config() -> dict:
|
|
"""Get display-related configuration."""
|
|
return load_config().get("display", DEFAULT_CONFIG["display"])
|
|
|
|
|
|
def get_backend_config() -> dict:
|
|
"""Get backend-related configuration."""
|
|
return load_config().get("backend", DEFAULT_CONFIG["backend"])
|
|
|
|
|
|
def get_theme_config() -> dict:
|
|
"""Get theme-related configuration."""
|
|
return load_config().get("theme", DEFAULT_CONFIG["theme"])
|
|
|
|
|
|
# Convenience accessors
|
|
def work_day_start_hour() -> int:
|
|
"""Get the work day start hour (for initial scroll position)."""
|
|
return get_display_config().get("work_day_start_hour", 7)
|
|
|
|
|
|
def work_day_end_hour() -> int:
|
|
"""Get the work day end hour."""
|
|
return get_display_config().get("work_day_end_hour", 19)
|
|
|
|
|
|
def include_weekends_default() -> bool:
|
|
"""Get default for including weekends."""
|
|
return get_display_config().get("include_weekends", True)
|
|
|
|
|
|
def minutes_per_row() -> int:
|
|
"""Get minutes per row (default 30)."""
|
|
return get_display_config().get("minutes_per_row", 30)
|
|
|
|
|
|
def day_column_width() -> int:
|
|
"""Get day column width."""
|
|
return get_display_config().get("day_column_width", 20)
|
|
|
|
|
|
def week_start_day() -> int:
|
|
"""Get the week start day (0=Sunday, 1=Monday, ..., 6=Saturday)."""
|
|
return get_display_config().get("week_start_day", 0)
|