From 2b9cd053501ce81753dd79acde8f3052d5950476 Mon Sep 17 00:00:00 2001
From: Jan Grewe <jan@faked.org>
Date: Tue, 6 Jun 2023 15:58:57 +0200
Subject: [PATCH] minify/gzip HTML and JS (12KB -> 3KB)

---
 data_src/index.html | 11 ++++++++-
 data_src/styles.css |  8 -------
 gzip_data.py        | 58 ---------------------------------------------
 minify_data.py      | 58 +++++++++++++++++++++++++++++++++++++++++++++
 platformio.ini      |  2 +-
 5 files changed, 69 insertions(+), 68 deletions(-)
 delete mode 100644 data_src/styles.css
 delete mode 100644 gzip_data.py
 create mode 100644 minify_data.py

diff --git a/data_src/index.html b/data_src/index.html
index 39a8da5..f0604eb 100644
--- a/data_src/index.html
+++ b/data_src/index.html
@@ -7,7 +7,16 @@
   <title>Matrix of Life</title>
   <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"
     integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
-  <link href="styles.css" rel="stylesheet">
+  <style>
+    html {
+      width: 100%;
+      height: 100%;
+    }
+
+    #wsMessages {
+      font-size: 0.7rem;
+    }
+  </style>
 </head>
 
 <body class="w-100 h-100 d-flex align-items-center" data-bs-theme="dark">
diff --git a/data_src/styles.css b/data_src/styles.css
deleted file mode 100644
index d2502b5..0000000
--- a/data_src/styles.css
+++ /dev/null
@@ -1,8 +0,0 @@
-html {
-  width: 100%;
-  height: 100%;
-}
-
-#wsMessages {
-  font-size: 0.7rem;
-}
diff --git a/gzip_data.py b/gzip_data.py
deleted file mode 100644
index 97ff223..0000000
--- a/gzip_data.py
+++ /dev/null
@@ -1,58 +0,0 @@
-Import('env', 'projenv')
-
-import os
-import gzip
-import shutil
-import glob
-
-def prepare_www_files(source, target, env):
-    #WARNING -  this script will DELETE your 'data' dir and recreate an empty one to copy/gzip files from 'data_src'
-    #           so make sure to edit your files in 'data_src' folder as changes madt to files in 'data' woll be LOST
-    #           
-    #           If 'data_src' dir doesn't exist, and 'data' dir is found, the script will autimatically
-    #           rename 'data' to 'data_src
-
-
-    #add filetypes (extensions only) to be gzipped before uploading. Everything else will be copied directly
-    filetypes_to_gzip = ['html', 'js', 'css', 'ico']
-    
-    print('[COPY/GZIP DATA FILES]')
-
-    data_dir = env.get('PROJECT_DATA_DIR')
-    data_src_dir = os.path.join(env.get('PROJECT_DIR'), 'data_src')
-
-    if(os.path.exists(data_dir) and not os.path.exists(data_src_dir) ):
-        print('  "data" dir exists, "data_src" not found.')
-        print('  renaming "' + data_dir + '" to "' + data_src_dir + '"')
-        os.rename(data_dir, data_src_dir)
-
-    if(os.path.exists(data_dir)):
-        print('  Deleting data dir ' + data_dir)
-        shutil.rmtree(data_dir)
-
-    print('  Re-creating empty data dir ' + data_dir)
-    os.mkdir(data_dir)
-
-    files_to_gzip = []
-    for extension in filetypes_to_gzip:
-        files_to_gzip.extend(glob.glob(os.path.join(data_src_dir, '*.' + extension)))
-    
-    print('  files to gzip: ' + str(files_to_gzip))
-
-    all_files = glob.glob(os.path.join(data_src_dir, '*.*'))
-    files_to_copy = list(set(all_files) - set(files_to_gzip))
-
-    print('  files to copy: ' + str(files_to_copy))
-
-    for file in files_to_copy:
-        print('  Copying file: ' + file + ' to data dir')
-        shutil.copy(file, data_dir)
-    
-    for file in files_to_gzip:
-        print('  GZipping file: ' + file + ' to data dir')
-        with open(file, 'rb') as src, gzip.open(os.path.join(data_dir, os.path.basename(file) + '.gz'), 'wb') as dst:        
-            dst.writelines(src)
-
-    print('[/COPY/GZIP DATA FILES]')
-    
-env.AddPreAction('$BUILD_DIR/littlefs.bin', prepare_www_files)
diff --git a/minify_data.py b/minify_data.py
new file mode 100644
index 0000000..3077b26
--- /dev/null
+++ b/minify_data.py
@@ -0,0 +1,58 @@
+Import('env', 'projenv')
+
+import os
+import gzip
+import shutil
+
+try:
+    import minify_html
+except ImportError:
+    env.Execute("$PYTHONEXE -m pip install minify-html")
+
+try:
+    from jsmin import jsmin
+except ImportError:
+    env.Execute("$PYTHONEXE -m pip install jsmin")
+
+data_dir = env.get('PROJECT_DATA_DIR')
+data_src_dir = os.path.join(env.get('PROJECT_DIR'), 'data_src')
+
+
+def gzip_file(src, dst, delete_source = False):
+    with open(src, 'rb') as f_in, gzip.open(dst + '.gz', 'wb') as f_out:
+        f_out.writelines(f_in)
+    if delete_source:
+        os.remove(src)
+
+
+def minify_file(filename):
+    file_src = os.path.join(data_src_dir, filename)
+    file_dst = os.path.join(data_dir, filename)
+    with open(file_src , 'r', encoding="utf-8") as f_in:
+        if filename.split(".")[-1] == "html":
+            minified = minify_html.minify(f_in.read(), minify_js=True, do_not_minify_doctype=True, keep_html_and_head_opening_tags=True, minify_css=True, remove_processing_instructions=True)
+        elif filename.split(".")[-1] == "js":
+            minified = jsmin(f_in.read())
+    with open(file_dst, "w", encoding="utf-8") as f_out:
+        f_out.write(minified)
+    gzip_file(file_dst, file_dst, True)
+
+
+def minify_data(source, target, env):
+    if(os.path.exists(data_dir) and not os.path.exists(data_src_dir) ):
+        print('  "data" dir exists, "data_src" not found.')
+        print('  renaming "' + data_dir + '" to "' + data_src_dir + '"')
+        os.rename(data_dir, data_src_dir)
+
+    if(os.path.exists(data_dir)):
+        print('  Deleting data dir ' + data_dir)
+        shutil.rmtree(data_dir)
+
+    print('  Re-creating empty data dir ' + data_dir)
+    os.mkdir(data_dir)
+
+    minify_file('index.html')
+    minify_file('main.js')
+    gzip_file(os.path.join(data_src_dir, 'favicon.ico'), os.path.join(data_dir, 'favicon.ico'))
+
+env.AddPreAction('$BUILD_DIR/littlefs.bin', minify_data)
diff --git a/platformio.ini b/platformio.ini
index 628b5ea..f9b3cae 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -18,7 +18,7 @@ monitor_speed = 115200
 monitor_filters = esp32_exception_decoder
 board_build.filesystem = littlefs
 extra_scripts =
-    post:gzip_data.py
+    post:minify_data.py
 platform_packages = framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#2.0.9
 board_build.arduino.upstream_packages = no
 lib_deps = 
-- 
GitLab