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/__init__.py +5 -0
- bloggy/build.py +608 -0
- bloggy/config.py +134 -0
- bloggy/core.py +1618 -0
- bloggy/main.py +96 -0
- bloggy/static/scripts.js +584 -0
- bloggy/static/sidenote.css +21 -0
- bloggy-0.1.40.dist-info/METADATA +926 -0
- bloggy-0.1.40.dist-info/RECORD +13 -0
- bloggy-0.1.40.dist-info/WHEEL +5 -0
- bloggy-0.1.40.dist-info/entry_points.txt +2 -0
- bloggy-0.1.40.dist-info/licenses/LICENSE +201 -0
- bloggy-0.1.40.dist-info/top_level.txt +1 -0
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
|