import os import shutil import minify_html from rjsmin import jsmin class Minify: def __init__(self, work_dir, raw_directory, min_directory): self.work_dir = work_dir self.raw_directory = raw_directory self.min_directory = min_directory self._bytes_saved = { 'html': 0, 'js': 0, 'css': 0 } print(f"Working directory: {self.work_dir}") print(f"Source directory: {self.raw_directory}") print(f"Data directory: {self.min_directory}") def run(self): print("--- Running minifier ---") self._copy_source() minify_files = self._find_minify_candidates(self.min_directory) for file in minify_files: self._minify(file) print("---") def show_stats(self, key=None): if key is not None: print(f"Saved {self._bytes_saved[key]} bytes by minifying `.{key}` files") else: total = 0 for key in self._bytes_saved: print(f"Saved {self._bytes_saved[key]} bytes by minifying `.{key}` files") total = total + self._bytes_saved[key] print(f"Total {total} bytes saved") def _find_minify_candidates(self, folder): minify_candidates = [] for root, dirs, files in os.walk(folder): for file in files: if file.lower().endswith(('.htm', '.html', '.js', '.css')): minify_candidates.append(os.path.join(root, file)) return minify_candidates def _update_saved_count(self, category, amount): self._bytes_saved[category] = self._bytes_saved[category] + amount def _minify(self, file): if file.lower().endswith(('.html', '.htm')): content = self._read_file(file) content_minified = self._min_html(content) print(f" -> Minified {file} [saved {len(content)-len(content_minified)} bytes]") self._write_file(file, content_minified) elif file.lower().endswith('.js'): content = self._read_file(file) content_minified = self._min_js(content) self._write_file(file, content_minified) print(f" -> Minified {file} [saved {len(content)-len(content_minified)} bytes]") else: print(f" -> No minifier available for file {file}") def _min_html(self, content): size_pre = len(content) content = minify_html.minify(content, minify_js=True, remove_processing_instructions=True) size_after = len(content) self._update_saved_count('html', size_pre-size_after) return content def _min_js(self, content): size_pre = len(content) content = jsmin(content) size_after = len(content) self._update_saved_count('js', size_pre-size_after) return content def _copy_source(self): shutil.copytree(self.raw_directory, self.min_directory, dirs_exist_ok=True) def _read_file(self, file): with open(file, mode="r", encoding="utf-8") as f: content = f.read() return content def _write_file(self, file, content): with open(file, mode="w", encoding="utf-8") as f: f.write(content) def _list_dir(self, filetype): filtered = [] files = os.listdir(self.min_directory) for file in files: if file.endswith(f'.{filetype}'): filepath = os.path.join(self.min_directory, file) filtered.append(filepath) return filtered def minify(source, target, env): # work_dir = os.path.dirname(os.path.abspath(__file__)) work_dir = os.getcwd() raw_directory = os.path.join(work_dir, 'data_pre') min_directory = os.path.join(work_dir, 'data') print("-- Removing previous data directory") shutil.rmtree(min_directory, ignore_errors=True) print("-- Running data minify script") mc = Minify(work_dir, raw_directory, min_directory) mc.run() mc.show_stats() Import("env") minify(None, None, None)