import sys
import os
import shutil
import subprocess
class SiteCompressor:
"""
Compresses a static web site generated by Sphinx by:
(1) Merging all _static directories into a single _static directory at the
top level.
(2) Using gzip to compress the file types below, adding a .gz suffix to
the filename.
"""
gzip_extensions = ['.html', '.css', '.js', '.woff', '.svg']
image_extensions = ['.png', '.pdf', '.svg',]
def __init__(self, site):
if not os.path.isdir(site):
raise RuntimeError(
'A Brotlifier must be instantiated with a directory')
self.site = os.path.abspath(site)
def merge_static_dirs(self):
static_dirs = []
for dirpath, dirnames, filenames in os.walk(self.site):
if dirpath.endswith('_static') and not os.path.islink(dirpath):
static_dirs.append(dirpath)
main_static_dir = os.path.join(self.site, '_static')
try:
static_dirs.remove(main_static_dir)
except ValueError:
pass
for dirpath in static_dirs:
shutil.copytree(dirpath, main_static_dir, symlinks=True,
dirs_exist_ok=True)
relpath = os.path.relpath(main_static_dir, os.path.dirname(dirpath))
shutil.rmtree(dirpath)
os.symlink(relpath, dirpath)
def clean_images(self):
"""All images should be in _static or _images."""
to_delete = []
for dirpath, dirnames, filenames in os.walk(self.site):
if dirpath.find('_static') >= 0 or dirpath.find('_images') >= 0:
continue
for filename in filenames:
base, ext = os.path.splitext(filename)
if ext in self.image_extensions:
print('deleting', os.path.join(dirpath, filename))
to_delete.append(os.path.join(dirpath, filename))
for path in to_delete:
os.unlink(path)
def compress_files(self):
"""Compress compressible files."""
compressible = []
for dirpath, dirnames, filenames in os.walk(self.site):
for filename in filenames:
base, ext = os.path.splitext(filename)
if ext in self.gzip_extensions:
compressible.append(os.path.join(dirpath, filename))
for path in compressible:
subprocess.run(['gzip', '--best', path])
if __name__ == '__main__':
try:
site = sys.argv[1]
except IndexError:
print('Please provide the site root directory as an argument.')
sys.exit(1)
if not os.path.isdir(site):
print('The site root must be a directory.')
sys.exit(1)
compressor = SiteCompressor(site)
print('Merging _static directories ..')
compressor.merge_static_dirs()
print("Deleting extraneous images ...")
compressor.clean_images()
print('Compressing files ...')
compressor.compress_files()