hugoifier 0.1.0__tar.gz
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.
- hugoifier-0.1.0/LICENSE +21 -0
- hugoifier-0.1.0/MANIFEST.in +4 -0
- hugoifier-0.1.0/PKG-INFO +99 -0
- hugoifier-0.1.0/README.md +64 -0
- hugoifier-0.1.0/hugoifier/__init__.py +3 -0
- hugoifier-0.1.0/hugoifier/cli.py +127 -0
- hugoifier-0.1.0/hugoifier/config.py +90 -0
- hugoifier-0.1.0/hugoifier/utils/__init__.py +0 -0
- hugoifier-0.1.0/hugoifier/utils/analyze.py +87 -0
- hugoifier-0.1.0/hugoifier/utils/cloudflare.py +31 -0
- hugoifier-0.1.0/hugoifier/utils/complete.py +248 -0
- hugoifier-0.1.0/hugoifier/utils/decapify.py +273 -0
- hugoifier-0.1.0/hugoifier/utils/deploy.py +28 -0
- hugoifier-0.1.0/hugoifier/utils/generate_decap_config.py +10 -0
- hugoifier-0.1.0/hugoifier/utils/hugoify.py +167 -0
- hugoifier-0.1.0/hugoifier/utils/parser.py +32 -0
- hugoifier-0.1.0/hugoifier/utils/theme_finder.py +72 -0
- hugoifier-0.1.0/hugoifier/utils/theme_patcher.py +72 -0
- hugoifier-0.1.0/hugoifier/utils/translate.py +25 -0
- hugoifier-0.1.0/hugoifier.egg-info/PKG-INFO +99 -0
- hugoifier-0.1.0/hugoifier.egg-info/SOURCES.txt +39 -0
- hugoifier-0.1.0/hugoifier.egg-info/dependency_links.txt +1 -0
- hugoifier-0.1.0/hugoifier.egg-info/entry_points.txt +2 -0
- hugoifier-0.1.0/hugoifier.egg-info/requires.txt +11 -0
- hugoifier-0.1.0/hugoifier.egg-info/top_level.txt +1 -0
- hugoifier-0.1.0/pyproject.toml +75 -0
- hugoifier-0.1.0/requirements.txt +4 -0
- hugoifier-0.1.0/setup.cfg +4 -0
- hugoifier-0.1.0/setup.py +5 -0
- hugoifier-0.1.0/tests/test_analyze.py +60 -0
- hugoifier-0.1.0/tests/test_cloudflare.py +18 -0
- hugoifier-0.1.0/tests/test_complete.py +119 -0
- hugoifier-0.1.0/tests/test_config.py +72 -0
- hugoifier-0.1.0/tests/test_decapify.py +191 -0
- hugoifier-0.1.0/tests/test_deploy.py +18 -0
- hugoifier-0.1.0/tests/test_generate_decap_config.py +41 -0
- hugoifier-0.1.0/tests/test_hugoify.py +70 -0
- hugoifier-0.1.0/tests/test_parser.py +18 -0
- hugoifier-0.1.0/tests/test_theme_finder.py +79 -0
- hugoifier-0.1.0/tests/test_theme_patcher.py +102 -0
- hugoifier-0.1.0/tests/test_translate.py +44 -0
hugoifier-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 CONFLICT LLC. All rights reserved.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
hugoifier-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: hugoifier
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: AI-powered Hugo theme converter with Decap CMS integration
|
|
5
|
+
Author: CONFLICT LLC
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://hugoifier.dev
|
|
8
|
+
Project-URL: Documentation, https://hugoifier.dev
|
|
9
|
+
Project-URL: Repository, https://github.com/ConflictHQ/hugoifier
|
|
10
|
+
Project-URL: Issues, https://github.com/ConflictHQ/hugoifier/issues
|
|
11
|
+
Keywords: hugo,cms,decap,static-site,theme,ai,converter
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Site Management
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: anthropic>=0.5.0
|
|
25
|
+
Requires-Dist: openai>=1.0.0
|
|
26
|
+
Requires-Dist: google-generativeai>=0.3.0
|
|
27
|
+
Requires-Dist: pyyaml>=6.0
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest>=7.3.0; extra == "dev"
|
|
30
|
+
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
|
|
31
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
32
|
+
Requires-Dist: build>=1.0.0; extra == "dev"
|
|
33
|
+
Requires-Dist: twine>=4.0.0; extra == "dev"
|
|
34
|
+
Dynamic: license-file
|
|
35
|
+
|
|
36
|
+
# Hugoifier (AI-Powered Theme Converter)
|
|
37
|
+
|
|
38
|
+
A utility that takes your HTML template/website or Hugo them and generates a production-ready Hugo theme with Decap CMS integration.
|
|
39
|
+
|
|
40
|
+
## What is it?
|
|
41
|
+
|
|
42
|
+
Hugoifier is a Python-based utility that:
|
|
43
|
+
|
|
44
|
+
- Converts any HTML/JS/CSS theme into a Hugo-compatible theme using AI.
|
|
45
|
+
- Extracts layout data into structured files (`data/*.yaml` or `data/*.json`) to make the theme editable via Decap CMS.
|
|
46
|
+
- Generates and wires Decap CMS into the Hugo setup, making it fully ready for content management.
|
|
47
|
+
- Uses OpenAI's efficient AI models to analyze theme files and determine the best Hugo template tag placements.
|
|
48
|
+
|
|
49
|
+
## Core Features & Workflow
|
|
50
|
+
|
|
51
|
+
### Step 1: AI-Powered HTML Conversion
|
|
52
|
+
|
|
53
|
+
- Uses GPT-4-Turbo to analyze an HTML theme and suggest where Hugo template tags (`{{ .Title }}`, `{{ .Content }}`, etc.) should be placed.
|
|
54
|
+
- Identifies partials (e.g., `header.html`, `footer.html`) and reusable elements.
|
|
55
|
+
- Converts all hardcoded links, images, and text into Hugo-friendly components.
|
|
56
|
+
|
|
57
|
+
### Step2 2: Decap CMS Integration
|
|
58
|
+
|
|
59
|
+
- Extracts the site structure elements (navigation, hero sections, footers) into YAML/JSON files in Hugo's `data/` directory.
|
|
60
|
+
- Generates a Decap CMS `config.yml` file with proper collections for pages, posts, and layout elements.
|
|
61
|
+
- Ensures the generated theme is fully editable via Decap CMS.
|
|
62
|
+
|
|
63
|
+
### Step3 3: Automation & Deployment
|
|
64
|
+
|
|
65
|
+
- Provides a Python CLI tool to automate the entire conversion process.
|
|
66
|
+
- Offer interactive mode for customization and auto mode for full automation.
|
|
67
|
+
- Ensure themes are deployable on Cloudflare Pages CMS setups.
|
|
68
|
+
- Deploy the CMS on Cloudflare Pages.
|
|
69
|
+
|
|
70
|
+
## Getting Started
|
|
71
|
+
|
|
72
|
+
### Prerequisites
|
|
73
|
+
|
|
74
|
+
- Python 3.11.4
|
|
75
|
+
- Hugo extended version
|
|
76
|
+
- OpenAI API key
|
|
77
|
+
- Cloudflare account (for deployment)
|
|
78
|
+
|
|
79
|
+
### Installation
|
|
80
|
+
|
|
81
|
+
1. **Clone the repository:**
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
git clone https://github.com/yourusername/hugo-ifier.git
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
2. **Install the required Python packages:**
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
pip install -r requirements.txt
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Usage
|
|
94
|
+
|
|
95
|
+
Run the CLI tool to start the conversion process:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
python cli.py convert --input theme.html --output hugo-theme
|
|
99
|
+
```
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Hugoifier (AI-Powered Theme Converter)
|
|
2
|
+
|
|
3
|
+
A utility that takes your HTML template/website or Hugo them and generates a production-ready Hugo theme with Decap CMS integration.
|
|
4
|
+
|
|
5
|
+
## What is it?
|
|
6
|
+
|
|
7
|
+
Hugoifier is a Python-based utility that:
|
|
8
|
+
|
|
9
|
+
- Converts any HTML/JS/CSS theme into a Hugo-compatible theme using AI.
|
|
10
|
+
- Extracts layout data into structured files (`data/*.yaml` or `data/*.json`) to make the theme editable via Decap CMS.
|
|
11
|
+
- Generates and wires Decap CMS into the Hugo setup, making it fully ready for content management.
|
|
12
|
+
- Uses OpenAI's efficient AI models to analyze theme files and determine the best Hugo template tag placements.
|
|
13
|
+
|
|
14
|
+
## Core Features & Workflow
|
|
15
|
+
|
|
16
|
+
### Step 1: AI-Powered HTML Conversion
|
|
17
|
+
|
|
18
|
+
- Uses GPT-4-Turbo to analyze an HTML theme and suggest where Hugo template tags (`{{ .Title }}`, `{{ .Content }}`, etc.) should be placed.
|
|
19
|
+
- Identifies partials (e.g., `header.html`, `footer.html`) and reusable elements.
|
|
20
|
+
- Converts all hardcoded links, images, and text into Hugo-friendly components.
|
|
21
|
+
|
|
22
|
+
### Step2 2: Decap CMS Integration
|
|
23
|
+
|
|
24
|
+
- Extracts the site structure elements (navigation, hero sections, footers) into YAML/JSON files in Hugo's `data/` directory.
|
|
25
|
+
- Generates a Decap CMS `config.yml` file with proper collections for pages, posts, and layout elements.
|
|
26
|
+
- Ensures the generated theme is fully editable via Decap CMS.
|
|
27
|
+
|
|
28
|
+
### Step3 3: Automation & Deployment
|
|
29
|
+
|
|
30
|
+
- Provides a Python CLI tool to automate the entire conversion process.
|
|
31
|
+
- Offer interactive mode for customization and auto mode for full automation.
|
|
32
|
+
- Ensure themes are deployable on Cloudflare Pages CMS setups.
|
|
33
|
+
- Deploy the CMS on Cloudflare Pages.
|
|
34
|
+
|
|
35
|
+
## Getting Started
|
|
36
|
+
|
|
37
|
+
### Prerequisites
|
|
38
|
+
|
|
39
|
+
- Python 3.11.4
|
|
40
|
+
- Hugo extended version
|
|
41
|
+
- OpenAI API key
|
|
42
|
+
- Cloudflare account (for deployment)
|
|
43
|
+
|
|
44
|
+
### Installation
|
|
45
|
+
|
|
46
|
+
1. **Clone the repository:**
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
git clone https://github.com/yourusername/hugo-ifier.git
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
2. **Install the required Python packages:**
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pip install -r requirements.txt
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Usage
|
|
59
|
+
|
|
60
|
+
Run the CLI tool to start the conversion process:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
python cli.py convert --input theme.html --output hugo-theme
|
|
64
|
+
```
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Hugo-ifier CLI Tool
|
|
3
|
+
|
|
4
|
+
Usage examples:
|
|
5
|
+
python cli.py complete themes/revolve-hugo
|
|
6
|
+
python cli.py complete themes/revolve-hugo --output /tmp/my-site
|
|
7
|
+
HUGOIFIER_BACKEND=openai python cli.py complete themes/revolve-hugo
|
|
8
|
+
python cli.py analyze themes/revolve-hugo
|
|
9
|
+
python cli.py hugoify themes/revolve-hugo
|
|
10
|
+
python cli.py decapify output/revolve-hugo
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import argparse
|
|
14
|
+
import logging
|
|
15
|
+
import sys
|
|
16
|
+
|
|
17
|
+
from .utils.analyze import analyze
|
|
18
|
+
from .utils.cloudflare import configure_cloudflare
|
|
19
|
+
from .utils.complete import complete
|
|
20
|
+
from .utils.decapify import decapify
|
|
21
|
+
from .utils.deploy import deploy
|
|
22
|
+
from .utils.hugoify import hugoify
|
|
23
|
+
from .utils.parser import parse
|
|
24
|
+
from .utils.translate import translate
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def main():
|
|
28
|
+
parser = argparse.ArgumentParser(
|
|
29
|
+
description="Hugo-ifier — AI-powered Hugo theme converter",
|
|
30
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
31
|
+
epilog=__doc__,
|
|
32
|
+
)
|
|
33
|
+
parser.add_argument(
|
|
34
|
+
'--backend', choices=['anthropic', 'openai', 'google'],
|
|
35
|
+
help='AI backend to use (overrides HUGOIFIER_BACKEND env var)',
|
|
36
|
+
)
|
|
37
|
+
subparsers = parser.add_subparsers(dest="command")
|
|
38
|
+
|
|
39
|
+
# complete — full pipeline
|
|
40
|
+
complete_parser = subparsers.add_parser("complete", help="Run the full pipeline (analyze → hugoify → decap)")
|
|
41
|
+
complete_parser.add_argument("path", help="Path to the theme directory")
|
|
42
|
+
complete_parser.add_argument("--output", "-o", help="Output directory (default: output/{theme-name})")
|
|
43
|
+
complete_parser.add_argument("--cms-name", default=None, help="Whitelabel CMS name")
|
|
44
|
+
complete_parser.add_argument("--cms-logo", default=None, help="Whitelabel logo URL")
|
|
45
|
+
complete_parser.add_argument("--cms-color", default=None, help="Whitelabel top-bar hex color")
|
|
46
|
+
|
|
47
|
+
# analyze
|
|
48
|
+
analyze_parser = subparsers.add_parser("analyze", help="Analyze a theme and report structure")
|
|
49
|
+
analyze_parser.add_argument("path", help="Path to the theme")
|
|
50
|
+
|
|
51
|
+
# hugoify
|
|
52
|
+
hugoify_parser = subparsers.add_parser("hugoify", help="Convert HTML to Hugo theme (or validate existing Hugo theme)")
|
|
53
|
+
hugoify_parser.add_argument("path", help="Path to HTML file or theme directory")
|
|
54
|
+
|
|
55
|
+
# decapify
|
|
56
|
+
decapify_parser = subparsers.add_parser("decapify", help="Add Decap CMS to an assembled Hugo site")
|
|
57
|
+
decapify_parser.add_argument("path", help="Path to the Hugo site directory")
|
|
58
|
+
decapify_parser.add_argument("--cms-name", default=None, help="Whitelabel CMS name (default: 'Content Manager')")
|
|
59
|
+
decapify_parser.add_argument("--cms-logo", default=None, help="Whitelabel logo URL")
|
|
60
|
+
decapify_parser.add_argument("--cms-color", default=None, help="Whitelabel top-bar hex color")
|
|
61
|
+
|
|
62
|
+
# translate
|
|
63
|
+
translate_parser = subparsers.add_parser("translate", help="Translate content to another language")
|
|
64
|
+
translate_parser.add_argument("path", help="Path to the content file")
|
|
65
|
+
translate_parser.add_argument("--target-language", default="Spanish", help="Target language (default: Spanish)")
|
|
66
|
+
|
|
67
|
+
# parse / lint
|
|
68
|
+
parser_parser = subparsers.add_parser("parser", help="Parse and lint (stub)")
|
|
69
|
+
parser_parser.add_argument("path", help="Path to the theme")
|
|
70
|
+
|
|
71
|
+
# deploy (stub)
|
|
72
|
+
deploy_parser = subparsers.add_parser("deploy", help="Deploy to Cloudflare (stub)")
|
|
73
|
+
deploy_parser.add_argument("path", help="Path to the site")
|
|
74
|
+
deploy_parser.add_argument("zone", help="Cloudflare zone")
|
|
75
|
+
|
|
76
|
+
# cloudflare (stub)
|
|
77
|
+
cloudflare_parser = subparsers.add_parser("cloudflare", help="Configure Cloudflare (stub)")
|
|
78
|
+
cloudflare_parser.add_argument("path", help="Path to the site")
|
|
79
|
+
cloudflare_parser.add_argument("zone", help="Cloudflare zone")
|
|
80
|
+
|
|
81
|
+
args = parser.parse_args()
|
|
82
|
+
|
|
83
|
+
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
|
84
|
+
|
|
85
|
+
# Override backend if specified on command line
|
|
86
|
+
if args.backend:
|
|
87
|
+
import config as cfg
|
|
88
|
+
cfg.BACKEND = args.backend
|
|
89
|
+
|
|
90
|
+
try:
|
|
91
|
+
if args.command == "complete":
|
|
92
|
+
result = complete(
|
|
93
|
+
args.path,
|
|
94
|
+
output_dir=args.output,
|
|
95
|
+
cms_name=args.cms_name,
|
|
96
|
+
cms_logo=args.cms_logo,
|
|
97
|
+
cms_color=args.cms_color,
|
|
98
|
+
)
|
|
99
|
+
print(result)
|
|
100
|
+
elif args.command == "analyze":
|
|
101
|
+
print(analyze(args.path))
|
|
102
|
+
elif args.command == "hugoify":
|
|
103
|
+
print(hugoify(args.path))
|
|
104
|
+
elif args.command == "decapify":
|
|
105
|
+
print(decapify(
|
|
106
|
+
args.path,
|
|
107
|
+
cms_name=args.cms_name,
|
|
108
|
+
cms_logo=args.cms_logo,
|
|
109
|
+
cms_color=args.cms_color,
|
|
110
|
+
))
|
|
111
|
+
elif args.command == "translate":
|
|
112
|
+
print(translate(args.path, target_language=args.target_language))
|
|
113
|
+
elif args.command == "parser":
|
|
114
|
+
print(parse(args.path))
|
|
115
|
+
elif args.command == "deploy":
|
|
116
|
+
print(deploy(args.path, args.zone))
|
|
117
|
+
elif args.command == "cloudflare":
|
|
118
|
+
print(configure_cloudflare(args.path, args.zone))
|
|
119
|
+
else:
|
|
120
|
+
parser.print_help()
|
|
121
|
+
except (ValueError, EnvironmentError) as e:
|
|
122
|
+
print(f"Error: {e}", file=sys.stderr)
|
|
123
|
+
sys.exit(1)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
if __name__ == "__main__":
|
|
127
|
+
main()
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Multi-backend AI configuration.
|
|
3
|
+
|
|
4
|
+
Set HUGOIFIER_BACKEND env var to switch backends:
|
|
5
|
+
anthropic (default) — claude-sonnet-4-6
|
|
6
|
+
openai — gpt-4-turbo
|
|
7
|
+
google — gemini-1.5-pro
|
|
8
|
+
|
|
9
|
+
Model can be overridden per-backend:
|
|
10
|
+
ANTHROPIC_MODEL, OPENAI_MODEL, GOOGLE_MODEL
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import os
|
|
14
|
+
|
|
15
|
+
BACKEND = os.getenv('HUGOIFIER_BACKEND', 'anthropic').lower()
|
|
16
|
+
|
|
17
|
+
# Anthropic settings
|
|
18
|
+
ANTHROPIC_API_KEY = os.getenv('ANTHROPIC_API_KEY')
|
|
19
|
+
ANTHROPIC_MODEL = os.getenv('ANTHROPIC_MODEL', 'claude-sonnet-4-6')
|
|
20
|
+
|
|
21
|
+
# OpenAI settings
|
|
22
|
+
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
|
|
23
|
+
OPENAI_MODEL = os.getenv('OPENAI_MODEL', 'gpt-4-turbo')
|
|
24
|
+
|
|
25
|
+
# Google settings
|
|
26
|
+
GOOGLE_API_KEY = os.getenv('GOOGLE_API_KEY')
|
|
27
|
+
GOOGLE_MODEL = os.getenv('GOOGLE_MODEL', 'gemini-1.5-pro')
|
|
28
|
+
|
|
29
|
+
MAX_TOKENS = int(os.getenv('HUGOIFIER_MAX_TOKENS', '4096'))
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def call_ai(prompt: str, system: str = "You are a helpful Hugo theme conversion assistant.") -> str:
|
|
33
|
+
"""
|
|
34
|
+
Call the configured AI backend and return the response text.
|
|
35
|
+
This is the single entry point for all AI calls in the codebase.
|
|
36
|
+
"""
|
|
37
|
+
if BACKEND == 'anthropic':
|
|
38
|
+
return _call_anthropic(prompt, system)
|
|
39
|
+
elif BACKEND == 'openai':
|
|
40
|
+
return _call_openai(prompt, system)
|
|
41
|
+
elif BACKEND == 'google':
|
|
42
|
+
return _call_google(prompt, system)
|
|
43
|
+
else:
|
|
44
|
+
raise ValueError(
|
|
45
|
+
f"Unknown backend: {BACKEND!r}. "
|
|
46
|
+
"Set HUGOIFIER_BACKEND to 'anthropic', 'openai', or 'google'."
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _call_anthropic(prompt: str, system: str) -> str:
|
|
51
|
+
if not ANTHROPIC_API_KEY:
|
|
52
|
+
raise EnvironmentError("ANTHROPIC_API_KEY is not set")
|
|
53
|
+
import anthropic
|
|
54
|
+
client = anthropic.Anthropic(api_key=ANTHROPIC_API_KEY)
|
|
55
|
+
message = client.messages.create(
|
|
56
|
+
model=ANTHROPIC_MODEL,
|
|
57
|
+
max_tokens=MAX_TOKENS,
|
|
58
|
+
system=system,
|
|
59
|
+
messages=[{"role": "user", "content": prompt}],
|
|
60
|
+
)
|
|
61
|
+
return message.content[0].text
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _call_openai(prompt: str, system: str) -> str:
|
|
65
|
+
if not OPENAI_API_KEY:
|
|
66
|
+
raise EnvironmentError("OPENAI_API_KEY is not set")
|
|
67
|
+
from openai import OpenAI
|
|
68
|
+
client = OpenAI(api_key=OPENAI_API_KEY)
|
|
69
|
+
response = client.chat.completions.create(
|
|
70
|
+
model=OPENAI_MODEL,
|
|
71
|
+
messages=[
|
|
72
|
+
{"role": "system", "content": system},
|
|
73
|
+
{"role": "user", "content": prompt},
|
|
74
|
+
],
|
|
75
|
+
max_tokens=MAX_TOKENS,
|
|
76
|
+
)
|
|
77
|
+
return response.choices[0].message.content.strip()
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _call_google(prompt: str, system: str) -> str:
|
|
81
|
+
if not GOOGLE_API_KEY:
|
|
82
|
+
raise EnvironmentError("GOOGLE_API_KEY is not set")
|
|
83
|
+
import google.generativeai as genai
|
|
84
|
+
genai.configure(api_key=GOOGLE_API_KEY)
|
|
85
|
+
model = genai.GenerativeModel(
|
|
86
|
+
model_name=GOOGLE_MODEL,
|
|
87
|
+
system_instruction=system,
|
|
88
|
+
)
|
|
89
|
+
response = model.generate_content(prompt)
|
|
90
|
+
return response.text
|
|
File without changes
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Analyzes a Hugo theme or raw HTML theme and reports structure + recommendations.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import os
|
|
7
|
+
|
|
8
|
+
from ..config import call_ai
|
|
9
|
+
from .theme_finder import find_hugo_theme, find_raw_html_files
|
|
10
|
+
|
|
11
|
+
SYSTEM = "You are an expert Hugo theme developer analyzing themes for conversion."
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def analyze(path: str) -> str:
|
|
15
|
+
logging.info(f"Analyzing {path} ...")
|
|
16
|
+
|
|
17
|
+
info = find_hugo_theme(path)
|
|
18
|
+
|
|
19
|
+
if info:
|
|
20
|
+
return _analyze_hugo_theme(info)
|
|
21
|
+
else:
|
|
22
|
+
return _analyze_raw_html(path)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _analyze_hugo_theme(info: dict) -> str:
|
|
26
|
+
theme_dir = info['theme_dir']
|
|
27
|
+
theme_name = info['theme_name']
|
|
28
|
+
example_site = info['example_site']
|
|
29
|
+
|
|
30
|
+
# Collect layout files
|
|
31
|
+
layouts = []
|
|
32
|
+
for root, dirs, files in os.walk(os.path.join(theme_dir, 'layouts')):
|
|
33
|
+
for f in files:
|
|
34
|
+
if f.endswith('.html'):
|
|
35
|
+
rel = os.path.relpath(os.path.join(root, f), theme_dir)
|
|
36
|
+
layouts.append(rel)
|
|
37
|
+
|
|
38
|
+
# Collect content types from exampleSite
|
|
39
|
+
content_types = []
|
|
40
|
+
if example_site:
|
|
41
|
+
content_dir = os.path.join(example_site, 'content')
|
|
42
|
+
if os.path.isdir(content_dir):
|
|
43
|
+
content_types = [
|
|
44
|
+
d for d in os.listdir(content_dir)
|
|
45
|
+
if os.path.isdir(os.path.join(content_dir, d))
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
report = [
|
|
49
|
+
f"Theme: {theme_name}",
|
|
50
|
+
f"Theme dir: {theme_dir}",
|
|
51
|
+
f"Layouts ({len(layouts)}):",
|
|
52
|
+
*[f" {layout}" for layout in sorted(layouts)],
|
|
53
|
+
f"Content types: {content_types}",
|
|
54
|
+
f"ExampleSite: {example_site or 'none'}",
|
|
55
|
+
"",
|
|
56
|
+
"Status: Already a Hugo theme. Use 'complete' to assemble a working site.",
|
|
57
|
+
]
|
|
58
|
+
return "\n".join(report)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _analyze_raw_html(path: str) -> str:
|
|
62
|
+
html_files = find_raw_html_files(path)
|
|
63
|
+
if not html_files:
|
|
64
|
+
return f"No HTML files found at {path}"
|
|
65
|
+
|
|
66
|
+
# Read main HTML file for AI analysis
|
|
67
|
+
main = next(
|
|
68
|
+
(f for f in html_files if os.path.basename(f).lower() == 'index.html'),
|
|
69
|
+
html_files[0],
|
|
70
|
+
)
|
|
71
|
+
with open(main, 'r', errors='replace') as f:
|
|
72
|
+
html = f.read()[:20000]
|
|
73
|
+
|
|
74
|
+
prompt = f"""Analyze this HTML theme file and provide:
|
|
75
|
+
1. Identified reusable components (header, footer, nav, sidebar, etc.)
|
|
76
|
+
2. Recommended Hugo template tags for dynamic content
|
|
77
|
+
3. Suggested partial splits
|
|
78
|
+
4. Content sections that should be data/ YAML files for Decap CMS
|
|
79
|
+
|
|
80
|
+
HTML:
|
|
81
|
+
{html}"""
|
|
82
|
+
|
|
83
|
+
try:
|
|
84
|
+
return call_ai(prompt, SYSTEM)
|
|
85
|
+
except Exception as e:
|
|
86
|
+
logging.error(f"AI analysis failed: {e}")
|
|
87
|
+
return f"HTML theme with {len(html_files)} files. AI analysis failed: {e}"
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Configures and deploys a Hugo site to Cloudflare, handling page creation,
|
|
3
|
+
DNS settings, and deployment via the Cloudflare API.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import logging
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# Function to configure and deploy to Cloudflare
|
|
10
|
+
def configure_cloudflare(path, zone):
|
|
11
|
+
logging.info(f"Starting Cloudflare configuration for {path} in zone {zone}...")
|
|
12
|
+
try:
|
|
13
|
+
# Placeholder logic for Cloudflare configuration
|
|
14
|
+
# This could involve API calls to Cloudflare to create pages, set DNS, etc.
|
|
15
|
+
logging.info("Creating Cloudflare page...")
|
|
16
|
+
# Example API call to create a page
|
|
17
|
+
# cloudflare_api.create_page(path, zone)
|
|
18
|
+
|
|
19
|
+
logging.info("Deploying site...")
|
|
20
|
+
# Example API call to deploy the site
|
|
21
|
+
# cloudflare_api.deploy_site(path, zone)
|
|
22
|
+
|
|
23
|
+
logging.info("Configuring DNS settings...")
|
|
24
|
+
# Example API call to configure DNS
|
|
25
|
+
# cloudflare_api.configure_dns(path, zone)
|
|
26
|
+
|
|
27
|
+
logging.info("Cloudflare configuration complete.")
|
|
28
|
+
return "Cloudflare configuration complete"
|
|
29
|
+
except Exception as e:
|
|
30
|
+
logging.error(f"Error during Cloudflare configuration: {e}")
|
|
31
|
+
return "Cloudflare configuration failed"
|