-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathbuild.py
More file actions
executable file
·354 lines (309 loc) · 12.7 KB
/
build.py
File metadata and controls
executable file
·354 lines (309 loc) · 12.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
#!/usr/bin/python3
import os
import sys
import subprocess
import json
import time
from pathlib import Path
from datetime import datetime
# Set current directory as the working directory
GREGORY_DIR = os.getenv('GREGORY_DIR', os.getcwd())
WEBSITE_PATH = os.getenv('WEBSITE_PATH', 'public')
now = datetime.now()
datetime_string = now.strftime("%d-%m-%Y_%Hh%Mm%Ss")
# Optional imports with fallbacks
try:
from dotenv import load_dotenv
load_dotenv()
except ImportError:
print("Warning: python-dotenv not installed. Environment variables will not be loaded from .env file.")
# press kit variables
directory_name = 'gregory-ai-press-kit'
folder_id = '1KuEj8mERv5FcLfmJ1hP840GMrREoJpRc'
def check_dependencies(feature):
"""Check if dependencies for a specific feature are available."""
if feature == 'presskit':
try:
# Try to import local presskit module
import sys
sys.path.append(os.getcwd()) # Add current directory to path
import presskit
return True
except ImportError as e:
print(f"Warning: presskit module error: {e}")
print("Make sure 'gregoryai-41cd67dab7a5.json' credentials file exists.")
print("You may need to install required dependencies:")
print("pip install google-api-python-client google-auth")
return False
elif feature == 'metabase':
try:
import jwt
return True
except ImportError:
print("Warning: PyJWT not installed. Metabase embed generation will be skipped.")
print("Install with: pip install PyJWT")
return False
elif feature == 'git':
try:
import git
return True
except ImportError:
print("Warning: GitPython not installed. Using subprocess for git operations.")
return False
return False
def install_dependencies(feature):
"""Attempt to install missing dependencies for a specific feature."""
try:
if feature == 'presskit':
print("Attempting to install Google API dependencies...")
subprocess.check_call([sys.executable, "-m", "pip", "install",
"google-api-python-client", "google-auth"])
return True
elif feature == 'metabase':
print("Attempting to install PyJWT...")
subprocess.check_call([sys.executable, "-m", "pip", "install", "PyJWT"])
return True
elif feature == 'git':
print("Attempting to install GitPython...")
subprocess.check_call([sys.executable, "-m", "pip", "install", "GitPython"])
return True
return False
except subprocess.CalledProcessError as e:
print(f"Failed to install dependencies: {e}")
return False
def pull_from_github():
print('''
####
## PULL FROM GITHUB
####
''')
# Try to use GitPython if available, or install it if possible
if not check_dependencies('git'):
if '--auto-install' in sys.argv:
print("Missing git dependencies. Attempting to install...")
install_dependencies('git')
if check_dependencies('git'):
import git
os.chdir(GREGORY_DIR)
g = git.cmd.Git(GREGORY_DIR)
output = g.pull()
print(output)
else:
# Fallback to using subprocess
subprocess.run(["git", "pull"])
def delete_temporary_files():
print('\n# delete temporary files')
for name in ['articles', 'trials']:
for ext in ['.xlsx', '.json', '.csv']:
file = Path(f'content/developers/{name}_{datetime_string}{ext}')
if file.exists():
file.unlink()
def process_presskit():
print('''
####
## PROCESS PRESS KIT
####
''')
# Check for dependencies and attempt to install if missing
if not check_dependencies('presskit'):
print("Missing presskit dependencies. Attempting to install...")
if not install_dependencies('presskit'):
print("Could not install presskit dependencies. Skipping presskit processing.")
return
# Check again after attempting to install
if not check_dependencies('presskit'):
print("Skipping presskit processing due to missing dependencies.")
return
try:
# Ensure we're importing the local presskit module
import sys
sys.path.append(os.getcwd()) # Add current directory to path
import presskit
print("Processing presskit files...")
presskit.setup_dir(directory_name)
presskit.process_folder(folder_id, directory_name)
presskit.create_zip_from_folder(directory_name, 'content/gregoryai_press.zip')
print("Presskit processing completed successfully.")
except Exception as e:
print(f"Error processing presskit: {e}")
print("Check if the Google Drive credentials file exists and is valid.")
def get_hugo_version():
"""Get the Hugo version to use from environment or arguments."""
# Check command-line arguments first
for arg in sys.argv:
if arg.startswith('--hugo-version='):
version = arg.split('=')[1]
print(f"Using Hugo version: {version}")
return version
# Check environment variable
hugo_version = os.environ.get('HUGO_VERSION', 'latest')
if hugo_version != 'latest':
print(f"Using Hugo version from HUGO_VERSION: {hugo_version}")
return hugo_version
def check_docker():
"""Check if Docker is available in the system."""
try:
result = subprocess.run(["docker", "--version"], capture_output=True, text=True)
if result.returncode == 0:
print(f"Using Docker: {result.stdout.strip()}")
return True
else:
print("Docker is not running or accessible.")
return False
except FileNotFoundError:
print("Docker is not installed or not in PATH.")
print("Please install Docker to use this script: https://docs.docker.com/get-docker/")
return False
def check_output_directory():
"""Check if the output directory is accessible and writable."""
website_path = os.environ.get("WEBSITE_PATH", "/var/www/gregory-ms.com")
try:
# Create the directory if it doesn't exist
os.makedirs(website_path, exist_ok=True)
# Check if we can write to it
test_file = Path(website_path) / ".write_test"
test_file.touch()
test_file.unlink()
return True
except (PermissionError, OSError) as e:
print(f"Warning: Output directory {website_path} is not writable: {e}")
print("You may need to run this script with sudo or change WEBSITE_PATH to a writable location.")
print("Example: WEBSITE_PATH=./public python build.py --build")
return False
def build_website():
print('''
####
## RUN HUGO BUILD USING DOCKER
####
''')
if not check_docker():
sys.exit(1)
if not check_output_directory():
sys.exit(1)
# Get the target website path - default to /var/www/gregory-ms.com/ if not specified
website_path = os.environ.get("WEBSITE_PATH", "/var/www/gregory-ms.com")
current_dir = os.getcwd()
# Check if output directory exists on host, create if it doesn't
host_website_path = Path(website_path)
if not host_website_path.exists():
print(f"Output directory {website_path} does not exist. Creating it...")
try:
os.makedirs(website_path, exist_ok=True)
print(f"Created output directory: {website_path}")
except PermissionError:
print(f"Error: No permission to create directory {website_path}")
print("You may need to run this script with sudo or create the directory manually.")
return
# Get user and group info for file ownership
try:
import pwd
import grp
uid = pwd.getpwnam('gregory').pw_uid
gid = grp.getgrnam('www-data').gr_gid
user_opts = ["--user", f"{uid}:{gid}"]
except (KeyError, ImportError):
print("Warning: Could not determine UID/GID for gregory:www-data. Files may be owned by root.")
print("Ensure user 'gregory' and group 'www-data' exist on the host system.")
user_opts = []
# Get Hugo version to use
hugo_version = get_hugo_version()
hugo_image = f"hugomods/hugo:{hugo_version}"
# Use Docker to run Hugo with proper environment variables and volume mounts
docker_command = [
"docker", "run", "--rm",
*user_opts,
"-v", f"{current_dir}:/src", # Mount source code
"-v", f"{website_path}:/output", # Mount output directory
"-e", "NODE_ENV=production", # Ensure production mode for JS builds
hugo_image,
"hugo", "-d", "/output", "--gc", "--minify" # Output to mounted volume
]
print(f"Building website to host directory: {website_path}")
# Run the Docker command
result = subprocess.run(docker_command)
if result.returncode == 0:
print(f"Website built successfully in {website_path} directory")
else:
print(f"Error building website. Check Docker output for details.")
print("If permission errors occur, ensure you have write access to the output directory.")
def serve_website():
print('''
####
## RUN HUGO SERVER USING DOCKER
####
''')
if not check_docker():
sys.exit(1)
current_dir = os.getcwd()
# Get Hugo version to use
hugo_version = get_hugo_version()
hugo_image = f"hugomods/hugo:{hugo_version}"
# Use Docker to run Hugo server with proper flags for interactive use
docker_command = [
"docker", "run", "--rm", "-it",
"-p", "1313:1313",
"-v", f"{current_dir}:/src",
hugo_image,
"hugo", "server", "--bind", "0.0.0.0"
]
print("Starting Hugo server using Docker...")
print("Access the site at http://localhost:1313/")
print("Press Ctrl+C to stop the server.")
# Run the Docker command (this will block until Ctrl+C)
try:
subprocess.run(docker_command)
except KeyboardInterrupt:
print("\nHugo server stopped")
def show_help():
print('''
Gregory MS Website Build Script
===============================
Usage:
python build.py [options]
Options:
--build Build the website using Docker (production mode)
--server Start Hugo server using Docker (development mode)
--fast Pull from GitHub and build the website (skip presskit processing)
--auto-install Automatically install missing Python dependencies
--hugo-version=<ver> Specify Hugo version to use (e.g., latest, 0.121.0, exts-0.121.0)
--output=<path> Set the output directory for the built website
--help Show this help message
Environment Variables:
WEBSITE_PATH Set the output directory for the built website
Default: /var/www/gregory-ms.com
HUGO_VERSION Set the Hugo version to use (e.g., latest, 0.121.0, exts-0.121.0)
Default: latest
Description:
This script builds the Gregory MS website using Docker to run Hugo.
It also processes press kit materials and generates metabase embeds.
The built website will be output to the host directory specified by
WEBSITE_PATH environment variable (/var/www/gregory-ms.com by default).
For full functionality, install required dependencies:
pip install python-dotenv GitPython PyJWT google-api-python-client google-auth
Make sure the Google Drive credentials file 'gregoryai-41cd67dab7a5.json' exists in the project root.
''')
if __name__ == '__main__':
# Check for output directory in arguments (format: --output=/path/to/dir)
for arg in sys.argv:
if arg.startswith('--output='):
output_path = arg.split('=')[1]
os.environ['WEBSITE_PATH'] = output_path
print(f"Setting output directory to: {output_path}")
if '--help' in sys.argv or len(sys.argv) == 1:
# If --help is passed or no arguments provided, show the help message
show_help()
if len(sys.argv) == 1:
print("\nNo option specified. Use --build to build the website or --server to start the development server.")
elif '--server' in sys.argv:
# If --server is passed, run the Hugo server using Docker
serve_website()
elif '--build' in sys.argv or '--fast' in sys.argv:
# If --build or --fast is passed as a command-line argument, pull and build
# Check if output directory is writable
check_output_directory()
pull_from_github()
if '--fast' not in sys.argv:
# Only run these if not in fast mode
process_presskit()
delete_temporary_files()
build_website()