Files
Kobelly/build_assets.py

143 lines
4.7 KiB
Python

#!/usr/bin/env python3
"""
Asset build script for Kobelly Web Solutions
Handles CSS and JS minification with cache busting
"""
import os
import hashlib
import shutil
from datetime import datetime
from cssmin import cssmin
from jsmin import jsmin
def get_file_hash(filepath):
"""Generate MD5 hash of file content for cache busting"""
with open(filepath, 'rb') as f:
return hashlib.md5(f.read()).hexdigest()[:8]
def minify_css(input_file, output_file):
"""Minify CSS file"""
try:
with open(input_file, 'r', encoding='utf-8') as f:
css_content = f.read()
minified_css = cssmin(css_content)
with open(output_file, 'w', encoding='utf-8') as f:
f.write(minified_css)
print(f"✓ CSS minified: {input_file}{output_file}")
return True
except Exception as e:
print(f"✗ Error minifying CSS {input_file}: {e}")
return False
def minify_js(input_file, output_file):
"""Minify JavaScript file"""
try:
with open(input_file, 'r', encoding='utf-8') as f:
js_content = f.read()
minified_js = jsmin(js_content)
with open(output_file, 'w', encoding='utf-8') as f:
f.write(minified_js)
print(f"✓ JS minified: {input_file}{output_file}")
return True
except Exception as e:
print(f"✗ Error minifying JS {input_file}: {e}")
return False
def create_cache_busted_assets():
"""Create cache-busted versions of assets"""
static_dir = 'static'
css_dir = os.path.join(static_dir, 'css')
js_dir = os.path.join(static_dir, 'js')
# Ensure directories exist
os.makedirs(css_dir, exist_ok=True)
os.makedirs(js_dir, exist_ok=True)
# CSS files
css_files = [
('main.css', 'main.min.css')
]
# JS files
js_files = [
('main.js', 'main.min.js')
]
print("🔨 Building assets...")
print(f"📅 Build time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print()
# Process CSS files
for input_file, output_file in css_files:
input_path = os.path.join(css_dir, input_file)
output_path = os.path.join(css_dir, output_file)
if os.path.exists(input_path):
if minify_css(input_path, output_path):
# Generate cache-busted filename
file_hash = get_file_hash(output_path)
cache_busted_name = f"main.{file_hash}.min.css"
cache_busted_path = os.path.join(css_dir, cache_busted_name)
# Copy minified file to cache-busted version
shutil.copy2(output_path, cache_busted_path)
print(f"✓ Cache-busted CSS created: {cache_busted_name}")
else:
print(f"⚠️ CSS file not found: {input_path}")
print()
# Process JS files
for input_file, output_file in js_files:
input_path = os.path.join(js_dir, input_file)
output_path = os.path.join(js_dir, output_file)
if os.path.exists(input_path):
if minify_js(input_path, output_path):
# Generate cache-busted filename
file_hash = get_file_hash(output_path)
cache_busted_name = f"main.{file_hash}.min.js"
cache_busted_path = os.path.join(js_dir, cache_busted_name)
# Copy minified file to cache-busted version
shutil.copy2(output_path, cache_busted_path)
print(f"✓ Cache-busted JS created: {cache_busted_name}")
else:
print(f"⚠️ JS file not found: {input_path}")
print()
print("🎉 Asset build completed!")
def clean_old_assets():
"""Clean old cache-busted assets"""
static_dir = 'static'
css_dir = os.path.join(static_dir, 'css')
js_dir = os.path.join(static_dir, 'js')
# Remove old cache-busted files
for directory in [css_dir, js_dir]:
if os.path.exists(directory):
for filename in os.listdir(directory):
if filename.startswith('main.') and filename.endswith('.min.css') or filename.endswith('.min.js'):
if not filename in ['main.min.css', 'main.min.js']: # Keep the base minified files
filepath = os.path.join(directory, filename)
os.remove(filepath)
print(f"🗑️ Removed old asset: {filename}")
if __name__ == '__main__':
import sys
if len(sys.argv) > 1 and sys.argv[1] == 'clean':
print("🧹 Cleaning old assets...")
clean_old_assets()
print("✓ Cleanup completed!")
else:
clean_old_assets()
create_cache_busted_assets()