bloggy 0.1.40__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
bloggy/config.py ADDED
@@ -0,0 +1,134 @@
1
+ """Configuration management for Bloggy.
2
+
3
+ Supports loading configuration from:
4
+ 1. .bloggy file (TOML format) in the current directory or blog root
5
+ 2. Environment variables (as fallback)
6
+ 3. Default values
7
+
8
+ Priority: .bloggy file > environment variables > defaults
9
+ """
10
+
11
+ import os
12
+ import tomllib
13
+ from pathlib import Path
14
+ from typing import Optional
15
+
16
+
17
+ class BloggyConfig:
18
+
19
+ """Configuration handler for Bloggy."""
20
+
21
+ def __init__(self, config_path: Optional[Path] = None):
22
+ """Initialize configuration.
23
+
24
+ Args:
25
+ config_path: Optional path to .bloggy file. If not provided, will search
26
+ in current directory and BLOGGY_ROOT.
27
+ """
28
+ self._config = {}
29
+ self._load_config(config_path)
30
+
31
+ def _load_config(self, config_path: Optional[Path] = None):
32
+ """Load configuration from .bloggy file if it exists."""
33
+ # Try to find .bloggy file
34
+ config_file = None
35
+
36
+ if config_path and config_path.exists():
37
+ config_file = config_path
38
+ else:
39
+ # Search in BLOGGY_ROOT first (if set)
40
+ root = os.getenv('BLOGGY_ROOT')
41
+ if root:
42
+ root_config = Path(root) / '.bloggy'
43
+ if root_config.exists():
44
+ config_file = root_config
45
+
46
+ # Then search in current directory
47
+ if not config_file:
48
+ cwd_config = Path.cwd() / '.bloggy'
49
+ if cwd_config.exists():
50
+ config_file = cwd_config
51
+
52
+ # Load the config file if found
53
+ if config_file:
54
+ try:
55
+ with open(config_file, 'rb') as f:
56
+ self._config = tomllib.load(f)
57
+ print(f"✓ Loaded configuration from: {config_file}")
58
+ except Exception as e:
59
+ print(f"Warning: Failed to load {config_file}: {e}")
60
+ self._config = {}
61
+
62
+ def get(self, key: str, env_var: str, default: any = None) -> any:
63
+ """Get configuration value with priority: config file > env var > default.
64
+
65
+ Args:
66
+ key: Key in the .bloggy config file
67
+ env_var: Environment variable name
68
+ default: Default value if not found
69
+
70
+ Returns:
71
+ Configuration value
72
+ """
73
+ # First check config file
74
+ if key in self._config:
75
+ return self._config[key]
76
+
77
+ # Then check environment variable
78
+ env_value = os.getenv(env_var)
79
+ if env_value is not None:
80
+ return env_value
81
+
82
+ # Finally return default
83
+ return default
84
+
85
+ def get_root_folder(self) -> Path:
86
+ """Get the blog root folder path."""
87
+ root = self.get('root', 'BLOGGY_ROOT', '.')
88
+ return Path(root).resolve()
89
+
90
+ def get_blog_title(self) -> str:
91
+ """Get the blog title."""
92
+ from .core import slug_to_title # Import here to avoid circular dependency
93
+
94
+ title = self.get('title', 'BLOGGY_TITLE', None)
95
+ if title:
96
+ return title.upper()
97
+
98
+ # Default to root folder name
99
+ return slug_to_title(self.get_root_folder().name).upper()
100
+
101
+ def get_host(self) -> str:
102
+ """Get the server host."""
103
+ return self.get('host', 'BLOGGY_HOST', '127.0.0.1')
104
+
105
+ def get_port(self) -> int:
106
+ """Get the server port."""
107
+ port = self.get('port', 'BLOGGY_PORT', 5001)
108
+ return int(port)
109
+
110
+ def get_auth(self):
111
+ """Get authentication credentials from config, env, or default (None)."""
112
+ user = self.get('username', 'BLOGGY_USER', None)
113
+ pwd = self.get('password', 'BLOGGY_PASSWORD', None)
114
+ return user, pwd
115
+
116
+
117
+
118
+ # Global config instance
119
+ _config: Optional[BloggyConfig] = None
120
+
121
+
122
+ def get_config() -> BloggyConfig:
123
+ """Get or create the global configuration instance."""
124
+ global _config
125
+ if _config is None:
126
+ _config = BloggyConfig()
127
+ return _config
128
+
129
+
130
+ def reload_config(config_path: Optional[Path] = None):
131
+ """Reload configuration, optionally from a specific path."""
132
+ global _config
133
+ _config = BloggyConfig(config_path)
134
+ return _config